Tuesday, July 7, 2009

An IRC alerter written using Apache Camel and Java

IRC is a great tool if you have a bunch of people working on the same thing in different locations. One of the biggest problems I found with it is that I sometimes miss pings. I don’t always have the IRC window open, and although the client I use most (Trillian) has nice popups in the corner, I still sometimes miss a ping, simply because I’m away from my computer. I know there are some other IRC clients that can send you special alerts, but I just happen to like Trillian, so I didn’t want to abandon it just because I was missing one little thing...

While being annoyed with this for a little while, I came across the Apache Camel IRC component. Great - that should sort me out. I’ll just simply write a Camel route that connects to the IRC channel and sends me an alert of some sort when someone pings me.

After running the Camel Maven archetype for Java projects:
>mvn archetype:generate -DarchetypeGroupId=org.apache.camel.archetypes -DarchetypeArtifactId=camel-archetype-java -DarchetypeVersion=2.0-SNAPSHOT -DarchetypeRepository=https://repository.apache.org/content/groups/snapshots-group
I was able to get this going fairly quickly! The archetype creates a Maven Camel project for you with an example route in it. You can run it now with:

mvn install camel:run

Next step: write a Camel route that reads my IRC messages for me.
For this I’m simply using a URL in Camel to connect to the IRC server, e.g. I’m using the following to connect to the CXF IRC channel at irc.codehaus.org:
irc://my_user@irc.codehaus.org/#cxf?nickname=my_user
Once logged in you simply receive all the messages sent over the channel, in the process() method of your Camel route, so I can configure my route something like this:
public void configure() {
  String url =
    "irc://my_user@irc.codehaus.org/#cxf?nickname=my_user";
  from(url).process(new Processor() {
    public void process(Exchange ex) throws Exception {
      String msg = ex.getIn().toString();
      System.out.println(msg);
    }
  }
}

The process() callback gets called whenever a message is sent over the IRC channel, so now we can do something with it!

This is where I started experimenting :) I wrote a little generic IRC client that can connect to any number of IRC channels and searches any messages coming in for a certain text string.
If there is a match, it opens a dialog on my screen that will stay there until I click it away, now I don’t miss it any more! I’m also using the new Java 6 tray icon functionality, to show a little popup balloon.




I put the code (under the Apache license) in SVN over here: http://coderthoughts.googlecode.com/svn/trunk/irc-alerter. No built executables yet, but you can simply check it out and run it with the following command:
mvn install camel:run -Dirc.alerter.channels=c:\path\to\channels.xml
since it’s pure java, it should work on mac, linux etc too :) I used Maven 2.0.9 and Java 6.

The format of the channels.xml file is as follows:

<channels>
 <match string="davidb"/> <!-- the text you want to match -->
 <password file="c:/davidb/etc/camel-irc.pwd"/>
 <channel name="cxf" user="my_user" nick="my_user" host="irc.codehaus.org"/>
 <channel name="somechannel" user="davidb" nick="davidb_camel" host="some_host" port="6667"/>
</channels>

So this one matches any message that contains 'davidb'. Obviously you’d put your match in there.
For each channel you specify the channel name, username, nickname, hostname and optionally the port. You probably want to use a different nick name than the one you use from your ordinary IRC client.
The passwords for the various servers are in a separate file, which you can put in an encrypted directory in your file system. These are properties files, your camel-irc.pwd file could look like this:

my_user@irc.codehaus.org=somepass
someuser@somehost=someotherpass

This has been a lot of fun to do. I’m still amazed how easy it was to create this app using Camel, and I’ll never miss an IRC ping ever again! (Well, I hope).

Source code - can be checked out from Subversion here: http://coderthoughts.googlecode.com/svn/trunk/irc-alerter

4 comments:

gashcrumb said...

That's excellent, I'll have to try this. I've been contemplating perhaps doing a bridge between IRC and Google talk (well XMPP) so I could just respond to messages from either my phone or browser regardless of where I'm at, that'd totally beat leaving an IRC client open all the time.

Heath said...

Did you consider using the Eclipse Communication Framework? It integrates with eclipse and has an IRC connector.

Scott Lewis said...

Hi David.

Heath said:

Did you consider using the Eclipse Communication Framework? It integrates with eclipse and has an IRC connector.

Some details of bot framework at

http://wiki.eclipse.org/Bot_Framework
http://wiki.eclipse.org/IRC_Bot

davidb said...

I have just updated the code to support SSL, to define an ssl-enabled channel add the secure attribute to the definition, like this:
<channel name="somesslchannel" user="davidb" nick="davidb_camel" host="some_host" port="6667" secure="yes"/>