CI Workflows and Bots

Written by: Chris Ward
6 min read

Chat bots are everywhere. Suddenly our messaging services are inundated with small automated systems inhabiting spaces in the domain of human-to-human communication. We can now have conversations with bots that help us buy products, book travel, make meetings, solve customer service issues, and much more.

Here in Berlin, there are now two meetups dedicated to bots, and they piqued my interest in writing a series of articles covering how to use and create them. Of course for Codeship, this had to be bots for helping you build, deploy, or monitor your applications.

What Is a Bot?

To begin, let's cover what a bot actually is. A bot is not a new concept. In the past, they were a way for programmers to push their skills by creating an automated system in an attempt to convince a human that they were speaking to another human (and passing the Turing test). In recent years, they have come to mean the systems that live in chat platforms I outlined above. But in summary, a bot processes natural language (text or spoken), interprets it, responds, and so it goes.

There are two broad forms of bots:

  • Those based on preprogrammed rules that have a limited set of uses.

  • Those based on machine learning that begins with a set of training data and learns as it works.

For the rest of this article, I will stick to the first, simpler type. The second type is much more complex, and for the needs of this article, the simpler type is enough. Bots can live independently, or part of an existing messaging platform, so again for simplicity and appropriateness, I will use Slack for this article.

!Sign up for a free Codeship Account

Building a Bot for Slack

In case you don't use or know Slack, it's a popular messaging application for teams. But its coolest feature is its level of integration. It allows for a dizzying amount of options to make the application streamline your workflow, but this article covers the bot user option.

While each messaging platform offers different options for managing bots, you will still need to write code. Slack has two recommendations for removing much of the boilerplate code you need: node-slack-client and BotKit (you can also use it for building bots on other platforms).

I opted for BotKit. At first I struggled to get it working, not due to a lack of documentation, as there are loads available, but due to a lot of tutorials being slightly different to keep up with. Slack's changing APIs and knowing which is the most accurate is hard. Eventually, I found that this tutorial worked for me, and I recommend that during steps 3 and 4 you also take the opportunity to customize your bot. Here are screenshots from mine.

After following all the steps you should have a bot on your specified team that you can issue commands to. Try @bot-name color, @bot-name uptime.

If you crack open the code you downloaded, you will see that it's JavaScript. You can add custom 'skills' inside the skills folder, and BotKit will load them. Create a new file in that folder called codeship.js and add the following boilerplate code:

module.exports = function(controller) {

The bot will use the Codeship API to access certain details of our account. Fortunately, someone has already created a node module you can use. Add it to package.json, run npm install, and include it in codeship.js:

var Codeship = require('codeship-node');
var codeship = new Codeship({apiKey: '<api-key>'});

Now expand the controller you created:

module.exports = function(controller) {
  controller.hears('projects', 'direct_message,direct_mention', function (bot, message) {
    codeship.projects.list(function (err, projects) {
      if (err) {
        bot.reply(message, "I'm sorry, there was an error retrieving projects from CodeShip.");
      for (var i in projects) {
        bot.reply(message, projects[i].repository_name + ' -' + projects[i].id);

The controller.* methods allow you to respond to certain events. In this case, controller.hears (documentation here) matches certain phrases and keywords. As parameters, it accepts the pattern as an exact word or regex string, the types of message events to listen on (BotKit abstracts most message events across all the platforms it supports, but there are specific ones), an optional middleware function, and a callback.

The codeship.projects.list function is from the npm module you installed earlier and it returns all your Codeship projects. Based on the success of the function call, we use the bot.reply method (documentation here) that accepts as parameters the incoming message object (which itself contains metadata about the message), the response text you want to send, and an optional callback function.

As you can see, adding responses to other keywords or phrases to trigger other Codeship endpoints is relatively straightforward. If you're interested in adding more, then I've created a basic repository of code, and I welcome your pull requests to make the bot more useful.

To start the application, run this inside the application folder: clientId="<client-id>" clientSecret="<client-secret>" PORT=3000 node .

Expose your machine to the internet with a tool like ngrok and open the URL it generates. When you click the large Slack button you see, the bot will ask for access to your team channel.

Packaging Your Bot

Great, the bot is locally tested and working, but it's not much use living on your machine or in GitHub. To distribute it widely, it needs to run on a publicly accessible server. I hosted mine on Heroku here and then updated the auth and events URLs to match the new address.

Slack has a distribution checklist to run through before you distribute to the world, available under the Manage Distribution tab. But to get to that list, you need to complete prior steps. If you've followed all the steps so far, then most of these will be complete, except the step asking you to ensure that you have removed all hardcoded URLs. As this application doesn't have any, check the box.

The final list asks you to check details like scopes (what details from users your bot accesses), user experience, copyright violations, landing pages, and more. In some ways, completing these steps may be more complex than creating the bot in the first place.

As the bot in this tutorial isn't quite ready for prime time yet, and Slack reviews all bots, I haven't sent it to distribution yet. But if you are keen on helping me as I noted above, then I'm sure we could submit it soon and have a bot that everyone can use.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.