The message that mentioned finance and tagged nobody
The Problem
Somebody types "can we loop in finance on this?" in a product channel. Nobody tags the finance channel. The thread moves on. Three weeks later there is a contract nobody in finance has seen. That is not a tooling problem in any obvious sense. Slack worked exactly as designed. Search would have found the message if anyone had known to look for it. The failure is that the people who needed to know were never told, and nothing in the workspace was watching for the difference between mentioning a team and involving one.
Why Keyword Matching Does Not Solve This
The instinct is to grep for the word "finance" and alert on it. That produces a channel nobody reads inside a week, because "finance" appears in sentences that have nothing to do with governance, and the sentences that do matter often do not contain the word at all. What actually carries the signal is structure.
A Slack message is not plain text on the wire. When someone references a channel, it arrives looking like this:
Can we loop in <#C01ABCDEF|finance> before this goes out?
That is a channel reference, distinct from a mention that notifies the channel, and it survives in the event payload whether or not anyone was actually alerted. It means the workspace already knows the difference between "I said the word finance" and "I pointed at the finance channel and did not bring anyone in". Nobody was reading it. So the bot parses references rather than words. It maps channel IDs to what those channels are for, and it looks for the specific shape of a message that points at a governance channel from outside it. Context beats keywords, and in this case the context was already structured and already being thrown away.
Two Decisions That Mattered More Than the Detection
It joins every public channel by itself. The obvious build asks an admin to add the bot wherever it should watch, which means coverage is a function of somebody remembering. Every channel created after launch is a gap, and nobody finds out until something is missed in one. Instead it lists the public channels through the API and joins them, then listens for channel_created and joins new ones as they appear. Coverage is complete by construction rather than by diligence, across more than a hundred channels.
It runs on Socket Mode. The usual Slack integration takes an inbound webhook, which means a public HTTPS endpoint that anyone can reach and that has to be secured, monitored and kept alive. Socket Mode reverses the direction: the bot opens an outbound connection and Slack pushes events down it. For an organisation that would otherwise be exposing a new inbound surface to catch its own internal messages, that trade is worth taking on its own.
The Constraint That Shaped the Deployment
Socket Mode has a consequence that only shows up on deploy. Because the bot never receives inbound HTTP, it never binds a port, and the platform hosting it was watching for exactly that to decide whether the service was alive. A correctly working bot looked, to the host, like a process that had failed to start.
The fix is a sidecar: a minimal HTTP server inside the same process whose only job is to answer a health check.
import express from "express";
const app = express();
app.get("/", (_req, res) => res.send("Bot is running"));
app.listen(process.env.PORT || 3000);
Ten lines that do nothing for the product and without which the product does not stay running. It is worth saying plainly, because this is the part that never appears in an architecture diagram and is most of what deployment actually is: the platform has an opinion about what a healthy service looks like, and you either meet it or you do not run.
Scopes, Deliberately Narrow
The bot holds channels:join, channels:history and chat:write. Public channels only, no user impersonation, no private conversations, no ability to act as anyone. A tool that reads a workspace to improve governance has to be governable itself, and the smallest scope set that does the job is the one that survives the security review it will eventually get.
What It Changed
Coverage went from whichever channels someone remembered to whichever channels exist. Finance mentions that previously depended on a person noticing now arrive in one place with the surrounding context attached. The work of watching moved off people and into something that does not get busy or go on leave.
The wider lesson is about where automation should sit. This one requires no configuration, adapts to new channels on its own, and nobody in the workspace has to change how they write. The best version of a system like this is one the team never thinks about, which is also the version that is hardest to justify building, because the evidence of it working is the absence of an expensive surprise.
Top comments (0)
Comments
No comments yet. Start the discussion.