msnp.py Tutorial

Manish Jethani (manish_jethani -@- yahoo.com)

Version 0.4 - Dec 24, 2003


1. So what is it?

msnp.py is an implementation of the MSN instant messaging protocol in the Python programming language. This pure Python package makes it extremely easy, quick, and efficient to build applications that need to interact with the MSN messaging service.

msnp.py is based on the works of Mike Mintz.

2. Let's get started

Assuming the package has been installed, it's time to get our hands dirty.

Note: If you haven't yet installed it, it can be downloaded as a tarball/zip file, or as a Windows installable. Before msnp.py, you need to have a Python 2.3+ distribution installed on your system. If you're not familiar with the Python language, it's never too late to start!

2.1 Import the package

Just start up your Python interpreter, and issue the following command:

>>> import msnp

This will silently import the msnp package into your current namespace. Let's see the list of available msnp objects:

>>> dir(msnp)
['Chat', 'ChatCallbacks', 'Error', 'Friend', 'FriendList', 'Group', 'Lists',
'PrivacyModes', 'Session', 'SessionCallbacks', 'States', '__all__',
'__builtins__', '__doc__', '__file__', '__name__', '__path__', 'chat',
'codec', 'command', 'error', 'friend', 'net', 'protocol', 'session']

That was a listing from version 0.4 of msnp.py.

2.2 The 3-step login

We'll start by writing a program to login. Let's just do it at the interpreter prompt:

>>> import msnp
>>> msn = msnp.Session()
>>> msn.login('trinity@hotmail.com', 'Z10N0101')

That's it! No kidding.

Well, of course, that login is pretty much useless; the server will throw us off in no time. To do anything useful, we must write a proper program, with some kind of an event loop.

2.3 Event loop

import msnp
import time

msn = msnp.Session()
msn.login('trinity@hotmail.com', 'Z10N0101')

while True:
Now this should work better. At least the server's not going to throw us off. Calling the process method at regular intervals ensures that the program can keep interacting with the MSN server(s). If you're writing a GUI application, you'll probably set up a timer for triggering process calls.

But we still wouldn't know what's happening. Which brings us to the next point. Callbacks.

2.4 Callbacks

There needs to be a way for msnp.py to tell us what's happening; things like ``Who's online?'', ``What's my display (nick) name?'', ``Who's trying to message me?'', and so on. This is done by means of a callback interface--a set of functions that need to be implemented by the client, for listening on specific events. To start with, we'll implement only one function in our callback interface implementation.
import msnp
import time

class MsnListener(msnp.SessionCallbacks):
    def state_changed(self, state):
        if state == msnp.States.ONLINE:
            print 'You are now online.'

msn = msnp.Session(MsnListener())
msn.login('trinity@hotmail.com', 'Z10N0101')

while True:
The only thing added over the previous program is the MsnListener class, and the extra parameter passed to the msnp.Session constructor. MsnListener implements only one callback function--state_changed, which tells the client about the presence state of the user logged in. The state parameter will have a value of msnp.States.ONLINE, when the user has just logged in. See dir(msnp.States) for a complete list of supported presence states.

As an exercise, you could implement the friend_online callback function of the msnp.SessionCallbacks class. This function will be called once, for every online contact on your friend list, immediately after logging in, and every time an online contact changes his presence state. See help(msnp.SessionCallbacks.friend_online) for help on the parameters.

2.5 Instant messages

Here's a program that echoes all incoming messages back to the sender:
# echobot.py -- echo messages back to sender

import msnp
import time

class MsnChatListener(msnp.ChatCallbacks):
    def message_received(self, passport_id, display_name, text, charset):
        print '%s: %s' % (passport_id, text)
        self.chat.send_message(text, charset)

class MsnListener(msnp.SessionCallbacks):
    def chat_started(self, chat):
        callbacks = MsnChatListener()
        chat.callbacks = callbacks
        callbacks.chat = chat

msn = msnp.Session(MsnListener())
msn.login('trinity@hotmail.com', 'Z10N0101')

while True:
    msn.process(chats = True)
First, note that this time we've implemented the chat_started callback function, and dropped support for state_changed. The chat_started function is called either when you've requested a chat conversation (using the start_chat method) with another MSN contact, or when an MSN contact has invited you to chat. In either case, msnp.py handles all the gory details itself, and calls chat_started when you're ready to chat. In this example, a chat is never started by us, but instead as a result of someone inviting us.

chat_started takes a single parameter--the instance of msnp.Chat representing the chat session. The chat session is much like the main login session; it has its own process method; it also has its own callback interface, of which MsnChatListener is an implementation. On the second and third lines of chat_started, we're letting chat and callbacks know about each other.

In MsnChatListener, we've implemented the message_received callback, which (so obviously) is called when a message is received from another user. To echo the message back to the sender, we simply call send_message on self.chat. See help(msnp.ChatCallbacks.message_received), help(msnp.ChatCallbacks.send_message).

Did you notice the modified call to msn.process, on the second last line? The chats = True option tells msn to process commands for all currently active chat sessions.

I hope you're impressed ;-) As an exercise, you could write a program that sends a (possibly random) message to every contact that comes online. Hints: msnp.SessionCallbacks.friend_online, msnp.Session.start_chat, msnp.SessionCallbacks.chat_started, msnp.ChatCallbacks.friend_joined, msnp.Chat.send_message. (Don't blame me if you get sued for this.)

3. Topics

<!-- TODO: Fill this space. -->

SourceForge.net Logo   Valid HTML 4.01!

manish_jethani -@- yahoo.com

Copyright © 2003 Manish Jethani