# :title: Twitter Relay plugin for Rbot # # Copyright John Leach 2008, http://johnleach.co.uk # # Licensed under the terms of the GNU General Public License v2 or higher # # Follows one users rss feed and announces new twitters into the configured # channels. I use it to track a dedicated Twitter user that follows channel # member's Twitter updated. This is better than following multiple user rss # feeds directly because it save bandwidth (and load on Twitter :) # # Set twitter_relay.username to the name of the twitter user to follow. # Set twitter_relay.channels to a list of the channels you want the twits # announced to (bot must be on the channel) # # Thanks to the Rbot Twitter plugin by Carter Parks and Giuseppe "Oblomov" # Bilotta # require 'rexml/rexml' require 'cgi' class TwitterRelayPlugin < Plugin Config.register Config::IntegerValue.new('twitter_relay.sleep', :default => 300, :validate => Proc.new{|v| v > 50}, :desc => "How many seconds between checking the Twitter feed") Config.register Config::StringValue.new('twitter_relay.username', :default => '', :desc => "The Twitter user to check for friend updates") Config.register Config::ArrayValue.new('twitter_relay.channels', :default => [], :desc => "List of channels to announce twits to") def initialize super @http_headers = { 'X-Twitter-Client' => 'rbot twitter relay plugin' } @last_updated = Time.now @channels = @bot.config['twitter_relay.channels'] @sleep = @bot.config['twitter_relay.sleep'] set_twitter_user(@bot.config['twitter_relay.username']) if @twitter_user.empty? or @channels.empty? error "twitter_relay.user or twitter_relay.channels config is unset!" else log "Starting twitter_relay timer for #{@sleep} seconds, following user #{@twitter_user} and announcing on channels #{@channels.join(', ')}" @timer = @bot.timer.add(@sleep) { update_statuses } end end def set_twitter_user(username) @twitter_user = URI.escape(username.to_s) @uri = @twitter_user.nil? ? nil : "http://twitter.com/statuses/friends_timeline/#{@twitter_user}.xml" end def cleanup @bot.timer.remove @timer unless @timer.nil? super end def update_statuses response = @bot.httputil.get(@uri, :headers => @http_headers, :cache => false) if response begin rex = REXML::Document.new(response) newest_time = @last_updated rex.root.elements.each("status") do |st| time = Time.parse(st.elements['created_at'].text) next if time <= @last_updated newest_time = time if newest_time < time now = Time.now # Sometimes, time can be in the future; invert the relation in this case delta = ((time > now) ? time - now : now - time) msg = st.elements['text'].to_s + " (#{Utils.secs_to_string(delta.to_i)} ago via #{st.elements['source'].to_s})" author = Utils.decode_html_entities(st.elements['user'].elements['name'].text) rescue "" @channels.each do |chan| @bot.say chan.strip, "via twitter, #{author} #{Utils.decode_html_entities(msg).ircify_html}" end end @last_updated = newest_time rescue error $! return false end return true else return false end end end plugin = TwitterRelayPlugin.new plugin.map 'twitrelay update', :action => 'update_statuses'