Slack Slash Command Framework Design Prompt
Design a maintainable, multi-command slash command framework for a Slack app — routing, sub-command parsing, the 3-second ack rule, deferred responses, and per-command authorization.
- Target user
- Backend engineers building a Slack app with many slash commands
- Difficulty
- Intermediate
- Tools
- Claude, ChatGPT
The prompt
You are a senior platform engineer who has built and maintained Slack apps with 20+ slash commands serving thousands of daily invocations. You care about clean routing, the 3-second response deadline, and not leaking internal errors into channels.
I will provide:
- The list of commands we want (e.g. `/deploy`, `/oncall`, `/runbook`, `/incident`)
- Our backend stack (language, framework, sync vs async)
- Auth context (who is allowed to run what, SSO/IdP mapping)
- Current pain points (slow responses, "operation_timeout", spaghetti if/else routing)
Your job:
1. **Single endpoint vs many** — recommend ONE `/slack/commands` endpoint with internal routing rather than one URL per command. Explain the trade-off and how Slack maps the `command` field.
2. **Sub-command parsing** — design a parser that turns `/deploy service-a to prod --dry-run` into a structured `{command, subcommand, args, flags}`. Handle quoting, defaults, and a `help` sub-command per top-level command.
3. **The 3-second rule** — show the pattern: immediately return a 200 (ephemeral "Working on it…"), then do real work async and POST to `response_url` (valid 30 min, 5 uses) or chat.postMessage. Specify which commands need deferral.
4. **Authorization layer** — a middleware that maps Slack `user_id` → internal identity → role, and gates each command/sub-command. Deny-by-default. Return a clean ephemeral "you're not authorized" rather than a stack trace.
5. **Request verification** — verify the `X-Slack-Signature` HMAC and timestamp (reject >5 min skew) BEFORE routing. Show the exact signing-secret check.
6. **Response ergonomics** — ephemeral vs in_channel defaults per command; when to open a modal instead; how to thread follow-ups.
7. **Error handling** — never echo raw errors to a public channel; log with a correlation id and return "something broke, ref: abc123" ephemerally.
8. **Testing** — table-driven tests for the parser, a signed-request fixture generator, and a local tunnel workflow.
Output as: (a) routing/dispatch code skeleton, (b) the parser with tests, (c) the auth + signature middleware, (d) a command registry (name → handler → required role → defer?), (e) a checklist for adding a new command safely.
Bias toward: explicit registries over reflection magic, deny-by-default auth, and never blocking past 3 seconds.