Channels
Slack
Connect your AI agent to Slack workspaces.
Setup
pnpm add @slack/boltCreate Your Slack App
- Go to api.slack.com/apps and click Create New App
- Choose From scratch, give it a name, select your workspace
- Enable Socket Mode (sidebar → Socket Mode → toggle on):
- Generate an app-level token with
connections:writescope - Save it as
SLACK_APP_TOKEN=xapp-...
- Generate an app-level token with
- Add Bot Scopes (sidebar → OAuth & Permissions → Scopes):
chat:write— send messagesapp_mentions:read— detect @mentionsim:history— read DM historyim:read— access DMsim:write— send DMsusers:read— show user display names to the agentfiles:read— receive file shares (images, voice, documents)files:write— send filesreactions:write— status reactions
- Subscribe to Events (sidebar → Event Subscriptions → toggle on):
- Bot events:
message.im,app_mention
- Bot events:
- Install to Workspace (sidebar → Install App → Install):
- Copy "Bot User OAuth Token" → save as
SLACK_BOT_TOKEN=xoxb-...
- Copy "Bot User OAuth Token" → save as
- Copy "Signing Secret" from Basic Information → save as
SLACK_SIGNING_SECRET=...
Usage
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
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
appTokenand provide aport. Needs a publicly accessible URL; point the Event Subscriptions Request URL at Bolt's default endpointhttps://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)