I recently had a project to setup an Instant Messenger Robot for Windows Live Messenger. A IM robot can have many purposes such as:
- Keeping track of when contacts are online/offline and when they were last seen.
- Broadcasting a message to all contacts.
- Automatically answering common questions.
- Notifying contacts about new events. A newer site http://notify.me has a nice IM Robot that notifies you when a RSS feed is updated. This works well in conjuction with sites like craigslist.
- Keeping track of code snippets
- Checking the weather
- Checking server status
An IM robot can be setup to automate just about any task.
What IM Library to Use
Setting up a IM robot can be a bit of work especially if starting from scratch. There are a lot of libraries out there that can be used to help simplify the process. The trouble is a lot of libraries are not kept up to date and fail to work as IM protocols change.
I did some digging and found a library that would provide a good foundation to build a IM Robot that can do just about anything. I saw implementations in PHP, C, Java, Perl and Python. After some testing I concluded the Java MSN Library would be a very good fit.
How To Use It
Using this library with java is pretty straight forward. First, the library must be added to the classpath. The step to take to complete this will depend on how your developing your java code. The most basic method to add a library to your classpath is to do this at run time with a command such as:
java -classpath MyLibrary.jar MyPackage.MyClass
A better approach would be to setup the classpath in a manifest file. The manifest file is then placed inside the jar file and tells the executable jar where to look for the libraries. This manifest file should look something like the following (note the class-path on line 5):
Manifest-Version: 1.0 Ant-Version: Apache Ant 1.7.1 Created-By: 14.3-b01 (Sun Microsystems Inc.) Main-Class: imstatus.Main Class-Path: lib/jml-1.0b4-full.jar lib/httpcore-4.0.1.jar lib/mysql-co nnector-java-5.1.6-bin.jar X-COMMENT: Main-Class will be added automatically by build
This is setup so that the 3 required libraries are in the lib folder. These 3 libraries are needed for setting up an IM robot and can be downloaded from the following locations:
Now that the libraries are setup we can begin to use them.
Developing the IM Robot Code
There are a few examples of using the Java MSN Library on the main page. However, they are a tad confusing as it creates a new BasicMessenger class. This is confusing as the library already has a BasicMessenger class which is abstract. The library also has a SimpleMessenger class which is a subclass of BasicMessenger. This class appears to be the correct implementation that we would want to use to create a new IM Robot. However, the original authors made the constructor protected so that we cannot instantiate the class outside of the original package. Since we want a simple way to create an IM Robot I have modified the original source code to have a public constructor for the SimpleMessenger class. This new package can be downloaded from our server.
With this new package we can very easily create a new IM Robot with the following two lines of code (make sure to replace yourLogin and yourPassword):
SimpleMessenger messenger = new SimpleMessenger(Email.parseStr("yourLogin@msn.com"), "yourPassword"); messenger.login();
With that code in our main funtion we can run it and test that the Robot automatically logs into Windows Live Messenger.
Of course, that code just logs the Robot into Windows Live Messenger. The next step is to setup the robot to do something interesting. This is one feature that is very nice about the Java MSN Library as it has listeners for many different events. For example we can detect when the robot has finished logging in with the following:
messenger.addListener(new MsnAdapter() { // Setup the login completed event @Override public void loginCompleted(MsnMessenger messenger) { MsnOwner owner = messenger.getOwner(); owner.setInitStatus(MsnUserStatus.ONLINE); owner.setStatus(MsnUserStatus.ONLINE); // Setup the contact list event messenger.addContactListListener(new ContactListAdapter()); } });
Then we can take this a step further and detect when a status changes for one of the robots contacts with something like the following:
messenger.addListener(new MsnAdapter() { // Setup the login completed event @Override public void loginCompleted(MsnMessenger messenger) { MsnOwner owner = messenger.getOwner(); owner.setInitStatus(MsnUserStatus.ONLINE); owner.setStatus(MsnUserStatus.ONLINE); // Setup the contact list event messenger.addContactListListener(new ContactListAdapter()); } });
The above code will detect when the robot has finished logging in and then setup a new listener to detect when a contacts status has changed. The new listener invokes the ContactListAdapter class when a status has changed. This contactListAdapter class is setup as followes:
class ContactListAdapter extends MsnContactListAdapter { @Override public void contactStatusChanged(MsnMessenger messenger, MsnContact contact) { System.out.println(contact.getEmail()+" is currently "+contact.getStatus()); // Can add code here to store the status in a database } }
We can still take this a step further and setup the robot to handle automatically adding contacts when a contact requests it. This logic can be added to the ContactListAdapter class with something like the following:
class ContactListAdapter extends MsnContactListAdapter { @Override public void contactListSyncCompleted(MsnMessenger messenger) { MsnContact[] contacts = messenger.getContactList().getContactsInList(MsnList.AL); for (int i = 0; i < contacts.length; i++) { contactStatusChanged(messenger,contacts[i]); } } @Override public void contactAddedMe(MsnMessenger messenger, MsnContact contact) { messenger.addFriend(contact.getEmail(), contact.getDisplayName()); } @Override public void contactAddedMe(MsnMessenger messenger, MsnContactPending[] pending){ for(int i=0; i<pending.length; i++){ messenger.addFriend(pending[i].getEmail(), pending[i].getDisplayName()); } } @Override public void contactStatusChanged(MsnMessenger messenger, MsnContact contact) { System.out.println(contact.getEmail()+" is currently "+contact.getStatus()); // Can add code here to store the status in a database } }
There you have it! Put all of the above code together and you will have a robot that knows how to automatically add contacts and keep track of when a contact’s status changes.