safubot - an event-driven chatbot framework for Ruby

Overview

Safubot is a chatbot framework for Twitter and XMPP which aims to abstract away the idiosyncracies of the underlying APIs, allowing you to focus on writing request-processing logic. Of course, if you want to use service-specific features (such as responding to timeline tweets) it lets you do that too!

Installation

gem install safubot

Requirements

Safubot uses MongoDB for storage. It's easy to install and pretty awesome!

Documentation

http://rdoc.info/gems/safubot

Sample Usage

require 'safubot'

class NiftyBot < Safubot::Bot
  def initialize
    # Check the MongoMapper docs (http://www.mongomapper.com/documentation/) if you want
    # to do something more sophisticated than an authless localhost connection.
    super(:database => "niftybot")

    # To access the underlying delegation targets:
    # Safubot::Twitter::Bot bot.twitter
    # ::Twitter::Client bot.twitter.client
    # ::TweetStream::Client bot.twitter.stream
    enable_twitter({
        :username => "niftybot",
        :consumer_key => CONSUMER_KEY,
        :consumer_secret => CONSUMER_SECRET,
        :oauth_token => OAUTH_TOKEN,
        :oauth_token_secret => OAUTH_TOKEN_SECRET
    })

    # Similarly, for XMPP:
    # Safubot::XMPP::Bot bot.xmpp
    # ::Blather::Client bot.xmpp.client
    enable_xmpp({
        :jid => "niftybot@jabber.org/niftyhost",
        :password => JABBER_PASSWORD
    })

    # A Request can be sourced from a:
    #   * Twitter mention
    #   * Twitter DM
    #   * XMPP chat message
    # The "respond" method will reply using the appropriate medium.
    on(:request) do |req|
      if req.text.match /nifty/i
        respond req, "Yep, I'm a nifty bot! :3"
      else
        raise ArgumentError, "This isn't nifty at all! :("
      end
    end

    # Any unhandled errors encountered during request processing
    # will come through here.
    on(:request_error) do |req, e|
      respond req, "#{e}"
    end
  end
end

# This will fork the Twitter/XMPP streaming processes as needed
# and then wait for them. You can call run_nowait if you want
# a non-blocking form.
NiftyBot.new.run

Logging

Safubot::Log behaves as a Logger instance and will write to stdout by default. You can also tell it to write to a file:

Safubot::Log.path = "/some/cool/logfile"

Specific Examples

Find the last processed request from a user

on(:request) do |req|
  req.user.requests.where(:processed => true).sort(:created_at.desc).first
end

Update our twitter account

@twitter.client.update("Hello there, wonderful, scary world of Twitter! I am so *not* a spambot.")

Reply to a non-request timeline tweet

@twitter.on(:timeline) do |tweet|
  if tweet.raw['user']['screen_name'] == "unnali"
    @twitter.reply tweet, "Is HaeSeun OSS yet? :O"
  end
end

Start an unprompted conversation with an XMPP user

@xmpp.on(:ready) do
  @xmpp.tell('^_^@jabber.org', "You'd best be maintaining safubot!")
end