Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Guide: how to make irc messages in a screen on a remote server appear in your Mac OS X Lion Notification Center with the help of terminal-notifier

Irssi in Mac OS X Notification Center

Mou icon

Overview

This guide will explain how you can make irc messages in a screen on a remote server appear in your Mac OS X Lion Notification Center with the help of terminal-notifier.

We will also explain how the process can be automatically started each time you log in to your Mac and ensure the connection to the server is kept alive.

While this is a guide on how to make it work with irssi you can imagine all the possibilties this opens up! You could for instance set up a task on your server that logs certain error messages from your server log files etc.

Table of Contents

Requirements

We assume that you have the following knowledge and tools:

  • Mac OS X 10.8 or greater
  • Remote server running a screen session with irssi
  • You use an ssh key to connect to the remote server (For Part 4 atleast)
  • Basic knowledge on the above terms and programs including Terminal

(Go to Top)


Part 1: Writing messages to file on a remote server

The first thing we need is a script for irssi that will write what we want to display in the notification center to a file on the remote server.

We'll use fnotify in this walktrough, but feel free to create your own script that will retrive what you want it to retrieve.

fnotify was authored by Thorsten Leemhuis and released under the GNU General Public License.

  1. Connect to your remote server
  2. Go to ~/.irssi/scripts (Create any missing folders)
  3. Create the file fnotify.pl
  4. Copy and paste the code from https://gist.github.com/matthutchinson/542141 into the file
  5. Continue irssi from an already existing screen session or start irssi
  6. In irssi, load your script by typing /script load fnotify.pl

Testing and use

Irssi should now begin to write private messages and hilights you receive to the log file. If you didn't change the code this should be saved to the file ~/.irssi/fnotify

Ensure this is working by having another irc user hilight you or send you a private message and then open /.irssi/fnotify to see if the message was written to it.

By default it's likely that your IRC username trigger hilights, but you can also add other terms it should match. You can do this with /hilight. Please type /help hilight in irssi for more details.

If you ever create your own script remember that you'll have to reload the script in irssi each time you have saved changes before irssi will execute the updates. You can do this simply by repeating the command /script load fnotify.pl.

(Go to Top)


Part 2: Installing terminal-notifier on your Mac

terminal-notifier is a very useful tool that makes it easy to trigger OS X Notifications from Terminal and scripts.

The official readme from the developer should be good enough to show you how to install and use it.

The next parts assume however that you have installed the ruby-version as detailed below. Ruby on your Mac will be required

  1. Type gem install terminal-notifier in Terminal

Testing and use

Once the ruby-version is installed you can test it by typing the following in Terminal.

terminal-notifier -title 'Title' -message 'This is a simple test message.' -activate com.apple.Terminal

This should cause a notification message to appear on your screen and you will see the confirmation message * Notification delivered. in your Terminal window. If you click on the notification box you will activate Terminal.

(Go to Top)


Part 3: Read messages from server and send notifications

Now you need to create a script on your Mac that will read from the file on the server in "real time" and then send the messages to the Mac OS X Notification Center with terminal-notifier.

Below we have provided you with a basic function you can use and experiment with. This script displays the messages but will also look for links. If it finds a link it uses the -open flag in terminal-notifier to make it so the url opens in your browser if you click on the notification message. When there is no link it will activate the Terminal-window instead.

irssi_notifier() {
	ssh user@remoteserver.com 'echo -n "" > ~/.irssi/fnotify; tail -f ~/.irssi/fnotify' | \
        	while read heading message; do
			url=`echo \"$message\" | grep -Eo 'https?://[^ >]+' | head -1`;

			if [ ! "$url" ]; then
				terminal-notifier -title "\"$heading\"" -message "\"$message\"" -activate com.apple.Terminal;
			else
				terminal-notifier -title "\"$heading\"" -message "\"$message\"" -open "\"$url\"";
			fi;
		done
	}

Please note that you will need to change ssh user@remoteserver.com in the code above to your correct information.

  1. Open or create the file ~/.bash_profile
  2. Copy and paste the code above into ~/.bash_profile
  3. Fix the ssh-details in the script and save
  4. Reload .bash_profile by typing . ~/.bash_profile in Terminal

Testing, use and solving ssh-problem

When typing irssi_notifier in Terminal you should now be able to manully run the process. The process will not end until the script either fails, you close the Terminal-window or you send a sigkill-signal.

In some cases you may experience that the script seems to silently fail or that it fails after a certain amount of time. You may notice this by seeing hilights in your irssi, but having received no notifications on your Mac. This is usually due to connection timing out without your ssh client being made aware of it. What you need to do is to send "a request" to the server about keeping your connection to the server alive.

In order to fix this problem you need to edit either one of these files: /etc/ssh/ssh_config or ~/.ssh/config and add this on the first line: ServerAliveInterval 180 . You can read more on these links: 1, 2

