Skip to content

Instantly share code, notes, and snippets.

@ELLIOTTCABLE
Created February 11, 2015 20:13
Show Gist options
  • Save ELLIOTTCABLE/82502ffcd260332cd9e2 to your computer and use it in GitHub Desktop.
Save ELLIOTTCABLE/82502ffcd260332cd9e2 to your computer and use it in GitHub Desktop.
> ruby run.rb
Visit this URL: https://api.twitter.com/oauth/authorize?oauth_token=<snip>
Enter the PIN: <snip>
Access token: <snip>
Access token secret: <snip>
@ELLIOTTCVBLE: starting tweet stream
/Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter-5.13.0/lib/twitter/streaming/response.rb:21:in `on_headers_complete': Twitter::Error::Unauthorized
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter-5.13.0/lib/twitter/streaming/response.rb:16:in `<<'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter-5.13.0/lib/twitter/streaming/response.rb:16:in `<<'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter-5.13.0/lib/twitter/streaming/connection.rb:22:in `stream'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter-5.13.0/lib/twitter/streaming/client.rb:118:in `request'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter-5.13.0/lib/twitter/streaming/client.rb:91:in `user'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/twitter_ebooks-3.0.8/lib/twitter_ebooks/bot.rb:340:in `start'
from run.rb:48:in `block (2 levels) in <main>'
from run.rb:47:in `each'
from run.rb:47:in `block in <main>'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `call'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run_machine'
from /Users/ec/.rvm/gems/ruby-2.2.0/gems/eventmachine-1.0.7/lib/eventmachine.rb:187:in `run'
from run.rb:46:in `<main>'
require 'twitter_ebooks'
require 'oauth'
# Information about a particular Twitter user we know
class UserInfo
attr_reader :username
# @return [Integer] how many times we can pester this user unprompted
attr_accessor :pesters_left
# @param username [String]
def initialize(username)
@username = username
@pesters_left = 1
end
end
class CloneBot < Ebooks::Bot
attr_accessor :original, :model, :model_path
def configure
# Configuration for all CloneBots
self.consumer_key = "<snip>"
self.consumer_secret = "<snip>"
self.blacklist = ['dril']
self.delay_range = 2..300
@userinfo = {}
auth
end
def auth
consumer = OAuth::Consumer.new(@consumer_key, @consumer_secret,
{ :site => "https://api.twitter.com", :scheme => :header })
request_token = consumer.get_request_token(:oauth_callback => :oob)
puts "Visit this URL: #{request_token.authorize_url}"
print "Enter the PIN: "
access_token = request_token.get_access_token :oauth_verifier => gets.chomp
@access_token = access_token.token
@access_token_secret = access_token.secret
puts "Access token: #{@access_token}"
puts "Access token secret: #{@access_token_secret}"
end
def top100; @top100 ||= model.keywords.take(100); end
def top20; @top20 ||= model.keywords.take(20); end
def on_startup
load_model!
scheduler.cron '0 0 * * *' do
# Each day at midnight, post a single tweet
tweet(model.make_statement)
end
end
def on_message(dm)
delay do
reply(dm, model.make_response(dm.text))
end
end
def on_mention(tweet)
# Become more inclined to pester a user when they talk to us
userinfo(tweet.user.screen_name).pesters_left += 1
delay do
reply(tweet, model.make_response(meta(tweet).mentionless, meta(tweet).limit))
end
end
def on_timeline(tweet)
return if tweet.retweeted_status?
return unless can_pester?(tweet.user.screen_name)
tokens = Ebooks::NLP.tokenize(tweet.text)
interesting = tokens.find { |t| top100.include?(t.downcase) }
very_interesting = tokens.find_all { |t| top20.include?(t.downcase) }.length > 2
delay do
if very_interesting
favorite(tweet) if rand < 0.5
retweet(tweet) if rand < 0.1
if rand < 0.01
userinfo(tweet.user.screen_name).pesters_left -= 1
reply(tweet, model.make_response(meta(tweet).mentionless, meta(tweet).limit))
end
elsif interesting
favorite(tweet) if rand < 0.05
if rand < 0.001
userinfo(tweet.user.screen_name).pesters_left -= 1
reply(tweet, model.make_response(meta(tweet).mentionless, meta(tweet).limit))
end
end
end
end
# Find information we've collected about a user
# @param username [String]
# @return [Ebooks::UserInfo]
def userinfo(username)
@userinfo[username] ||= UserInfo.new(username)
end
# Check if we're allowed to send unprompted tweets to a user
# @param username [String]
# @return [Boolean]
def can_pester?(username)
userinfo(username).pesters_left > 0
end
# Only follow our original user or people who are following our original user
# @param user [Twitter::User]
def can_follow?(username)
@original.nil? || username == @original || twitter.friendship?(username, @original)
end
def favorite(tweet)
if can_follow?(tweet.user.screen_name)
super(tweet)
else
log "Unfollowing @#{tweet.user.screen_name}"
twitter.unfollow(tweet.user.screen_name)
end
end
def on_follow(user)
if can_follow?(user.screen_name)
follow(user.screen_name)
else
log "Not following @#{user.screen_name}"
end
end
private
def load_model!
return if @model
@model_path ||= "model/#{original}.model"
log "Loading model #{model_path}"
@model = Ebooks::Model.load(model_path)
end
end
CloneBot.new("ELLIOTTCVBLE") do |bot|
bot.original = "ELLIOTTCABLE"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment