April 14, 2016 - No Comments!

How to code a job searching AI Bot with Hubot and Slack

Part Four in my ongoing "job board" coding series (others here, here and here): Coding a bot to look for jobs for you. Facebook recently announced their chatbots thing: Chatbots are not that super new, but more fuel is now on the fire and chatbots are probably app-killers - So let's make our own super simple one!


We're going to use Github's awesome Hubot for our bot kit and we will plug it into Slack, because we are always on Slack, amirite?

Pre-requisites for this episode? Node, npm, git, yeoman, Hubot, Slack and a Bot token, and Heroku to deploy. Also some knowledge of Coffeescript, and the command line (terminal) will help.

Step 1: Git yo-self (lol) Hubot, and Install as per instructions (maybe you want to use the name "jobbot" for now, to make things simpler)

Step 2: Read about and get a bot token from Slack and take note of it.

Step 3: Open a Heroku account - Trust me, unless you are Mr Devops this will save a lot of pain.

Program the bot!

Yes, the beautiful thing about using Hubot is we simply roll up our sleeves and start programming AI into our bot.  In the scripts folder, create a new coffeescript file called jobbot.coffee


module.exports = (jobbot) ->

Jobbot is born, with the capacity to do absolutely zero.

jobbot.respond /wakeup!/i, (res) ->
  res.send "Yes?"

Jobbot will answer "Yes?", when you tell him (literally) to "wakeup!" - eg. @jobbot wakeup!.  The .respond command will be invoked when the bot is actively referenced, eg. with the @symbol.

jobbot.hear /work/i, (res) ->
  res.send "Did someone mention work? Ask me if there are 'any jobs today?
  ' and I'll take a look for you"

.hear allows our bot to listen in on the room's conversation, and certain words trigger its attention, possibly it will respond (but not necessarily...). In this example, if Job bot hears the word "work" in any conversation it will incite you to invoke its favourite (and only) task, that of looking for a job for you. It's pretty keen.

jobbot.respond /any jobs today?/i, (res) ->
  res.send "Checking..."

  jobapi = "https://jobs.github.com/positions.json"

   .get() (err,response,body) ->
   if err
    res.send "Encountered an error :( #{err}"

   data = JSON.parse body

   suggest = data[Math.floor(Math.random() * data.length)]
   res.send "How about #{suggest.title} at #{suggest.company} in #{suggest.location}? #{suggest.url}"

So, Job bot's main task is to go and look for a nice Job opportunity for you. In our example he will check Github for developer jobs and offer you one of them at random.

So what is happening up there? Firstly, when Job bot is specifically asked "any jobs today?" it will politely inform you it is "Checking...". Because there may be a delay connecting, you may have to wait...

While you are waiting, Job bot checks its limited dictionary of job boards (Github jobs), and asks it kindly for the current list of jobs, no ifs or buts: Kindly, because we politely inform Github that we are expecting a JSON response (which is not necessary), and we also reply with a totally uninformative error message if something goes wrong somewhere. Clearly this will be handled better in a professional environment, right?, right?

When Job bot receives the list, he will pick one at random, and suggest it to you. Isn't that nice?

NB: Coffeescript is very pedantic about indenting. Triple check your indenting is correct. If you get any "res is not defined" errors or similar, it's probably this.

Let Hubot know about your script

Finally, we must tell the Hubot framework to include our new script when it runs by including it in the hubot-scripts.json file, like so:


Clearly, you can add as many scripts you like.

And that's it. Job bot is simple, and effective in his small way.

Connect Slack

The awesome thing about Hubot is that it is client agnostic: We use a plugin to enable it to "talk" with our client - which is called an adapter. We will be using the Slack adapter. Install it via npm like this:

npm install hubot-slack --save

Testing the bot

You can run Job bot in the command line as explained in the Hubot docs (link above). But it is more satisfying to see it respond in Slack. We can do this without deploying by fetching the Slack token you requested above (right?) and then passing it to local Hubot and adding the Slack adapter, like this:

HUBOT_SLACK_TOKEN=xoxb-34005417601-pQWVEfulJVw7qLxlx7YCBnSh ./bin/hubot --adapter slack

You should see your bot active in Slack. Wake him up, mention work and then ask for some jobs.


Deploying the bot

The github adapter repo has a good guide for deploying Hubot to Slack here, as well as other adapters. It goes something like this:

You'll need the bot token you requested as above, and your Heroku account. I recommend installing Heroku toolbelt, as we will use it here and it's pretty awesome actually. So, from the command line (with toolbelt installed and logged in):

heroku create myjobbot

Heroku will need your Slack token in order to connect the dots. So fetch your token and set it like this:

heroku config:set HUBOT_SLACK_TOKEN=xoxb-1234567890-XXXXXXXXXXXXXXXXXXX

This creates a (free) app instance on Heroku stack. It needs our git repo. If you haven't already, create a git repo, add everything and commit!

git init
git add .
git commit -m "Go go gadget jobs!"

("Go go gadget jobs" is not a good commit message btw)

Now we push that repo to Heroku which will take care of all the devops muckiness that we designers simply can't handle, thusly:

git push heroku master

Heroku will do its thing on the command line, which is itself a bot in some ways, I guess.

The free Heroku dyno sleeps pretty quickly, you may want to use this Heroku keep alive option to keep it burning longer.

And, in theory, you're good to go! You know that things can wrong at every turn, so ping me @derrybirkett if you really need to. Otherwise, follow the links and make sure no steps have been missed (and the coffeescript indenting is kosher).

PS: Here is my Jobbot repo if you want to check it out.

Published by: Derry Birkett in Development

Leave a Reply