It took me SO LONG to find this info

This post is going to be short, but hopefully will help you avoid the troubles that befell me. I wanted to make a Slack bot using Python. “How hard can it be?”, I thought. “I’ve done it many times before”, I thought.

Think again.

The problem is that Slack has changed the way their APIs work. The old way is now referred to as a “classic app” with a “bot scope”, and that way is deprecated and you can’t really create apps like that now, so you have to do a whole other thing.

In this post, I will detail the steps necessary to create a simple bot that will listen for messages and reply to them. That’s all the scaffolding you’ll need (or that I needed) to create your apps, but I had to search for many hours to discover this information. Hopefully Google will be kinder to you and point you to this post quickly.

The steps

The first step is to forget all about slack-sdk, a bunch of other libraries and whatnot. What you need is slack-bolt, that’s what will let you make a bot quickly and easily, and is the Official Way™️ to create Slack bots, so pip install slack-bolt. The getting started guide is a good (if a bit verbose) way to get the gist of what to do.

After you’ve installed bolt, you need to create an app, turn on “Enable Events” under “Event Subscriptions”, and add the app_mentions:read, chat:write, and im:history scopes, so the bot can view messages that mention it and send messages of its own. You should also click on “Subscribe to bot events” and add app_mention, message.im, and message.mpim, to let your bot access all the DMs it’s in and mentions of it. Furthermore, you should enable “Socket Mode” under “Socket Mode”, which will let you skip the webhook setup and will let your bot connect to Slack from behind a firewall or without having a hostname pointed to it. The “getting started” link above does a good job detailing these as well.

Then, you need to install the bot to your workspace by clicking “Install App to Workspace” in “OAuth & Permissions”, and copy the token you get, which you’ll need to use in the code below.

Sample code

After you’ve done the above, it’s time to listen for and reply to messages.

Here’s some code that uses Socket Mode to connect to Slack, for simplicity. You need to define the two environment variables shown in the code for it to run:

import os
import re

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

app = App(token=os.environ["SLACK_BOT_TOKEN"])


@app.message(re.compile("(hello|hi)", re.I))
def say_hello_regex(say, context):
    greeting = context["matches"][0]
    say(f"{greeting}, <@{context['user_id']}>, how are you?")


@app.message(re.compile(""))
def catch_all(say, context):
    """A catch-all message."""
    say(f"I didn't get that, <@{context['user_id']}>.")


@app.event("app_mention")
def handle_app_mention_events(body, client, say):
    # Reply to mentions in a thread.
    client.chat_postMessage(
        channel=body["event"]["channel"],
        thread_ts=body["event"]["thread_ts"],
        text=f"Yes <@{body['event']['user']}>.",
    )


if __name__ == "__main__":
    handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
    handler.start()

Don’t forget to change to Webhooks mode for production (that is left as an exercise for the reader, as I didn’t need to do it so I don’t really have a good example).

Epilogue

That’s it! I hope I helped. The biggest time-waster for me is that I didn’t realize that slack-bolt was the official way to write Slack bots nowadays.

Many thanks to my friend Alex for pointing me in the right direction with this.

If you have any questions or comments, please Tweet or toot at me, or email me directly.