[Twisted-Python] Writing a Jabber client

E.A.M. Huijbers E.A.M.Huijbers at student.tue.nl
Mon May 24 11:10:09 EDT 2004


Hi all,

I'm having trouble writing a Jabber client with Twisted. I came across a 
simple sample[0], and tried to build out from it, but for some reason 
it's barely working.

When I run the application in the attached script, the logon goes fine, 
and I can receive messages sent to the account, but it never seems to 
receive subscription requests. When I ran it on an account that already 
had some items on the contact list, I did receive <presence> messages to 
indcate that a user changed status, but I don't receive <presence 
type="subscribe"> messages...

Ultimately, I tacked a "/*" handler on to the code to see if I was 
receiving any packets at all, but the only thing that seems to trigger 
anything are messages.

This is very frustrating for me. Is it a problem with the code, or am I 
missing something in the Jabber protocol?

Any help would be greatly appreciated.

- Rico

P.S: Please don't mind the code, I know it's a bit (a lot) hackish right 
now, but my first step is to get it running. I'll make it beautiful 
afterwards ;) .

[0] http://randomthoughts.vandorp.ca/WK/blog/706?t=item

##### code starts here #####

from twisted.protocols.jabber import client, jid
from twisted.protocols import xmlstream
from twisted.xish import domish

from twisted.internet import reactor

name = 'Foo'
server='bar.com'
resource = 'PythonBot'
password = 'foobar'
me = '%s@%s/%s' % (name, server, resource)

thexmlstream = None
tryandregister = 1

def initOnline(xmlstream):
    global factory
    print 'Initializing...'
    xmlstream.addObserver('/message', gotMessage)
    xmlstream.addObserver('/presence', gotPresence)
    xmlstream.addObserver('/iq', gotIq)
    xmlstream.addObserver('/*', gotSomething)

def authd(xmlstream):
    thexmlstream = xmlstream
    print "we've authd!"
    print repr(xmlstream)

    #need to send presence so clients know we're
    #actually online
    presence = domish.Element(('jabber:client', 'presence'))
    presence.addElement('status').addContent('Online')
    xmlstream.send(presence)

    initOnline(xmlstream)

def gotMessage(el):
    print 'Got message: %s' % str(el.attributes)

def gotSomething(el):
    print 'Got something: %s -> %s' % (el.name, str(el.attributes))

def gotIq(el):
    print 'Got IQ: %s' % str(el.attributes)

def gotPresence(el):
    print 'We got a presence message!'
    print repr(el.attributes)
    try:
        t = el.attributes['type']
        if t == 'subscribe':
            # Grant every subscription request
            xmlstream.send(domish.Element(('jabber:client', 'presence'), 
attribs={
                'from': me,
                'to':el.attributes['from'],
                'type':'subscribed'
            }))
    except KeyError:
        # Big fat ignore
        pass

def invaliduserEvent(xmlstream):
    print 'Invalid user!'
    global tryandregister
    if tryandregister:
        tryandregister = 0
        print 'Attempting to register...'
        global factory
        factory.authenticator.registerAccount(name, password)
    else:
        global reactor
        reactor.stop()

def authfailedEvent(xmlstream):
    global reactor
    print 'Auth failed!'
    reactor.stop()

def registerfailedEvent(xmlstream):
    global reactor
    print 'Register failed!'
    reactor.stop()

myJid = jid.JID(me)
secret = password
factory = client.basicClientFactory(myJid,secret)

# Register authentication callbacks
factory.addBootstrap(xmlstream.STREAM_AUTHD_EVENT, authd)
factory.addBootstrap(client.BasicAuthenticator.INVALID_USER_EVENT, 
invaliduserEvent)
factory.addBootstrap(client.BasicAuthenticator.AUTH_FAILED_EVENT, 
authfailedEvent)
factory.addBootstrap(client.BasicAuthenticator.REGISTER_FAILED_EVENT, 
registerfailedEvent)

# Go!
reactor.connectTCP(server, 5222, factory)
reactor.run()




More information about the Twisted-Python mailing list