Writing Custom Bot Commands for Slack

Part 1 of 2

Jim Clark
The Composition
5 min readOct 20, 2017

--

Your team is already living in Slack. The commands you need to do your job should be there too. Our powerful Slack integration is core to Atomist’s vision of comprehensive automation.

You might want to know which services have had new releases in the last 24 hours. During project planning sessions, you might need to see a list of all unassigned issues. You shouldn’t need to switch tools just to fetch status info from your internal systems. These things form the basis for how your team gets things done. They have to be simple to create. They have to be simple to evolve.

At Atomist, we’ve been working on a solution to this problem. There’s a lot to talk about so we’re planning a series of blog posts; however, we’ll start with something that you’ll find useful on day 1. We’re going to look at adding new “Commands” to Slack. Specifically, we’re going to show you how to build a command that pulls data from Stack Overflow into a channel. Running through this exercise will take approximately 10 minutes of your time. It will also pave the path for us to address some really cool features:

  • Handling events from external systems
  • Adding buttons and menus to your Slack conversations
  • Updatable messages made easy: broadcast status into Slack
  • Identity federation: stop embedding secrets and tokens in your scripts (seriously, we have to stop doing this)

Step 1: Add the Bot to your Slack Team

If you have previously added the Atomist bot to your team, then you can skip this step. Otherwise, click this button to add Atomist to your Slack team (if you don’t have a Slack team, or you cannot add a bot to your existing team, you can create a team for free):

When the bot first arrives in your team, it will send you a welcome message as a DM. This message will contain a link to take you through the GitHub authorization flow. We will use your GitHub identity to authenticate the client that we’ll create in the next step. After completing the GitHub authorization, the bot will send you another DM indicating that you’re ready to proceed.

Now you’re ready to start giving the bot some new skills! (See our docs if you need any help adding Atomist bot to your Slack team).

Step 2: Create a new Command

Our “intent” is to have the bot search Stack Overflow. We’d like the bot to recognize that the command should run when someone asks the bot to search so. In addition, we’d like the bot to get a search query string from the user. We call this a Command Handler.

Here’s what the code looks like:

Notice that we have decorated the SearchStackOverflow class with information about the phrase that we’d like the bot to recognize:

Also notice that we’ve decorated a field with information about the parameter that should be extracted from the conversation.

After we have told the bot what command to listen for and the parameter to collect for that command, the handle function implements the command logic:

  • Query stack overflow (using the axios http client library for Node.js)
  • Create a Slack message from the Stack Overflow results using the handleResult method (not shown)
  • “Respond” to the original Slack message
  • Indicate that we successfully responded with the results, or send an error message

A GitHub repository containing the fully working example of this Command Handler is available here. However, we’ve got an easier way for you to try this out locally!

Step 3: Register your new Command with Atomist

We’ve created a handy script to get started with your new automation. There are two prerequisites:

  1. You’ll need to have Node.js already installed.
  2. You’ll need to know your Slack team ID. You can get this ID from Slack by typing team in a DM to the @atomist bot.

Once you know your team ID, review the Atomist setup script and then open a terminal and run the following to clone the client project and start the client:

Note: replace TEAM_ID with your Slack team ID

You should see a Node.js process running in your console now with output like this.

Step 4: Try it out in Slack!

You can now go into the #general channel, invite the bot (by doing/invite @atomist — Slack bots don’t go where they’re not invited) and type @atomist search so q=<your-query-string>to search Stack Overflow from Slack.

Voila! You have successfully provided a new bot command to your Slack team! It’s that easy.

By starting with the automation running on your laptop, you have an ideal environment to develop and test your new automation (these command handlers are really easy to test!). But your team is going to love this new command, so it can’t go away when you close the lid on your laptop. You’re going to want to run this on one of your own servers, or on a public cloud. In fact, this programming model permits us to deploy these handlers as serverless functions running in the cloud!

You can now try making a change to the handle function (in atomist-blogs/sof-command/src/commands/SearchStackOverflow.ts). You could update the intent, or add a new parameter. You could even add an additional command! The Node.js process will automatically detect changes and restart your client. Then try out your change in Slack. Instructions on how to use npm to continue working on this project are included in the repo’s README.

Summary

Command handlers are a great way to add functionality to your bot; they represent an important part of the overall vision that Rod discusses in his previous post. In the next post of this series, we’ll look at enhancing the bot’s behavior using events from external systems (like GitHub, CI, etc.). Once we have a bot that can respond to external events, we can move on to building actionable, and updatable messages.

Continue to the next post in this series.

--

--