# Slack

Symi connects to Slack through a Slack App you create in your workspace. Default mode is **Socket Mode** (no public webhook required); HTTP Events API mode is also supported.

## Prerequisites

- A Slack workspace where you can create and install an app. Workspace admin approval may be required depending on org policy.
- The Symi gateway running locally or on a reachable host. Socket Mode does not require the gateway to be publicly reachable.

## Socket Mode setup (recommended)

1. **Create the Slack app**
   Go to [api.slack.com/apps](https://api.slack.com/apps) → _Create New App_ → _From scratch_. Name it (e.g., "Symi"), pick your workspace.

2. **Enable Socket Mode**
   Left sidebar → _Socket Mode_ → toggle on. Generate an app-level token with the `connections:write` scope — this is your `appToken` (starts with `xapp-`).

3. **Add bot scopes**
   Left sidebar → _OAuth & Permissions_ → _Bot Token Scopes_. Add at minimum:
   - `chat:write` — send messages
   - `im:history` — read DMs
   - `im:read` — list DMs
   - `users:read` — look up user info
   - `app_mentions:read` — respond to @mentions in channels
   - `channels:history` — read channel messages (for channel integrations)

4. **Subscribe to events**
   Left sidebar → _Event Subscriptions_ → toggle on. Under _Subscribe to bot events_ add:
   - `message.im` — direct messages
   - `app_mention` — @mentions in channels
   - `message.channels` (optional) — messages in public channels the bot is in

5. **Install to workspace**
   Left sidebar → _Install App_ → _Install to Workspace_. Approve the scopes. Copy the bot token that appears (starts with `xoxb-`) — this is your `botToken`.

6. **Add to `~/.symi/symi.json`**

   ```json
   {
     "channels": {
       "slack": {
         "botToken": "xoxb-...",
         "appToken": "xapp-...",
         "mode": "socket"
       }
     }
   }
   ```

7. **Restart the gateway** to pick up the config. You should see `channel=slack socket connected` in the logs.

## HTTP Events API mode

Use this when your Symi host is publicly reachable (or via a Tailscale funnel) and you'd rather not hold a WebSocket open.

1. Complete steps 1, 3, and 4 above.
2. _Event Subscriptions_ → _Request URL_ → enter `https://<your-symi-host>/slack/events`. Slack will verify.
3. `~/.symi/symi.json`:
   ```json
   {
     "channels": {
       "slack": {
         "botToken": "xoxb-...",
         "signingSecret": "<from-Basic-Information>",
         "mode": "http"
       }
     }
   }
   ```
4. Restart the gateway.

## Pairing (DMs)

By default, Slack DMs require pairing. The first time a user DMs the bot, they'll receive a pairing code prompt. This prevents unauthorized users from invoking your agent. Configure pairing behaviour in `channels.slack.pairing` (see full channel docs for the exact schema).

## Slash commands

Symi exposes a catalog of slash commands in Slack (`/symi`, `/new`, `/outlook login`, etc.) once the bot is installed. The exact command set depends on which plugins are enabled in your config.

## Troubleshooting

- **"not_in_channel" when sending** — invite the bot to the channel first: `/invite @Symi`.
- **No events arriving in Socket Mode** — verify `appToken` has `connections:write`, and that the app is installed (not just created).
- **HTTP 401 on events** — signing secret mismatch. Re-copy from _Basic Information_ → _Signing Secret_.
- **DMs silently ignored** — check pairing status. New users must complete pairing before DMs flow to the agent.

## Limitations

- File uploads/attachments are not yet fully handled in all flows — text messages are the primary supported shape.
- Reaction-based commands depend on the workspace's reaction configuration and Slack plan tier.
- Threaded messages are supported but require the bot to be in the channel where the thread lives.
