more than meets the eye


I am an operational tool and infrastructure developer at Yieldbot who is lazy by nature.

I don't even wait till I do something twice before scripting it

man ChatOps | more

It's not all about the bots!

ChatOps brings common operational tasks and the conversations surrounding them into a single shared view

Conversation-driven development and operations

  • Github Releases
  • Asana Tasks
  • Jenkins Builds

Be careful of the Decepticons!

  • Should everyone in the channel access the bot?
  • Should the bot play God?
  • Mobile devices?



Web based chat client capable of supporting large teams and serval different types of integrations including multiple bots


  • developed at Github
  • written in Node.js
  • scripts can be written in js or cs
  • large open source community constantly submitting new scripts


  • cloud application platform
  • 100+ service add-ons
  • easily scalable


  • JavaScript runtime
  • event-driven
  • non-blocking I/O model

Ship It

  1. setup Slack
  2. setup dev environment
  3. setup Heroku
  4. launch it
  5. code / debug it

Roll Out

Setup Slack

  • create a slack account
  • create a channel
  • setup integration

Setup Development Environment

vagrant up
vagrant ssh
curl | sh
nvm install 0.12.7
npm install -g hubot coffee-script yo generator-hubot

Create A Bot

mkdir ~/bot
cd ~/bot
yo hubot
npm install hubot-slack --save

Setup Heroku

sudo wget -O- | sh
git init && git add --all && git commit -m 'initial commit'
heroku create optimus-prime
heroku addons:create redistogo:nano --app optimus-prime
npm install hubot-heroku-keepalive --save
heroku config:set HUBOT_HEROKU_KEEPALIVE_URL= --app optimus-prime
heroku config:set HEROKU_URL= --app optimus-prime
heroku config:set HUBOT_SLACK_TOKEN=xoxb-11995843430-XPP92BkpOEUrmsGxgEeXLy7L --app optimus-prime

Pencils Down Class

git push heroku master
heroku ps:scale web=1

But I Wanted Fortress Maximus

.hear && .respond

module.exports = (robot) ->
  robot.hear /roll out/i, (res) ->
    # Optimus will respond to any string containing 'roll out'   

  robot.respond /Autobots, transform and roll out/i, (res) ->
    # You need to directly call Optimus

.send || .reply || .emote

module.exports = (robot) ->
  robot.hear /roll out/i, (res) ->
  res.reply "Who gave you the leadership matrix"

robot.respond /Autobots, transform and roll out/i, (res) ->
  res.send "Let's kick some Decepticon butt"

robot.hear /Predacons, merge to become Predaking/i, (res) ->
  res.emote "[Predacons transform into Predaking]"

capturing data

robot.respond /arise (.*)/i, (res) ->
  autobot = res.match[1]
  if autobot is " Rodimus Prime"
    res.reply "I knew you had potential"
    res.send "One day, an Autobot shall rise from our ranks, 
    and use the power of the Matrix to light our darkest hour."

external api calls

  data = JSON.stringify({
    autobot_city: 'transform'
    .header('Content-Type', 'application/json')
    .post(data) (err, res, body) ->

local testing and debugging

Run locally `bin/hubot`

Debug remote bot locally `heroku logs`

Additional Resources