4 # :title: Twitter Status Update for rbot
6 # Author:: Carter Parks (carterparks) <carter@carterparks.com>
7 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
9 # Copyright:: (C) 2007 Carter Parks
10 # Copyright:: (C) 2007 Giuseppe Bilotta
12 # Users can setup their twitter username and password and then begin updating
18 class TwitterPlugin < Plugin
19 Config.register Config::IntegerValue.new('twitter.status_count',
20 :default => 1, :validate => Proc.new { |v| v > 0 && v <= 10},
21 :desc => "Maximum number of status updates shown by 'twitter status'")
36 'X-Twitter-Client' => 'rbot twitter plugin'
40 # return a help string when the bot is asked for help on this plugin
41 def help(plugin, topic="")
42 return "twitter status [nick] => show nick's (or your) status | twitter update [status] => updates your status on twitter | twitter identify [username] [password] => ties your nick to your twitter username and password"
45 # update the status on twitter
46 def get_status(m, params)
48 nick = params[:nick] || @registry[m.sourcenick + "_username"]
51 m.reply "you should specify the username of the twitter touse, or identify using 'twitter identify [username] [password]'"
55 user = URI.escape(nick)
57 count = @bot.config['twitter.status_count']
58 uri = "http://twitter.com/statuses/user_timeline/#{user}.xml?count=#{count}"
60 response = @bot.httputil.get(uri, :headers => @header, :cache => false)
67 rex = REXML::Document.new(response)
68 rex.root.elements.each("status") { |st|
69 # month, day, hour, min, sec, year = st.elements['created_at'].text.match(/\w+ (\w+) (\d+) (\d+):(\d+):(\d+) \S+ (\d+)/)[1..6]
70 # debug [year, month, day, hour, min, sec].inspect
71 # time = Time.local(year.to_i, month, day.to_i, hour.to_i, min.to_i, sec.to_i)
72 time = Time.parse(st.elements['created_at'].text)
75 msg = st.elements['text'].to_s + " (#{Utils.secs_to_string(delta.to_i)} ago via #{st.elements['source'].to_s})"
76 texts << Utils.decode_html_entities(msg).ircify_html
80 m.reply "could not parse status for #{nick}"
83 m.reply texts.reverse.join("\n")
86 m.reply "could not get status for #{nick}"
91 # update the status on twitter
92 def update_status(m, params)
95 unless @registry.has_key?(m.sourcenick + "_password") && @registry.has_key?(m.sourcenick + "_username")
96 m.reply "you must identify using 'twitter identify [username] [password]'"
100 user = URI.escape(@registry[m.sourcenick + "_username"])
101 pass = URI.escape(@registry[m.sourcenick + "_password"])
102 uri = "http://#{user}:#{pass}@twitter.com/statuses/update.xml"
104 msg = params[:status].to_s
107 m.reply "your status message update is too long, please keep it under 140 characters if possible, 160 characters maximum"
112 m.reply "your status message is longer than 140 characters, which is not optimal, but I'm going to update anyway"
115 source = "source=rbot"
116 msg = "status=#{CGI.escape(msg)}"
117 body = [source,msg].join("&")
119 response = @bot.httputil.post(uri, body, :headers => @header)
122 if response.class == Net::HTTPOK
123 m.reply "status updated"
125 m.reply "could not update status"
129 # ties a nickname to a twitter username and password
130 def identify(m, params)
131 @registry[m.sourcenick + "_username"] = params[:username].to_s
132 @registry[m.sourcenick + "_password"] = params[:password].to_s
133 m.reply "you're all setup!"
137 # create an instance of our plugin class and register for the "length" command
138 plugin = TwitterPlugin.new
139 plugin.map 'twitter identify :username :password', :action => "identify", :public => false
140 plugin.map 'twitter update *status', :action => "update_status", :threaded => true
141 plugin.map 'twitter status [:nick]', :action => "get_status", :threaded => true