From-Scratch Build · 03 · ChatOps
A Slack bot small enough to read in one sitting — and exactly the right size to finally understand how a bot actually works: a long-lived program listening to a firehose of messages, waking up only when someone @-mentions it.
What it is
A busy team's chat needs a helper — something that lives in Slack and answers questions about the team's activities and software stack. This little bot does exactly that, and it's deliberately tiny, which is exactly why it's a perfect first bot to build from scratch.
Strip away the ambition and what's left is the canonical shape of every chat bot: connect, listen forever, and react when addressed. Learning that skeleton is worth far more than the feature it shipped with.
The core idea I wanted to learn: a bot is not a website that waits for requests. It's a process that holds an open connection and reads an endless stream of events, filtering for the few that are meant for it.
The stack
The whole bot is two short scripts — one to find the bot's user ID, one to run it.
Real Time Messaging — a WebSocket "firehose" that streams every event in the workspace as it happens.
The Python SDK that opens the RTM socket (rtm_connect), reads events (rtm_read) and posts replies (chat.postMessage).
Secrets stay out of the code: the bot token and bot ID are read from SLACK_BOT_TOKEN and BOT_ID.
How it works
The entire bot is one idea repeated forever: read the firehose, check if a message was aimed at me, respond. Here's the skeleton I built to internalise it:
# connect once, then loop forever if slack.rtm_connect(): while True: events = slack.rtm_read() # the firehose for e in events: if AT_BOT in e.get("text", ""): # was I mentioned? cmd = e["text"].split(AT_BOT)[1].strip() handle(cmd, e["channel"]) # react time.sleep(1) # don't busy-spin
A one-off script calls users.list and matches the bot's name to learn its <@ID> mention string.
rtm_connect() opens the WebSocket. From here, every message in the workspace streams in.
Most events aren't for the bot. It only acts on messages whose text contains its <@ID>.
Take the text after the mention, decide what it means, and post a reply back to the same channel.
Reflection
<@ID> appears in the message text.print_bot_id step.