#!/usr/bin/python # Simple Jabber/Twitter gateway. # Copyright (C) 2009, Kees Cook # License: GPLv3 import twitter import xmpp import sys, time import configobj client_name = 'JabTwit' client_url = 'http://www.outflux.net' client_version = '0.1' client_conf = 'jabtwit.conf' # Load configuration cfg = configobj.ConfigObj(client_conf) required = { 'twitter_user': 'Your Twitter username', 'twitter_password': 'Your Twitter password', 'jabber_user': 'Jabber JID for this bot (bot@jabber.domain)', 'jabber_password': 'Jabber password for this bot', 'owner': 'Your Jabber JID (self@jabber.domain)' } missed = False for field in sorted(required): if field not in cfg.keys(): print >>sys.stderr, "%s is missing required field '%s': %s" % \ (client_conf, field, required[field]) missed = True if missed: sys.exit(1) api = None # Authenticate twitter via OAuth (totally broken???) if 0 and not 'access_token' in cfg.keys(): import oauthtwitter req = oauthtwitter.OAuthApi(cfg['CONSUMER_KEY'], cfg['CONSUMER_SECRET']) request_token = req.getRequestToken() authorization_url = req.getAuthorizationURL(request_token) print >>sys.stderr, "enter PIN after authenticating: %s" % (authorization_url) pin = sys.stdin.readline().strip() print '[%s]' % (request_token) req = oauthtwitter.OAuthApi(cfg['CONSUMER_KEY'], cfg['CONSUMER_SECRET'], request_token) print '[%s]' % (pin) access_token = req.getAccessToken(pin) cfg['access_token'] = access_token cfg.write() api = oauthtwitter.OAuthApi(cfg['CONSUMER_KEY'], cfg['CONSUMER_SECRET'], cfg['access_token']) else: api = twitter.Api(username=cfg['twitter_user'], password=cfg['twitter_password']) # Source only works with OAuth now :( api.SetXTwitterHeaders(client_name,client_url,client_version) api.SetSource('%s' % (client_url, client_name)) # Get current state status = api.GetFriendsTimeline(count=1)[0] since_id = status.id twitter_refresh = time.time() # force immediate update # Set up Jabber jid=xmpp.JID(cfg['jabber_user']) user,server,password=jid.getNode(),jid.getDomain(),cfg['jabber_password'] conn=xmpp.Client(server)#,debug=[]) def jabber_message(conn,mess): global twitter_refresh user=mess.getFrom() # Verify we know who we're dealing with if str(user).split('/')[0] != cfg['owner']: conn.send(xmpp.Message(mess.getFrom(),"I do not know you, sorry.")) return text=mess.getBody() api.PostUpdate(text) # force immediate refresh twitter_refresh = time.time() #conn.send(xmpp.Message(mess.getFrom(),"[sent]")) def Disconnected(conn): conn.reconnectAndReauth() def cycle_once(conn): try: conn.Process(1) except KeyboardInterrupt: return 0 return 1 def cycle_forever(conn): global twitter_refresh, since_id while cycle_once(conn): now = time.time() if now > twitter_refresh: #conn.send(xmpp.Message(cfg['owner'],"[twitter refresh (%d)]" % (since_id))) twitter_refresh = now + 60 updates = api.GetFriendsTimeline(since_id=since_id) for status in updates: conn.send(xmpp.Message(cfg['owner'],"%s: %s" % (status.user.screen_name, status.text))) since_id = status.id conres=conn.connect((server,int(cfg.get('jabber_port','5222'))), secure=int(cfg.get('jabber_secure','1'))) if not conres: print "Unable to connect to server %s!"%server sys.exit(1) if conres<>'tls': print "Warning: unable to estabilish secure connection - TLS failed!" authres=conn.auth(user,password) if not authres: print "Unable to authorize on %s - check login/password."%server sys.exit(1) if authres<>'sasl': print "Warning: unable to perform SASL auth os %s. Old authentication method used!"%server conn.RegisterHandler('message',jabber_message) conn.sendInitPresence() conn.RegisterDisconnectHandler(Disconnected) cycle_forever(conn)