iChat Notification with Growl

So there you are doing your work and of course being the geeks that we all are you have about three hundred windows open, give or take a few hundred. Then the iChat icon starts bouncing…

Now you might be very organized and have the iChat window in a certain spot on the screen or even on a certain space in Spaces. You might be a whiz with Exposé and immediately find the right iChat window in the myriad of windows that are open. Or you might have one or two 27″ displays and not really care about this.

But for the rest us, wouldn’t it be nice if say a small window floated into the screen with a notification and the person who sent the message and maybe even the message? And it would have to be unobtrusive and float away just as quickly. You could glance at the notification and decide there and then wether it is necessary to dig out that iChat window.

Incidentally, this is what Growl really does well.

This window will float serenely in front of everything for a few seconds.

And with the scripting interface in iChat it is fairly simple to set up. After installing Growl, take this script:

property growlAppName : "Growl iChat"

property notificationNames : {"Buddy Became Available", ¬
	"Buddy Became Unavailable", ¬
	"Message Received", ¬
	"Completed File Transfer"}
property defaultNotificationNames : {"Buddy Became Available", ¬
	"Buddy Became Unavailable", ¬
	"Message Received", ¬
	"Completed File Transfer"}

using terms from application "iChat"

	on buddy became available theBuddy
		my registerWithGrowl()

		tell application "iChat"
			tell theBuddy
				set theTitle to full name & " became available"
				set theDesc to status message
				set theIcon to image
			end tell
		end tell
		my notify(theTitle, theDesc, theIcon, "Buddy Became Available")
	end buddy became available

	on buddy became unavailable theBuddy
		my registerWithGrowl()

		tell application "iChat"
			tell theBuddy
				set theTitle to full name & " went away"
				set theDesc to status message
				set theIcon to image
			end tell
		end tell
		my notify(theTitle, theDesc, theIcon, "Buddy Became Unavailable")
	end buddy became unavailable

	on message received theText from theBuddy for theTextChat
		my registerWithGrowl()

		tell application "iChat"
			set theIcon to image of theBuddy
			set theTitle to full name of theBuddy
		end tell
		my notify(theTitle, theText, theIcon, "Message Received")
	end message received

	on completed file transfer theTransfer
		my registerWithGrowl()
		tell application "iChat"
			tell theTransfer
				if transfer status is finished then
					if direction is incoming then
						set theTitle to "Received File "
						set theDesc to "from "
					else
						set theTitle to "Sent File "
						set theDesc to "to "
					end if

					set theTitle to theTitle & (file as string)
					set theDesc to theDesc & full name of buddy
				end if
			end tell
		end tell
		my notify(theTitle, theDesc, theIcon, "Message Received")
	end completed file transfer
end using terms from

on registerWithGrowl()
	tell application "GrowlHelperApp"
		register as application growlAppName all notifications notificationNames default notifications notificationNames icon of application "iChat"
	end tell
end registerWithGrowl

on notify(theTitle, desc, icondata, notificationName)
	tell application "GrowlHelperApp"
		if icondata is "" or icondata is missing value then
			notify with name notificationName title theTitle description desc application name growlAppName icon of application "iChat"
		else
			notify with name notificationName title theTitle description desc application name growlAppName image icondata
		end if
	end tell
end notify

Copy the code into AppleScript Editor and save the file as “Growl iChat” (as a script file) in ~/Library/Scripts/iChat/

In iChat, go to Preferences -> Alerts and select the Event “Message Received”, check “Run Applescript” and choose “Growl iChat.scpt”

I also setup the script to react to “Buddy Becomes Available,” “Buddy Becomes Unavailable” and “File Transfer Completed.” The great thing is that you don’t have to enable all notifications. You can even set it up individually so that you get notifications for some buddies, but not others. It should be easy to adapt the script to more actions if you wanted to.

On man Pages

So you’re writing this email explaining to a customer or colleague on how to do some really cool thing (say hide a file in the Finder) in Terminal. The command for that is chflags, but of course you can’t remember the exact syntax. So you open Terminal and write man chflags and find the correct options.1

However reading longer man pages (try ssh or bash) in the Terminal can be kind of painful. I’m sure some of you have encountered this command before:

man -t chflags | open -f -a "Preview"

which uses the -t flag to pass the output to groff and generate a postscript file which we then pipe into the Preview app, using open‘s -f option to pipe the stdin into a file to open in a GUI app. Preview will then convert the postscript to PDF and display the result.

I think this started to work in Tiger and you should immediately go and add this command to your shell’s profile.2 Which is nice but you still have to make the roundtrip to the Terminal.3

Enter Snow Leopard Automator Services. Open Automator. Create a new service. Leave the settings to work on ‘text’ in ‘any application’. Search for the ‘Run Shell Script’ action and double click to add to the workflow. Leave the Shell at ‘/bin/bash’ but set the ‘Pass Input’ option to ‘as arguments.’

Replace the default code with

man -t "$1" | open -f -a /Applications/Preview.app
Screenshot of the workflow in Automator

Save the Service and give it a nice name, such as “Open Man Page.”

Then in any application4 you can ctrl/right/double-finger click on a word and “Open Man Page” will be an option in the menu.5 You can even go to System Preferences -> Keyboard -> and add a keyboard shortcut to the command.6 If any other command in the man page strikes your curiosity, just ctrl/right/double-finger click the word in Preview and select “Open Man Page” again.

Another rarely known but quite useful trick is that you can create hyperlinks to man pages with the x-man-page://command URL.7 This will open the man page in man in a new Terminal window. This is especially useful in IM sessions.


  1. chflags [no]hidden /path/to/file
  2. for me the relevant line looks like: function preman() { man -t "$@" | open -f -a "Preview" ;}
  3. though you could save the resulting PDF and attach it to the email, especially if you have a customer who can’t find his or her way around the command line.
  4. well… most…
  5. it may be under a under an extra level “Services” Menu. Some applications do not show Services in the context menu, but all will show the “Services” Menu under the Application Menu
  6. I usually don’t bother since I immediately forget any new keystrokes I assign. Your memory may work better.
  7. I once had somebody freak out on me because I made him open Terminal on his Mac with this…