Twitter + Jabber = Jitter?
I’ve been playing with Twitter lately – I created a Booko Twitter account to reserve the account name while I consider using it. I’ve got my own Twitter account and I had a bit of a play around with it, but honestly using Twitter via the web seems like a drag. Yet another page to watch. Plus, I subscribed to the MelbTransport guy’s page and all I could think was “Can’t I filter this to show me only the updates I’m interested in?” – apparently no, you can’t.
I had a look at the applications out there to manage your tweets but all I could think was “Man, another app to run, another distraction.”. I’ve already got email and IM, I don’t really want another app bouncing in the Dock to tell me someone’s posted a message. So, I got to thinking, maybe there’s a way to get Twitter messages to be sent to me via IM? Had a brief look around but didn’t immediately find anything suitable. A quick Google however netted two interesting Ruby Gems – twitter and xmpp4r-simple, which give you a nice Ruby interface to Twitter and Jabber. So, after a couple of hours of hacking around, getting my Twitter account temporarily rate limited and creating Jabber accounts, I’ve got a very simple Twitter <-> Jabber gateway going.
It will post tweets to your Jabber account & you can reply! Your reply will get posted to Twitter. As an added bonus I added filtering so I can see only what I want from MelbTransport guy’s updates. You can easily add your own filters in there – hopefully it’s pretty straight forward.
Now, I know this isn’t beautiful, elegant Ruby code – feel free to leave constructive criticism in the comments.
#!/usr/bin/env ruby
require 'rubygems'
require 'twitter'
require 'xmpp4r-simple'
require 'benchmark'
jabber_user="sendinguser@jabber.org.au"
jabber_pass=""
$receiving_jabber = "receivinguser@jabber.org.au"
twitter_user="twitteruser"
twitter_pass=""
jabber = twitter = nil
cj = Benchmark.realtime {jabber = Jabber::Simple.new(jabber_user, jabber_pass)}
puts "Connecting to Jabber: #{cj}"
ct = Benchmark.realtime {twitter = Twitter::Base.new(twitter_user, twitter_pass) }
puts "Connecting to Twitter: #{ct}"
def filters(status)
if status.user.name == "MelbTransport"
yield if status.text =~ /Craigieburn|Broadmeadows|Upfield/
else
yield
end
end
def get_tweets(twitter, tweets, jabber)
begin
twitter.timeline.reverse.each do |s|
if tweets[s.id].nil?
filters(s) { jabber.deliver($receiving_jabber, "#{s.user.name} says: #{s.text}") }
tweets[s.id] = "Sent"
end
end
rescue Twitter::CantConnect
puts "Can't connect. Sleeping."
sleep 120
retry
end
end
def post_tweets(twitter, jabber)
jabber.received_messages { |msg| twitter.post(msg.body) if msg.type == :chat }
end
def main(twitter, jabber)
tweets = {}
while true
puts "Action!"
get_tweets(twitter, tweets, jabber)
post_tweets(twitter, jabber)
sleep 60
end
end
main(twitter, jabber)
Edits:Reversed the order of the timeline to match how they should show up in IM (IE – oldest at the top, newest at the bottom.