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!