@Claude In Slack Is Four Components. Here's The Whole Build.

Anthropic shipped @Claude as a first-class Slack participant and LinkedIn spent a week calling it a paradigm shift. It's four components: a webhook, a history fetch, a context assembler, and an async job runner. If you're staring at a $30-per-seat quote wondering whether you actually need it — or you're the builder whose clients keep forwarding you that quote — this is the teardown.
The four components, drawn end-to-end
The mention-your-bot pattern has one novel piece and three pieces of plumbing that have shipped in production since GitHub open-sourced Hubot in 2015. Here they are in order of execution:
- Mention webhook. Slack, Telegram, Discord, WhatsApp Business — every one of them POSTs to an HTTPS endpoint the instant a user tags your bot. ~20 lines of code.
- Channel history fetch. On mention, you call the platform's
conversations.history(Slack) orgetUpdates(Telegram) endpoint and pull the last N messages. That's your immediate context window. - Context assembly. Take that history, optionally join it with a jobs table or vector store for anything older than the channel window, and build a single prompt.
- Async job runner with callback. Claude can take 20–40 seconds. Slack expects a 200 within 3. So you ack fast, enqueue the real work in Redis, and a worker posts the reply back into the thread when it finishes.
That's the system. The "remembers across days" magic that everyone got excited about? A jobs table with a thread_id column and a SELECT. Not new technology.
What each component actually costs to run
- Webhook receiver: FastAPI or Express, one route, ~$0 marginal.
- History fetch: 1 API call per mention, rate-limited but free.
- Context assembler: pure Python/TS, no external cost.
- Worker + Redis: 1 process, ~150 MB RAM on a $6 VPS.
Component 1 & 2: webhook and history in ~40 lines
Here's a stripped Slack handler. It verifies the signature, acks in under a second, pulls the last 20 messages, and drops the job on a queue.
from fastapi import FastAPI, Request, BackgroundTasks
from slack_sdk import WebClient
import os, hmac, hashlib, time, redis, json
app = FastAPI()
slack = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
q = redis.Redis.from_url(os.environ["REDIS_URL"])
@app.post("/slack/events")
async def events(req: Request, bg: BackgroundTasks):
body = await req.body()
# Signature verification omitted for brevity — do NOT ship without it
payload = json.loads(body)
if payload.get("type") == "url_verification":
return {"challenge": payload["challenge"]}
event = payload["event"]
if event["type"] == "app_mention":
history = slack.conversations_history(
channel=event["channel"], limit=20
)["messages"]
job = {
"channel": event["channel"],
"thread_ts": event.get("thread_ts") or event["ts"],
"user": event["user"],
"text": event["text"],
"history": history,
}
q.lpush("claude_jobs", json.dumps(job))
return {"ok": True}
Two things worth calling out. First, always verify the X-Slack-Signature header — Slack's docs walk through the HMAC. Skip it and anyone can POST fake mentions to your endpoint. Second, that conversations_history call is your entire "context window" for zero-effort setups. Twenty messages is usually plenty; if a thread runs long, switch to conversations_replies with the thread_ts.
Component 3: context assembly is where the product actually lives
This is the part the launch video skipped, and it's the only piece where you have real leverage. Fetching 20 messages and shoving them at Claude gets you a demo. Joining those messages against your CRM, your invoice history, and last week's on-call notes gets you a product.
A reasonable prompt assembler looks like this:
def build_prompt(job, db):
thread_id = job["thread_ts"]
prior = db.execute(
"SELECT question, answer FROM jobs "
"WHERE thread_id=%s AND status='done' "
"ORDER BY created_at ASC LIMIT 10",
(thread_id,),
).fetchall()
recent = "\n".join(
f"{m.get('user','?')}: {m['text']}" for m in reversed(job["history"])
)
memory = "\n".join(f"Q: {p.question}\nA: {p.answer}" for p in prior)
return f"""You are the ops bot for Acme Inc.
Prior thread context:
{memory or '(none)'}
Recent channel messages:
{recent}
The user just asked: {job['text']}
Answer concisely. If you need CRM or invoice data, call the appropriate tool."""
The jobs table is the "persistence across days" that got framed as a feature. Schema:
| column | type | purpose |
|---|---|---|
| id | uuid | primary key |
| thread_id | text | Slack thread_ts / Telegram message_thread_id |
| channel | text | routing |
| question | text | user's tagged message |
| answer | text | worker output |
| status | enum | queued / running / done / failed |
| created_at | timestamp | ordering + TTL |
That's it. That is the memory system.
Component 4: async worker with callback
Slack's 3-second ack rule is the reason you cannot answer inline. Every production build of this pattern uses a queue. Redis + one worker process handles thousands of mentions a day on a $6 box.
# worker.py
import redis, json, os, anthropic, time
from slack_sdk import WebClient
r = redis.Redis.from_url(os.environ["REDIS_URL"])
slack = WebClient(token=os.environ["SLACK_BOT_TOKEN"])
claude = anthropic.Anthropic()
while True:
_, raw = r.brpop("claude_jobs")
job = json.loads(raw)
prompt = build_prompt(job, db)
resp = claude.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
)
answer = resp.content[0].text
slack.chat_postMessage(
channel=job["channel"],
thread_ts=job["thread_ts"],
text=answer,
)
db.execute(
"INSERT INTO jobs(thread_id, question, answer, status) "
"VALUES (%s, %s, %s, 'done')",
(job["thread_ts"], job["text"], answer),
)
Real numbers from a client bot I run on Telegram with this exact shape: median mention-to-reply is 8.2 seconds, p95 is 19 seconds, and the box (a $6/mo VPS with 1 vCPU / 1 GB RAM) sits at 4% CPU handling roughly 400 mentions/day.
Failure modes you actually hit in production
- Claude times out or 529s — retry twice with exponential backoff, then post an apology into the thread instead of leaving the user hanging.
- Slack rate-limits
conversations.historyat Tier 3 (~50/min) — cache per-channel for 30 seconds. - Worker dies mid-job — mark jobs
runningwith a heartbeat; re-queue anything running >60s. - Duplicate mention deliveries — Slack retries on non-200; dedupe on
event_id.
The $3,600 vs $150 math
Let's price the exact same capability two ways for a 10-person team.
| Line item | Anthropic Team plan | Self-hosted |
|---|---|---|
| Seats (10 × $30/mo) | $3,600/yr | — |
| VPS ($6/mo) | — | $72/yr |
| Anthropic API usage (~400 msgs/day, Sonnet) | included | ~$60–90/yr |
| Redis (bundled on VPS) | — | $0 |
| Domain + TLS (Let's Encrypt) | — | ~$12/yr |
| Total year one | $3,600 | ~$150 |
That's a 24× gap for a pattern that a competent operator wires up in a weekend. And the self-hosted version isn't locked to Slack — the same four components drop into Telegram for teams that already live there, WhatsApp Business for field ops, or Discord for community businesses. "Meet users where they work" stops being a marketing line and becomes an architecture decision.
Two honest caveats on that math. If your team already pays for Anthropic Team for the Claude web app, the Slack integration is a free add-on and the calculation flips. And if your ops person bills at $150/hr, a 16-hour build is $2,400 — still cheaper than year one, break-even happens fast, but it's not zero.
Who should pay Anthropic and who should build
Pay Anthropic if:
- You're a regulated shop with SOC 2 / HIPAA obligations and a security team that won't approve a custom bot with
chat:writeon your workspace. - Procurement is a 6-week gate and you don't have infra ownership.
- Nobody on your team wants to own a worker process at 2 AM.
Build it if:
- You have a dev-friendly operator (or you are one).
- Your workflows need to touch your CRM, invoicing system, or internal database — off-the-shelf can't do that.
- You want the same bot on two or more channels (Slack + WhatsApp is the most common combo I see).
The primitive is not the moat. The integration into your specific workflow is the moat. A bot that knows your customers, has read/write access to your pipeline, and can actually close a loop — that's worth building. A bot that summarizes the last 20 messages in a channel is worth $0 because in twelve months every messaging platform will ship a first-party version.
Why bizflowai.io helps with this
Most of what we ship for clients is exactly this pattern, extended: a mention-driven bot on Slack, Telegram or WhatsApp that reads a specific channel, joins the message against the client's CRM or invoicing system, drafts a reply or triggers a workflow (send quote, update status, schedule follow-up), and logs everything to a jobs table the operator can audit. The four-component skeleton in this post is the starting point. What clients pay for is the integration into their stack — the part Anthropic's $30/seat plan doesn't touch.
Your one action this week
Open your team's messaging tool. Find the one question that gets asked three times a week where someone always answers by pulling context from two other places. That's your first tag-your-AI target. Write the four components against it: which webhook, which history call, what context sources, what callback action. If you can name all four in a paragraph, you have a spec. A spec is 2–3 days of work for a builder who's done it before.
Want more like this?
I publish practical AI automation, GenAI engineering, and faceless content workflows on YouTube every week.
Subscribe to bizflowai.io on YouTube — never miss a new tutorial.
Planning an AI automation project or need a second opinion on your architecture?
Connect with me on LinkedIn — Lazar Milicevic, GenAI Engineer & bizflowai.io Founder.
Visit bizflowai.io for our services, case studies, and AI consulting.
Frequently asked questions
What is the 'tag-your-AI' pattern in Slack?
Tag-your-AI is a pattern where mentioning a bot (like @Claude) in a messaging platform triggers a webhook that reads channel history, assembles context, and posts a reply back to the thread. It relies on four components: a mention webhook, a channel history fetch, context assembly, and an async job runner with callback. The novelty is only the mention event firing a webhook; the rest is standard plumbing.
How do I build a self-hosted Claude Slack bot?
Wire up four components: (1) a mention webhook endpoint that Slack POSTs to when your bot is tagged, (2) a call to Slack's messages.list to fetch recent channel history, (3) context assembly combining that history with data from a jobs table or vector store, and (4) an async job runner using Redis and a worker that acknowledges fast, processes the request, then posts the reply back to the thread.
How does Claude remember conversations across days in Slack?
Persistence across days is implemented as a jobs table with a status column and a thread ID. When a new mention arrives on the same thread, the system runs a SELECT to look up prior jobs, hydrates their outputs, and includes them in the new prompt. It is a database lookup, not new AI technology, and can be replicated with any standard SQL setup.
When should I pay for Anthropic Team plan vs self-host a Claude bot?
Pay Anthropic's $30/seat/month Team plan if you're a regulated enterprise with SOC 2 obligations, procurement gates, and a security team that won't approve self-hosted bots touching Slack. Self-host if you're a small or mid-sized business with a developer-friendly operator and custom workflows. Self-hosting on a $6 VPS plus API usage runs about $150/year versus $3,600/year for ten seats, roughly a 24x cost gap.
Why does the tag-your-AI integration matter more than the LLM itself?
The LLM primitive is becoming a commodity and every major messaging platform will ship a first-party version within twelve months. The competitive moat is not the model but the integration: a bot that knows your business, connects to your CRM, inbox, and invoicing system, and can close the loop. The primitive is free; the workflow-specific integration is the actual product.