What is Growl?
[b]Growl[/b] is a very popular freeware global notification system written for OS X that installs itself as a preference pane and/or a menubar icon and menu. Applications use Growl to display small notifications in a consistent manner controllable by the user. Notifications can appear even if the application is in the background or hidden when the notification event occurs. Applications that use Growl register a ticket with Growl when they start up and these can be seen in the preference pane. As notifiable events occur, these are sent to Growl for display, e.g., “Feed Download Session Ended”.
A lot of current OS X applications can do this if the user has Growl installed (It is not part of OS X): Firefox, NetNewsWire, NewsFire, Quicksilver, Shiira, Skype, Transmit, Twitterific, VLC media player, Yahoo! Messenger, and Google Notifier, to name only a sub-set of them. There are also plug-ins to enable Growl notifications in other Macintosh applications that don’t build Growl in, and these include iChat, iTunes, Mail, Thunderbird, Safari, MS Entourage, and Camino.
The preference pane provided allows the user to customize the display he/she sees and to turn them off and on as desired. The menubar icon gives easy access to a menu of some of the features as well as a link to the preference pane. If you’re wondering if a particular App. has Growl capability, right-click on the application, choose “Show Package Contents” in the contextual menu, and look in the Frameworks folder for “Growl.framework”.
Growl also installs a daemon; the GrowlHelperApp, and it is AppleScriptable. This article is about using Growl notifications from your scripts.
Gimme an Example
I have a script for getting going in the morning that does a lot of things: it presents a notification of how many emails I have waiting and opens the appropriate mailboxes, it opens The AppleScript BBS and two other forums I follow, and it posts two other notifications telling me about upcoming medical appointments and upcoming extended family birthdays. They’re a good example, so I show them below (click on the figures if you actually want to read them, and note that I’m an old guy):
Figure 2: Upcoming Birthdays
Figure 3: Upcoming Appointments
If I haven’t convinced you that you need Growl, here’s a second opinion by Alex Tan in his ForeverGeek blog. If you’re a lover of the Terminal, you can even post notifications from your shell scripts as shown in this hint from MacOSXHints.
Growl Setup
As mentioned earlier, Growl notifications must be registered with Growl or they won’t happen. In a given script registration, you can declare more than one note and thereafter use any of them without registering again. You don’t have to register more than one note to change the title, content, icon, etc. of a notification, but if you don’t use multiple notes, then the user (probably you) cannot format the notes from a given script separately in the Growl Preference Pane, giving them different background and text colors, for example. The Growl Preference Pane is where these settings happen. Before proceeding to the prefpanes, let’s deal with registering a ticket with Growl.
Scripting a Notification
Assuming that at this point you have downloaded and installed Growl (the latest version is 1.1.2 and saved the uninstaller AppleScript app and weblinks that that come with it, you’re ready to post a note.
The Growl Documentation for AppleScript includes the following script as a sample (I’ve embedded some additional comments and marked them **):
tell application "GrowlHelperApp" -- ** the daemon that is behind the scenes
-- Make a list of all the notification types that this script will ever send:
-- ** They really mean "ever" or you'll have to reregister.
set the allNotificationsList to {"Test Notification" , "Another Test Notification"}
-- Make a list of the notifications that will be enabled by default.
-- ** We'll see shortly that a note must be enabled and the user can disable it.
-- Notifications not enabled by default can be enabled later in the 'Applications' tab of the growl prefpane.
set the enabledNotificationsList to {"Test Notification"} -- ** just one turned on, the other not.
-- Register our script with growl.
-- You can optionally (as here) set a default icon for this script's notifications.
-- ** Theoretically, you only have to register once, but there is absolutely no harm in doing
-- it every time the script runs, [i]i.e.[/i], leaving this line in your script.
register as application "Growl AppleScript Sample" all notifications allNotificationsList default notifications enabledNotificationsList icon of application "Script Editor"
-- Send a Notification...
-- This one will appear because it was enabled by default.
notify with name "Test Notification" title "Test Notification" description "This is a test AppleScript notification." application name "Growl AppleScript Sample"
-- This one will not appear -- it wasn't enabled by default so the user has to turn it on in the 'Applications' tab of the Growl prefpane to see it.
notify with name "Another Test Notification" title "Another Test Notification :) " description "Alas � you won't see me until you enable me yourself..." application name "Growl AppleScript Sample"
end tell
After you run and save this script, go to the Growl Menubar menu (the icon looks like this ) and select “Open Growl Preferences…”. Click the “Applications” tab and in the top pane find the ticket for “Growl AppleScript Sample” with a Script Editor icon next to it. It should be enabled, but if you uncheck it, it will no longer show. If you haven’t enabled the Growl Menu, just go to the Growl preference pane in System Preferences and click the Applications tab.
Figure 4 below shows the pane for the Applications tab where the list shows all the tickets Growl has registered. Search in the list for the Growl AppleScript Sample there and select it. You will see that it is enabled. If you uncheck it in this view and run the sample script again, you will not see a growl result even though you have registered it again. The user rules here – not our script.
Figure 4: Application Settings Pane
Figure 5: Application Settings Configuration
Now (and this can be a bit confusing) click on the Configure button, leaving the Growl AppleScript Sample script selected. A new pane appears as shown in Figure 5. The point to remember in this pane is that you are configuring the selection in the previous applications list pane. The name is shown in the title just under the Applications tab on this pane. Next to the name is a button to return to the list view. Below that are two more tabs. The Application tab is to configure several things that don’t yet work for an AppleScript. "Inform nameOfApp when notification is clicked is in the works but not working, but if the “Use custom starting position:” radio button is clicked, it is possible if the style permits, to relocate the starting position of the notification. Bezel, however, cannot be located this way.
When you click on the “Notifications” tab, the pane in Figure 6 below appears. Here, there is a drop-down menu showing the registered notifications for the application or script. Since we have Growl AppleScript Sample selected in the Application list, there are two notifications in the menu: “Another Test Notification” which is not enabled, and “Test Notification” which is. Here you can select the Default style for the notification, and enable or disable it here.
[url=http://files.macscripter.net/unscripted/Growl/NotificationConfig.jpg][/url] [url=http://files.macscripter.net/unscripted/Growl/DisplayOptions.jpg][/url] [i] Figure 6. Notification Configuration[/i] [i]Figure 7. Display Options[/i]In the next tab, “Display Options”, the pane in Figure 7 appears. You can play with and see how these options will look. Try selecting Bezel, for example, and clicking the Preview button. Note that this is one of the few display formats among the standards that you can move to anywhere on your primary screen. Candybars and Smoke are styles that can be placed on a second display (I have two screens, and use this feature). Priority formats are set here as well, for those styles that support them, as Smoke does. To set the background and text colors for each of the priority levels (the default level is 0) click on their respective boxes. I only use two of these – the default (0), and Emergency (2) levels for smoke. To see what you get, use the Preview button.
Bear in mind that in this tab you are setting the defaults for the display formats and will get a different pane for each. MailMe, doesn’t have a display – it sends mail instead to the address you enter in its pane. If you’re not happy with the styles provided, there are others developed by third parties to be found found in Custom Growl Styles at ResExellence.com.
Growl Registrations must declare the application name that will want the notification (your script), the names you will be giving to the various notifications you want to send (the ‘all’ list), and which ones you want turned on immediately (the defaults list). You can also append the icon of any application to these notifications (as the default – you can change icons later).
Growl Notifications must have a name, a title, a description (which is the text to be displayed below the title), and a “with name” term which specifies which of the notes you’ve registered you want to display. In addition to these, however, you can add the icon of an application, e.g. for iCal: icon of application “iCal”, and this will appear in the note. You can also use PICT images, and more likely, images of your own. These are specified in a notify statement by alias, by posix path, or by URI (file:///PathtomyPic.jpg). Finally, as mentioned earlier, you can set priorities, but there is no way to alter their formats from a script yet – you’ll have to set them in the prefpane.
More Scripts
There is a script in ScriptBuilders to growl your iCal alarms by imAGn Software (free). It’s called GrowlIt. Also available at imAGn’s site. With the developer’s kind permission, I have included it below as an example of how to Growl notifications from applications that don’t growl them.
-- GrowlIt
-- Description:
-- An applescript that displays events and to-do's from iCal as Growl notifications.
-- Based on multiple other Applescripts found in multiple sites.
-- No warranty. Tested with iCal 2.0.5 and Growl 0.7.6 under Mac OS X Tiger 10.4.10
-- Written by L.A. [email]software@imagn.net[/email]
-- Last modified: 08/31/2007
-- Comments with ** added by Adam Bell
-----------------------------------------------------------------------------------------------------------------------------
set myAllNotesList to {"Events"}
set appName to "GrowlIt"
set now to current date -- ** See note on next statement
set startD to now - 2 * hours -- ** By setting time of "now" to 0 this would be all day
set endD to now + 1 * days -- ** Change this if you want a longer preview.
-- ** First register a ticket with Growl...
tell application "GrowlHelperApp" to �
register as application appName all notifications myAllNotesList default notifications myAllNotesList icon of application "iCal"
-- ** Then get something to Growl about from iCal
tell application "iCal"
repeat with thisCalendar in calendars
repeat with thisEvent in ((every event of thisCalendar) whose ((start date ≥ startD and start date ≤ endD) or (end date ≥ now and start date ≤ startD)))
set theEventSummary to ""
set theEventDescription to ""
if exists open file alarm of thisEvent then
set interValue to trigger interval of open file alarm of thisEvent
if (start date of thisEvent is greater than (now - (interValue * minutes) - (1 * minutes)) and start date of thisEvent is less than (now - (interValue * minutes) + (1 * minutes))) then
tell thisEvent
if exists summary of thisEvent then
set theEventSummary to (summary & " in " & (interValue * -1) & " minutes")
end if
set interValue to trigger interval of first open file alarm of thisEvent
if exists description of thisEvent then
set theEventDescription to description
end if
end tell
-- ** Finally, GrowlIt.
-- ** Note that the note is "sticky"; you have to click it to dismiss it.
tell application "GrowlHelperApp" to �
notify with name "Events" title theEventSummary description theEventDescription application name appName with sticky
end if
end if
end repeat
end repeat
end tell
The Upsides of Growling Messages
Unlike an AppleScript Dialog, Growl notifications have several advantages.
- 1. They are quite configurable with a broad array of templates available
- 2. Some templates provide moveability from the default upper right hand corner
- 3. Notifications can be made transparent
- 4. Background and Text colors are configurable
- 5. Notifications do not block the script, they just inform while the script keeps running
- 6. More than one can appear at a time and they automatically avoid overlapping.
Unfortunately, Growl does not return a result from a notification so your script cannot determine whether a sticky note has been dismissed or not. Only a dialog will do that.
Checking for Growl
A lot of Mac users, but certainly not all, have Growl installed. If you are going to distribute a script that uses Growl notifications, however, or perhaps one that is bilingual (using a dialog if not Growl) you have to check whether the GrowlHelperApp is running before attempting to register your ticket or the user will get an error. A script like the one that follows shows how I do it:
-- To be saved as "NoteTester.scpt" to give it a name.
tell application "System Events" to set GrowlRunning to exists application process "GrowlHelperApp"
set Message to "So this message appears in Growl"
set altMsg to "So this message is a dialog"
NotifyMe(Message, altMsg, GrowlRunning) -- Obviously, Titles could be included.
-- The Handler
to NotifyMe(msg, altMsg, Growler)
if Growler then
tell application "GrowlHelperApp"
register as application "NoteTester.scpt" all notifications {"Note"} default notifications {"Note"} icon of application "Script Editor"
notify with name "Note" title "GrowlHelperApp is Running" description msg application name "NoteTester.scpt"
end tell
else
display dialog altMsg with title "GrowlHelperApp not Running" with icon 0
end if
end NotifyMe
A final example needs some explanation. I have a lot of memory, so I leave a lot of applications running all the time: iPulse, Quicksilver, Journler, CopyPaste X, Script Debugger 4, NetNewsWire, Eudora, Camino, iCal, and BBEdit would be a typical set, and there are several faceless applications running as well in my menu bar: twitterific, Google Notifier, Meteo (weather), Growl, MenuCalendarClock, and ChimeHours.app. Logging out and in again, or a restart, rare though they are for me, virtually freeze the machine while all this gets going if I leave them all in the Accounts > Login Items preferences.
To avoid this, I’ve taken eight of them out of my Accounts > Login Items list and moved aliases of each to a “Startup Delayed” folder in my home folder. This way, the machine is mine again much sooner while an startup AppleScript application called Startup.Delayed.app, after a 15-second wait, starts the delayed set at six-second intervals and lets me get to work on what is running. To keep me informed as this process unfolds, I growl a series of notifications only the last of which is sticky, and the iintermediates are set to fade in 3.5 seconds. It goes like this:
-- set up some generic notes
property Note_1 : "15-second pre-launch delay." & return & "To be launched:" & return
property Note_2 : "Now launching "
property Note_3 : "All delayed apps have been launched"
-- set up some generic titles
property Title_1 : "Delayed Startup"
property Title_2 : "Launching Delayed Apps."
property Title_3 : "Delayed launches completed"
-- register these growls
tell application "GrowlHelperApp" to register as application "DelayedNote" all notifications {"Note_1", "Note_2", "Note_3"} default notifications {"Note_1", "Note_2", "Note_3"}
-- get the list of apps and names for the first growl
tell application "Finder"
set theDSfolder to alias ((path to home folder as text) & "Startup Delayed:")
set lateStartApps to every item of theDSfolder
set tNames to name of every item of theDSfolder
set NList to return
repeat with N in tNames
set NList to NList & N & return
end repeat
set DSCount to count lateStartApps
-- Growl the beginning of the delay before launching
my growlIt(Title_1, Note_1 & NList, false)
do shell script "sleep 15" -- less cpu intensive than delay 15 though not as accurate.
-- launch the delayed apps at 6-second intervals, each with a growl.
repeat with k from 1 to count of lateStartApps
my growlIt(Title_2, Note_2 & item k of tNames, false)
open item k of lateStartApps
do shell script "sleep 6"
end repeat
-- announce that I'm done -- leave the note on screen.
my growlIt(Title_3, Note_3, true)
end tell
-- the handler
to growlIt(aTitle, aNote, hold)
tell application "GrowlHelperApp" to notify with name "Note_1" title aTitle description return & aNote application name "DelayedNote" image from location alias ((path to documents folder as text) & "Journler-myIcons:Family.tif") sticky hold -- I've included a picture in the growls.
end growlIt
Because I have set the time to live of each of the non-sticky notifications to 3.5 seconds, the appearance on my screen is a series of growls letting me know what’s going on, each of which fades before the next is posted. The last one sticks so I know all is well.
If you don’t have Growl installed in your system, you really should try it. It’s not large, the daemon (GrowlHelperApp) occupies only 43 MB of real memory on my machine, and you’ll get notices from lots of applications that are Growl-enabled. When I don’t need user feedback, I always use growls to tell me what’s going on. When I’m testing scripts with shell scripts that take time, I often use a growl to let me know that the shell script has begun and another to let me know it’s done. Whenever you need an asynchronous message, Growl is the way to go.
Happy Growling!