twitter plugin: initial commit (#145 with changes)
[rbot] / data / rbot / plugins / twitter.rb
1 #-- vim:sw=2:et
2 #++
3 #
4 # :title: Twitter Status Update for rbot
5 #
6 # Author:: Carter Parks (carterparks) <carter@carterparks.com>
7 # Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
8 #
9 # Copyright:: (C) 2007 Carter Parks
10 #
11 # Users can setup their twitter username and password and then begin updating
12 # twitter whenever
13
14 require 'rexml/rexml'
15
16 class TwitterPlugin < Plugin
17   def initialize
18     super
19     
20     class << @registry
21       def store(val)
22         val
23       end
24       def restore(val)
25         val
26       end
27     end
28   end
29   
30   # return a help string when the bot is asked for help on this plugin
31   def help(plugin, topic="")
32     return "twitter status [status] => updates your status on twitter | twitter identify [username] [password] => ties your nick to your twitter username and password"
33   end
34   
35   # update the status on twitter
36   def get_status(m, params)
37   
38     nick = params[:nick] || @registry[m.sourcenick + "_username"]
39
40     if not nick
41       m.reply "you should specify the username of the twitter touse, or identify using 'twitter identify [username] [password]'"
42       return false
43     end
44       
45     # TODO configurable count
46     uri = "http://twitter.com/statuses/user_timeline/#{URI.escape(nick)}.xml?count=3"
47     
48     response = @bot.httputil.get(uri)
49     debug response
50
51     texts = []
52     
53     if response
54       begin
55         rex = REXML::Document.new(response)
56         rex.root.elements.each("status") { |st|
57           msg = st.elements['text'].to_s + " (#{st.elements['created_at'].to_s} via #{st.elements['source'].to_s})"
58           texts << Utils.decode_html_entities(msg).ircify_html
59         }
60       rescue
61         error $!
62         m.reply "could not parse status for #{nick}"
63         return false
64       end
65       m.reply texts.reverse.join("\n")
66       return true
67     else
68       m.reply "could not get status for #{nick}"
69       return false
70     end
71   end
72   
73   # update the status on twitter
74   def update_status(m, params)
75   
76
77     unless @registry.has_key?(m.sourcenick + "_password") && @registry.has_key?(m.sourcenick + "_username")
78       m.reply "you must identify using 'twitter identify [username] [password]'"
79       return false
80     end
81       
82     uri = "http://#{URI.escape(@registry[m.sourcenick + "_username"])}:#{URI.escape(@registry[m.sourcenick + "_password"])}@twitter.com/statuses/update.xml"
83     
84     response = @bot.httputil.post(uri, "status=#{URI.escape(params[:status].to_s)}")
85     debug response
86     
87     if response.class == Net::HTTPOK
88       m.reply "status updated"
89     else
90       m.reply "could not update status"
91     end
92   end
93   
94   # ties a nickname to a twitter username and password
95   def identify(m, params)
96     @registry[m.sourcenick + "_username"] = params[:username].to_s
97     @registry[m.sourcenick + "_password"] = params[:password].to_s
98     m.reply "you're all setup!"
99   end
100 end
101
102 # create an instance of our plugin class and register for the "length" command
103 plugin = TwitterPlugin.new
104 plugin.map 'twitter identify :username :password', :action => "identify", :public => false
105 plugin.map 'twitter update *status', :action => "update_status", :threaded => true
106 plugin.map 'twitter status [:nick]', :action => "get_status", :threaded => true
107