Skip to content

Instantly share code, notes, and snippets.

@QuietMisdreavus
Created December 27, 2017 15:53
Show Gist options
  • Save QuietMisdreavus/cb987e5d22aa5408f84883ec7f4c588f to your computer and use it in GitHub Desktop.
Save QuietMisdreavus/cb987e5d22aa5408f84883ec7f4c588f to your computer and use it in GitHub Desktop.
require 'twitter_ebooks'
# bot code shamelessly stolen from https://github.com/mispy/ebooks_example
# 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 MyBot < Ebooks::Bot
attr_accessor :original, :model, :model_path
# Configuration here applies to all MyBots
def configure
# Consumer details come from registering an app at https://dev.twitter.com/
# Once you have consumer details, use "ebooks auth" for new access tokens
self.consumer_key = '' # Your app consumer key
self.consumer_secret = '' # Your app consumer secret
# Users to block instead of interacting with
#self.blacklist = ['tnietzschequote']
# Range in seconds to randomize delay when bot.delay is called
self.delay_range = 20..60
@userinfo = {}
end
def top100; @top100 ||= model.keywords.take(100); end
def top20; @top20 ||= model.keywords.take(20); end
def new_post!
post = nil
begin
if post.nil?
post = tweet(model.make_statement)
else
delay do
text = model.make_response(post.text)
log "creating self-reply with: '#{text}'"
post = twitter.update(text, {in_reply_to_status_id: post.id})
conversation(post).add(post)
end
end
end while rand < 0.3
end
def on_startup
load_model!
# start with a tweet so we don't have a dead spot if i restart between posts
scheduler.in '10s' do
new_post!
end
scheduler.every '4h' do
# tweet something every four hours
new_post!
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.casecmp(@original) == 0 || 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
# Make a MyBot and attach it to an account
MyBot.new("qm_grey_ebooks") do |bot|
bot.access_token = ""
bot.access_token_secret = ""
bot.original = "QuietMisdreavus"
end
# vim: expandtab shiftwidth=2
[Unit]
Description=qm_grey_ebooks twitter bot
[Service]
Type=simple
User=misdreavus
Environment="PATH=/home/misdreavus/.gem/ruby/2.4.0/bin:$PATH"
WorkingDirectory=/home/misdreavus/git/grey_ebooks
ExecStartPre=/home/misdreavus/.gem/ruby/2.4.0/bin/ebooks archive QuietMisdreavus corpus/QuietMisdreavus.json
ExecStartPre=/home/misdreavus/.gem/ruby/2.4.0/bin/ebooks consume corpus/QuietMisdreavus.json
ExecStart=/home/misdreavus/.gem/ruby/2.4.0/bin/ebooks start
[Install]
WantedBy=network.target
[Unit]
Description=Reload grey_ebooks.service
[Service]
ExecStart=/usr/bin/reload-grey-ebooks.sh
[Unit]
Description=Automatic model refresh for grey_ebooks twitter bot
[Timer]
OnCalendar=00:30
Persistent=true
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment