Growl for Windows Application Integration Guide Table of Contents Overview Getting Started Registering Your Application Sending Notifications Callbacks Custom Attributes Authorization & Encryption Network Notifications Errors Best Practices Full Sample Code Overview The GrowlConnector libraries make it easy to send Growl notifications from your application. You can send notifications to the local machine, or send notifications to a Growl instance over the network or internet. Because Growl for Windows uses the standard GNTP protocol, you can even send notifications to instances of Growl running on Mac computers or any device that understands GNTP. Getting Started The first step in enabling your application to send Growl notifications is to download the appropriate GrowlConnector libraries for the programming language you use. At this time, the following libraries are available: C# (for all .NET languages, including VB.NET, VC++.NET, and ASP.NET) Javascript ActionScript (for Flash, Flex, and AIR) COM-compatible (for C++, VB, and other COM-compatible languages) Additional libraries are under development for other languages as well. Since Growl for Windows uses the GNTP protocol, any GNTP-compatible library can be used (maybe link to Growl/OSX site with other bindings?) The details for including/referencing the libraries will vary by language, but each library includes specific instructions on how to get started. The actual usage of the various libraries is standardized though, and this guide is a general purpose guide on how to use the libraries, using the .NET library as an example. To use the GrowlConnector libraries in .NET, two files are required: Growl.CoreLibrary.dll Growl.Connector.dll Add references to these two assemblies in your project. The main class you will be using is Growl.Connector.GrowlConnector, which is responsible for registering your application, sending notifications, and handling callbacks. Registering Your Application In order to send notifications to Growl, you must first register your application. If you do not register your application, your notifications will be discarded by Growl. The first step is to create an instance of the GrowlConnector class: GrowlConnector growl = new GrowlConnector(); This same instance can be used to register your application as well as send notifications, so it is best to create it with the appropriate scope instead of constantly recreating it. If you need to specify a password, you can set it in an overloaded constructor, or set it via the .Password property later. If you are sending notifications over the network to a remote Growl instance, you can set the hostname and port in the constructor as well (see the Network Notifications section below). In order to register, you must include information about your application, as well as about the types of notifications you intend to send. To create your Application object: Application application = new Application("YOUR_APP_NAME"); application.Icon = @"c:\image.png"; The value for application.Icon can be a file path, a URL, or an array of bytes representing the raw binary data. For each type of notification your application intends to send, you should create a NotificationType object: NotificationType downloadComplete = new NotificationType("COMPLETE", "Download Complete"); NotificationType filePublished = new NotificationType("PUBLISHED", "File Published"); The first parameter is used to identify the notification type when sending notifications. The second parameter is the name of the notification type that is displayed to the user in their Growl client. You can also set a default icon for each notification type if you want by setting the Icon property of each NotificationType object. Individual notifications that don’t supply their own icon will fall back to using the default icon for their type, or the application’s icon if neither is set. If your notifications of a certain type always use the same icon, it is easier to set it here for the NotificationType as a whole and not have to resend it with each individual notification. Now that you have declared your application and notification types, you need to register with Growl: growl.Register(application, new NotificationType[] { downloadComplete, filePublished }); Now that your application has registered, you can send notifications at any time. You only need to register once, but since Growl may not always be running the first time your application runs, it is good practice to re-register each time your application starts up. Reregistering your application if it is already registered does not hurt anything. If you ever decide you want to send more/less/different notification types, you must reregister all intended notification types. Sending Notifications To send a notification, the first step is to create a Notification object: Notification notification = new Notification("YOUR_APP_NAME", "NOTIFICATION_NAME", "ID", "File download is complete", "The file 'test.txt' was successfully downloaded to 'c:\temp'"); The value for “YOUR_APP_NAME” should match the value you used when you registered, and the value of “NOTIFICATION_NAME” should match the name of one of the NotificationTypes you registered as well. The “ID” parameter can optionally be left null or empty and is an application-specific value that you can use to identify notifications during callback (see the Callbacks section for more information). You can also optionally set values for the Icon, Priority, and other properties. To send the notification: growl.Notify(notification); When the Growl server receives your request, the notification will be handled as per the user’s prefences. NOTE: Any values sent to Growl (including the notification title, text, callback data, etc) must *not* contain any carriage return/line feed character sequences (\r\n). This sequence is used as the end-of-line delimiter in the GNTP protocol. If you want to send a line break as part of your value, you should use a single newline character (\n). Callbacks When you send a notification to Growl, it is not just a one-way operation. Growl can report back to your application based on the user’s actions (clicked the notification, closed the notification, etc). Using callbacks requires two steps: registering an event handler to handle the callback event and specifying your callback parameters when sending your notification. To register a callback event handler: growl.NotificationCallback +=new GrowlConnector.CallbackEventHandler(growl_NotificationCallback); The handler needs to be registered before you send notifications. To specify that you want to receive a callback, use an overloaded version of the Notify method: CallbackContext context = new CallbackContext(); context.Data = "ANY_DATA_YOU_WANT_RETURNED"; context.Type = "string"; growl.Notify(notification, context); The Data and Type specified in the CallbackContext will be returned in the callback event. The data can be anything appropriate for your application, including strings, numbers, serialized data, or anything else. The Type does not need to be of a recognized language type – it can be any value that has meaning to your application. If you send a notification with callback information, Growl will respond when your notification is clicked on by the user or closed (either explicitly by the user or automatically due to lack of user interaction). In the growl_NotificationCallback event handler that was registered earlier: void growl_NotificationCallback(Response response, CallbackData callbackContext) { string s = String.Format("CALLBACK RECEIVED: {0} - {1} {2} - {3}", callbackContext.NotificationID, callbackContext.Data, callbackContext.Type, callbackContext.Result); Console.WriteLine(s); } Callbacks work by keeping a socket connection open between your application and Growl for the lifetime of the notification. Alternatively, you can specify a URL as the target of your callback. Specifying a URL callback is similar to a regular callback, with a little bit more information: CallbackContext context = new CallbackContext(); context.Data = "ANY_DATA_YOU_WANT_RETURNED"; context.Type = "string"; UrlCallbackTarget target = new UrlCallbackTarget(); target.Method = "POST"; target.Url = "http://www.website.com/callback.cgi"; context.SetUrlCallbackTarget(target); growl.Notify(notification, context); When using a URL callback, a socket connection is not kept open, and the NotificationCallback event is not raised. The URL target can use GET or POST and the data sent looks like: "notification-id={0}&notification-callbackaction={1}&notification-callback-context={2}&notificationcallback-context-type={3}" Whether using regular callbacks or URL callbacks, you can use the Notification-ID to identify which notification is making the callback (which makes it a good idea to use unique values when creating your Notification objects). Custom Attributes In addition to the defined properties that are sent in a GNTP request, you can also include additional custom properties. Consider a music player that wants to send additional track information such as artist, album, genre, duration, and rating – these are properties specific to the sending application and thus not part of the defined notification spec, but could be useful information to display nonetheless. Custom attributes come in two flavors: text and binary. To add either type: notification.CustomTextAttributes.Add("Rating", "5 Stars"); notification.CustomTextAttributes.Add("Genre", "Alternative"); notification.CustomBinaryAttributes.Add("Sound", new BinaryData(new byte[] { ...bytes... })); Custom attributes can be attached to an Application, NotificationType, or Notification and are inherited down the chain. Any custom attributes are passed to the display that handles the notification. While most generic displays will not recognize these custom values and ignore them, a custom display could be written that can take advantage of the extended information. Some displays and Growl servers may also return additional custom attributes in their responses. You can access these custom attributes via the Response object that is returned in the NotificationCallback event. Authorization & Encryption TODO Network Notifications Usually, your application will want to send notifications to the Growl instance running on the same machine. However, if you have a web server or remote machine that you would like to send notification from but don’t have a local Growl instance on that machine to receive them, you can send notifications across the network. When creating your GrowlConnector instance, you must specify the hostname and port you would like to send to: GrowlConnector growl = new GrowlConnector("password", "hostname", port); Note that you must also specify the server password – all network notifications require that the password be provided. The default port that GNTP uses is 23053, but you may specify a different value if required. Other than specifying the hostname and port, sending notifications over the network works exactly the same as sending notifications locally, including callbacks. Errors If the GrowlConnector cannot connect to Growl or the Growl server returns an error response for another reason, the GrowlConnector.ErrorResponse event will be raised. To handle this event, simply add an event handler when creating your GrowlConnector instance: growl.ErrorResponse += new GrowlConnector.ResponseEventHandler(growl_ErrorResponse); Then in the growl_ErrorResponse event handler: void growl_ErrorResponse(Response response) { string s = String.Format("Error - {0} : {1}", response.ErrorCode, response.ErrorDescription); Console.WriteLine(s); } A complete list of error codes is presented below: 100 – [reserved] 200 - TIMED_OUT The server timed out waiting for the request to complete 201 – NETWORK_FAILURE The server was unavailable or the client could not reach the server for any reason 300 - INVALID_REQUEST The request contained an unsupported directive, invalid headers or values, or was otherwise malformed 301 - UNKNOWN_PROTOCOL The request was not a GNTP message 302 - UNKNOWN_PROTOCOL_VERSION The request specified an unknown or unsupported GNTP version 303 - REQUIRED_HEADER_MISSING The request was missing required information 400 – NOT_AUTHORIZED The request supplied a missing or wrong password/key or was otherwise not authorized 401 – UNKNOWN_APPLICATION Application is not registered to send notifications 402 – UNKNOWN_NOTIFICATION Notification type is not registered by the application 500 – INTERNAL_SERVER_ERRIR An internal server error occurred while processing the request Best Practices Create your GrowlConnector object with the appropriate scope so you can reuse it Set the default Icon for each NotificationType Assign unique IDs to your Notifications Register your application each time your application starts up Refrain from using \r\n in your values; use \n instead Full Sample Code TODO