Hitchhiker’s Guide to Tweetbots: Hosting a Hubot on OpenShift

Robots

Want to host a Hubot on the open source OpenShift Platform as a Service but not sure how? Don’t panic — this blog post has you covered like a good-sized towel.

Hubot is an open source, customizable ‘life embetterment’ robot created by GitHub and written in CoffeeScript on Node.js. Hubot can be used to run scripts to perform all sorts of different automated tasks triggered by interactions via interfaces such as shell, Internet Relay Chat, Skype, Twitter, or XMPP. In this blog post, I will explain how I created a Hubot hosted on OpenShift that tweets quotes from Marvin, the depressed robot in The Hitchhiker’s Guide to the Galaxy. However, this post will help you get a Hubot up and running to perform other tasks too.

Prerequisites for Hosting a Hubot on OpenShift

If you do not have an OpenShift account yet, you should first sign up for a free account on OpenShift Online, which will give you three gears (containers) in which to run applications. At the time of writing, each of these free gears came with 512MB of RAM and 1GB of disk space.

The next step is to install the RHC client tools on your machine to help you communicate with the OpenShift platform. There are instructions on how to do that for a variety of operating systems at the OpenShift Dev Center. Once the RHC tools are installed, run the command rhc setup on the command line to configure RHC ready for use.

Finally, if you want to develop and test your Hubot locally as well as in the cloud, you should install Hubot and CoffeeScript on your machine, which require Node.js and NPM. Depending on what you want to do with your Hubot, you may want to install the Redis key-value store as well. In this blog post I will assume Redis is needed, but you can use Hubot without it.

There are instructions for getting started with Hubot in the official docs. In short, once you have Node.js and NPM, you can install Hubot and CoffeeScript with the following command:

$ npm install -g hubot coffee-script

The process to install and start Redis will depend on your system. On Fedora, I installed it with the command yum install redis and started it with redis-server /etc/redis.conf.

Create OpenShift App

Once you are all set up, you can create a Hubot on OpenShift with the following command:

$ rhc app create hubot nodejs-0.10 http://cartreflect-claytondev.rhcloud.com/reflect?github=smarterclayton/openshift-redis-cart --from-code=https://github.com/codemiller/hubot-openshift

This creates an OpenShift application called hubot with two cartridges: Node.js 0.10 and a community-created cartridge for Redis that is hosted on GitHub. The --from-code argument at the end tells OpenShift to replace the stock Node.js code template with a base repository I have created for Hubot. This is just the standard code generated when I created a Hubot from scratch with a few small additions to tell OpenShift how to run it. If you have an existing Hubot you would like to migrate to OpenShift, once you’ve created a Node.js/Redis OpenShift application you can skip to the Migrate an Existing Hubot section, where I explain those additions.

Once the OpenShift application has been created, RHC will clone the new Git repository containing the app source code to your local machine. Change into the new directory, which will have the same name as the application, in this case hubot.

Test Locally

You can test your new Hubot locally using the default shell adapter. Firstly, start Redis if you have it installed (otherwise you will see Redis connection errors). Then, from the newly cloned directory, run the following command to start the bot, passing the name you want to give it as an argument. I have called my bot HubotOpenShift.

$ ./bin/hubot --name HubotOpenShift

There are several included scripts that will be loaded. Try running a few commands, such as the following:

HubotOpenShift> HubotOpenShift help
HubotOpenShift> HubotOpenShift ping
HubotOpenShift> HubotOpenShift the rules
HubotOpenShift> HubotOpenShift map me sydney
HubotOpenShift> HubotOpenShift pug me
HubotOpenShift> HubotOpenShift ship it

You can use the command exit to quit.

Choose Scripts

The official Hubot docs explain the different sources of Hubot scripts and how to use them. Have a look at some of the offerings and decide which scripts you want to use with your Hubot.

In addition to the bundled scripts, I wanted to add one to produce quotes from Marvin the Robot. Someone had helpfully written that already and published it via NPM.

To add this script to my OpenShift app, I ran the following command from the repository:

$ npm install hubot-marvin --save

Next, I added the dependency to the external-scripts.json file:

["hubot-marvin"]

This made some new commands available when interacting with my Hubot:

HubotOpenShift> HubotOpenShift how are you
HubotOpenShift> I'm feeling very depressed.
HubotOpenShift> HubotOpenShift hitchhike me
HubotOpenShift> Here I am, brain the size of a planet and they ask me to take you down to the bridge. Call that job satisfaction? 'Cos I don't.

You can install new scripts to customize your Hubot’s behavior, or write your own.

Choose Adapter

Once you have some scripts, the next choice to make is which adapter your Hubot will use. The shell adapter is great for testing but you’ll probably want something more if you would like your Hubot to interact with other people.

I have chosen to use a Twitter adapter for my Hubot so it can interact with the world by tweeting responses to Twitter users.

To get started with this, I installed the hubot-twitter NPM package with the following command:

$ npm install hubot-twitter --save

Next, I made a Twitter account for my bot and created a new Twitter application, supplying the OpenShift app URL (you can view this with rhc app show). I set the Twitter application permissions to Read and Write (via Permissions > Access) and generated API keys and an access token (under API Keys in the Twitter Application Management console).

Hubot needs to know the API keys, access tokens and secrets in order to post to Twitter. These are communicated via environment variables. When testing locally, you can set the environment variables however you usually would, such as with a command like export HUBOT_TWITTER_KEY=foo.

