|
| 1 | +# Receiving Slack Events Locally |
| 2 | + |
| 3 | +## Prerequisites |
| 4 | + |
| 5 | +- Docker Compose |
| 6 | +- A Slack App with Event Subscriptions enabled |
| 7 | +- An [ngrok](https://ngrok.com) account (free tier works) |
| 8 | + |
| 9 | +## 1. Create a Slack App |
| 10 | + |
| 11 | +1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App** |
| 12 | +2. Choose **From scratch**, pick a name and workspace |
| 13 | +3. Under **Basic Information → App Credentials**, copy the **Signing Secret** |
| 14 | + |
| 15 | +## 2. Start the stack |
| 16 | + |
| 17 | +```bash |
| 18 | +docker compose --profile dev up |
| 19 | +``` |
| 20 | + |
| 21 | +This starts NATS, the Slack webhook receiver, and ngrok. Find the public tunnel |
| 22 | +URL in the ngrok container logs: |
| 23 | + |
| 24 | +```bash |
| 25 | +docker compose logs ngrok |
| 26 | +``` |
| 27 | + |
| 28 | +Look for the `slack` tunnel URL (e.g. `https://def456.ngrok-free.app`). |
| 29 | + |
| 30 | +## 3. Enable Event Subscriptions |
| 31 | + |
| 32 | +1. In your Slack App settings, go to **Event Subscriptions** |
| 33 | +2. Toggle **Enable Events** to On |
| 34 | +3. Set the **Request URL** to `https://<ngrok-url>/webhook` |
| 35 | +4. Slack will send a `url_verification` challenge — the server responds |
| 36 | + automatically |
| 37 | +5. Under **Subscribe to bot events**, add the events you need: |
| 38 | + - `message.channels` — public channels |
| 39 | + - `message.groups` — private channels |
| 40 | + - `message.im` — direct messages |
| 41 | + - `app_mention` — @mentions anywhere |
| 42 | +6. Click **Save Changes** |
| 43 | + |
| 44 | +## 4. Enable Interactivity (optional) |
| 45 | + |
| 46 | +1. Go to **Interactivity & Shortcuts** |
| 47 | +2. Toggle **Interactivity** to On |
| 48 | +3. Set the **Request URL** to the same `https://<ngrok-url>/webhook` |
| 49 | +4. Click **Save Changes** |
| 50 | + |
| 51 | +Block actions, modal submissions, and shortcuts will be published to NATS on |
| 52 | +`slack.interaction.{type}` subjects (e.g. `slack.interaction.block_actions`). |
| 53 | + |
| 54 | +## 5. Register Slash Commands (optional) |
| 55 | + |
| 56 | +1. Go to **Slash Commands** and click **Create New Command** |
| 57 | +2. Set the **Request URL** to the same `https://<ngrok-url>/webhook` |
| 58 | +3. Fill in the command name, description, and usage hint |
| 59 | +4. Click **Save** |
| 60 | + |
| 61 | +Slash commands will be published to NATS on `slack.command.{command_name}` |
| 62 | +subjects (e.g. `slack.command.trogon`). |
| 63 | + |
| 64 | +## 6. Install the app to your workspace |
| 65 | + |
| 66 | +1. Go to **OAuth & Permissions** |
| 67 | +2. Under **Scopes → Bot Token Scopes**, ensure you have the scopes required |
| 68 | + by the events you subscribed to |
| 69 | +3. Click **Install to Workspace** and authorize |
| 70 | + |
| 71 | +## 7. Verify |
| 72 | + |
| 73 | +Send a message in a channel where the app is installed. You should see: |
| 74 | + |
| 75 | +- The webhook receiver log the incoming event |
| 76 | +- The event published to NATS on `slack.event.message` |
| 77 | + |
| 78 | +You can inspect NATS with: |
| 79 | + |
| 80 | +```bash |
| 81 | +nats sub -s nats://nats.trogonai.orb.local:4222 "slack.>" |
| 82 | +``` |
| 83 | + |
| 84 | +Without `--profile dev`, ngrok is excluded and only the core services start. |
| 85 | + |
| 86 | +## NATS subject mapping |
| 87 | + |
| 88 | +| Slack payload | NATS subject | `X-Slack-Payload-Kind` header | |
| 89 | +|---|---|---| |
| 90 | +| Events API (`event_callback`) | `slack.event.{event.type}` | `event` | |
| 91 | +| Interactions (block actions, modals) | `slack.interaction.{type}` | `interaction` | |
| 92 | +| Slash commands | `slack.command.{command_name}` | `command` | |
| 93 | + |
| 94 | +## Environment variables |
| 95 | + |
| 96 | +| Variable | Required | Default | Description | |
| 97 | +|---|---|---|---| |
| 98 | +| `SLACK_SIGNING_SECRET` | yes | — | Slack app signing secret | |
| 99 | +| `NGROK_AUTHTOKEN` | yes (dev profile) | — | ngrok auth token | |
| 100 | +| `SLACK_WEBHOOK_PORT` | no | `3000` | HTTP port for the webhook receiver | |
| 101 | +| `SLACK_SUBJECT_PREFIX` | no | `slack` | NATS subject prefix | |
| 102 | +| `SLACK_STREAM_NAME` | no | `SLACK` | JetStream stream name | |
| 103 | +| `SLACK_STREAM_MAX_AGE_SECS` | no | `604800` | Max message age in seconds (default 7 days) | |
| 104 | +| `SLACK_NATS_ACK_TIMEOUT_SECS` | no | `10` | NATS acknowledgement timeout in seconds | |
| 105 | +| `SLACK_MAX_BODY_SIZE` | no | `1048576` | Max HTTP request body size in bytes (default 1 MB) | |
| 106 | +| `SLACK_TIMESTAMP_MAX_DRIFT_SECS` | no | `300` | Max allowed clock drift in seconds (default 5 min) | |
| 107 | +| `RUST_LOG` | no | `info` | Log level | |
0 commit comments