You are not logged in.
What is Growl?
Growl 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):
Applescript:
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 <img src="http://files.macscripter.net/unscripted/Growl/growlmenu.jpg">) 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.
Applescript:
-- 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.<ul><li>1. They are quite configurable with a broad array of templates available
<li>2. Some templates provide moveability from the default upper right hand corner
<li>3. Notifications can be made transparent
<li>4. Background and Text colors are configurable
<li>5. Notifications do not block the script, they just inform while the script keeps running
<li>6. More than one can appear at a time and they automatically avoid overlapping.</ul>
The Major Downside of Growling Messages
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:
Applescript:
-- 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:
Applescript:
-- 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!
iMac running OS X 10.13.1
Offline
It just took me a long time to figure this out so i thought I would share...
If you want to add the GrowlHelperApp to your "Library" window in Script Editor you need to navigate to the preference pane file in the Finder at this location:
MacintoshHDName/Users/YourUserName/Library/PreferencePanes/Growl.prefPane
Right-Click on this file and show package contents. Go into the "Resources" folder and you will find the GrowlHelperApp.
In Script Editor, open the Library window and click on the plus sign. Drag and drop the GrowlHelperApp file from the Finder into this open dialog window so you can select it. This seems very roundabout but you can't navigate into the package contents inside an open window so you have to get in there through the Finder first.
Offline
Say dude, awesome post. I have been looking for another way besides dialog and voice to provide messages.
I hide most of my drives from finder completely so I made this script as a way to gain quick access to them. I was using voice output as an error handler. Now that I have read your post I am incorporating Growl into it. I have also included the check statement so that it will use the voice command if Growl is not available.
--Sorry if my code is a bit clunky, I have only been working with applescripts for the last two weeks but have used other languages for some time now. I am new to the Mac seen and will be exploring other Mac specific languages in the future. Any suggestions that could streamline my script or improve it are welcome.
Thx again to Adam Bell for this awesome post.
Applescript:
-- Open Drive
-- Created by DemonXstreeM on 5/28/09
global Message
global altMsg
global GrowlRunning
global Sw
tell application "System Events" to set GrowlRunning to exists application process "GrowlHelperApp"
set Message to "Note"
set altMsg to "Note2"
to NotifyMe(msg, altMsg, Growler)
if Growler then
tell application "GrowlHelperApp"
register as application "OpenDrive" all notifications {"Note", "Note2"} default notifications {"Note", "Note2"} icon of application "Script Editor"
if Sw = Message then
notify with name Message title "Alas �" description "Volume name does not exist" application name "OpenDrive"
else
notify with name altMsg title "Good By" description "" application name "OpenDrive"
end if
end tell
else
if Sw = Message then
say "Volume name does not exist." using "Zarvox"
else
say "Good By!" using "Bad News"
end if
end if
end NotifyMe
on openDrive()
-- set myIcon to ("///icon.icns") as POSIX file -- set custom icon if you like
try
tell application "Finder"
activate
display dialog "Enter Disk Name" default answer ¬
"Volume Name" buttons {"Never Mind", "Ok"} default button ¬
("Ok") with title "Open Drive" -- with icon myIcon -- if using custom icon
set dialogInfo to result
set selectedButton to button returned of dialogInfo
get selectedButton
set dName to text returned of dialogInfo
end tell
if button returned of dialogInfo is ("Ok") then
do shell script "open /Volumes/" & "'" & dName & "'"
else
set Sw to altMsg
NotifyMe(Message, altMsg, GrowlRunning)
end if
on error
set Sw to Message
NotifyMe(Message, altMsg, GrowlRunning)
openDrive()
end try
end openDrive
openDrive()
Last edited by DemonXstreeM (2009-05-30 11:39:24 pm)
Offline
Hello,
So for an Applescript studio app, there is no need to add the Growl Framework to our ressources ?
From what I understand, the Growl Framework is only useful for ppl developping in cocoa right ?
Offline
So for an Applescript studio app, there is no need to add the Growl Framework to our ressources ?
Yes, there is no need, but consider that the project can only be compiled on a machine with GrowlHelper.app installed and any Growl terminology causes a runtime error if Growl is not installed on the target machine
regards
Stefan
Offline
Yes, there is no need, but consider that the project can only be compiled on a machine with GrowlHelper.app installed and any Growl terminology causes a runtime error if Growl is not installed on the target machine
Yep, but I added a check at startup to make sure that growl is indeed installed and running on the target machine -- which keeps errors from happening, like Adam Bell posted up there.
I think I'm good because that looks about right :
Applescript:
on will open theObject
tell application "System Events" to set Growler to exists application process "GrowlHelperApp"
if Growler then
tell application "GrowlHelperApp" to register as application "MyApp" all notifications {"Note"} default notifications {"Note"} icon of application "MyApp"
end if
end will open
-- my code and blah blah here
set theTitle to "Info"
set msg to "this is a notification"
to DisplayGrowlNote(msg, theTitle, Growler)
to DisplayGrowlNote(msg, theTitle, Growler)
if Growler then
tell application "GrowlHelperApp"
notify with name "Note" title theTitle description msg application name "MyApp"
end tell
end if
set msg to ""
end DisplayGrowlNote
Thanks for your answer StefanK
Offline
This is a really cool thread, and I'm going to try that Delayed Startup script, but I do have one question about Growl.
How do you make it so a Growl alert you run from an AppleScript replaces any other Growl alert that is on the screen, so that the new alert "replaces" the old one immediately, with no delay?
I use an AppleScript to change tracks in iTunes, and when I run it a few times, the notifications start building up and there's a big delay. I figured setting "Stay on Screen" to "Never" would do the trick, but it doesn't seem to.
Any ideas?
Offline
I live happily with a message or two that doesn't die but I have figured that if I use some utility to simulate a mouse click with a screen region that would do the trick. There are some stuff like that which I have seen on some linux page but on a Mac Os x in context with timing of milli seconds - a timer library.
So, If you use that utility to click on your corner of the screen before publishing a growl message I guess you would be safe.
Mercurial vcs is a joy to use for scripting.
Offline
It seems as though a custom icon for an applet in Growl System Prefs is broken when you specify your custom app as the provider of the icon. When I say applet, I mean when you save the script as an app to be run in Applications. I'm thinking the applet may be missing some real designation as an application. I've tried renaming icons and switching their directories to no avail. Just want to point that out. It doesn't bother me that much, but just kind of messes with my sense of completion.
Offline