Developing for Hubot with CoffeeScript, Node.js, and Heroku

Over the weekend I started playing around with Hubot, GitHub’s recently open-sourced robot written in CoffeeScript and Node.js. Hubot is made up of three main components: the robot engine itself, the communication adapters, and the command scripts. Hubot has multiple communication adapters that allow you to talk to Hubot through Campfire, XMPP, HipChat, Twitter, SMS, email, and many more. These communication adapters feed messages to different command scripts for weather, news, stocks, and other useful information. And these scripts are also very extensible, making it easy for people to build customized scripts for their own Hubot installation. The robot engine is the glue that brings these two components together to form a friendly, integrated robot.

Hubot is written in Coffeescript and Node.js, two very powerful technologies that are mainly used for server-side I/O applications. Node.js is a JavaScript-based framework and CoffeeScript is a lightweight language that compiles into JavaScript. Because these two technologies are based on JavaScript, the syntax for both of these should be very similar. Hubot also relies on a Node Package Manager, or NPM, for installing dependencies and for installing publicly-available script extensions for Hubot.

Hubot can be easily deployed to Heroku, a cloud hosting platform for Ruby-based applications. Heroku also offers some basic deployment environments, including an Ubuntu-based environment with Node.js support. I will spare you the deployment details as these are pretty straightforward. Needless to say, I had a Hubot installation up and running on Heroku in about 10 minutes. Once you get Hubot installed, the real fun begins.

This weekend I made two contributions to Hubot over on GitHub. The first was modifying the Google Talk adapter for Hubot to change the default status from “Chatty” to “Available”. This was happening because the adapter, which relies on XMPP to communicate with Google Talk, was sending a <status>chat</status> stanza unnecessarily. I did some research on the XMPP protocol and found that when establishing presence with an XMPP server, the user’s default status will be available and that sending a <status /> stanza was not needed. I forked the Hubot repository on GitHub and these changes were later pulled into the master branch.

The second contribution that I made to Hubot was on the weather script. Originally, when you asked Hubot for weather information, the script would merely dump the data to you in an instant message. Keeping with the “friendly” personality that Hubot has, I decided to revamp the formatting to provide a more “natural language” in Hubot’s replies and add some additional features to this script. This post wouldn’t be complete without some code, so take a look at the snippet below:

So what I’m doing in the script above is downloading the weather data from a hidden Google API, for simplicity’s sake, and parsing this data when the robot engine hears the words “weather me ..”. Unfortunately, this Google API only responds in XML format, which requires some additional legwork to extract the data. You can also see how Hubot responds in a “natural” format, making him seem more like a “person” rather than a command line. I forked the Hubot scripts repository on GitHub and these changes were later pulled into the master branch.

All in all, Hubot is a very powerful robot with a lot of community support behind it. I really think that we’re going to see some pretty amazing things come out of GitHub’s move to open-source their once-internal tool. There are hundreds of scenarios where Hubot can make an impact in a company, no matter what the size. And with such an extensible and easy-to-use framework for building custom plugins and scripts that interact with different APIs and web services, Hubot is hugely powerful.

You should follow @mbmccormick on twitter right now

Because who wouldn't want to keep tabs on this passionate software developer, elite hacker, food connoisseur, and dog lover? No one, that's who.