Advertisement
Guest User

bots.rb

a guest
Nov 8th, 2014
315
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.70 KB | None | 0 0
  1. #!/usr/bin/env ruby
  2. # encoding: utf-8
  3.  
  4. require 'twitter_ebooks'
  5. include Ebooks
  6.  
  7. CONSUMER_KEY = "xxxxx"
  8. CONSUMER_SECRET = "xxxxx"
  9. OAUTH_TOKEN = "xxxxx"
  10. OAUTH_TOKEN_SECRET = "xxxxx"
  11.  
  12. ROBOT_ID = "ebooks" # Prefer not to talk to other robots
  13. TWITTER_USERNAME = “raf_ebooks" # Ebooks account username
  14. TEXT_MODEL_NAME = “raf_ebooks" # This should be the name of the text model
  15.  
  16. DELAY = 2..30 # Simulated human reply delay range, in seconds
  17. BLACKLIST = ['tinysubversions', 'dril'] # users to avoid interaction with
  18. SPECIAL_WORDS = ['singularity', 'world domination'] # Words we like
  19. BANNED_WORDS = ['voldemort', 'evgeny morozov', 'heroku'] # Words we don't want to use
  20.  
  21. # Track who we've randomly interacted with globally
  22. $have_talked = {}
  23. $banned_words = BANNED_WORDS
  24.  
  25. # Overwrite the Model#valid_tweet? method to check for banned words
  26. class Ebooks::Model
  27.   def valid_tweet?(tokens, limit)
  28.     tweet = NLP.reconstruct(tokens)
  29.     found_banned = $banned_words.any? do |word|
  30.       re = Regexp.new("\\b#{word}\\b", "i")
  31.       re.match tweet
  32.     end
  33.     tweet.length <= limit && !NLP.unmatched_enclosers?(tweet) && !found_banned
  34.   end
  35. end
  36.  
  37. class GenBot
  38.   def initialize(bot, modelname)
  39.     @bot = bot
  40.     @model = nil
  41.  
  42.     bot.consumer_key = CONSUMER_KEY
  43.     bot.consumer_secret = CONSUMER_SECRET
  44.  
  45.     bot.on_startup do
  46.       @model = Model.load("model/#{modelname}.model")
  47.       @top100 = @model.keywords.top(100).map(&:to_s).map(&:downcase)
  48.       @top50 = @model.keywords.top(20).map(&:to_s).map(&:downcase)
  49.     end
  50.  
  51.     bot.on_message do |dm|
  52.       bot.delay DELAY do
  53.         bot.reply dm, @model.make_response(dm[:text])
  54.       end
  55.     end
  56.  
  57.     bot.on_follow do |user|
  58.       bot.delay DELAY do
  59.         bot.follow user[:screen_name]
  60.       end
  61.     end
  62.  
  63.     bot.on_mention do |tweet, meta|
  64.       # Avoid infinite reply chains
  65.       next if tweet[:user][:screen_name].include?(ROBOT_ID) && rand > 0.05
  66.  
  67.       author = tweet[:user][:screen_name]
  68.       next if $have_talked.fetch(author, 0) >= 5
  69.       $have_talked[author] = $have_talked.fetch(author, 0) + 1
  70.  
  71.       tokens = NLP.tokenize(tweet[:text])
  72.       very_interesting = tokens.find_all { |t| @top50.include?(t.downcase) }.length > 2
  73.       special = tokens.find { |t| SPECIAL_WORDS.include?(t) }
  74.  
  75.       if very_interesting || special
  76.         favorite(tweet)
  77.       end
  78.  
  79.       reply(tweet, meta)
  80.     end
  81.  
  82.     bot.on_timeline do |tweet, meta|
  83.       next if tweet[:retweeted_status] || tweet[:text].start_with?('RT')
  84.       author = tweet[:user][:screen_name]
  85.       next if BLACKLIST.include?(author)
  86.  
  87.       tokens = NLP.tokenize(tweet[:text])
  88.  
  89.       # We calculate unprompted interaction probability by how well a
  90.       # tweet matches our keywords
  91.       interesting = tokens.find { |t| @top100.include?(t.downcase) }
  92.       very_interesting = tokens.find_all { |t| @top50.include?(t.downcase) }.length > 2
  93.       special = tokens.find { |t| SPECIAL_WORDS.include?(t) }
  94.  
  95.       if special
  96.         favorite(tweet)
  97.         favd = true # Mark this tweet as favorited
  98.  
  99.         bot.delay DELAY do
  100.           bot.follow author
  101.         end
  102.       end
  103.  
  104.       # Any given user will receive at most one random interaction per 12h
  105.       # (barring special cases)
  106.       next if $have_talked[author]
  107.       $have_talked[author] = $have_talked.fetch(author, 0) + 1
  108.  
  109.       if very_interesting || special
  110.         favorite(tweet) if (rand < 0.5 && !favd) # Don't fav the tweet if we did earlier
  111.         retweet(tweet) if rand < 0.1
  112.         reply(tweet, meta) if rand < 0.1
  113.       elsif interesting
  114.         favorite(tweet) if rand < 0.1
  115.         reply(tweet, meta) if rand < 0.05
  116.       end
  117.     end
  118.  
  119.     # Reset list of mention recipients every 12 hrs:
  120.     bot.scheduler.every '12h' do
  121.       $have_talked = {}
  122.     end
  123.  
  124.     # 80% chance to tweet every 2 hours
  125.     bot.scheduler.every '2h' do
  126.       if rand <= 0.8
  127.         bot.tweet @model.make_statement
  128.       end
  129.     end
  130.   end
  131.  
  132.   def reply(tweet, meta)
  133.     resp = @model.make_response(meta[:mentionless], meta[:limit])
  134.     @bot.delay DELAY do
  135.       @bot.reply tweet, meta[:reply_prefix] + resp
  136.     end
  137.   end
  138.  
  139.   def favorite(tweet)
  140.     @bot.log "Favoriting @#{tweet[:user][:screen_name]}: #{tweet[:text]}"
  141.     @bot.delay DELAY do
  142.       @bot.twitter.favorite(tweet[:id])
  143.     end
  144.   end
  145.  
  146.   def retweet(tweet)
  147.     @bot.log "Retweeting @#{tweet[:user][:screen_name]}: #{tweet[:text]}"
  148.     @bot.delay DELAY do
  149.       @bot.twitter.retweet(tweet[:id])
  150.     end
  151.   end
  152. end
  153.  
  154. def make_bot(bot, modelname)
  155.   GenBot.new(bot, modelname)
  156. end
  157.  
  158. Ebooks::Bot.new(TWITTER_USERNAME) do |bot|
  159.   bot.oauth_token = OAUTH_TOKEN
  160.   bot.oauth_token_secret = OAUTH_TOKEN_SECRET
  161.  
  162.   make_bot(bot, TEXT_MODEL_NAME)
  163. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement