May 2014

Volume 29 Number 5

The Working Programmer : Growl Notification System: Simpler Is Better

Ted Neward | May 2014

Ted NewardIn all the histrionics that get stirred up around UI and UX, you often lose sight of the fact that sometimes the best UI isn’t the fanciest, most dazzling display of HTML/CSS/JavaScript or mind-blowing animations, but a simple message tucked away in the corner. A lot of what happens, particularly with enterprise systems, are “headless” kinds of operations with no UI.

You still need ways to reach out to the user, though, and ask him to perform actions. You could build a simple little UI utility to give you that, or you could leverage somebody else’s utility that’s already built and debugged and likely has a lot more features than you’d include.

Growl Basics

Growl (available for download for Windows at growlforwindows.com) is the Windows port of the Mac utility of the same name and is billed as the “Ultimate Notification System.” Fundamentally, it isn’t difficult to understand. It resides on your machine, hiding out in the notification tray in the lower-right corner of your Windows desktop view, and listens for notifications.

When a message comes through, it pops up a small message box to alert the user. Then you can send these messages across the network as encrypted or password-protected, to avoid having network sniffers watch the traffic. Fundamentally, though, it’s about providing the user with notification messages, a la the “toaster” messages you used to see back when instant messaging was hot and MSN Messenger was a thing. That’s it, for the most part.

Keep in mind not all developer utilities and solutions have to be these large, grand-scale architectural marvels. In fact, sometimes the most elegant solution to a problem is often a small, singularly focused component that follows the Keep it simple, stupid (KISS) principle. Growl does one thing and does it well: It lets you notify a user (or multiple users, if you start thinking about stretching this across the network) of something happening that would otherwise get past him.

When I first introduced Growl, for example, it was as part of the Oak build system. This was essentially a “continuous build” system. Any time a source file was modified, it would trigger a rebuild of the project. The problem, of course, is if the rebuild isn’t something being kicked off by the developer front-and-center staring at Visual Studio, how would the developer know about build problems? The build system sends a notification to Growl, and it surreptitiously displays the build results to the user, tucked away in the corner where it won’t demand attention or get in the way of whatever he’s doing.

Growling It doesn’t take much to think of other situations where this functionality can be useful, both inside and outside a developer-­minded context. To developers, this can be useful when long-running tasks (such as builds, data loads, ETL processes and so on) are executing in the background, giving you a heads-up when they’re finished. To systems administrators, this can be incredibly useful for critical-error conditions that require near-immediate human intervention but don’t warrant terminating operations completely.

For the user, this can be a useful tool for a whole slew of things, including a kind of “push notification” system for applications inside the corporate network, such as when particular data records the user cares about (ones he’s currently working on, for example) are being updated, or when events occur within the system (startup, shutdown, system-wide user messages, whatever) need to be pushed in front of the user’s eyes. Even networked games could use it, to tell a player when it’s his turn.

Growl also lets you “forward” messages to other computers. If a message destined to reach your eyes doesn’t find you because you’re on lunch, you can configure Growl to send that message to your phone, tablet or group of other computers. You could also have it send an e-mail message or tweet (publicly or direct message) to an account. A user can configure Growl to play sounds (or not) on a per-registered-application basis, set the priority of those notifications on a per-registered-application basis and so on.

Growl may not be much, but it’s a pretty useful “not very much” kind of tool. Programming to it is ridiculously simple. Once you’ve installed Growl, you can send Growl notifications (from batch files or Windows PowerShell scripts, for example) using the command-line “growlnotify” tool installed in the Growl for Windows folder. Kick one off using the following at the command line (assuming C:\Program Files\Growl for Windows, the default Growl installation directory, is on your PATH):

growlnotify "This is a test message"

Assuming Growl was installed successfully, it will respond at the command line with “Notification sent successfully.” A little blue message window will pop up in the corner of your desktop. Open the Growl icon in the system notification tray to examine the configuration options, including the ability to forward messages on to other machines, and use the “/?” command-line parameter to explore how to send Growl notifications across the network. Experiment with some of these options before reading further, because the options seen here pretty much directly reflect the APIs available when writing code to use Growl notifications.

The Growl SDK

The Growl SDK is a thin layer over the Growl Network Transport Protocol (GNTP), a TCP/IP wire protocol strongly reminiscent of HTTP. Given that Growl has been around for a while, it’s not surprising there are several libraries built to abstract the details of that protocol. These are collectively referred to as “Growl Connect” libraries.

The same Web site (growlforwindows.com) from which you get the Growl-for-Windows bits also has links to the Microsoft .NET Framework libraries for Growl, as well as links for C++, COM and even SQL Server-to-Growl libraries. (Think about that last one for a moment. It’s a package to let you use SQL Server scripts to reach out and send a notification to interested parties, such as DBAs.)

Once the Growl .NET libraries are pulled down, open the .zip file. It contains a sample C# app and a sample Visual Basic .NET app, but what you want specifically are the two .NET assemblies in the “libraries” folder: Growl.CoreLibrary.dll and Growl.Connector.dll. (These are also installed as part of Growl in the Growl home directory, if the SDK download gets lost somewhere.) In any .NET project, simply reference these two as library assemblies, and things are good to go.

Connecting and Registering A Growl client needs to register with Growl before it can send notifications—Growl will ignore any notifications it receives from unregistered applications. Fortunately, not only is this a one-time-only step, but the SDK makes it pretty trivial. Just create a GrowlConnector object (including target hostname and port if reaching out to a remote machine, if desired), and then include some simple information about the application being registered:

var connector = new GrowlConnector();
var thisApp = new Application("GrowlCL");
thisApp.Icon = @".\app.png";

The icon can be a filename, URL or array of bytes. (Both of these classes, by the way, come from the GrowlConnector namespace.)

Growl thinks of notifications as grouped by type. A Web browser might send “file download started” notifications, “file download completed” notifications and so on. A game might send “new game offered,” “player resigned,” “your turn,” “other player turn completed” and other similar kinds of notifications. Growl wants applications to register these notification types so the user can configure how each kind of notification will be handled. A new Growl client needs to define its notification types and then pass them to the GrowlConnector.Register method to complete registration:

// Two kinds of messages: insults and compliments
var insultType = new NotificationType("INSULT", "SICK BURN!");
var compType = new NotificationType("COMPLIMENT", "Nice message");
connector.Register(thisApp, new NotificationType[] { insultType, compType });

The first parameter is the string that your code will use to indicate the type of notification. The second is the string that will be displayed in the user’s Growl app when viewed. Like the Application object, NotificationType also has an Icon property. This allows for different icons to be displayed along with the text of the message on a per-notification-type basis. It isn’t necessary, but certainly helps the final product look more polished.

Note that if the preceding code is run, Growl will pop up a message saying, “GrowlCL has registered” if this is the first time this app has communicated with the Growl app on this machine.

Notify Once the app and its notification types are registered with Growl, it’s a pretty simple matter to send a notification. Just create a Notification object, passing in the app name, the notification type string, an optional identifier to uniquely identify this notification (why you might want that I’ll get to in just a moment), and the title and body of the message to send, and then send the Notification object off to Growl using the Notify method:

var notification = new Notification("GrowlCL", "INSULT", null, 
  "YO MAMA!",  "Your mama is so fat, she dropped an apple " + 
  "and it entered orbit around her.");
connector.Notify(notification);

When the Growl app receives the message, it’ll pop up in the lower corner (by default) of the screen.

Yeah, it really is that easy.

Can You Read Me Now? Sometimes you like to know what the user did with the notification. Did she just close it without looking, or did she actually read the message? This can actually be quite important in call centers, where supervisors need to know if employees are in fact reading the daily up-sell special offers, as required.

Growl permits this by registering callbacks, which can either be .NET event handler methods or WebHooks—URLs to which Growl will POST an HTTP request containing data such as the aforementioned ID parameter of the notification sent. In the event the Growl Connector library can’t reach the targeted Growl instance, it’ll issue an error, but only if the client code has registered an event handler (ErrorResponse) on the GrowlConnector object.

The event handler method will receive an error code and a description of the error that looks almost identical to HTTP error codes and descriptions, making them pretty self-explanatory. The Growl Connector docs (the “Growl for Windows Application Inte­gration Guide” in the downloaded SDK .zip) has a table listing all of these errors, but they’re all pretty straightforward (“200 - TIMED OUT,” “201 - NETWORK FAILURE” and so on).

Just That Easy

Growl isn’t going to win any awards for “most complex architecture.” If it can be described almost completely in a single magazine article, then it’s definitely a pretty simple, straightforward, low surface-­area kind of tool. That, in a nutshell, is probably its greatest strength. Quite frankly, it’s the best compliment any technologist can bestow on a library or tool—it’s just that easy to use. Happy coding!


Ted Neward is the CTO at iTrellis, a consulting services company. He has written more than 100 articles and authored and coauthored a dozen books, including “Professional F# 2.0” (Wrox, 2010). He’s a C# MVP and speaks at conferences around the world. He consults and mentors regularly—reach him at ted@tedneward.com or ted@itrellis.com if you’re interested in having him come work with your team, and read his blog at blogs.tedneward.com.

Thanks to the following technical expert for reviewing this article: Brian Dunnington (independent consultant)