How to Build a Simple Slack Bot

Bob, Tue 04 April 2017, Tools

API, automation, bot, chatbot, deployment, nohup, shell, slack

I was playing with Slack's Real Time Messaging API the other day. Building a bot is pretty easy. In this article a simple example.

Bots are hot

This was an interesting coding exercise, but also keep in mind its relevance. Bots are hot, people have become comfortable with conversational interfaces.

some commands our bot listens to

(GIF made with 100DaysOfCode day 003 script)

Slack API

About Slack's Real Time Messaging API:

The Real Time Messaging API is a WebSocket-based API that allows you to receive events from Slack in real time and send messages as users. It's sometimes referred to as simply the "RTM API". It is the basis for all Slack clients. It's also commonly used with the bot user integration to create helper bots for your team.

Getting ready

Read here about Bot Users, you need to create a new bot user first. This will give you an API Token. Keep this private! I added mine to .bashrc to keep it out of version control. I retrieve it like this:

slack_client = SlackClient(os.environ.get('SLACK_BOT_TOKEN'))

Secondly you need to pip install slackclient, I also used some other modules.

I took the starterbot code I found in this excellent article: How to Build Your First Slack Bot with Python. This made it a lot easier because it catered for all the initial setup, listening for mentions of the bot, intercepting targeted messages.

Only thing you have to do is to get the BOT ID and store it in your login script (in my case .bashrc):

$ python
Bot ID for 'pybitesbot' is XYZ

# .bashrc
export SLACK_BOT_TOKEN=ABC      # first step
export BOT_ID=XYZas retrieved from previous command
export WEATHER_API=123          # used for one of the command scripts, see below

Bot actions

I wrote a bunch of scripts which respond to different commands, some also as part of our 100DaysOfCode challenge. I put them in the commands subdirectory. This structure makes it easy to add more commands over time.

In the main bot script I import all the commands:

from commands.mood import get_mood  # just a silly one
from commands.special import celebration
from commands.articles import get_num_posts
from commands.challenge import create_tweet
from import get_weather  # bot reports more sun and later sunset Spain vs Australia (sorry Julian haha)

# and put them in a COMMANDS dict
cmd_names = ('mood', 'celebration', 'num_posts', '100day_tweet', 'weather')
cmd_functions = (get_mood, celebration, get_num_posts, create_tweet, get_weather)
COMMANDS = dict(zip(cmd_names, cmd_functions))

I then overwrote the (provided) handle_command function to have the bot respond to various commands.

def handle_command(cmd, channel):

    cmd = cmd.split()
    cmd, args = cmd[0], cmd[1:]

    if cmd in COMMANDS:
        if args:
            response = COMMANDS[cmd](*args)
            response = COMMANDS[cmd]()
        response = ('Not sure what you mean? '
            'I can help you with these commands:\n'

    slack_client.api_call("chat.postMessage", channel=channel,
                        text=response, as_user=True)

Lastly under main this starts the loop:

if slack_client.rtm_connect():


And that's it for the code. On my server I run the bot with nohup to keep it running:

nohup python3 &

Update: I found an issue where the bot stopped working, so I added a little script (based on this SO answer) to respawn it:

$ cat
until $cmd; do
    echo "Slack bot crashed with exit code $?.  Respawning.." >&2
    sleep 1

$ ./
StarterBot connected and running!

... pressing ctrl + c

^CTraceback (most recent call last):
File "", line 44, in <module>

    Slack bot crashed with exit code 1.  Respawning..   => thanks for the shell script
    StarterBot connected and running!

# that was for demo, I still use nohup to leave the shell
$ nohup  &


And there you go ... as you can see we had some fun with it the other day :)

bot smart ass I

bot smart ass II

What's next?

Although this tutorial showed a simple deterministic bot, this really inspired me to think about ways we can make our pybitesbot smarter and help us automate tasks. Or what if we open up a Slack for our community and we have a bot helping people with common Python questions? That would be really cool!

I will do a part 2 when we have more progress in this space ...

The full code of the bot is here. We encourage you to fork it and start building your own cool bot (and tell us about it in the comments below).

Keep Calm and Code in Python!

-- Bob

PyBites Python Tips

Do you want to get 250+ concise and applicable Python tips in an ebook that will cost you less than 10 bucks (future updates included), check it out here.

Get our Python Tips Book

"The discussions are succinct yet thorough enough to give you a solid grasp of the particular problem. I just wish I would have had this book when I started learning Python." - Daniel H

"Bob and Julian are the masters at aggregating these small snippets of code that can really make certain aspects of coding easier." - Jesse B

"This is now my favourite first Python go-to reference." - Anthony L

"Do you ever go on one of those cooking websites for a recipe and have to scroll for what feels like an eternity to get to the ingredients and the 4 steps the recipe actually takes? This is the opposite of that." - Sergio S

Get the book