8.7 KiB
summary, read_when
| summary | read_when |
|---|---|
| Slack socket mode setup and Clawdbot config | Setting up Slack or debugging Slack socket mode |
Slack (socket mode)
Setup
- Create a Slack app (From scratch) in https://api.slack.com/apps.
- Socket Mode → toggle on. Then go to Basic Information → App-Level Tokens → Generate Token and Scopes with scope
connections:write. Copy the App Token (xapp-...). - OAuth & Permissions → add bot token scopes (use the manifest below). Click Install to Workspace. Copy the Bot User OAuth Token (
xoxb-...). - Event Subscriptions → enable events and subscribe to:
message.*(includes edits/deletes/thread broadcasts)app_mentionreaction_added,reaction_removedmember_joined_channel,member_left_channelchannel_renamepin_added,pin_removed
- Invite the bot to channels you want it to read.
- Slash Commands → create
/clawdif you useslack.slashCommand. If you enablecommands.native, add slash commands for the built-in chat commands (same names as/help). - App Home → enable the Messages Tab so users can DM the bot.
Use the manifest below so scopes and events stay in sync.
Manifest (optional)
Use this Slack app manifest to create the app quickly (adjust the name/command if you want).
{
"display_information": {
"name": "Clawdbot",
"description": "Slack connector for Clawdbot"
},
"features": {
"bot_user": {
"display_name": "Clawdbot",
"always_online": false
},
"app_home": {
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
},
"slash_commands": [
{
"command": "/clawd",
"description": "Send a message to Clawdbot",
"should_escape": false
}
]
},
"oauth_config": {
"scopes": {
"bot": [
"chat:write",
"channels:history",
"channels:read",
"groups:history",
"groups:read",
"groups:write",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"mpim:write",
"users:read",
"app_mentions:read",
"reactions:read",
"reactions:write",
"pins:read",
"pins:write",
"emoji:read",
"commands",
"files:read",
"files:write"
]
}
},
"settings": {
"socket_mode_enabled": true,
"event_subscriptions": {
"bot_events": [
"app_mention",
"message.channels",
"message.groups",
"message.im",
"message.mpim",
"reaction_added",
"reaction_removed",
"member_joined_channel",
"member_left_channel",
"channel_rename",
"pin_added",
"pin_removed"
]
}
}
}
If you enable commands.native, add one slash_commands entry per command you want to expose (matching the /help list).
Scopes (current vs optional)
Slack's Conversations API is type-scoped: you only need the scopes for the conversation types you actually touch (channels, groups, im, mpim). See https://api.slack.com/docs/conversations-api for the overview.
Required by current code
chat:write(send/update/delete messages viachat.postMessage) https://api.slack.com/methods/chat.postMessageim:write(open DMs viaconversations.openfor user DMs) https://api.slack.com/methods/conversations.openchannels:history,groups:history,im:history,mpim:history(conversations.historyinsrc/slack/actions.ts) https://api.slack.com/methods/conversations.historychannels:read,groups:read,im:read,mpim:read(conversations.infoinsrc/slack/monitor.ts) https://api.slack.com/methods/conversations.infousers:read(users.infoinsrc/slack/monitor.ts+src/slack/actions.ts) https://api.slack.com/methods/users.inforeactions:read,reactions:write(reactions.get/reactions.add) https://api.slack.com/methods/reactions.get https://api.slack.com/methods/reactions.addpins:read,pins:write(pins.list/pins.add/pins.remove) https://api.slack.com/scopes/pins:read https://api.slack.com/scopes/pins:writeemoji:read(emoji.list) https://api.slack.com/scopes/emoji:readfiles:write(uploads viafiles.uploadV2) https://api.slack.com/messaging/files/uploading
Not needed today (but likely future)
mpim:write(only if we add group-DM open/DM start viaconversations.open)groups:write(only if we add private-channel management: create/rename/invite/archive)chat:write.public(only if we want to post to channels the bot isn't in) https://api.slack.com/scopes/chat:write.publicusers:read.email(only if we need email fields fromusers.info) https://api.slack.com/changelog/2017-04-narrowing-email-accessfiles:read(only if we start listing/reading file metadata)
Config
Slack uses Socket Mode only (no HTTP webhook server). Provide both tokens:
{
"slack": {
"enabled": true,
"botToken": "xoxb-...",
"appToken": "xapp-...",
"groupPolicy": "open",
"dm": {
"enabled": true,
"policy": "pairing",
"allowFrom": ["U123", "U456", "*"],
"groupEnabled": false,
"groupChannels": ["G123"]
},
"channels": {
"C123": { "allow": true, "requireMention": true },
"#general": {
"allow": true,
"autoReply": false,
"users": ["U123"],
"skills": ["search", "docs"],
"systemPrompt": "Keep answers short."
}
},
"reactionNotifications": "own",
"reactionAllowlist": ["U123"],
"actions": {
"reactions": true,
"messages": true,
"pins": true,
"memberInfo": true,
"emojiList": true
},
"slashCommand": {
"enabled": true,
"name": "clawd",
"sessionPrefix": "slack:slash",
"ephemeral": true
},
"textChunkLimit": 4000,
"mediaMaxMb": 20
}
}
Tokens can also be supplied via env vars:
SLACK_BOT_TOKENSLACK_APP_TOKEN
Ack reactions are controlled globally via messages.ackReaction +
messages.ackReactionScope.
Sessions + routing
- DMs share the
mainsession (like WhatsApp/Telegram). - Channels map to
slack:channel:<channelId>sessions. - Slash commands use
slack:slash:<userId>sessions. - Native command registration is controlled by
commands.native; text commands require standalone/...messages and can be disabled withcommands.text: false. Slack slash commands are managed in the Slack app and are not removed automatically. Usecommands.useAccessGroups: falseto bypass access-group checks for commands. - Full command list + config: Slash commands
DM security (pairing)
- Default:
slack.dm.policy="pairing"— unknown DM senders get a pairing code (expires after 1 hour). - Approve via:
clawdbot pairing approve --provider slack <code>. - To allow anyone: set
slack.dm.policy="open"andslack.dm.allowFrom=["*"].
Group policy
slack.groupPolicycontrols channel handling (open|disabled|allowlist).allowlistrequires channels to be listed inslack.channels.
Channel options (slack.channels.<id> or slack.channels.<name>):
allow: allow/deny the channel whengroupPolicy="allowlist".requireMention: mention gating for the channel.autoReply: iftrue, reply to every message (overridesrequireMention).users: optional per-channel user allowlist.skills: skill filter (omit = all skills, empty = none).systemPrompt: extra system prompt for the channel (combined with topic/purpose).enabled: setfalseto disable the channel.
Delivery targets
Use these with cron/CLI sends:
user:<id>for DMschannel:<id>for channels
Tool actions
Slack tool actions can be gated with slack.actions.*:
| Action group | Default | Notes |
|---|---|---|
| reactions | enabled | React + list reactions |
| messages | enabled | Read/send/edit/delete |
| pins | enabled | Pin/unpin/list |
| memberInfo | enabled | Member info |
| emojiList | enabled | Custom emoji list |
Notes
- Mention gating is controlled via
slack.channels(setrequireMentiontotrue);routing.groupChat.mentionPatternsalso count as mentions. - Reaction notifications follow
slack.reactionNotifications(usereactionAllowlistwith modeallowlist). - For the Slack tool, reaction removal semantics are in /tools/reactions.
- Attachments are downloaded to the media store when permitted and under the size limit.