Once again you should ensure irssi is writing hilights and private messages to the log file on the server. If you receive a hilight in irssi on the server while the function irssi_notifier is running on your local machine, you should see the Mac OS X notification popping up shortly thereafter.

When you do changes to .bash_profile you'll always need to reload it before the changes will have any effect.

(Go to Top)


Part 4: Start task when logging in

It would not feel very intuitive if we had to check on whether the task was running at all times. Having to start it manually every time we logged in wouldn't be a lot of fun either.

There is a brilliant way to make sure it's always running and that it starts automatically when we log in.

  1. Create the file ~/irssi_notifier_run.sh
  2. You need to give the system permission to execute/run the file, so do chmod a+x ~/irssi_notifier_run.sh
  3. Paste the code below into it:
#!/bin/sh
source ~/.bash_profile; irssi_notifier;
  1. Go to ~/Library/LaunchAgents
  2. Create the file com.prebenlm.irssi_notifier.plist
  3. Paste the following into the file:
<?xml version="1.0" encoding="UTF-8"?>
	<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
	<plist version="1.0">
		<dict>
			<key>Label</key>
			<string>com.identifier.irssi_notifier</string>
			<key>Program</key>
			<string>/Users/user/irssi_notifier_run.sh</string>
			<key>KeepAlive</key>
			<true/>
		</dict>
	</plist>

There are two things you can change here:

  • com.identifier.irssi_notifier this is the normal "naming convention". The file should start with com. Then the next bit is an "identifier". Apple for instance use apple and Valve use valvesoftware. It's like a company / author name. irrsi_notifier is the script / action name here.
  • /Users/user/irssi_notifier_run.sh you'll need to change from "user" to your username and double check rest of the path.
  1. To add this task to the user account, type this in Terminal: launchctl load ~/Library/LaunchAgents/com.identifier.irssi_notifier.plist (Remember to fix the path if necessary)

Testing and use

If you log out and log in you should still receive notifications about new hilights and private messages. The best thing is that you do not need to do anything more to make it happen!

If you have protected your ssh key (used for logging into your server without your server password) with a pass phrase ssh-agent will be triggered on startup by the task irssi_notifier. You will then be prompted for the ssh pass phrase before it can start.

If it doesn't seem to be working, you can check for errors related to the task by tailing the system log tail -f /var/log/system.log

(Go to Top)


Resources that helped me

I would've been unable to figure all of this out on my own. I really appreciate all the resources I've been through in order to make this work like I envisioned.

osxdaily.com had this very helpful guide on terminal-notifier: http://osxdaily.com/2012/08/03/send-an-alert-to-notification-center-from-the-command-line-in-os-x/

matthewhutchinson.net had a guide on how to combine irssi, screen, fnotify and Growl: http://matthewhutchinson.net/2010/8/21/irssi-screen-fnotify-and-growl-on-osx

spatof.org wrote a function that I built upon: http://www.spatof.org/zshaolin/misc/im/irc.html

Kent on stackoverflow.com was very helpful when I needed assistance to retrieve url from string http://stackoverflow.com/a/16502803/1015149

trisweb on stackoverflow.com had a very good reply on a question about tasks that run in the background on startup http://stackoverflow.com/a/13372744/1015149

Both nileshbansal and http://ocaoimh.ie/ for providing information on the ssh fix. Originally I had another source for this, but forgot to write about it before.


Questions and suggestions for improvements

Please do not hesitate to contact me if you find anything that is unclear or you are having trouble following any of the steps. I would also be happy if someone wishes to contribute to this guide.

(Go to Top)

