Welcome! This guide will tell you all you need to know about integrating support for Snarl into your application, and more besides.
There are two ways to talk to Snarl:
Talking to Snarl natively is pretty straightforward, but you have to do a bit of extra work, and you really need to understand the request structure and Snarl's concept of transports. The best way, therefore, is to use a library or header file.
The recommended approach is to use the Snarl Framework as this:
Alternatively, any of the following can be used, especially if you'd rather integrate Snarl support directly into your application and not rely on middleware:
As well as the above, Snarl also supports:
As of V44 (Release 3.0), the way notifications are interacted with by the user has changed. While completely transparent to applications, the changes - and the reasoning behind the changes - are documented here.
Applications talk to Snarl by sending a request. A request is simply a command with zero or more arguments separated by ampersands, and each argument consists of a variable name and value separated by an equals sign. If a command has arguments, the first argument is separated from the command by a question mark, as follows:
How the request is actually sent to Snarl depends on the transport that is used. Briefly, a transport is a low-level mechanism that handles the communication between your application and Snarl itself. Transports are described in more detail in the API Reference; however, unless you're wanting to access the API directly, you typically won't need to worry about this as the library or header you use will handle it.
Each request returns a result which indicates whether it was successful or not. Usually, a return value of zero indicates success and a non-zero value indicates an error of some sort (see the Status Codes section for more information on error values). How the result is returned to your application depends on the library or header file you're using, so check the documentation for it for more information.
The rest of this guide explains how applications should best work with Snarl. Where examples are provided, they usually use the API format in order to remain language-agnostic. Again, check the documentation for the library you're using for information specific to it.
The first thing your application should do is register with Snarl. It can do this at any time, although it must register before attempting to send any notifications. The most common method is to register as part of the application's initialisation process, however it is recommended that the application registers each time it generates a notification - this avoids issues which can occur if Snarl is unloaded and then reloaded after the application has registered.
Applications register with Snarl using the register command, for example:
Applications must provide at least a valid signature and title in order to successfully register with Snarl. The signature is used to uniquely identify the application and the title identifies the application to the user.
In order to ensure your application's signature is unique, the recommendation is to follow the Internet Media type (also known as MIME content type) format as defined in IETF RFC 2046 which contains the application vendor's name - specifically:
Applications should also provide an icon which helps identify it to the user, the icon can be an image file stored on the computer or remote filesystem, a URL to an icon, a handle to a Windows icon, an icon in a resource file, or a stock icon provided with Snarl. If an icon isn't provided, Snarl will try to use the application's own icon. For more information, see Icons below.
Events allow the user to selectively configure the different types of notifications your application generates. While it's feasible to have no events, this limits the end user to an all-or-nothing approach when it comes to determining which notifications they wish to receive, leading to a poor user experience.
To add an event, use the addclass command. Note that while the settings for each event persist after your application has quit, the events themselves do not, so your application must add its events each time it registers.
Enabled by default
Defaults - title, text, sound, icon
To remove a notification class use remclass. Removing classes is only necessary if you wish to dynamically change the classes your application is providing while the application is running.
An application creates a notification using the notify command. This command accepts a large number of arguments, however most are optional. Firstly, the application must supply it's signature (and password if one was used during registration) and the name of the notification class to use to display it. It must also supply at least one of a title, body text or an icon.
The following pseudo-code creates a simple notification:
All notifications should include an icon. In fact, it may be sufficient to simply provide an icon with no title or body text in order to get the intention of the notification across (for example, the "Volume muted" notification generated by AudioMon). An icon can be provided in two ways: either indirectly by referencing a file or stock icon:
Or by including it as byte data within the request itself:
The former method is preferred as it keeps the length of the request down, and no time is spent encoding and decoding the icon data. However, if the notification is being sent to a remote computer, and that icon will not exist on the computer (or is not accessible to it), then sending the icon as data is the only option.
Note that when attempting to pass an HICON (that is, a GDI handle to icon data), the HICON value must be passed as a string value prefixed with "%" - for example, "%123456". The value should not be converted to hexadecimal, or otherwise modified. The following pseudo-code indicates this further:
If an icon isn't provided Snarl will try to use the application's own icon. For more information, including a more detailed explanation of how icon data should be encoded, see the section on Icons below.
Snarl can play a sound when it displays the notification, as follows:
Prefixing the sound with an exclamation mark indicates that a system sound with the supplied name should be played.
Although applications can provide their own sound for the notification to play, doing this has been deprecated as of Snarl 2.3 in favour of allowing the user to choose two sounds: one for normal priority notifications and one for high priority notifications as this helps ensure consistency across all notifications. As always, the user is able to control which sounds are played and can disable all sounds if they so wish.
The amount of time a notification should remain on-screen can be provided by the application as follows:
There are two special values which can be used: zero, to indicate that the notification should remain on-screen until specifically dismissed by the user, and -1 (the default) to indicate that the notification should remain on-screen for the default amount of time (which is user-configurable).
Note that any value supplied should be considered as a suggested duration. Snarl may impose restrictions on the value supplied - especially if the notification has a low priority, or will be displayed non-interactively. Generally speaking, applications should avoid prescribing the amount of time a notification should remain on screen and leave it to Snarl and the user to decide.
A priority of -1 indicates the notification is of low importance and, as such, isn't detrimental to the user if they don't actually see if appear. A priority of 1 indicates the notification is of high importance, in which case Snarl will attempt to ensure the notification is displayed to the user; a priority of zero is effectively a no-op - Snarl treats the notification as a regular notification.
With the release of Snarl 2.4, each application may only have one low priority notification may be on-screen at any one time. When a new low priority notification appears, any existing low priority notification the application may have created is removed before the new one is displayed. Additionally, low priority notifications are not displayed or logged as missed while the user is away or busy.
Conversely, high priority notifications are displayed even when Snarl's Do Not Disturb mode is enabled. For this reason alone they should be used very sparingly (see the Notification Guidelines section for more information). Examples of notifications for which a high priority might be suitable include:
Of course, if the user has to leave home at 6pm to catch his or her 11pm flight, they might consider an alarm or hourly reminder suitable for high priority status. The difference here though is that this would be a user choice, not an application choice. Generally speaking, it's best to assume your notification does not need to be a high priority one and leave it to the user to decide for themselves.
With the release of Snarl 2.5.1, an application can assign a sensitivity rating to a notification. Currently, Snarl doesn't take any specific action based on the rating assigned; instead the value is passed through to the handling style, which may then take action. The sensitivity is assigned as follows:
An example may be a style which checks the user's IP address and then blocks or redacts the content of a notification if the user is not on their corporate LAN.
Each notification may have a default callback. This is something that is either launched by Snarl on behalf of the application or something which is returned to the application as an event. Either way, the event is triggered by the user "invoking" (clicking on the main body) a notification:
Irrespective of the type of callback used, it always assigned as follows:
You should consider carefully whether it's appropriate to include a default callback. Typically, a user will simply click on the notification expecting to dismiss it; if doing this causes some action to occur - for example opening a URL in a web browser - this is likely to have a negative impact on the user. See the Notification Guidelines for more information.
Actions can be used to augment the content of a notification. For example, a "new email received" notification may add Open, Reply, Forward and Mark as Read actions. If a notification is assigned at least one action, a gear wheel gadget will appear below the close gadget (see image below) when the mouse pointer is moved over the notification - clicking the gadget pops open a menu displaying the actions.
An application adds actions to a notification by including one or more
Each action has a label and a callback. The label is displayed in the menu; the callback follows the same pattern as the default callback (see above) and thus can be a:
The following pseudo code creates the notification above:
Selecting each action causes the values 900, 0, 911 and 666 respectively to be sent to the application as
In addition to the standard arguments, an application can also pass custom values inside a notification. These values may simply be useful if the style logs them, or they may be recognised by a specialised style and acted up accordingly.
In order to implement some form of standardisation, there are two types of custom value:
Pre-defined values begin with a recognised prefix and should only be used to pass data of the defined type. The following table lists the currently defined values:
User-defined values begin with either
Furthermore, developers can request blocks of
When your application exits, it should unregister with Snarl. This removes it from the list of registered applications and allows Snarl to free resources it may have allocated while the application was running.
Applications unregister using the unregister command, as follows:
If a password was used when the application registered, the same password must be used to successfully unregister.
Introduced in V43 of the API, application's can provide a password then they register with Snarl. The password is then used to prevent other applications from creating notifications by masquerading as an already registered application. Once created, the password must be included in all requests sent to Snarl in order for them to be accepted.
The recommendation is that the password should be generated dynamically by the application on launch and should use a string of randomly generated alphanumeric characters. The Snarl Framework takes care of password creation automatically, and many libraries and helper modules include macros for doing this.
An event is something which happens asynchronously to your application's program flow. There are two types of event: those generated by the user interacting with a notification your application has displayed and those generated by Snarl itself when either it's running state or the user's presence has changed.
callbacks from a notification when clicked, closed, action selected, etc.
events from Snarl when it starts, stops, etc.
From HICON, resources, etc.
Base64 / Phat 64 encoding.
The former method is preferred as it keeps the length of the request down, and no time is spent encoding and decoding the icon data. However, if the n
'''icon-base64''' should contain the icon data encoded using MIME (Base64). When supplying MIME encoded data, any trailing '=' characters must be replaced by '%' symbols before passing to Snarl as the equals signs will confuse the request parser.
Or SSA's as they're known :)
Scripted applications are those which utilise interpreted languages over those which compile code into an executable block. Scripted languages offer many advantages over compiled programs - not least as they are usually very lightweight, applications are quick to developer and - most of all - invariably free to purchase. The most obvious scripted languages are MS-DOS and VBScript, although may more are available.
For all their simplicity, scripted languages tend to lack the ability to receive events. This means that recognising when Snarl launches or terminates, when a notification has been invoked by a user, etc. are difficult - if not impossible - for a scripted language to implement. When it comes to signalling a notification has been interacted with, there are some options: the script could simply supply a command or URL to launch, or the name of another script to run; recognising when Snarl launches or terminates however is not so straightforward.
At the present time, the recommendations for using Snarl from scripted applications are as follows:
Further improvements are planned in this area and this section will be updated accordingly.
Frequently applications will need to alert the user about certain events. These events can be blocking (modal) whereby normal application execution cannot continue until the user has either acknowledged the event or selected an option to proceed with. An obvious example of such an event is an application querying if the current document should be saved or discarded. Some events, however, do not need the user to explicitly acknowledge them, or to select an option - these events are non-blocking and could include notifying the user that they have a new email, the battery on their device is getting low, a new contact has signed in, and so on.
For the latter category of notification, modal dialog boxes are both unintuitive and unsuitable in a multi-tasking environment and, as such, different options must be considered, including:
All of the above have individual flaws and also require additional code to be added to the application. Furthermore - and probably worst of all - none of these methods allow for user customisation of how (or, indeed, if) the notification is displayed.
Where a user receives a notification is becoming more important as well. It is perfectly conceivable that a user may which to be emailed, be sent an SMS, or receive a push notification that notifies them that a particular event has occurred. An example would be a developer who sets his project compiling and then leaves for a coffee break - he or she would want to be notified that the compilation succeeded or if any errors were detected, and they would want to receive when away from their workstation.
A single service which takes care of all this is a necessity. Having a single service:
In addition to the problem of how a user should be notified of a particular event, it's also a question of allowing the user to decide when they're notified of a particular event. Take the following scenario:
In this scenario, Bob would not want to be disturbed by Sarah's IM message but he would most definitely want to know that he'd forgotten to plug his laptop in and that the battery was getting low. This highlights the need to for contextualisation of alerts - in this case, Bob would enable Do Not Disturb mode ensuring that priority notifications (the one about his battery getting low) would still be displayed while others (Sarah's friendly but unwanted) IM wouldn't.
In order to maintain a consistent appearance, your application should follow these guidelines. They're not meant to be restrictive; instead they are recommendations.