Class: Safubot::Twitter::Bot
- Inherits:
-
Object
- Object
- Safubot::Twitter::Bot
- Includes:
- Evented
- Defined in:
- lib/safubot/twitter.rb
Overview
A Twitter::Bot instance provides a Safubot::Bot with Twitter-specific processing.
Instance Attribute Summary (collapse)
-
- (Object) client
readonly
Returns the value of attribute client.
-
- (Object) opts
readonly
Returns the value of attribute opts.
-
- (Object) pid
readonly
Returns the value of attribute pid.
-
- (Object) stream
readonly
Returns the value of attribute stream.
-
- (Object) username
readonly
Returns the value of attribute username.
Instance Method Summary (collapse)
-
- (Object) handle_message(message)
Stores a DM and creates a matching Request as needed.
-
- (Object) handle_request(req)
Emit a request event unless the request is already processed.
-
- (Object) handle_tweet(status)
Stores a tweet.
-
- (Object) init_stream
Initializes the TweetStream client.
-
- (Bot) initialize(options = {})
constructor
Options are passed straight through to ::TweetStream and ::Twitter, but the :username is ours and important.
-
- (Object) pull
Pulls DMs and mentions using the AJAX API.
-
- (Object) reply(tweet, text)
Replies to a tweet using the appropriate mentions.
-
- (Object) reply_header(tweet)
Constructs the appropriate series of mentions for a reply to this tweet.
-
- (Object) run
Starts our TweetStream client running in a new process.
-
- (Object) run_stream
Runs the TweetStream client.
-
- (Object) send(resp)
Sends a Twitter-sourced Response to the appropriate target.
-
- (Object) stop
Shut down the TweetStream client.
Methods included from Evented
#bind, #emit, #on, #once, #unbind
Constructor Details
- (Bot) initialize(options = {})
Options are passed straight through to ::TweetStream and ::Twitter, but the :username is ours and important.
283 284 285 286 287 288 289 290 291 292 293 294 |
# File 'lib/safubot/twitter.rb', line 283 def initialize(={}) defaults = { :username => nil, :consumer_key => nil, :consumer_secret => nil, :oauth_token => nil, :oauth_token_secret => nil, :auth_method => :oauth } @opts = defaults.merge() DirectMessage.ensure_index('raw.id', :unique => true) @username = @opts[:username] @client = Object::Twitter::Client.new(@opts) end |
Instance Attribute Details
- (Object) client (readonly)
Returns the value of attribute client
160 161 162 |
# File 'lib/safubot/twitter.rb', line 160 def client @client end |
- (Object) opts (readonly)
Returns the value of attribute opts
160 161 162 |
# File 'lib/safubot/twitter.rb', line 160 def opts @opts end |
- (Object) pid (readonly)
Returns the value of attribute pid
160 161 162 |
# File 'lib/safubot/twitter.rb', line 160 def pid @pid end |
- (Object) stream (readonly)
Returns the value of attribute stream
160 161 162 |
# File 'lib/safubot/twitter.rb', line 160 def stream @stream end |
- (Object) username (readonly)
Returns the value of attribute username
160 161 162 |
# File 'lib/safubot/twitter.rb', line 160 def username @username end |
Instance Method Details
- (Object) handle_message(message)
Stores a DM and creates a matching Request as needed.
180 181 182 183 |
# File 'lib/safubot/twitter.rb', line 180 def () return if .sender.screen_name == @username DirectMessage.from().make_request end |
- (Object) handle_request(req)
Emit a request event unless the request is already processed.
175 176 177 |
# File 'lib/safubot/twitter.rb', line 175 def handle_request(req) emit(:request, req) unless req.nil? || req.processed end |
- (Object) handle_tweet(status)
Stores a tweet. If this tweet is directed at us, create a matching Request. Otherwise, emit a :timeline event.
187 188 189 190 191 192 193 194 |
# File 'lib/safubot/twitter.rb', line 187 def handle_tweet(status) return if status.user.screen_name == @username if status.text.match(/@#{@username}/i) Tweet.from(status).make_request else emit(:timeline, Tweet.from(status)) end end |
- (Object) init_stream
Initializes the TweetStream client.
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/safubot/twitter.rb', line 227 def init_stream @stream = TweetStream::Client.new(@opts) @stream. do || req = () handle_request(req) if req.is_a? Request end @stream.on_error do |err| if err.match(/invalid status code: 401/) Log.error "TweetStream authentication failure!" else Log.error "Unhandled TweetStream error: #{error_report($!)}" end end @stream.on_inited do Log.info("TweetStream client is online at @#{@username} :3") end end |
- (Object) pull
Pulls DMs and mentions using the AJAX API. Used in tandem with the streaming API to ensure we don’t miss too much while we’re offline.
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/safubot/twitter.rb', line 210 def pull begin @client..each do || () end @client.mentions.each do |mention| handle_tweet(mention) end rescue ::Twitter::Error::ServiceUnavailable Log.error "Twitter: Couldn't pull tweets due to temporary service unavailability." rescue Exception => e Log.error "Twitter: Unhandled error: #{error_report(e)}" end end |
- (Object) reply(tweet, text)
Replies to a tweet using the appropriate mentions.
204 205 206 |
# File 'lib/safubot/twitter.rb', line 204 def reply(tweet, text) @client.update("#{reply_header(tweet)} #{text}", :in_reply_to_status_id => tweet.raw['id']) end |
- (Object) reply_header(tweet)
Constructs the appropriate series of mentions for a reply to this tweet.
197 198 199 |
# File 'lib/safubot/twitter.rb', line 197 def reply_header(tweet) (["@#{tweet.username}"] + (tweet.header_mentions - ["@#{@username}"])).join end |
- (Object) run
Starts our TweetStream client running in a new process.
267 268 269 270 271 272 273 |
# File 'lib/safubot/twitter.rb', line 267 def run @pid = Process.fork do Signal.trap("TERM") { stop } init_stream run_stream end end |
- (Object) run_stream
Runs the TweetStream client.
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 |
# File 'lib/safubot/twitter.rb', line 249 def run_stream begin @stream.userstream do |status| req = handle_tweet(status) handle_request(req) if req.is_a? Request end rescue Exception => e unless e.is_a?(Interrupt) || e.is_a?(SignalException) Log.error "TweetStream client exited unexpectedly: #{error_report(e)}" Log.error "Restarting TweetStream client in 5 seconds." sleep 5; init_stream; run_stream end else Log.info("TweetStream client shutdown complete.") end end |
- (Object) send(resp)
Sends a Twitter-sourced Response to the appropriate target.
163 164 165 166 167 168 169 170 171 172 |
# File 'lib/safubot/twitter.rb', line 163 def send(resp) source = resp.request.source if source.is_a?(DirectMessage) @client.(source.raw['sender']['screen_name'], resp.text) elsif source.is_a?(Tweet) reply("#{source.header_mentions.join(' ')} #{resp.text}") else raise NotImplementedError, "Don't know how to send response to a #{req.source.class}!" end end |
- (Object) stop
Shut down the TweetStream client.
276 277 278 279 |
# File 'lib/safubot/twitter.rb', line 276 def stop @stream.stop if @stream Process.kill("TERM", @pid) if @pid end |