= Robut
The friendly plugin-enabled HipChat bot.
== NOTE: Breaking backwards compatibility!
A little while ago, HipChat changed the way their mention names
work. Instead of just using the first name ('@robut'), they now use
the full name ('@RobutTRobot'). Starting from v0.4.0, robut uses this
new format by default. If you prefer the old style, you can set it in
your Chatfile:
config.mention_name = 'robut'
== Installation and usage
Robut can be installed by running gem install robut. This
installs the +robut+ binary. When run, +robut+ reads a Chatfile,
connects to the specified HipChat server and chatroom, and feeds every
line said in the chatroom through the plugins configured by the
Chatfile.
Once robut is running, the plugins listen to what's being said in the
chatroom. Most plugins listen for @replies to robut:
@robut lunch? # => "Banh Mi!"
@robut calc 1 + 1 # => 2
Others listen to everything, and don't require an @reply.
Some of the included plugins require extra gems to be installed:
[Robut::Plugin::TWSS] requires the twss gem.
[Robut::Plugin::Calc] requires the calc gem.
[Robut::Plugin::Weather] requires the nokogiri gem.
[Robut::Plugin::GoogleImages] requires the google-search gem.
A list of known 3rd-party plugins is available on the wiki: https://github.com/justinweiss/robut/wiki/Robut-Plugins
Feel free to add your own creations!
== The Chatfile
When the +robut+ command runs, it looks for and evals ruby code in a
file called +Chatfile+ in the current directory. You can override the
configuration file by passing +robut+ a path to a Chatfile as the
first parameter:
robut /path/to/Chatfile
The Chatfile is just ruby code. A simple example can be found here: Chatfile[https://github.com/justinweiss/robut/blob/master/examples/Chatfile]
=== Adding and configuring plugins
Plugins are ruby classes, so enabling a plugin just requires requiring
the plugin file, optionally configuring the plugin class, and adding
the class to the global plugin list:
require 'robut/plugin/lunch'
Robut::Plugin::Lunch.places = ["Banh Mi", "Mad Oven", "Mod Pizza", "Taphouse"]
Robut::Plugin.plugins << Robut::Plugin::Lunch
Each plugin can be configured differently, or not at all. It's best to
look at the docs for the plugins you want to use to figure out what
kind of configuration they support.
Some plugins might require storage (like the `lunch` plugin). You can
configure the type of storage you want to use based on the need for
persistence. The default is the HashStore which is in-memory only. Below
is an example of using the YamlStore.
Robut::Connection.configure do |config|
# ...
Robut::Storage::YamlStore.file = "~/.robut_store"
config.store = Robut::Storage::YamlStore
end
=== Configuring the HipChat connection
The Chatfile also configures the HipChat connection. This is done in a
Robut::Connection.configure block:
# Configure the robut jabber connection and you're good to go!
Robut::Connection.configure do |config|
config.jid = '...@chat.hipchat.com/bot'
config.password = 'password'
config.nick = 'Bot Nick'
config.rooms = ['1234_room_1@conf.hipchat.com', '1234_room_2@conf.hipchat.com']
# Custom @mention name
config.mention_name = 'Bot'
# Example of the YamlStore which uses a yaml file for persistence
Robut::Storage::YamlStore.file = "~/.robut_store"
config.store = Robut::Storage::YamlStore
# Add a logger if you want to debug the connection
# config.logger = Logger.new(STDOUT)
end
This block usually goes at the end of the Chatfile.
== Built-in plugins
Robut includes a few plugins that we've found useful:
[Robut::Plugin::Calc] a simple calculator.
@robut calc 1 + 1 # => 2
[Robut::Plugin::Lunch] a random decider for lunch locations.
@robut lunch? # => "Banh Mi!"
[Robut::Plugin::Meme] generates meme images using memecaptain.
@robut meme all_the_things drink; all the beer
[Robut::Plugin::GoogleImages] does a google image search for a query and returns the first result.
@robut image ship it
[Robut::Plugin::Sayings] a simple regex listener and responder.
You're the worst robot ever, @robut. # => I know.
[Robut::Plugin::TWSS] an interface to the TWSS gem. Listens to anything said in the chat room and responds "That's what she said!" where appropriate.
well hurry up, you're not going fast enough # => "That's what she said!"
[Robut::Plugin::Echo] echo back whatever it gets.
@robut echo hello world # => "hello world"
[Robut::Plugin::Say] invokes the "say" command (text-to-speech).
@robut say this rocks # (make sure robut is running on a machine with speakers :)
[Robut::Plugin::Ping] responds with "pong".
@robut ping # => "pong"
[Robut::Plugin::Later] performs the given command after waiting an arbitrary amount of time.
@robut in 5 minutes echo @justin wake up! # => (5 minutes later) "@justin wake up!"
[Robut::Plugin::Weather] uses Google Weather to fetch for the weather for a given location and day.
@robut seattle weather saturday? # => "Forecast for Seattle, WA on Sat: Sunny, High: 77F, Low: 55F"
[Robut::Plugin::Alias] creates aliases to other robut commands.
@robut alias "cowboy" "@robut play bon jovi wanted dead or alive" # Cuz somtimes you need it.
@robut alias w weather? # less typing for common stuff
[Robut::Plugin::Quips] stores and posts Bugzilla-style quips.
@robut add quip It was great when I wrote it!
@robut quip # => It was great when I wrote it!
@robut remove quip It was great when I wrote it!
[Robut::Plugin::Help] lists usage for all the plugins loaded into robut
@robut help # => command usage
== Writing custom plugins
You can supply your own plugins to Robut. To create a plugin, include
the Robut::Plugin module and implement the handle(time,
sender_nick, message) to perform any plugin-specific logic.
Robut::Plugin provides a few helper methods that are documented
in its class definition.
== Contributing
To test your changes:
1. Install [Bundler](http://gembundler.com/)
2. Run `bundle install`
3. Make your changes and run `bundle exec ruby -Ilib bin/robut ~/MyTestingChatfile`
4. Add tests and verify by running `bundle exec rake test`
Once your changes are ready:
1. Fork robut
2. Create a topic branch: `git checkout -b my_branch`
3. Commit your changes
4. Push to your branch: `git push origin my_branch`
5. Send me a pull request
6. That's it!
== Todo
* More plugins!