Hubot

A Look Inside Our Robot Friend

  1. Setting Up Hubot
  2. Coffeescript Primer
  3. Hubot Overview
  4. APIs

(disclaimer: this assumes OSX. commands should translate easily to windows and linux.)

Prerequisites

3 Easy Steps

  1. Install Node & Redis
    (brew install node redis)
  2. Follow brew's instructions to run redis
  3. Install Hubot
    (npm install -g hubot)

An Heroku account is suggested.

Find a Nice Home

cd to your "projects" directory

run hubot -c airbot to generate a boilerplate

cd airbot

npm install

Hello World

run bin/hubot

type hubot ping and hit enter

A Brief Diversion into Coffeescript

introMessage = (user) ->
    if user?.name? and user?.hobby?
      "hello, I am #{response.name}, " +
                "a #{response.hobby}ist."
    else
      message = "Please tell me more about yourself."

    message

me =
  name: "Jack"
  hobby: "Hubot curation"

console.log introMessage(me)

#hello, I am Jack, a Hubot curationist

Hubot Structure

  • Procfile (Heroku startup script)
  • README.md
  • bin/ (contains hubot executable)
  • external-scripts.json (list of packages from npm)
  • hubot-scripts.json (list of packages from hubot-scripts)
  • package.json (node package manager metainformation)
  • scripts/ (custom hubot script directory)

A Hubot Script Example

create and edit scripts/goodbye.coffee


goodbyes = [
  "Bye, {name}.",
  "Later, {name}.",
  "Take care, {name}."
]

goodbye = (name) ->
  index = parseInt(Math.random() * goodbyes.length)
  message = goodbyes[index]
  message.replace(/{name}/, name);

module.exports = (robot) ->
  robot.hear /(bye|later),?\s(.*)/i, (msg) ->
    if robot.name.toLowerCase() == msg.match[2].toLowerCase()
      byeMessage = goodbye(msg.message.user.name)
      msg.send(byeMessage)
            

run bin/hubot again

say goodbye Hubot

say later, Hubot

See? Regexes ARE fun!

hubot-scripts

github.com/github/hubot-scripts

hubot will automatically download and keep up-to-date any hubot-scripts you add

copy the dependencies from the hubot-script into your package.json

an example from clark.coffee:

# Description:
#   None
#
# Dependencies:
#   "clark": "0.0.5"
#
# Configuration:
#   None
#
# Commands:
#   hubot clark <data> - build sparklines out of data
#
# Author:
#   ajacksified

Towards the bottom of package.json:

{
  /* ... snip ... */
  "dependencies": {
    "hubot": "2.6.1",
    "hubot-scripts": "2.5.1",
    "optparse": "1.0.4",
    "underscore": "1.4.4",
    "clark": "0.0.6"
  }
}

edit hubot-scripts.json

add "clark.coffee"

run bin/hubot

say hubot clark 1 2 3 4 5

hubot persistance

simple storage through hubot.brain

overloaded by redis-brain, mongo-brain, etc.

(you can find these in hubot-scripts or write your own)

You can save any arbitrary data in the brain.

# you may want to wait until the brain has been initialized
# and there is a database connection
robot.brain.on 'loaded', ->
  robot.brain.lastAccessed = new Date()
  robot.brain.seagulls = 12
  robot.brain.flowers = { pansies: true, daffodils: false }


  # hubot brain runs on events
  robot.brain.emit 'save'

hubot http listener

create and edit scripts/say.coffee

querystring = require('querystring')

module.exports = (robot) ->
  robot.router.get "/hubot/say", (req, res) ->
    query = querystring.parse(req._parsedUrl.query)
    message = query.message

    user = {}
    user.room = query.room if query.room

    robot.send(user, message)
    res.end "said #{message}"

edit package.json to include
"querystring": ">= 0.1.0" in the dependencies

run npm install to install the new dependency

run bin/hubot

visit localhost:8080/say?message=hello

Deployment

99 times out of 100, you'll probably just deploy to Heroku

hubot -c created a Heroku Procfile for you

run Heroku create

deploy with git push heroku master

start with heroku ps:scale web=1

(you'll only have to run ps:scale this the first time)

Chat Adapters

Hubot ships with a Campfire adapter. You can get more from hubot-scripts.

Assuming Heroku deployment, run

Heroku config:add \
HUBOT_CAMPFIRE_TOKEN=secret \
HUBOT_CAMPFIRE_ROOMS=123,456 \
HUBOT_CAMPFIRE_ACCOUNT="hubot"

(replacing rooms with actual room ids from Campfire)