Bots are a useful way to interact with chat services such asSlack. If you have never built a bot before, thispost provides an easy starter tutorial for combining theSlack API with Python to create your first bot.
We will walk through setting up your development environment, obtaining aSlack API bot token and coding our simple bot in Python.
Tools We Need
Our bot, which we will name 'StarterBot', requires Python and the Slack API.To run our Python code we need:
- Either Python 2 or 3
- pip andvirtualenv to handle Pythonapplication dependencies
- Free Slack account - you need to be signed into atleast one workspace where you have access to building apps.
Xplenty's data integration platform makes it easy for you to integrate Looker with Slack to process your data, no coding required. Clerk lets you send and receive text messages (.SMS/MMS.) all inside of Slack. Bring your business phone to Slack and start text messaging your customers in real-time. Confirm appointments, ask for re.
It is also useful to have the Slack API docs handywhile you're building this tutorial.
All the code for this tutorial is available open source under the MIT licensein the slack-starterbot publicrepository.
Establishing Our Environment
We now know what tools we need for our project so let's get our developmentenvironment set up. Go to the terminal (or Command Prompt on Windows) andchange into the directory where you want to store this project. Withinthat directory, create a new virtualenv to isolate our applicationdependencies from other Python projects.
- Integromat gives you the ability to integrate Twilio with many other services.
- Twilio simplifies worldwide connectivity with cloud-based communications APIs and SDKs for SMS, Voice & Messaging apps. Software developers can use the tools.
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 andreceive messages from a Slack channel. Install the slackclient library withthe pip
command:
When pip
is finished you should see output like this and you'll beback at the prompt.
We also need to create a Slack App to recievean API token for your bot. Use 'Starter Bot' as your App name. If you are signedinto more than one workspace, pick a Development Workspace from the dropdown.
After submitting the form, keep the app configuration page open.
Slack APIs and App Configuration
We want our Starter Bot to appear like any other user in your team - it willparticipate in conversations inside channels, groups, and DMs. In a SlackApp, this is called a bot user, whichwe set up by choosing 'Bot Users' under the 'Features' section. Afterclicking 'Add a Bot User', you should choose a display name, choose adefault username, and save your choices by clicking 'Add Bot User'. You'llend up with a page that looks like the following:
The slackclient
library makes it simple to use Slack'sRTM 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 forboth APIs.
Click on the 'Install App' under the 'Settings' section. The button on this pagewill 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 asenvironment variables. Back in your terminal, export the Slack token with thename SLACK_BOT_TOKEN
:
Nice, now we are authorized to use the Slack RTM and Web APIs as a bot user.
Coding Our Starter Bot
We've got everything we need to write the Starter Bot code. Create a new filenamed starterbot.py
and include the following code in it.
With our dependencies imported we can use them to obtain the environmentvariable 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 tostore 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 aWeb API method (auth.test
) to findStarter Bot's user ID.
Each bot user has a user ID for each workspace the Slack App is installedwithin. Storing this user ID will help the program understand if someone hasmentioned the bot in a message.
Next, the program enters an infinite loop, where each time the loop runs theclient recieves any events that arrived from Slack's RTM API. Notice thatbefore the loop ends, the program pauses for one second so that it doesn't looptoo fast and waste your CPU time.
For each event that is read, the parse_bot_commands()
function determines ifthe event contains a command for Starter Bot. If it does, then command
willcontain a value and the handle_command()
function determines whatto do with the command.
We've laid the groundwork for processing Slack events and calling Slack methodsin the program. Next, add three new functions above the previous snippet tocomplete handling commands:
The parse_bot_commands()
function takes events from Slack and determinesif they are commands directed at Starter Bot. There are manyevent types that our bot will encounter, but tofind commands we only want to considermessage events. Message events also havesubtypes, but the commands we want to find won't have any subtype defined. Thefunction filters out uninteresting events by checking these properties. Now weknow the event represents a message with some text, but we want to find outif 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 thenwe compare that to the user ID we stored earlier for Starter Bot. If they arethe same, then we know this is a bot command, and return the command text withthe channel ID.
Twilio Texting
The parse_direct_mentions()
function uses a regular expression to determineif a user is being mentioned at the beginning of the message. It returnsthe user ID and the remaining message (and None, None
if no mention wasfound).
The last function, handle_command()
is where in the future you'll add all theinteresting commands, humor, and personality for Starter Bot. For now, it hasjust one example command: do. If the command starts with a known command, itwill have an appropriate response. If not, a default response is used. Theresponse is sent back to Slack by calling thechat.postMessage
Web APImethod with the channel.
Here is how the entire program should look when it's all put together(you can alsoview the file in GitHub):
Now that all of our code is in place we can run our Starter Bot on thecommand line with the python starterbot.py
command.
In Slack, create a new channel and invite Starter Bot or invite it to anexisting 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
Wrapping Up
Twilio Slack Tutorial
Alright, now you've got a simple Starter Bot with a bunch of places in thecode 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:
- Attach a persistent relational database orNoSQL back-end such asPostgreSQL, MySQL or SQLiteto save and retrieve user data
- Add another channel to interact with the botvia SMSorphone calls
- Integrate other web APIs such asGitHub or Twilio
- Explore other Slack Platform APIs and the reasons you might use one over another.
- Build an onboarding bot using the Slack Events API
Questions? Contact me via Twitter@fullstackpythonor @mattmakai. I'm also on GitHub withthe username mattmakai.
See something wrong in this post? Forkthis page's source on GitHuband submit a pull request.