from twisted.words.protocols.jabber import client, jid from twisted.words.xish import domish, xmlstream from twisted.application import internet, service # Python bindings for Growl come with the SDK: # http://growl.info/downloads_developers.php from Growl import GrowlNotifier, Image JID = 'test@example.com' PASSWORD = 'secret' HOST = 'talk.google.com' def authenticated(stream): presence = domish.Element(('jabber:client','presence')) presence.addElement('status').addContent('Online') stream.send(presence) stream.addObserver('/message', lambda x: receivedMessage(stream, x)) stream.addObserver('/presence', lambda x: receivedPresence(stream, x)) #stream.addObserver('/*', lambda x: print(x.toXml())) roster_q = domish.Element(('jabber:client', 'iq')) roster_q['type'] = 'get' roster_q.addElement(('jabber:iq:roster', 'query')) stream.send(roster_q) def receivedMessage(stream, x): for e in x.elements(): if e.name == "body" and x.hasAttribute('type') and x['type'] == 'chat': g = GrowlNotifier(notifications=['xmpp'], applicationIcon=Image.imageWithIconForFile('/bin/sh')) g.register() message = str(e).split("\n") if len(message) > 1: g.notify('xmpp', message[0], "\n".join(message[1:])) else: g.notify('xmpp', '', "\n".join(message)) def receivedPresence(stream, x): if x.hasAttribute('type') and x['type'] == 'subscribe': presence = domish.Element(('jabber:client', 'presence')) presence['to'] = x['from'] presence['type'] = 'subscribed' stream.send(presence) application = service.Application('xmpp-growl') f = client.XMPPClientFactory(jid.JID(JID), PASSWORD) f.addBootstrap('//event/stream/authd', authenticated) internet.TCPClient(HOST, 5222, f).setServiceParent(service.IServiceCollection(application))