To set these environment variables on OpenShift, you can use the rhc env set command. For example, the following command would set the four required values for the hubot application:

$ rhc env set HUBOT_TWITTER_KEY=myappkey HUBOT_TWITTER_SECRET=myappsecret HUBOT_TWITTER_TOKEN=mytoken HUBOT_TWITTER_TOKEN_SECRET=mytokensecret -a hubot

You can set any environment variables required for your chosen Hubot adapter in the same way.

To test Hubot with the new adapter, you need to pass the adapter name as an argument when running the launch script:

$ ./bin/hubot --name HubotOpenShift --adapter twitter

For the Twitter adapter, the Hubot name used should be the same as the Twitter account username.

To tell OpenShift to launch Hubot the same way, open the package.json file in the app repository and change the values passed with -n (–name) and -a (–adapter) in scripts:start.

For my Hubot, this meant the start script now looked like this:

"start": "PORT=$OPENSHIFT_NODEJS_PORT BIND_ADDRESS=$OPENSHIFT_NODEJS_IP HEROKU_URL=$OPENSHIFT_APP_DNS REDIS_URL=redis://:$REDIS_PASSWORD@$OPENSHIFT_REDIS_HOST:$OPENSHIFT_REDIS_PORT bin/hubot -n HubotOpenShift -a twitter"

HEROKU_URL could more aptly be named PING_URL; it is the URL Hubot should ping regularly to ensure the instance remains active.

Migrate an Existing Hubot

So far, this blog post has focused on explaining how to create your very first Hubot using OpenShift. However, you may already have a Hubot you wish to migrate to the PaaS.

Moving your existing Hubot code to OpenShift is just a matter of adding it to the OpenShift application’s Git repository.

If your Hubot code is itself hosted in a Git repository, one way to achieve this is to merge the code with the OpenShift repo using a command such as the following, executed in the OpenShift repo. Make sure you git add and git commit any local repo changes first.

$ git pull -s recursive -X theirs git://github.com/user/myhubot.git

This command will merge your Hubot code into the OpenShift repo, using your files where there is a collision. One drawback of this approach is that your package.json will no longer contain the start script used to crank up Hubot on OpenShift. To fix this, add a start script such as the following back into your package.json:

"scripts": {
  "start": "PORT=$OPENSHIFT_NODEJS_PORT BIND_ADDRESS=$OPENSHIFT_NODEJS_IP HEROKU_URL=$OPENSHIFT_APP_DNS REDIS_URL=redis://:$REDIS_PASSWORD@$OPENSHIFT_REDIS_HOST:$OPENSHIFT_REDIS_PORT bin/hubot -n Hubot -a shell"
}

As mentioned above, the HEROKU_URL environment variable designates a URL Hubot should ping at regular intervals. This is because applications hosted free on Heroku are put into an idle mode after one hour of inactivity. On OpenShift, gears on the free tier are idled after 24 hours of inactivity; apps hosted with the $0/month Bronze plan are not subject to this.

Rather than doing a Git merge, you could opt to copy your code into the OpenShift repository manually. Whatever method you use, make sure the resulting repository still has the following two things:

  • A .openshift directory, including the marker file .openshift/markers/use_npm
  • A start script in package.json such as the one shown above

If your existing Hubot has Redis data you would like to migrate, you will need to do a Redis data dump and import the data to the OpenShift-hosted Redis instance.

If you have Redis installed, you can do this locally using port-forwarding and Redis commands such as those shown below. If not, you can use rhc scp to send your data dump to the OpenShift gear, and use rhc ssh to SSH into the gear and run the Redis command to import it.

$ rhc port-forward
Checking available ports ... done
Forwarding ports ...

To connect to a service running on OpenShift, use the Local address

Service   Local                OpenShift
--------- --------------- ---- ------------------
redis-ser 127.0.0.1:16379  =>  127.11.151.2:16379

Press CTRL-C to terminate port forwarding

# Put above into background or open new terminal
$ redis-cli -p 16379 -a redispassword --rdb dump.rdb

The password for the OpenShift Redis instance is stored in an environment variable. To check this, you can use rhc ssh to SSH into the OpenShift gear and run the command printenv | grep REDIS to view the REDIS environment variables and their values.

Deploy to OpenShift

Once you have added the desired changes to your Hubot to the local clone of the OpenShift app repository, you can deploy the code to OpenShift using standard Git commands.

git add -A
git commit -m "Adding Marvin script and Twitter adapter"
git push

Once the push is complete, your newly configured Hubot will be running in the cloud on OpenShift. For me, this meant HubotOpenShift was ready to respond to tweets.

Note that your OpenShift Hubot app will not have a web front-end because we haven’t created one; if you go to the URL you see when you issue the command rhc app show, you will get an error response. If you like, you can add a website for your Hubot using the same OpenShift application. To learn more about hosting Node.js projects on OpenShift, read Run Your Nodejs projects on OpenShift in Two Simple Steps.

Summary

Creating a Hubot hosted on OpenShift is fun and easy to do. You can spin up an OpenShift app that has Node.js and Redis ready and raring to go using a one-line terminal command. Deploying a bot is simply a matter of pushing your customized Hubot code to the OpenShift app’s Git repo, ensuring you have an OpenShift config directory with the use_npm marker and an appropriate start script in your package.json file. The rest is only limited by your imagination.

Happy coding, and don’t forget your towel!

Next Steps

Categories
Node.js, OpenShift Online
Tags
, , , , ,
  • Giancarlo Ventura Granados

    Great!