irssi_notifier() {
ssh user@remoteserver.com 'echo -n "" > ~/.irssi/fnotify; tail -f ~/.irssi/fnotify' | \
while read heading message; do
url=`echo \"$message\" | grep -Eo 'https?://[^ >]+' | head -1`;
if [ ! "$url" ]; then
terminal-notifier -title "\"$heading\"" -message "\"$message\"" -activate com.apple.Terminal;
else
terminal-notifier -title "\"$heading\"" -message "\"$message\"" -open "\"$url\"";
fi;
done
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.identifier.irssi_notifier</string>
<key>Program</key>
<string>/Users/user/irssi_notifier_run.sh</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
#!/bin/sh
source ~/.bash_profile;irssi_notifier;

heckran commented Nov 10, 2013

I'm receiving this error with when trying to run irssi_notifier.run.sh: ./irssi_notifier_run.sh: line 2: irssi_notifier: command not found. I don't get it why it doesn't run as sh, but if I manually run source ~/.bash_profile;irssi_notifier; it works.

edit: I'm using OSX 10.9

This is exactly what I was looking for, but when loading fnotify in Irssi, I get:

"Can't locate object method "e" via package "strict" at /home/fimp/.irssi/scripts/fnotify.pl line 1."

What should I do?

x1a0 commented Dec 3, 2013

@heckran I got same problem as you did. To make it run I had to put the bash function in ./irssi_notifier_run.sh file then directly call it there - no need to source ~/.bash_profile though.

x1a0 commented Dec 3, 2013

Now the script works. However when I use launchctl to load it it doesn't work. It seems it cannot ssh to remote server (as the fnotify file is not truncated). But run the script manually is fine. Any idea?

Thanks for great tutorial!

heckran commented Dec 7, 2013

@zhangxiao Thank you. It works now.

Which ssh should I be using by the way?

Remember to set chmod a+x on ~/irssi_notifier_run.sh. There's also a typo in 4.1: Create the file ~/irssi_notifies_run.sh.

Owner

prebenlm commented Jan 17, 2014

Hello, thank you for the comments.

I'm sorry for not replying, but seems I'm not notified of the comments here. I'm really sorry! Glad to see your issues got resolved, I'll try and update this guide with your tips soon :-)

I am very mobile when I work and often lose my connection. Will the notifier script resume the connection next time a connection is active?

There's a comment above from zhangxiao about "launchctl to load it it doesn't work". I'm having the same issue. It works great when I run irssi_notifier from terminal, and launchctl starts the process, but it simply doesn't work. No related errors in the log. ps -ax | grep irssi shows that the process is running.

andebor commented Sep 19, 2014

Hi! I just wanted to let you know of my solution.
I had the same problems as @joshualivesay. My launchctl process was running, but i didn't recieve any notifications. My scripts was working fine, when I ran it manually from the terminal.

By adding a log path I found that launchctl wouldn't recognize the command "terminal-notifier".
The reason for this is that launchctl doesn't source the same path as me and I needed to put the complete path of the command in the script.
I installed the terminal-notifier with homebrew and my command was located in /usr/local/bin.
Here is my plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Debug</key>
    <false/>
    <key>KeepAlive</key>
    <true/>
    <key>Label</key>
    <string>com.andebor.irssi_notifier</string>
    <key>Program</key>
    <string>/Users/andebor/.scripts/irssi_notifier_run.sh</string>
    <key>StandardErrorPath</key>
    <string>/var/log/irssi_notifier.log</string>
    <key>StandardOutPath</key>
    <string>/var/log/irssi_notifier.log</string>
</dict>
</plist>

I also didn't put any code in the bash_profile or bashrc. all the code is in these two files.
Here is my working script :

#!/bin/sh

irssi_notifier() {
    ssh andebor@myserver.com 'echo -n "" > ~/.irssi/fnotify; tail -f ~/.irssi/fnotify' | \
        while read heading message; do
            url=`echo \"$message\" | grep -Eo 'https?://[^ >]+' | head -1`;

                        if [ ! "$url" ]; then
                            /usr/local/bin/terminal-notifier -title "\"$heading\"" -message "\"$message\"" -activate com.apple.Terminal;
                        else
                            /usr/local/bin/terminal-notifier -title "\"$heading\"" -message "\"$message\"" -open "\"$url\"";
                        fi;
                done
    }

irssi_notifier;

widestm commented Nov 4, 2014

Got this working on Yosemite only by making it into an app with automator. Tested both your solution and andebors shown in the comments. You could add something about automator in the guide too. I used the solution posted here :) http://stackoverflow.com/questions/6442364/running-script-upon-login-mac .
Only problem I have now is, if I come back from sleep or login after a reboot the script doesn't show notifications from messages I got while being offline. Also if I turn the script off, and receive a message then turn the script on again it doesn't show the old ones.
You wouldn't happen to know a fix for this?

Oh and thanks for the great guide btw, would probably never have figured this out without it :)

It is really cool. That's what I was looking for 😄

So far it worked well for me, but since upgraded to OSX Yosemite 10.10.3, keep seeing following errors in systen.log :

Mar 23 12:05:55 shahsaifi com.apple.xpc.launchd[1] (com.identifier.irssi_notifier[16730]): FairPlay decryption failed on binary.
Mar 23 12:05:55 shahsaifi com.apple.xpc.launchd[1] (com.identifier.irssi_notifier): Service only ran for 0 seconds. Pushing respawn out by 10 seconds.
Mar 23 12:06:06 shahsaifi com.apple.xpc.launchd[1] (com.identifier.irssi_notifier[16779]): FairPlay decryption failed on binary.
Mar 23 12:06:06 shahsaifi com.apple.xpc.launchd[1] (com.identifier.irssi_notifier): Service only ran for 0 seconds. Pushing respawn out by 10 seconds.

nice, I had to reset-up and it is working well now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment