README.md in twitter_ebooks-2.3.2 vs README.md in twitter_ebooks-3.0.0

- old
+ new

@@ -1,12 +1,28 @@ -# twitter\_ebooks 2.3.2 +# twitter\_ebooks -Rewrite of my twitter\_ebooks code. While the original was solely a tweeting Markov generator, this framework helps you build any kind of interactive twitterbot which responds to mentions/DMs. See [ebooks\_example](https://github.com/mispy/ebooks_example) for an example of a full bot. +[![Gem Version](https://badge.fury.io/rb/twitter_ebooks.svg)](http://badge.fury.io/rb/twitter_ebooks) +[![Build Status](https://travis-ci.org/mispy/twitter_ebooks.svg)](https://travis-ci.org/mispy/twitter_ebooks) +[![Dependency Status](https://gemnasium.com/mispy/twitter_ebooks.svg)](https://gemnasium.com/mispy/twitter_ebooks) +A framework for building interactive twitterbots which respond to mentions/DMs. See [ebooks_example](https://github.com/mispy/ebooks_example) for a fully-fledged bot definition. + +## New in 3.0 + +- Bots run in their own threads (no eventmachine), and startup is parallelized +- Bots start with `ebooks start`, and no longer die on unhandled exceptions +- `ebooks auth` command will create new access tokens, for running multiple bots +- `ebooks console` starts a ruby interpreter with bots loaded (see Ebooks::Bot.all) +- Replies are slightly rate-limited to prevent infinite bot convos +- Non-participating users in a mention chain will be dropped after a few tweets +- [API documentation](http://rdoc.info/github/mispy/twitter_ebooks) + +Note that 3.0 is not backwards compatible with 2.x, so upgrade carefully! + ## Installation -Requires Ruby 1.9.3+ (2.1+ recommended) +Requires Ruby 2.0+ ```bash gem install twitter_ebooks ``` @@ -14,52 +30,67 @@ Run `ebooks new <reponame>` to generate a new repository containing a sample bots.rb file, which looks like this: ``` ruby # This is an example bot definition with event handlers commented out -# You can define as many of these as you like; they will run simultaneously +# You can define and instantiate as many bots as you like -Ebooks::Bot.new("abby_ebooks") do |bot| - # Consumer details come from registering an app at https://dev.twitter.com/ - # OAuth details can be fetched with https://github.com/marcel/twurl - bot.consumer_key = "" # Your app consumer key - bot.consumer_secret = "" # Your app consumer secret - bot.oauth_token = "" # Token connecting the app to this account - bot.oauth_token_secret = "" # Secret connecting the app to this account +class MyBot < Ebooks::Bot + # 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 - bot.on_message do |dm| + # Users to block instead of interacting with + self.blacklist = ['tnietzschequote'] + + # Range in seconds to randomize delay when bot.delay is called + self.delay_range = 1..6 + end + + def on_startup + scheduler.every '24h' do + # Tweet something every 24 hours + # See https://github.com/jmettraux/rufus-scheduler + # bot.tweet("hi") + # bot.pictweet("hi", "cuteselfie.jpg") + end + end + + def on_message(dm) # Reply to a DM # bot.reply(dm, "secret secrets") end - bot.on_follow do |user| + def on_follow(user) # Follow a user back # bot.follow(user[:screen_name]) end - bot.on_mention do |tweet, meta| + def on_mention(tweet) # Reply to a mention - # bot.reply(tweet, meta[:reply_prefix] + "oh hullo") + # bot.reply(tweet, meta(tweet)[:reply_prefix] + "oh hullo") end - bot.on_timeline do |tweet, meta| + def on_timeline(tweet) # Reply to a tweet in the bot's timeline - # bot.reply(tweet, meta[:reply_prefix] + "nice tweet") + # bot.reply(tweet, meta(tweet)[:reply_prefix] + "nice tweet") end +end - bot.scheduler.every '24h' do - # Tweet something every 24 hours - # See https://github.com/jmettraux/rufus-scheduler - # bot.tweet("hi") - # bot.pictweet("hi", "cuteselfie.jpg", ":possibly_sensitive => true") - end +# Make a MyBot and attach it to an account +MyBot.new("{{BOT_NAME}}") do |bot| + bot.access_token = "" # Token connecting the app to this account + bot.access_token_secret = "" # Secret connecting the app to this account end ``` -Bots defined like this can be spawned by executing `run.rb` in the same directory, and will operate together in a single eventmachine loop. The easiest way to run bots in a semi-permanent fashion is with [Heroku](https://www.heroku.com); just make an app, push the bot repository to it, enable a worker process in the web interface and it ought to chug along merrily forever. +'ebooks start' will run all defined bots in their own threads. The easiest way to run bots in a semi-permanent fashion is with [Heroku](https://www.heroku.com); just make an app, push the bot repository to it, enable a worker process in the web interface and it ought to chug along merrily forever. -The underlying [tweetstream](https://github.com/tweetstream/tweetstream) and [twitter gem](https://github.com/sferik/twitter) client objects can be accessed at `bot.stream` and `bot.twitter` respectively. +The underlying streaming and REST clients from the [twitter gem](https://github.com/sferik/twitter) can be accessed at `bot.stream` and `bot.twitter` respectively. ## Archiving accounts twitter\_ebooks comes with a syncing tool to download and then incrementally update a local json archive of a user's tweets. @@ -90,27 +121,26 @@ Text files use newlines and full stops to seperate statements. Once you have a model, the primary use is to produce statements and related responses to input, using a pseudo-Markov generator: ``` ruby -> require 'twitter_ebooks' > model = Ebooks::Model.load("model/0xabad1dea.model") > model.make_statement(140) => "My Terrible Netbook may be the kind of person who buys Starbucks, but this Rackspace vuln is pretty straight up a backdoor" > model.make_response("The NSA is coming!", 130) => "Hey - someone who claims to be an NSA conspiracy" ``` The secondary function is the "interesting keywords" list. For example, I use this to determine whether a bot wants to fav/retweet/reply to something in its timeline: ``` ruby -top100 = model.keywords.top(100) +top100 = model.keywords.take(100) tokens = Ebooks::NLP.tokenize(tweet[:text]) if tokens.find { |t| top100.include?(t) } - bot.twitter.favorite(tweet[:id]) + bot.favorite(tweet[:id]) end ``` -## Other notes +## Bot niceness -If you're using Heroku, which has no persistent filesystem, automating the process of archiving, consuming and updating can be tricky. My current solution is just a daily cron job which commits and pushes for me, which is pretty hacky. +twitter_ebooks will drop bystanders from mentions for you and avoid infinite bot conversations, but it won't prevent you from doing a lot of other spammy things. Make sure your bot is a good and polite citizen!