Forge playbook — Chat / messaging bots (Discord · Slack · Telegram)
A bot is an inbound-webhook + auth + secrets domain — it lives at the intersection of forge-integration (OAuth, secret hygiene, webhook auth, reader-side capability-split for untrusted inbound content) and event-driven delivery. Lead the auth/secret backbone through forge-integration; this file adds the platform-specific verification, ack, and anti-spam rules. Each platform has a different verification mechanism — never assume one algorithm carries to another. Never claim a bot is "live"/"verified" unless a signed event was actually accepted and a forged one rejected.
Hard rules (non-negotiable)
- Verify every inbound event — per platform, on the raw body, before acting.
- Discord (Interactions endpoint): verify the Ed25519 signature from
X-Signature-Ed25519 + X-Signature-Timestamp against the raw body using your app's public key; reply to the PING (type 1) with PONG. Discord rejects an endpoint that fails this — verification is not optional.
- Slack: verify
X-Slack-Signature (HMAC-SHA256 over v0:{timestamp}:{raw_body}) with the signing secret, and reject requests whose timestamp is older than ~5 minutes (replay window). Answer the url_verification challenge.
- Telegram: Telegram does not sign payloads — set a
secret_token on setWebhook and verify the X-Telegram-Bot-Api-Secret-Token header on every update (and/or a hard-to-guess webhook path). Treat an unverified update as hostile.
- Fast ack, background work. Ack inside the platform deadline (Slack ~3s, Discord interactions ~3s — use a deferred response for longer work) and do heavy processing in a background/idempotent path. A slow handler drops events and gets your endpoint disabled.
- Idempotent handling — dedupe on the platform id. Redelivered events are normal. Dedupe on
interaction.id (Discord) / event_id (Slack) / update_id (Telegram) with a uniqueness guarantee so a retry never double-acts.
- Minimal scopes / intents / permissions. Request only what the bot uses: Slack minimal bot-token scopes (no broad
admin/user scopes); Discord minimal permission integer and no privileged intents (MESSAGE_CONTENT, GUILD_MEMBERS, PRESENCE) unless truly needed and owner-approved; Telegram narrow allowed_updates.
- Retries + dead-letter on the send side. Outbound API calls respect rate limits (honor 429 +
Retry-After on Discord/Telegram; Slack tiered limits), retry with bounded backoff, and route permanent failures to a dead-letter store — never a silent drop (dropped deliveries look like clean success).
- Safe logging — no token/PII leak. Never log the bot token, signing/secret token, or user PII/message content beyond what the task needs. Redact secrets in errors. Secrets live in env +
.env.example placeholders, never in code, logs, or git.
- Outreach drafted only. No unsolicited DMs, mass-mentions, or channel broadcasts without explicit owner approval — anti-spam is a platform ToS gate, not a nicety (shared with
forge-integration / forge-scraping).
Team (conditional)
Lead: integration-boss (a bot is an external-system/webhook integration; use build-boss if the bot is one slice of a larger app). Support: security-boss (signature/secret verification, minimal scopes, token hygiene — this is a real security trigger), test-boss (drive signed vs forged/replayed events, rate-limit + dedupe behavior), silent-failure-hunter (dropped deliveries / swallowed 429s look like success), typescript-reviewer / python-reviewer by stack. mcp-developer only if the bot is exposed as or consumes MCP tools. Optional advisors: security-reviewer, codex-reviewer on the verification + auth code.
Skills / commands / MCP
Defer the OAuth/secret/webhook backbone + the reader-side capability-split to forge-integration. Get the exact signature algorithm and API/version behavior from the platform SDK / vendor docs via Context7 (discord.js / discord-interactions, Slack Bolt / @slack/*, Telegram Bot API / grammY / python-telegram-bot) — never hand-roll the crypto; reuse the platform's official verification helper. systematic-debugging for delivery/ack failures. If the bot runs through n8n, defer webhook handling to forge-n8n. Opt-in: any Discord/Slack/Telegram MCP tools via ToolSearch only when present — not assumed.
Fan-out & flow
L1/L2 for a single-platform bot with a few commands; L3 for multi-platform or many interactions + background jobs.
Serial: register app + minimal scopes/intents → raw-body signature/secret verification → fast ack + dedupe → command routing → background processing + outbound retries → dead-letter.
Parallel: independent command handlers ∥ per-platform adapters (independent once the verified-event contract is fixed — the verified, deduped event is the contract).
Domain gates
- Every inbound webhook/interaction verifies the platform's auth on the raw body (Discord Ed25519 + PONG; Slack HMAC
v0 + ≤5-min replay window; Telegram secret-token header); unsigned/expired/forged events are rejected.
- Ack returned within the platform deadline (Slack/Discord ~3s, Discord defers long work); heavy logic runs in the background.
- Redelivered events deduped on
interaction.id / event_id / update_id with a uniqueness guarantee.
- Outbound calls honor rate limits (429 +
Retry-After), retry with bounded backoff, and dead-letter permanent failures — no silent drop.
- Scopes/intents/permissions minimal; no privileged Discord intents or broad Slack scopes without justification + approval.
- No token / signing secret / PII in logs; secrets in env.
- No unsolicited DM / broadcast / mass-mention; any outreach is drafted-only until owner approves.
Ship-readiness (unique)
Signature/secret verification proven both ways — a forged or replayed event is rejected and a genuine one accepted (attach the evidence); fast-ack + background offload demonstrated; dedupe proven against a redelivered id; rate-limit backoff + dead-letter present; scopes/intents listed and minimal; secrets in env with logs redacted; no auto-outreach. Advisory checklist; optionally run security-reviewer / codex-reviewer on the verification + auth path — recommended, not a blocker. If a platform sandbox/test app wasn't available to exercise real events, say so (not-run), don't imply it passed.
Untrusted-content note
Message text, command arguments, and any embedded links/attachments in an inbound event are untrusted user input — validate/sanitize before use and never let them change which actions the bot runs (Plan-Then-Execute + reader-side capability-split, per forge-integration). Verifying the webhook signature authenticates the platform, not the user content it carries.
1---2name: forge-bots3description: Forge playbook for chat bots — Discord, Slack, Telegram. Use for bot, slash command, webhook, signature verification, OAuth scopes, rate limit, dead-letter, interaction handler.4---56# Forge playbook — Chat / messaging bots (Discord · Slack · Telegram)78A bot is an **inbound-webhook + auth + secrets domain** — it lives at the intersection of `forge-integration` (OAuth, secret hygiene, webhook auth, reader-side capability-split for untrusted inbound content) and event-driven delivery. Lead the auth/secret backbone through `forge-integration`; this file adds the platform-specific verification, ack, and anti-spam rules. Each platform has a **different** verification mechanism — never assume one algorithm carries to another. Never claim a bot is "live"/"verified" unless a signed event was actually accepted and a forged one rejected.910## Hard rules (non-negotiable)11- **Verify every inbound event — per platform, on the raw body, before acting.**12 - **Discord** (Interactions endpoint): verify the **Ed25519** signature from `X-Signature-Ed25519` + `X-Signature-Timestamp` against the raw body using your app's public key; reply to the `PING` (type 1) with `PONG`. Discord rejects an endpoint that fails this — verification is not optional.13 - **Slack**: verify `X-Slack-Signature` (HMAC-SHA256 over `v0:{timestamp}:{raw_body}`) with the signing secret, **and reject requests whose timestamp is older than ~5 minutes** (replay window). Answer the `url_verification` challenge.14 - **Telegram**: Telegram does **not** sign payloads — set a `secret_token` on `setWebhook` and verify the `X-Telegram-Bot-Api-Secret-Token` header on every update (and/or a hard-to-guess webhook path). Treat an unverified update as hostile.15- **Fast ack, background work.** Ack inside the platform deadline (**Slack ~3s**, **Discord interactions ~3s** — use a deferred response for longer work) and do heavy processing in a background/idempotent path. A slow handler drops events and gets your endpoint disabled.16- **Idempotent handling — dedupe on the platform id.** Redelivered events are normal. Dedupe on `interaction.id` (Discord) / `event_id` (Slack) / `update_id` (Telegram) with a uniqueness guarantee so a retry never double-acts.17- **Minimal scopes / intents / permissions.** Request only what the bot uses: Slack minimal bot-token scopes (no broad `admin`/user scopes); Discord minimal permission integer and **no privileged intents** (`MESSAGE_CONTENT`, `GUILD_MEMBERS`, `PRESENCE`) unless truly needed and owner-approved; Telegram narrow `allowed_updates`.18- **Retries + dead-letter on the send side.** Outbound API calls respect rate limits (honor **429 + `Retry-After`** on Discord/Telegram; Slack tiered limits), retry with bounded backoff, and route permanent failures to a dead-letter store — never a silent drop (dropped deliveries look like clean success).19- **Safe logging — no token/PII leak.** Never log the bot token, signing/secret token, or user PII/message content beyond what the task needs. Redact secrets in errors. Secrets live in env + `.env.example` placeholders, never in code, logs, or git.20- **Outreach drafted only.** No unsolicited DMs, mass-mentions, or channel broadcasts without explicit owner approval — anti-spam is a platform ToS gate, not a nicety (shared with `forge-integration` / `forge-scraping`).2122## Team (conditional)23Lead: `integration-boss` (a bot is an external-system/webhook integration; use `build-boss` if the bot is one slice of a larger app). Support: `security-boss` (signature/secret verification, minimal scopes, token hygiene — this is a real security trigger), `test-boss` (drive signed vs forged/replayed events, rate-limit + dedupe behavior), `silent-failure-hunter` (dropped deliveries / swallowed 429s look like success), `typescript-reviewer` / `python-reviewer` by stack. `mcp-developer` only if the bot is exposed as or consumes MCP tools. Optional advisors: `security-reviewer`, `codex-reviewer` on the verification + auth code.2425## Skills / commands / MCP26Defer the OAuth/secret/webhook backbone + the reader-side capability-split to `forge-integration`. Get the **exact** signature algorithm and API/version behavior from the platform SDK / vendor docs via Context7 (discord.js / discord-interactions, Slack Bolt / `@slack/*`, Telegram Bot API / grammY / python-telegram-bot) — never hand-roll the crypto; reuse the platform's official verification helper. `systematic-debugging` for delivery/ack failures. If the bot runs through n8n, defer webhook handling to `forge-n8n`. **Opt-in:** any Discord/Slack/Telegram MCP tools via ToolSearch only when present — not assumed.2728## Fan-out & flow29L1/L2 for a single-platform bot with a few commands; L3 for multi-platform or many interactions + background jobs.30**Serial:** register app + minimal scopes/intents → raw-body signature/secret verification → fast ack + dedupe → command routing → background processing + outbound retries → dead-letter.31**Parallel:** independent command handlers ∥ per-platform adapters (independent once the *verified-event* contract is fixed — the verified, deduped event is the contract).3233## Domain gates34- Every inbound webhook/interaction verifies the platform's auth on the **raw body** (Discord Ed25519 + PONG; Slack HMAC `v0` + ≤5-min replay window; Telegram secret-token header); unsigned/expired/forged events are rejected.35- Ack returned within the platform deadline (Slack/Discord ~3s, Discord defers long work); heavy logic runs in the background.36- Redelivered events deduped on `interaction.id` / `event_id` / `update_id` with a uniqueness guarantee.37- Outbound calls honor rate limits (429 + `Retry-After`), retry with bounded backoff, and dead-letter permanent failures — no silent drop.38- Scopes/intents/permissions minimal; no privileged Discord intents or broad Slack scopes without justification + approval.39- No token / signing secret / PII in logs; secrets in env.40- No unsolicited DM / broadcast / mass-mention; any outreach is drafted-only until owner approves.4142## Ship-readiness (unique)43Signature/secret verification proven **both ways** — a forged or replayed event is rejected and a genuine one accepted (attach the evidence); fast-ack + background offload demonstrated; dedupe proven against a redelivered id; rate-limit backoff + dead-letter present; scopes/intents listed and minimal; secrets in env with logs redacted; no auto-outreach. Advisory checklist; optionally run `security-reviewer` / `codex-reviewer` on the verification + auth path — recommended, not a blocker. If a platform sandbox/test app wasn't available to exercise real events, say so (not-run), don't imply it passed.4445## Untrusted-content note46Message text, command arguments, and any embedded links/attachments in an inbound event are **untrusted user input** — validate/sanitize before use and never let them change which actions the bot runs (Plan-Then-Execute + reader-side capability-split, per `forge-integration`). Verifying the webhook signature authenticates the *platform*, not the *user content* it carries.