How to build a simple Slack bot
By: Sascha Trifunovic
Tags: Nodejs, AI, Heroku, Bots, Programming

Slack is a wonderfully simple communication tool. Everybody is within reach of your fingertips. You can grab anybodies attention with a few key strokes. Distract them with a question whenever you are too bored to google the answer yourself ;-)

It does not take many workspaces you are coerced into joining before you turn off notification for most of the channels you are part of. However, some people have a very high signal to noise ratio and you would not mind being notified of their messages.

Fortunately, this conundrum can be easily be solved with a simple bot. So let’s learn how to create such a Slack bot.

If you don’t care about a step by step guide you can also just check out the final code.

Building the Slack bot

We will build our bot in Node.js, so you need to have node and npm installed. If you want to deploy your app to Heroku, you will also need a Heroku account, as well having their CLI installed. To run your app locally, you also need to install and run a RethinkDB instance.

To create the application, run the following in a terminal.



$ npm init -y

$ npm install $ mkdir stalker-bot && cd stalker-bot$ npm init -y$ npm install @slack/events-api @slack/web-api rethinkdb

This will initialize a Node.js app and install all required dependencies.

Listening to Slack events

We will create a Node.js server to listen to Slack events. Create an index.js file and add the following server code.

We first configure the slack libraries, namely the event listener server and the web client. We then listen to message events. Direct messages are interpreted as commands and messages in channels are listened to in case we need to notify a stalker.

Bot commands

We can chat directly with the bot to issue commands. The stalker bot knows about three commands:

subscribe to a user in a channel

to a user in a channel unsubscribe from a user in a channel

from a user in a channel list all current subscriptions

To save all subscriptions, we will use my favorite document database as of late, RethinkDB. It is similar to MongoDB but additionally has reactivity built into it and it is still open source. We will need two tables, one to save all users and one to save the subscriptions they have. We will deal with managing database connections and running migrations later.

Create a handler.js file and start with the following code. We first configure the Slack web client in order to be able to respond to events and add some database boilerplate before we handle the actual commands.

When handling commands we basically search for one of the three commands in the message. We also use a regular expression to be able to extract the user and the channel from the (un)subscribe commands.

Subscribe to a user

To subscribe to a user in a channel we first need to parse said user and channel from the subscription command. The parsed user and channel are saved in a subscription object which can have listeners. The listener, i.e., the command issuer is saved in the user table.

When a subscription is created, the bot also needs to join the respective channel in order to be able to listen to messages from the desired user.

Unsubscribe from a user

To unsubscribe from a user in a channel we also need to parse the command first and then revert the actions done in the subscription command. We remove the listener, i.e., the command issuer from the subscription or delete the subscription if there are no listeners.

When there are no more subscriptions to a channel we also have the bot leave it. This will lessen the messages the bot has to react through.

List subscriptions

Listing the subscriptions is a convenience command to see what users we are currently stalking.

Now that we have implemented all commands, lets do the actual stalking.

Do the actual stalking

When we subscribe to a user in a channel, the bot joins said channel. It handles each message and reacts accordingly if the message author is of interest. If there is a listener for said author, the bot sends a direct message to the listener.

Note: In order for our bot to serve its purpose, we obviously cannot disable notifications for direct messages.

Database management

Until now we have conveniently just gotten a database connection and assumed the required tables already exist. Now, the time has come to manage the actual RethinkDB connection and take care of the required migrations.

RethinkDB connection

We manage our RethinkDB connection lazily, i.e., we only create the (re-)connection when it is actually needed. The connection parameters are parsed from environment variables, or the defaults are used.

On Heroku, the RethinkDB Cloud add-on will set the environment variables. For a locally running instance of RethinkDB, the defaults should work.

Migration

The app does not work without a users and subscriptions tables. We thus need a database migration that adds these tables.

This migration checks if the required tables exists, and if it is missing, it creates them. It also creates the necessary secondary indices, one to find subscriptions by channel and one to find it by listeners.

Create a Heroku app

This step is optional. You can also run the app locally and use ngrok to receive the Slack events.

In order to deploy the application to Heroku we need to create a Heroku app:



$ heroku create

Creating app... done, ⬢ fast-inlet-79371

https://fast-inlet-79371.herokuapp.com/ | https://git.heroku.com/fast-inlet-79371.git $ git init$ heroku createCreating app... done, ⬢ fast-inlet-79371

Creating a Heroku app will give you back the URL with a random name. Take note of this URL as it is required for the Slack callback URL later on.

We will also need a RethinkDB instance to store and subscribe to the chat messages sent between users. You can do this via the RethinkDB Cloud add-on as follows:

$ heroku addons:create rethinkdb

The RethinkDB Cloud add-on is currently in alpha. Request an invite for your Heroku account email.

Deploy the application to Heroku

To deploy our slack bot to Heroku we need to create a Procfile . This file basically tells Heroku what processes to run.

// Procfile release: node migrate.js

web: node index.js

The release and web processes are recognized by Heroku as the command to run upon release and the main web app respectively.

Deploy the app to Heroku with

$ echo node_modules > .gitignore

$ git add .

$ git commit -m 'A stalker bot'

$ git push heroku master

The app will not work yet because it is missing two environment variables, namely SLACK_SIGNING_SECRET and SLACK_TOKEN . We will get them when we create the actual Slack application.

Create the Slack application

To create a Slack app go to api.slack.com/apps (if you are not signed in, sign in and then come back to this URL). Click on “Create App” and fill in a name and a workspace to associate the app with.

Permissions

First we need to declare all permissions we need for our app. This can be done in the “OAuth & Permissions” tab. Scroll down to the “Scopes” card and add the following “Bot Token Scopes”:

channels:history

channels:join

chat:write

im:history

The channels:history and im:history permission allows the bot to read messages in channels it belongs to as well as direct messages. The channels:join permission allows the bot to join new channels. Finally, the chat:write permission allows the bot to write direct messages (e.g., to you).

Set environment variables

We need two Slack keys in our bot. A signing secret to verify the message events we get from Slack and a token to authenticate our actions as a bot. The signing secret can be found in the “App Credentials” card in the “Basic Information” tab. The OAuth token is shown in the “OAuth & Permissions” tab. Add both keys to your Heroku app with

$ heroku config:set SLACK_SIGNING_SECRET=...

$ heroku config:set SLACK_TOKEN=xoxb-...

This will automatically restart the Heroku app and allow for the event subscription we add next to verify your correctly running endpoint.

Event Subscription

Our app only works if we can react to events that happen in the Slack workplace. Go to the “Event Subscriptions” tab and enable events. For the request URL put in the app URL you got from Heroku and add the events route, e.g., https://fast-inlet-79371.herokuapp.com/events . Then subscribe to the following bot events:

message.channels

message.im

You will see that these two events require the channels:history and im:history permissions which we added in the previous step. Save the changes for them to take effect.

Install app

Now we are ready to install the app in our workspace. Go to the “Basic Information” tab and click on “Install App to Workspace”. This will put you in the role of the app user and ask you to grant it the permissions the app requires.

Test it out

Go to your workspace and add the Stalker bot to your Apps. Test it out and subscribe to your favorite person in a busy channel full of noise. Each time the stalked person writes you will get a direct message to notify you.