Jabber in Twisted

Rico Huijbers E.A.M.Huijbers at REMOVEstudent.tue.nl
Fri May 21 14:10:37 EDT 2004


Does anybody have experience in writing Jabber clients 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 Python-list mailing list