Slack bot that summarises threads with Claude
Slack is the home of long, context-heavy engineering discussions. A 'TL;DR this thread' button is the single most universally wanted Slack feature. Building it teaches OAuth flows, async message handling, prompt engineering for anchored summaries, and the security discipline of multi-tenant SaaS.
Resume bullet (when finished)
“Built a Slack bot that listens to thread mentions, summarises long discussions using Claude with anchored citations, runs the summarisation in <8s p95, deployed to Fly.io with full secret rotation + per-workspace rate limiting.”
Locked tech stack
No "choose your language" — analysis paralysis kills completion. Follow the stack to the letter on your first build.
Milestones (7 · ~28h)
- M1~4h
Slack OAuth + 'hello world' bot
Bot installs into a workspace, responds 'hi' to @mention. Tokens stored encrypted in Postgres.
CHECK BEFORE MOVING ON:
- Why is bot token (`xoxb-`) different from user token (`xoxp-`)?
- What does Slack do if you mishandle the OAuth state parameter?
$ git commit -m "feat: Slack OAuth + echo bot" - M2~3h
Thread fetcher — pull last 200 messages from any thread
Slack `conversations.replies` API call. Handles pagination + rate limits cleanly.
CHECK BEFORE MOVING ON:
- What's the 200-msg limit hiding from you, and how do you detect it?
- How does Slack's rate-limit header differ from the standard `Retry-After`?
$ git commit -m "feat(slack): paginated thread fetcher" - M3~6h
Claude summary with anchored citations
Build a prompt that asks Claude to summarise + cite specific messages by timestamp. Output validated to contain N citations.
CHECK BEFORE MOVING ON:
- Why citations instead of free-text summary?
- What anti-hallucination check do you bake in before returning?
$ git commit -m "feat(ai): anchored-citation summarisation" - M4~4h
Per-workspace rate + cost cap
20 summaries/hour/workspace; $5/day/workspace ceiling. Friendly 'limit reached' message.
CHECK BEFORE MOVING ON:
- Why per-workspace and not per-user?
- What's the simplest way to track $-cost without weighing every token?
$ git commit -m "feat: workspace rate + cost limits" - M5~4h
Async event handling — <8s response budget
Slack requires 3s ack. Bot acks immediately, processes async, sends summary as a thread reply. p95 < 8s.
CHECK BEFORE MOVING ON:
- What's the Slack 3-second rule and how does asynchrony help?
- Where does most of the 8s actually go?
$ git commit -m "feat: async event flow + p95 budget" - M6~3h
Multi-tenant secret rotation
Workspace tokens encrypted at rest via Fernet (key in env). Token re-fetch path when Slack rotates.
CHECK BEFORE MOVING ON:
- Why encrypt at rest when the DB is already private?
- What's the fallback if a workspace's token expires mid-flight?
$ git commit -m "security: Fernet token encryption + rotation" - M7~4h
Deploy + observability
Fly.io deploy with `fly secrets`. Per-workspace metric counters (summaries, tokens, cost). One Grafana panel.
CHECK BEFORE MOVING ON:
- Why per-workspace metrics matter when you have one customer?
- What's the fastest path from 'bot crashed' to 'I know why'?
$ git commit -m "ops: Fly.io deploy + per-workspace metrics"
60-second demo storyboard
What you say in the recruiter screen when they ask "tell me about your latest project." Practice it out loud.
- 0-5s: 'I built a Slack bot that summarises long threads with Claude — anchored citations, not free text.'
- 5-25s: Live demo in a real (or recorded) workspace — long thread → @bot → 15 sec → summary with [1][2][3] cites linking back to specific messages.
- 25-40s: Show the rate + cost limits in the metrics dashboard.
- 40-55s: Walk one security decision (encryption-at-rest of tokens, why).
- 55-60s: 'Repo link, deployment URL, would love to hear how you'd handle longer threads.'
STAR talking points for behavioral round
STAR — ASYNC-BUDGET DESIGN
Situation: Slack requires a 3-second ACK or it retries. Task: fit a Claude summarisation that can take 6-12 seconds. Action: split the path — ack immediately, queue an async worker that posts a 'summarising...' message, then edits it with the final result. Result: zero 'Slack retried, bot replied twice' issues.
STAR — ANTI-HALLUCINATION
Situation: Claude initially invented citations like [4] when there were only 3 messages. Task: prevent it from claiming things weren't said. Action: post-process — extract every [N] from the summary, validate N ≤ message_count, regenerate on mismatch with stricter prompt. Result: zero hallucinated citations across 200 test threads.
STAR — MULTI-TENANT SECURITY
Situation: storing raw Slack bot tokens in Postgres felt fine until I thought about a backup leak. Task: encrypt at rest without changing the API. Action: introduced Fernet symmetric encryption with the key in fly secrets. Result: even a leaked DB snapshot reveals no usable tokens; key rotation is a one-line redeploy.
Production references — how grown-up systems do this
Slack →
Slack Bolt for Python is the canonical SDK — their docs cover OAuth, events, rate limits.
Anthropic →
Anthropic prompt engineering guide — anchored-citation pattern is shown in their RAG section.
Vercel AI SDK →
Their conversation + streaming patterns translate well to Slack's async flow — different language, same shape.
Self-review rubric (before you claim done)
Correctness
- Bot summarises threads up to 200 messages without truncation surprises.
- Every citation in the summary points to a real message timestamp.
- Rate limit triggers cleanly (21st summary/hour returns 'slow down' message).
- p95 end-to-end latency under 8 seconds in production.
Code quality
- Workspace tokens encrypted at rest (Fernet).
- All Slack API calls go through a single client with built-in rate-limit handling.
- Async path is cleanly separated from the sync ACK path.
- No secrets in code or repo — all via fly secrets.
Testing
- Mock Slack + Anthropic clients in unit tests; no real API calls in CI.
- Integration test exercises full /events webhook → ACK → summary post.
- Citation-validation logic has its own test suite (≥10 cases).
Docs
- README has install/setup/deploy in 3 paragraphs max.
- Architecture diagram showing Slack ↔ FastAPI ↔ Redis ↔ Anthropic ↔ Postgres.
- Privacy note explaining what's stored (token, not message content).
✱ AI code review
Get a senior-style review before you call it done
Push your finished work to GitHub, open a PR, paste the PR URL below. Claude reviews the diff against this project's rubric and replies with strengths, must-fix items, and one teachable principle.
Tick the rubric items honestly, write the README, push to GitHub, get the AI review above. Once it's clean, email support@learnpython.academy with the repo link — we feature the best ones on /success-stories.
Need Python first? Start Foundations →