Bots are a useful way to interact with chat services such as Slack. If you have never built a bot before, this post provides an easy starter tutorial for combining the Slack API with Python to create your first bot.
We will walk through setting up your development environment, obtaining a Slack API bot token and coding our simple bot in Python.
Our bot, which we will name "StarterBot", requires Python and the Slack API. To run our Python code we need:
It is also useful to have the Slack API docs handy while you're building this tutorial.
All the code for this tutorial is available open source under the MIT license in the slack-starterbot public repository.
We now know what tools we need for our project so let's get our development environment set up. Go to the terminal (or Command Prompt on Windows) and change into the directory where you want to store this project. Within that directory, create a new virtualenv to isolate our application dependencies from other Python projects.
Activate the virtualenv:
Your prompt should now look like the one in this screenshot.
The official slackclient API helper library built by Slack can send and receive messages from a Slack channel. Install the slackclient library with the pip command:
When pip is finished you should see output like this and you'll be back at the prompt.
We also need to create a Slack App to recieve an API token for your bot. Use "Starter Bot" as your App name. If you are signed into more than one workspace, pick a Development Workspace from the dropdown.
After submitting the form, keep the app configuration page open.
We want our Starter Bot to appear like any other user in your team - it will participate in conversations inside channels, groups, and DMs. In a Slack App, this is called a bot user, which we set up by choosing "Bot Users" under the "Features" section. After clicking "Add a Bot User", you should choose a display name, choose a default username, and save your choices by clicking "Add Bot User". You'll end up with a page that looks like the following:
The slackclient library makes it simple to use Slack's RTM API and Web API. We'll use both to implement Starter Bot, and they each require authentication. Conveniently, the bot user we created earlier can be used to authenticate for both APIs.
Click on the "Install App" under the "Settings" section. The button on this page will install the App into our Development Workspace. Once the App is installed, it displays a bot user oauth access token for authentication as the bot user.
A common practice for Python developers is to export secret tokens as environment variables. Back in your terminal, export the Slack token with the name SLACK_BOT_TOKEN:
Nice, now we are authorized to use the Slack RTM and Web APIs as a bot user.
We've got everything we need to write the Starter Bot code. Create a new file named starterbot.py and include the following code in it.
With our dependencies imported we can use them to obtain the environment variable values and then instantiate the Slack client.
The code instantiates the SlackClient client with our SLACK_BOT_TOKEN exported as an environment variable. It also declares a variable we can use to store the Slack user ID of our Starter Bot. A few constants are also declared, and each of them will be explained as they are used in the code that follows.
The Slack client connects to the Slack RTM API. Once it's connected, it calls a Web API method (auth.test) to find Starter Bot's user ID.
Each bot user has a user ID for each workspace the Slack App is installed within. Storing this user ID will help the program understand if someone has mentioned the bot in a message.
Next, the program enters an infinite loop, where each time the loop runs the client recieves any events that arrived from Slack's RTM API. Notice that before the loop ends, the program pauses for one second so that it doesn't loop too fast and waste your CPU time.
For each event that is read, the parse_bot_commands() function determines if the event contains a command for Starter Bot. If it does, then command will contain a value and the handle_command() function determines what to do with the command.
We've laid the groundwork for processing Slack events and calling Slack methods in the program. Next, add three new functions above the previous snippet to complete handling commands:
The parse_bot_commands() function takes events from Slack and determines if they are commands directed at Starter Bot. There are many event types that our bot will encounter, but to find commands we only want to consider message events. Message events also have subtypes, but the commands we want to find won't have any subtype defined. The function filters out uninteresting events by checking these properties. Now we know the event represents a message with some text, but we want to find out if Starter Bot is being mentioned in the text. The parse_direct_mention() function will figure out of the message text starts with a mention, and then we compare that to the user ID we stored earlier for Starter Bot. If they are the same, then we know this is a bot command, and return the command text with the channel ID.
The parse_direct_mentions() function uses a regular expression to determine if a user is being mentioned at the beginning of the message. It returns the user ID and the remaining message (and None, None if no mention was found).
The last function, handle_command() is where in the future you'll add all the interesting commands, humor, and personality for Starter Bot. For now, it has just one example command: do. If the command starts with a known command, it will have an appropriate response. If not, a default response is used. The response is sent back to Slack by calling the chat.postMessage Web API method with the channel.
Here is how the entire program should look when it's all put together (you can also view the file in GitHub):
Now that all of our code is in place we can run our Starter Bot on the command line with the python starterbot.py command.
In Slack, create a new channel and invite Starter Bot or invite it to an existing channel.
Now start giving Starter Bot commands in your channel.
Additional Note: Currently there's an issue with the websocket package and the CA certificate it uses, so if you encounter an error like:
There are a couple of things that can be done: 1. Downgrading the websocket-client library to 0.47.0 2. Or, download the certificate (wget https://www.tbs-certificats.com/issuerdata/DigiCertGlobalRootCA.crt), then set the environment variable export WEBSOCKET_CLIENT_CA_BUNDLE=DigiCertGlobalRootCA.crt
Alright, now you've got a simple Starter Bot with a bunch of places in the code you can add whatever features you want to build.
There is a whole lot more that could be done using the Slack RTM API and Python. Check out these posts to learn what you could do:
Questions? Contact me via Twitter @fullstackpython or @mattmakai. I'm also on GitHub with the username mattmakai.
See something wrong in this post? Fork this page's source on GitHub and submit a pull request.