summaryrefslogtreecommitdiff
path: root/data/rbot
diff options
context:
space:
mode:
authorNeoLobster <neolobster@snugglenets.com>2010-09-06 04:35:02 -0500
committerGiuseppe Bilotta <giuseppe.bilotta@gmail.com>2010-09-07 19:52:21 +0200
commit66ed4d5c2a9a4a018583dc5165e4f3b68d9781ba (patch)
treef3ea2de0dfed0cacf4236784b52437724d300f91 /data/rbot
parenta8f5948d947b0502a06fa56db301576a9b694ecb (diff)
twitter: add OAuth support
Module now requires twitter.key and twitter.secret config parameters for write access and private users' statuses. Added twitter authorize, twitter deauthorize, and twitter pin features, removed twitter identify feature, as basic authentication is no longer supported.
Diffstat (limited to 'data/rbot')
-rw-r--r--data/rbot/plugins/twitter.rb154
1 files changed, 99 insertions, 55 deletions
diff --git a/data/rbot/plugins/twitter.rb b/data/rbot/plugins/twitter.rb
index ec5e3b92..df834b0c 100644
--- a/data/rbot/plugins/twitter.rb
+++ b/data/rbot/plugins/twitter.rb
@@ -5,6 +5,7 @@
#
# Author:: Carter Parks (carterparks) <carter@carterparks.com>
# Author:: Giuseppe "Oblomov" Bilotta <giuseppe.bilotta@gmail.com>
+# Author:: "NeoLobster" <neolobster@snugglenets.com>
#
# Copyright:: (C) 2007 Carter Parks
# Copyright:: (C) 2007 Giuseppe Bilotta
@@ -12,16 +13,26 @@
# Users can setup their twitter username and password and then begin updating
# twitter whenever
+require 'oauth'
+require 'yaml'
require 'rexml/rexml'
-require 'cgi'
class TwitterPlugin < Plugin
- Config.register Config::IntegerValue.new('twitter.status_count',
- :default => 1, :validate => Proc.new { |v| v > 0 && v <= 10},
- :desc => "Maximum number of status updates shown by 'twitter status'")
- Config.register Config::IntegerValue.new('twitter.friends_status_count',
- :default => 3, :validate => Proc.new { |v| v > 0 && v <= 10},
- :desc => "Maximum number of status updates shown by 'twitter friends status'")
+ Config.register Config::StringValue.new('twitter.key',
+ :default => "",
+ :desc => "Twitter OAuth Consumer Key")
+
+ Config.register Config::StringValue.new('twitter.secret',
+ :default => "",
+ :desc => "Twitter OAuth Consumer Secret")
+
+ Config.register Config::IntegerValue.new('twitter.status_count',
+ :default => 1, :validate => Proc.new { |v| v > 0 && v <= 10},
+ :desc => "Maximum number of status updates shown by 'twitter status'")
+
+ Config.register Config::IntegerValue.new('twitter.friends_status_count',
+ :default => 3, :validate => Proc.new { |v| v > 0 && v <= 10},
+ :desc => "Maximum number of status updates shown by 'twitter friends status'")
def initialize
super
@@ -34,47 +45,48 @@ class TwitterPlugin < Plugin
val
end
end
-
- @header = {
- 'X-Twitter-Client' => 'rbot twitter plugin'
- }
end
- # return a help string when the bot is asked for help on this plugin
def help(plugin, topic="")
- return "twitter status [nick] => show nick's (or your) status, use 'twitter friends status [nick]' to also show the friends' timeline | twitter update [status] => updates your status on twitter | twitter identify [username] [password] => ties your nick to your twitter username and password | twitter actions [on|off] => enable/disable twitting of actions (/me does ...)"
+ return "twitter status [nick] => show nick's (or your) status, use 'twitter friends status [nick]' to also show the friends' timeline | twitter update [status] => updates your status on twitter | twitter authorize => Generates an authorization URL which will give you a PIN to authorize the bot to use your twitter account. | twitter pin [pin] => Finishes bot authorization using the PIN provided by the URL from twitter authorize. | twitter deauthorize => Makes the bot forget your Twitter account. | twitter actions [on|off] => enable/disable twitting of actions (/me does ...)"
end
# update the status on twitter
def get_status(m, params)
-
- nick = params[:nick] || @registry[m.sourcenick + "_username"]
-
friends = params[:friends]
+ if @registry.has_key?(m.sourcenick + "_access_token")
+ @access_token = YAML::load(@registry[m.sourcenick + "_access_token"])
+ nick = params[:nick] || @access_token.params[:screen_name]
+ else
+ if friends
+ m.reply "You are not authorized with Twitter. Please use 'twitter authorize' first to use this feature."
+ return false
+ end
+ nick = params[:nick]
+ end
if not nick
- m.reply "you should specify the username of the twitter touse, or identify using 'twitter identify [username] [password]'"
+ m.reply "you should specify the username of the twitter to use, or identify using 'twitter authorize'"
return false
end
+ count = @bot.config['twitter.friends_status_count']
user = URI.escape(nick)
-
- count = @bot.config['twitter.status_count']
- unless friends
- uri = "http://twitter.com/statuses/user_timeline/#{user}.xml?count=#{count}"
+ if @registry.has_key?(m.sourcenick + "_access_token")
+ if friends
+ #no change to count variable
+ uri = "https://api.twitter.com/1/statuses/friends_timeline.xml?count=#{count}"
+ response = @access_token.get(uri).body
+ else
+ count = @bot.config['twitter.status_count']
+ uri = "https://api.twitter.com/1/statuses/user_timeline.xml?screen_name=#{user}&count=#{count}"
+ response = @access_token.get(uri).body
+ end
else
- count = @bot.config['twitter.friends_status_count']
- auth = ""
- if m.private?
- auth << URI.escape(@registry[m.sourcenick + "_username"])
- auth << ":"
- auth << URI.escape(@registry[m.sourcenick + "_password"])
- auth << "@"
- end
- uri = "http://#{auth}twitter.com/statuses/friends_timeline/#{user}.xml"
+ #unauthorized user, will try to get from public timeline the old way
+ uri = "http://twitter.com/statuses/user_timeline/#{user}.xml?count=#{count}"
+ response = @bot.httputil.get(uri, :cache => false)
end
-
- response = @bot.httputil.get(uri, :headers => @header, :cache => false)
debug response
texts = []
@@ -124,35 +136,66 @@ class TwitterPlugin < Plugin
end
end
- # update the status on twitter
- def update_status(m, params)
-
+ def deauthorize(m, params)
+ if @registry.has_key?(m.sourcenick + "_request_token")
+ @registry.delete(m.sourcenick + "_request_token")
+ end
+ if @registry.has_key?(m.sourcenick + "_access_token")
+ @registry.delete(m.sourcenick + "_access_token")
+ end
+ m.reply "Done! You can reauthorize this account in the future by using 'twitter authorize'"
+ end
- unless @registry.has_key?(m.sourcenick + "_password") && @registry.has_key?(m.sourcenick + "_username")
- m.reply "you must identify using 'twitter identify [username] [password]'"
- return false
+ def authorize(m, params)
+ #remove all old authorization data
+ if @registry.has_key?(m.sourcenick + "_request_token")
+ @registry.delete(m.sourcenick + "_request_token")
+ end
+ if @registry.has_key?(m.sourcenick + "_access_token")
+ @registry.delete(m.sourcenick + "_access_token")
end
- user = URI.escape(@registry[m.sourcenick + "_username"])
- pass = URI.escape(@registry[m.sourcenick + "_password"])
- uri = "http://#{user}:#{pass}@twitter.com/statuses/update.xml"
+ key = @bot.config['twitter.key']
+ secret = @bot.config['twitter.secret']
+ @consumer = OAuth::Consumer.new(key, secret, {
+ :site => "https://api.twitter.com",
+ :request_token_path => "/oauth/request_token",
+ :access_token_path => "/oauth/access_token",
+ :authorize_path => "/oauth/authorize"
+ } )
+ @request_token = @consumer.get_request_token
+ @registry[m.sourcenick + "_request_token"] = YAML::dump(@request_token)
+ m.reply "Go to this URL to get your authorization PIN, then use 'twitter pin <pin>' to finish authorization: " + @request_token.authorize_url
+ end
- msg = params[:status].to_s
+ def pin(m, params)
+ unless @registry.has_key?(m.sourcenick + "_request_token")
+ m.reply "You must first use twitter authorize to get the PIN"
+ return false
+ end
+ @request_token = YAML::load(@registry[m.sourcenick + "_request_token"])
+ @access_token = @request_token.get_access_token( { :oauth_verifier => params[:pin] } )
+ @registry[m.sourcenick + "_access_token"] = YAML::dump(@access_token)
+ m.reply "Okay, you're all set"
+ end
- if msg.length > 160
- m.reply "your status message update is too long, please keep it under 140 characters if possible, 160 characters maximum"
- return
+ # update the status on twitter
+ def update_status(m, params)
+ unless @registry.has_key?(m.sourcenick + "_access_token")
+ m.reply "You must first authorize your Twitter account before tweeting."
+ return false;
end
+ @access_token = YAML::load(@registry[m.sourcenick + "_access_token"])
+
+ uri = "https://api.twitter.com/statuses/update.json"
+ msg = params[:status].to_s
if msg.length > 140
- m.reply "your status message is longer than 140 characters, which is not optimal, but I'm going to update anyway"
+ m.reply "your status message update is too long, please keep it under 140 characters"
+ return
end
- source = "source=rbot"
- msg = "status=#{CGI.escape(msg)}"
- body = [source,msg].join("&")
-
- response = @bot.httputil.post(uri, body, :headers => @header)
+ response = @access_token.post(uri, { :status => msg })
debug response
reply_method = params[:notify] ? :notify : :reply
@@ -167,7 +210,7 @@ class TwitterPlugin < Plugin
def identify(m, params)
@registry[m.sourcenick + "_username"] = params[:username].to_s
@registry[m.sourcenick + "_password"] = params[:password].to_s
- m.reply "you're all setup!"
+ m.reply "you're all set up!"
end
# update on ACTION if the user has enabled the option
@@ -198,9 +241,10 @@ end
# create an instance of our plugin class and register for the "length" command
plugin = TwitterPlugin.new
-plugin.map 'twitter identify :username :password', :action => "identify", :public => false
plugin.map 'twitter update *status', :action => "update_status", :threaded => true
-plugin.map 'twitter status [:nick]', :action => "get_status", :threaded => true
+plugin.map 'twitter authorize', :action => "authorize", :public => false
+plugin.map 'twitter deauthorize', :action => "deauthorize", :public => false
+plugin.map 'twitter pin :pin', :action => "pin", :public => false
plugin.map 'twitter actions [:toggle]', :action => "actions", :requirements => { :toggle => /^on|off$/ }
+plugin.map 'twitter status [:nick]', :action => "get_status", :threaded => true
plugin.map 'twitter :friends [status] [:nick]', :action => "get_status", :requirements => { :friends => /^friends?$/ }, :threaded => true
-