MyBotBoxMyBotBox

Slack

Trigger workflows from Slack events like mentions, messages, and reactions.

The Slack trigger turns a Slack app's Events API into a workflow start. Mention the bot, post in a channel, or react with an emoji — Slack signs the request, MyBotBox verifies the signature, deduplicates the delivery, and starts your workflow.

How to configure

  1. Create a Slack app at api.slack.com/apps → Create New App → From scratch. Under Event Subscriptions, toggle Enable Events on and paste the Webhook URL from the trigger as the Request URL. Slack performs a one-time URL-verification handshake — the trigger replies with the supplied challenge string automatically.
  2. Under Subscribe to bot events, add the events you want (e.g. app_mention, message.channels, reaction_added). Each event needs the matching OAuth scope (app_mentions:read, channels:history, reactions:read). Reinstall the app to your workspace after changing scopes.
  3. Copy the Signing Secret from Basic Information → App Credentials and paste it into the trigger's signing-secret field. Slack signs every request with HMAC-SHA256 over v0:<X-Slack-Request-Timestamp>:<raw_body> and sends X-Slack-Signature: v0=<hex>. Requests with skewed timestamps (>5 minutes) or bad signatures get 401.
  4. Slack delivers events as an event_callback envelope. Downstream blocks read <slack1.event.text>, <slack1.event.user>, <slack1.event.channel>. Verify by mentioning the bot in any channel it has been invited to — expect a fire within ~2 seconds. Slack retries on non-2xx for 3 attempts (1s/30s/300s); the trigger ACKs 200 within 100ms to avoid retries.

Signature format

HeaderValue
X-Slack-Signaturev0=<hex> HMAC-SHA256 over v0:<ts>:<raw_body> with the app signing secret
X-Slack-Request-TimestampUnix seconds; rejected if older than 5 minutes

The platform compares signatures with constant-time equality and rejects unsigned requests with 401 whenever the trigger has a signing secret configured. The same event_id from event_callback is used as the webhook_event_dedup key to make Slack's retries idempotent.

Sample payload

The trigger normalizes Slack's event_callback envelope; raw body shape:

{
  "token": "verification_token_deprecated_use_signing_secret",
  "team_id": "T01234567",
  "api_app_id": "A09876543",
  "event": {
    "type": "message",
    "channel": "C0AAAAAAA",
    "user": "U0BBBBBBB",
    "text": "Hey <@U0CCCCCCC> can you summarize this thread?",
    "ts": "1745700000.000200",
    "event_ts": "1745700000.000200",
    "channel_type": "channel",
    "team": "T01234567"
  },
  "type": "event_callback",
  "event_id": "Ev0DDDDDDD",
  "event_time": 1745700000,
  "authorizations": [
    {
      "enterprise_id": null,
      "team_id": "T01234567",
      "user_id": "U0CCCCCCC",
      "is_bot": true,
      "is_enterprise_install": false
    }
  ],
  "is_ext_shared_channel": false,
  "event_context": "4-eyJldCI6Im1lc3NhZ2UiLCJ0aWQiOiJUMDEyMzQ1NjcifQ"
}

Verify with the bundled scripts

A signed POST to a deployed staging trigger:

bun apps/sat/tests/staging/triggers/slack/verify.ts \
  https://mybotbox.com/api/webhooks/trigger/<path> \
  --secret=<slack-signing-secret>
python3 apps/sat/tests/staging/triggers/slack/verify.py \
  https://mybotbox.com/api/webhooks/trigger/<path> \
  --secret=<slack-signing-secret>

Both variants exit 0 and print [ok] HTTP 200 on success. Source: apps/sat/tests/staging/triggers/slack/verify.ts and verify.py.

Troubleshooting

  • 401 signature mismatch — the secret you pasted into the trigger does not match the app's Signing Secret (Basic Information → App Credentials). Slack also rotates the secret if you regenerate it.
  • 401 timestamp out of range — the caller's clock drifted >5 minutes from server time, or you replayed a captured request through the verify script much later.
  • No fire in workflow logs — check that the bot user has been invited to the channel and the matching OAuth scope is granted; reinstall the app after a scope change.
  • Duplicates — Slack retries on non-2xx. Trigger ACKs 200 immediately and dedupes on event_id via webhook_event_dedup. If you still see dupes, confirm migration 0109 has been applied on staging.