# Slack

URL: https://cogitator.app/docs/channels/slack

> Connect your AI agent to Slack workspaces.

## Setup

```bash
pnpm add @slack/bolt
```

## Create Your Slack App

1. Go to [api.slack.com/apps](https://api.slack.com/apps) and click **Create New App**
2. Choose **From scratch**, give it a name, select your workspace
3. **Enable Socket Mode** (sidebar → Socket Mode → toggle on):
   * Generate an app-level token with `connections:write` scope
   * Save it as `SLACK_APP_TOKEN=xapp-...`
4. **Add Bot Scopes** (sidebar → OAuth & Permissions → Scopes):
   * `chat:write` — send messages
   * `app_mentions:read` — detect @mentions
   * `im:history` — read DM history
   * `im:read` — access DMs
   * `im:write` — send DMs
   * `users:read` — show user display names to the agent
   * `files:read` — receive file shares (images, voice, documents)
   * `files:write` — send files
   * `reactions:write` — status reactions
5. **Subscribe to Events** (sidebar → Event Subscriptions → toggle on):
   * Bot events: `message.im`, `app_mention`
6. **Install to Workspace** (sidebar → Install App → Install):
   * Copy "Bot User OAuth Token" → save as `SLACK_BOT_TOKEN=xoxb-...`
7. Copy "Signing Secret" from Basic Information → save as `SLACK_SIGNING_SECRET=...`

## Usage

```typescript
import { slackChannel } from '@cogitator-ai/channels';

const slack = slackChannel({
  token: process.env.SLACK_BOT_TOKEN!,
  signingSecret: process.env.SLACK_SIGNING_SECRET!,
  appToken: process.env.SLACK_APP_TOKEN!,
});
```

## Configuration

```typescript
interface SlackConfig {
  token: string;
  signingSecret: string;
  appToken?: string; // enables Socket Mode
  port?: number; // HTTP mode port, default 3000
  mentionOnly?: boolean; // in channels, answer only messages that @mention the bot
}
```

The bot answers DMs and @mentions delivered as `app_mention` events and strips the mention from the text. Bot messages and edits/deletions (message subtypes other than `file_share`) are ignored. If the app also subscribes to `message.channels`, it answers every channel message unless `mentionOnly` is set; a mention that arrives both as a message and as `app_mention` is handled once.

With `RuntimeBuilder` (`cogitator.yml`), the tokens come from `SLACK_BOT_TOKEN`, `SLACK_SIGNING_SECRET` and `SLACK_APP_TOKEN`. Without `SLACK_APP_TOKEN` the channel runs in HTTP mode on `SLACK_PORT` (default 3000) and logs a warning.

## Features

| Feature          | Support                                                                       |
| ---------------- | ----------------------------------------------------------------------------- |
| DMs              | ✅                                                                             |
| Channel messages | ✅ (via @mention, `groupId` set so DM policies apply correctly)                |
| Threads          | ✅ replies go to the thread root                                               |
| Incoming files   | ✅ downloaded with the bot token (images → vision, audio → STT)                |
| Reactions        | ✅ via `reactions.add`                                                         |
| User names       | ✅ resolved via `users.info` (cached)                                          |
| Socket Mode      | ✅ (no public URL needed)                                                      |
| HTTP Mode        | ✅ (needs public endpoint)                                                     |
| Streaming (edit) | ✅ via `chat.update`                                                           |
| File uploads     | ✅ via `files.uploadV2` (buffers or URLs)                                      |
| Typing indicator | ❌ (no-op, Slack API doesn't support it)                                       |
| Markdown         | ✅ converted to mrkdwn (`**b**` → `*b*`, links → `<url\|text>`, `&<>` escaped) |

## Socket Mode vs HTTP

* **Socket Mode** (recommended for dev): no public URL needed, uses WebSocket. Requires `appToken`.
* **HTTP Mode**: omit `appToken` and provide a `port`. Needs a publicly accessible URL; point the Event Subscriptions Request URL at Bolt's default endpoint `https://your-host/slack/events`.

## Tips

* Socket Mode is the simplest way to get started — no ngrok or public server needed
* You need 3 tokens total: Bot Token (`xoxb-`), Signing Secret, and App Token (`xapp-`)
* Reinstall the app after changing scopes
* The bot must be invited to channels to respond there (DMs work automatically)
