Whether they're publishing notifications, responding to /slash
commands or carrying a conversation, bots have become an integral part of the way we work with Slack. A bot can do any number of things for your team as part of your day-to-day work, you're only limited by your imagination. For some first-hand experience, check out the Heroku Button Gallery, where users have created all types of bots: from fun bots like poker and Jeopardy!, to more practical ones like a bot that tracks the satisfaction of your team members or one that reminds your team to review existing pull requests.
That said, the real power and fun of Slack bots comes once you know how to build your own. In this post, we'll show you how to create and deploy a Slack bot that will respond to /slash
commands in order to show the top trending repos in GitHub. While a Slack bot can be built in practically any language, today we're going to build ours with Node, and not just because I 💖 Node. Anything beyond a simple notification bot depends on Slack's WebSocket-based RTM (Real Time Messaging) API, and WebSockets and Node go together like 🍔🍟.
We've got a lot of ground to cover, here's an outline of the journey we're about to take:
- Getting Started
- Publishing Notifications to Slack
- Receiving and Responding to
/slash
Commands - Connecting a Bot to the Slack RTM API
- Share Your Bot with the Heroku Button
- Epilogue
Getting Started
Let me introduce you to 🌟 Starbot, the example we'll be working with today. It's soon-to-be the easiest way to stay apprised of hip repos on GitHub, from the comfort of your favorite Slack channel.
Before you begin
Here's what you'll need:
- A Heroku account (signup)
- The Heroku CLI
- A Slack team to abuse
- Node (5.7.* preferably)
- The burning desire to scream IT'S ALIVE.
This guide bounces between Slack, Heroku and your local development machine — so I've prefixed the sub-titles with the applicable logo where appropriate.
Create a custom Slack integration
We're going to make a custom integration bot designed explicitly for your team. As a bonus, I'll show you how to easily distribute your bot using the Heroku Button, so that you can share your creation with everyone – even grandma.
(Note that if you are building a serious bot, you will ultimately want to run it on Hobby rather than Free dynos to avoid any issues with dyno sleeping and idling. But Free dynos are great for building and testing.)
First, visit slack.com/apps/build
and select "Make a Custom Integration" as seen below.
Run Starbot locally
Starbot is essentially a bare-bones Express app, you can find detailed instructions on running it locally in the projectsREADME.md
.
Clone the project
$ git clone https://github.com/mattcreager/starbot.git
$ cd starbot
Install dependencies
$ npm install
Copy .env-example
to .env
$ cp .env-example .env
Start Starbot
$ npm start
🚀 Starbot LIVES on PORT 3000 🚀
That's it! Visit localhost:3000 and make sure Starbot is running.
Deploy Starbot to Heroku
We could push our code to Heroku without ever visiting the command line, but what fun would that be?
Create a Heroku app, with the Heroku Toolbelt
$ heroku create {optional-app-name}
Creating app... done, stack is cedar-14
https://starbot-staging.herokuapp.com/
Push our code
$ git push heroku master
Counting objects: 15, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (15/15), 5.72 KiB | 0 bytes/s, done.
Total 15 (delta 0), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
...
remote: https://starbot-staging.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy.... done.
To https://git.heroku.com/starbot-staging.git
* [new branch] master -> master
Did we just deploy this application in two commands? Yes, yes we did! Heroku installed the dependencies in Starbot's package.json
file automatically, and gave us a URL so that we can visit our newly deployed app.
Open the app in a browser
$ heroku open
Now Starbot is running on Heroku, but it doesn't know anything about Slack, and Slack doesn't know anything about it. I expect they'll soon be fast friends, so let's make introductions.
Publish Notifications to Slack
While publishing notifications to Slack is the simplest of custom integrations, it's still pretty darn cool, especially with a sprinkling of Heroku Add-ons. Let's show Starbot how to find trending GitHub projects and publish them to a Slack channel every morning. In this case, Starbot is using the BotKit framework from the folks at Howdy.ai.
Set up an "Incoming WebHook" on Slack
Slack will provide us with the API endpoint, or webhook; later, we'll POST
data to this endpoint. Select "Incoming WebHooks" and choose a channel.
Again, the above selection can be found at {your-team}.slack.com/apps/build/custom-intergration
Now you're the proud new owner of a Slack "Incoming WebHook"! The configuration page includes a lot of great information about formatting and delivering messages to your new webhook, but what we need first is the "Webhook URL". It should look something like this:
https://hooks.slack.com/services/T0..LN/B0..VV1/br..dd
Found it? 👏 Now let's move right along.
Publish a Notification to Slack from Heroku
Now that we've deployed our Starbot to Heroku and added an incoming webhook on Slack, it's time to connect the dots.
First, remember the webhook URL I had you save? Let's put it to work by setting a WEBHOOK_URL
config var. This makes the value available to Starbot.
$ heroku config:set WEBHOOK_URL=https://hooks.slack.com/services/T0..LN/B0..VV1/br..dd
Setting config vars and restarting starbot-staging... done
WEBHOOK_URL: https://hooks.slack.com/services/T0..LN/B0..VV1/br..dd
Heroku Add-ons allow us to quickly extend the functionality of our application, in this case, we're going to use the Scheduler add-on to deliver trending GitHub repos to Slack daily.
We can provision the add-on from the dashboard, or from the CLI with the Heroku Toolbelt.
$ heroku addons:create scheduler
Creating scheduler-transparent-24143... done, (free)
Adding scheduler-transparent-24143 to starbot-staging... done
$ heroku addons:open scheduler
Then add a scheduled task, and configure it to run daily.
Our new scheduled task will create a one-off dyno and execute npm run notify
, which is defined in this bit of our package.json
.
{
"name": "starbot",
...
"scripts": {
"start": "node ./src",
"notify": "node ./src/tasks/notify",
"test": "standard"
},
...
"engines": {
"node": "5.7.1"
}
}
We could wait patiently for the task we scheduled to fire—or we could just run our own one-off dyno, and trigger the notification ourselves. Immediate gratification, FTW.
$ heroku run "npm run notify"
Let the notifications commence.
Receive and Respond to /slash
Commands
Slash commands are a personal favorite—enabling you to listen for a custom command, across channels, and triggering a POST
or GET
request to a configurable endpoint. In this case, that endpoint will be the Starbot application we deployed earlier, and responding to /slash
commands will let our bot do a lot more than post once a day!
Creating a /starbot
slash command
Return to the "Build a Custom Integration" page and select "Slash Commands".
Next, pick a name, it must begin with /
.
Now that we've created the command, we need to configure it. Starbot is expecting a POST
request to arrive at /commands/starbot
.
Slack has also provided us with a token specific to this command, something like: JzRR6hEuh3f749iXY3qEpVgN
. We're going to use this to verify the payload Starbot receives is coming from Slack.
It wouldn't hurt to choose an appropriate name, icon, descriptive label and some autocomplete text—you could make something up, or use the suggestions provided in Starbot's readme.
Configuring the /starbot
command on Heroku
We've already deployed Starbot to Heroku, so it's waiting patiently for POST
requests from Slack, but at the moment Slack's requests are going to receive a 402
(Unauthorized) response. To fix that, we'll need to authenticate the bot with Slack, which is easy. We'll just use the Heroku Toolbelt to set a STARBOT_COMMAND_TOKEN
config var.
$ heroku config:set STARBOT_COMMAND_TOKEN=JzRR6hEuh3f749iXY3qEpVgN
Setting config vars and restarting starbot-staging... done
STARBOT_COMMAND_TOKEN: JzRR6hEuh3f749iXY3qEpVgN
Your slash is my command
Connecting a Bot to the Slack RTM API
And finally the star of the show, a developer's best friend, the real-time bot. Fortunately, no matter how tricky your bot is to build, configuring and deploying it to Heroku is simple.
Connecting a bot to the Slack RTM API
Ok, one last trip to the "Build a Custom Integration" page and this time we're going to select "Bots".
We get to give our bot a name!
And again, we're presented with the opportunity to customize the bot we've just created by giving it a name, description, icon, etc. You'll notice that the bot isn't currently following any channels. Bots are like vampires: they must be invited to a channel before they can follow it (any takers for BuffyBot?).
Take note of the API token, which is going to look like this: xoxb-253973540645-lAJG4hL34343f3pk52BE6JO
. Without it, we won't be able to authenticate.
Configuring the bot on Heroku
The Starbot bot won't attempt to connect to Slack's RTM API without a token, so once more, let's use the Heroku Toolbelt to set a SLACK_TOKEN
config var.
$ heroku config:set SLACK_TOKEN=xoxb-253973540645-lAJG4hL34343f3pk52BE6JO
Setting config vars and restarting starbot-staging... done
SLACK_TOKEN: xoxb-253973540645-lAJG4hL34343f3pk52BE6JO
That's it! Head over to your Slack channel and use the /invite
command to invite our @starbot
bot to the channel. Then say hello to him, or her!
It's alive, it's alive, it's ALIVE!
Share Your Bot with the Heroku Button
The Slack Button makes it easy for other Slack users to add your bot to their team, but the Heroku Button makes it just as easy for other developers to deploy and manage your bot themselves.
Adding a button to your bot is as simple as creating an app.json
file, and adding the button to our GitHub readme.
Creating an app.json
The app.json
file is a manifest format for describing web apps. Here's the interesting bits from Starbot's app.json
:
{
"name": "🌟 Starbot",
"description": "tarbot is GitHub's trending open-source page, reincarnated as a Slack bot",
"repository": "https://github.com/mattcreager/starbot",
"env": {
"STARBOT_COMMAND_TOKEN": {
"description": "Slash command token, for the starbot command endpoint",
"required": true
},
"SLACK_TOKEN": {
"description": "Slack bot RTM API token",
"required": false
},
},
"image": "heroku/nodejs"
}
As you can see above, we begin by specifying our apps name, description and repo. We then declare the environment variables Starbot requires to run. Learn more about the app.json schema on the Dev Center.
Adding the Heroku Button to the repo
The last thing we must do before people can begin deploying Starbot with the Heroku Button, is to add it to the project's README.md
:
[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)
Heroku will automatically infer the repository URL from the referrer header when someone clicks on the button.
Epilogue
Now that you’ve got the basics down, a whole new world of functionality is at your team’s fingertips. Not just your team’s either–with a little more work you can offer your bot as a service for others on Slack through the App Directory. Peruse the directory to see the many ways teams are extending Slack, whether it's with the outside world through Customer Support apps, or internally with HR or Office Management. To learn more about offering your app, check out their getting started guide.