#!/usr/bin/env ruby require 'twitter_ebooks' include Ebooks CONSUMER_KEY = "" CONSUMER_SECRET = "" DELAY = 2..30 # Simulated human reply delay range in seconds BLACKLIST = ['insomnius', 'upulie'] # Grumpy users to avoid interaction with # Track who we've randomly interacted with globally $have_talked = {} class GenBot def initialize(bot, modelname) @bot = bot @model = nil bot.consumer_key = CONSUMER_KEY bot.consumer_secret = CONSUMER_SECRET bot.on_startup do @model = Model.load("model/#{modelname}.model") @top100 = @model.keywords.top(100).map(&:to_s).map(&:downcase) @top50 = @model.keywords.top(20).map(&:to_s).map(&:downcase) end bot.on_message do |dm| bot.delay DELAY do bot.reply dm, @model.make_response(dm[:text]) end end bot.on_follow do |user| bot.delay DELAY do bot.follow user[:screen_name] end end bot.on_mention do |tweet, meta| # Avoid infinite reply chains (very small chance of crosstalk) next if tweet[:user][:screen_name].include?('ebooks') && rand > 0.05 tokens = NLP.tokenize(tweet[:text]) very_interesting = tokens.find_all { |t| @top50.include?(t.downcase) }.length > 2 special = tokens.find { |t| ['ebooks', 'bot', 'bots', 'clone', 'singularity', 'world domination'].include?(t) } if very_interesting || special favorite(tweet) end reply(tweet, meta) end bot.on_timeline do |tweet, meta| next if tweet[:retweeted_status] || tweet[:text].start_with?('RT') next if BLACKLIST.include?(tweet[:user][:screen_name]) tokens = NLP.tokenize(tweet[:text]) # We calculate unprompted interaction probability by how well a # tweet matches our keywords interesting = tokens.find { |t| @top100.include?(t.downcase) } very_interesting = tokens.find_all { |t| @top50.include?(t.downcase) }.length > 2 special = tokens.find { |t| ['ebooks', 'bot', 'bots', 'clone', 'singularity', 'world domination'].include?(t) } if special favorite(tweet) bot.delay DELAY do bot.follow tweet[:user][:screen_name] end end # Any given user will receive at most one random interaction per day # (barring special cases) next if $have_talked[tweet[:user][:screen_name]] $have_talked[tweet[:user][:screen_name]] = true if very_interesting || special favorite(tweet) if rand < 0.5 retweet(tweet) if rand < 0.1 reply(tweet, meta) if rand < 0.1 elsif interesting favorite(tweet) if rand < 0.1 reply(tweet, meta) if rand < 0.05 end end # Schedule a main tweet for every day at midnight bot.scheduler.cron '0 0 * * *' do bot.tweet @model.make_statement $have_talked = {} end end def reply(tweet, meta) resp = @model.make_response(meta[:mentionless], meta[:limit]) @bot.delay DELAY do @bot.reply tweet, meta[:reply_prefix] + resp end end def favorite(tweet) @bot.log "Favoriting @#{tweet[:user][:screen_name]}: #{tweet[:text]}" @bot.delay DELAY do @bot.twitter.favorite(tweet[:id]) end end def retweet(tweet) @bot.log "Retweeting @#{tweet[:user][:screen_name]}: #{tweet[:text]}" @bot.delay DELAY do @bot.twitter.retweet(tweet[:id]) end end end def make_bot(bot, modelname) GenBot.new(bot, modelname) end Ebooks::Bot.new("username_ebooks") do |bot| # Ebooks account username bot.oauth_token = "" # oauth token for ebooks account bot.oauth_token_secret = "" # oauth secret for ebooks account make_bot(bot, "username") # This should be the name of the text model end