= 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!