Slack
Socket 模式(默认)
快速设置(初学者)
- 创建一个 Slack 应用并启用 Socket 模式(Socket Mode)。
- 创建一个 应用令牌(App Token)(xapp-...)和 机器人令牌(Bot Token)(xoxb-...)。
- 为 OpenClaw 设置令牌并启动网关(gateway)。
最小配置:
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-..."
}
}
}
设置步骤
- 在 https://api.slack.com/apps 创建一个 Slack 应用(从头开始)。
- Socket 模式(Socket Mode) → 开启。然后前往 基本信息(Basic Information) → 应用级令牌(App-Level Tokens) → 生成令牌和作用域(Generate Token and Scopes),使用 connections:write 作用域。复制 应用令牌(App Token)(xapp-...)。
- OAuth 与权限(OAuth & Permissions) → 添加机器人令牌作用域(使用下面的清单)。点击 安装到工作区(Install to Workspace)。复制 机器人用户 OAuth 令牌(Bot User OAuth Token)(xoxb-...)。
- 可选:OAuth 与权限(OAuth & Permissions) → 添加 用户令牌作用域(User Token Scopes)(参见下面的只读列表)。重新安装应用并复制 用户 OAuth 令牌(User OAuth Token)(xoxp-...)。
- 事件订阅(Event Subscriptions) → 启用事件并订阅:
- message.*(包括编辑/删除/线程广播)
- app_mention
- reaction_added、reaction_removed
- member_joined_channel、member_left_channel
- channel_rename
- pin_added、pin_removed
- 将机器人邀请到您希望它读取的频道。
- 斜杠命令(Slash Commands)→ 如果使用 channels.slack.slashCommand,创建 /openclaw。如果启用原生命令,为每个内置命令添加一个斜杠命令(与 /help 中的名称相同)。除非设置 channels.slack.commands.native: true,否则 Slack 的原生命令默认关闭(全局 commands.native 为 "auto",Slack 保持关闭)。
- 应用首页(App Home)→ 启用 消息标签(Messages Tab),以便用户可以向机器人发送私信。
使用下面的清单,以保持作用域和事件同步。
多账户支持:使用 channels.slack.accounts,为每个账户配置令牌和可选的 name。参见 gateway/configuration 了解共享模式。
OpenClaw 配置(最小)
通过环境变量设置令牌(推荐):
- SLACK_APP_TOKEN=xapp-...
- SLACK_BOT_TOKEN=xoxb-...
或通过配置:
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-..."
}
}
}
用户令牌(可选)
OpenClaw 可以使用 Slack 用户令牌(xoxp-...)进行读取操作(历史记录、固定消息、反应、表情符号、成员信息)。默认情况下保持只读:当存在用户令牌时,读取优先使用用户令牌,写入仍使用机器人令牌,除非您明确选择加入。即使 userTokenReadOnly: false,当机器人令牌可用时,写入操作仍优先使用机器人令牌。
用户令牌在配置文件中配置(不支持环境变量)。对于多账户,设置 channels.slack.accounts.<id>.userToken。
机器人 + 应用 + 用户令牌示例:
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
userToken: "xoxp-..."
}
}
}
显式设置 userTokenReadOnly 的示例(允许用户令牌写入):
{
channels: {
slack: {
enabled: true,
appToken: "xapp-...",
botToken: "xoxb-...",
userToken: "xoxp-...",
userTokenReadOnly: false
}
}
}
令牌使用
- 读取操作(历史记录、反应列表、固定消息列表、表情符号列表、成员信息、搜索)在配置时优先使用用户令牌,否则使用机器人令牌。
- 写入操作(发送/编辑/删除消息、添加/移除反应、固定/取消固定、文件上传)默认使用机器人令牌。如果 userTokenReadOnly: false 且没有机器人令牌可用,OpenClaw 会回退到用户令牌。
历史上下文(History context)
- channels.slack.historyLimit(或 channels.slack.accounts.*.historyLimit)控制将多少最近的频道/群组消息包装到提示中。
- 回退到 messages.groupChat.historyLimit。设置 0 以禁用(默认 50)。
HTTP 模式(Events API)
当您的网关可以通过 HTTPS 被 Slack 访问时,使用 HTTP webhook 模式(通常用于服务器部署)。 HTTP 模式使用 Events API + 交互性(Interactivity)+ 斜杠命令(Slash Commands),共享一个请求 URL。
设置步骤
- 创建一个 Slack 应用并 禁用 Socket 模式(Socket Mode)(如果只使用 HTTP,可选)。
- 基本信息(Basic Information) → 复制 签名密钥(Signing Secret)。
- OAuth 与权限(OAuth & Permissions) → 安装应用并复制 机器人用户 OAuth 令牌(Bot User OAuth Token)(xoxb-...)。
- 事件订阅(Event Subscriptions) → 启用事件并将 请求 URL(Request URL) 设置为您的网关 webhook 路径(默认 /slack/events)。
- 交互性和快捷方式(Interactivity & Shortcuts) → 启用并设置相同的 请求 URL(Request URL)。
- 斜杠命令(Slash Commands) → 为您的命令设置相同的 请求 URL(Request URL)。
请求 URL 示例: https://gateway-host/slack/events
OpenClaw 配置(最小)
{
channels: {
slack: {
enabled: true,
mode: "http",
botToken: "xoxb-...",
signingSecret: "your-signing-secret",
webhookPath: "/slack/events"
}
}
}
多账户 HTTP 模式:设置 channels.slack.accounts.<id>.mode = "http" 并为每个账户提供唯一的 webhookPath,以便每个 Slack 应用可以指向自己的 URL。
清单(Manifest)(可选)
使用此 Slack 应用清单快速创建应用(如果需要,调整名称/命令)。如果您计划配置用户令牌,请包含用户作用域。
{
"display_information": {
"name": "OpenClaw",
"description": "Slack connector for OpenClaw"
},
"features": {
"bot_user": {
"display_name": "OpenClaw",
"always_online": false
},
"app_home": {
"messages_tab_enabled": true,
"messages_tab_read_only_enabled": false
},
"slash_commands": [
{
"command": "/openclaw",
"description": "Send a message to OpenClaw",
"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"
],
"user": [
"channels:history",
"channels:read",
"groups:history",
"groups:read",
"im:history",
"im:read",
"mpim:history",
"mpim:read",
"users:read",
"reactions:read",
"pins:read",
"emoji:read",
"search:read"
]
}
},
"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"
]
}
}
}
如果启用原生命令,为您想要公开的每个命令添加一个 slash_commands 条目(与 /help 列表匹配)。使用 channels.slack.commands.native 覆盖。
作用域(Scopes)(当前 vs 可选)
Slack 的 Conversations API 是类型作用域的:您只需要实际接触的对话类型的作用域(channels、groups、im、mpim)。参见 https://docs.slack.dev/apis/web-api/using-the-conversations-api/ 获取概述。
机器人令牌作用域(Bot token scopes)(必需)
- chat:write(通过 chat.postMessage 发送/更新/删除消息) https://docs.slack.dev/reference/methods/chat.postMessage
- im:write(通过 conversations.open 打开用户私信) https://docs.slack.dev/reference/methods/conversations.open
- channels:history、groups:history、im:history、mpim:history https://docs.slack.dev/reference/methods/conversations.history
- channels:read、groups:read、im:read、mpim:read https://docs.slack.dev/reference/methods/conversations.info
- users:read(用户查找) https://docs.slack.dev/reference/methods/users.info
- reactions:read、reactions:write(reactions.get / reactions.add) https://docs.slack.dev/reference/methods/reactions.get https://docs.slack.dev/reference/methods/reactions.add
- pins:read、pins:write(pins.list / pins.add / pins.remove) https://docs.slack.dev/reference/scopes/pins.read https://docs.slack.dev/reference/scopes/pins.write
- emoji:read(emoji.list) https://docs.slack.dev/reference/scopes/emoji.read
- files:write(通过 files.uploadV2 上传) https://docs.slack.dev/messaging/working-with-files/#upload
用户令牌作用域(User token scopes)(可选,默认只读)
如果配置 channels.slack.userToken,请在 用户令牌作用域(User Token Scopes) 下添加这些。
- channels:history、groups:history、im:history、mpim:history
- channels:read、groups:read、im:read、mpim:read
- users:read
- reactions:read
- pins:read
- emoji:read
- search:read
目前不需要(但可能未来需要)
- mpim:write(仅当我们通过 conversations.open 添加群组私信打开/私信启动时)
- groups:write(仅当我们添加私有频道管理时:创建/重命名/邀请/归档)
- chat:write.public(仅当我们想发布到机器人不在其中的频道时) https://docs.slack.dev/reference/scopes/chat.write.public
- users:read.email(仅当我们需要从 users.info 获取电子邮件字段时) https://docs.slack.dev/changelog/2017-04-narrowing-email-access
- files:read(仅当我们开始列出/读取文件元数据时)
配置(Config)
Slack 仅使用 Socket 模式(无 HTTP webhook 服务器)。提供两个令牌:
{
"slack": {
"enabled": true,
"botToken": "xoxb-...",
"appToken": "xapp-...",
"groupPolicy": "allowlist",
"dm": {
"enabled": true,
"policy": "pairing",
"allowFrom": ["U123", "U456", "*"],
"groupEnabled": false,
"groupChannels": ["G123"],
"replyToMode": "all"
},
"channels": {
"C123": { "allow": true, "requireMention": true },
"#general": {
"allow": true,
"requireMention": true,
"users": ["U123"],
"skills": ["search", "docs"],
"systemPrompt": "Keep answers short."
}
},
"reactionNotifications": "own",
"reactionAllowlist": ["U123"],
"replyToMode": "off",
"actions": {
"reactions": true,
"messages": true,
"pins": true,
"memberInfo": true,
"emojiList": true
},
"slashCommand": {
"enabled": true,
"name": "openclaw",
"sessionPrefix": "slack:slash",
"ephemeral": true
},
"textChunkLimit": 4000,
"mediaMaxMb": 20
}
}
令牌也可以通过环境变量提供:
- SLACK_BOT_TOKEN
- SLACK_APP_TOKEN
确认反应(Ack reactions)通过 messages.ackReaction + messages.ackReactionScope 全局控制。使用 messages.removeAckAfterReply 在机器人回复后清除确认反应。
限制(Limits)
- 出站文本分块到 channels.slack.textChunkLimit(默认 4000)。
- 可选换行分块:设置 channels.slack.chunkMode="newline" 以在长度分块之前按空行(段落边界)分割。
- 媒体上传受 channels.slack.mediaMaxMb 限制(默认 20)。
回复线程(Reply threading)
默认情况下,OpenClaw 在主频道中回复。使用 channels.slack.replyToMode 控制自动线程:
| 模式 | 行为 |
|---|---|
| off | 默认。 在主频道中回复。仅当触发消息已在线程中时才使用线程。 |
| first | 第一条回复进入线程(在触发消息下),后续回复进入主频道。有助于保持上下文可见,同时避免线程混乱。 |
| all | 所有回复都进入线程。保持对话集中,但可能降低可见性。 |
该模式适用于自动回复和代理工具调用(slack sendMessage)。
按聊天类型的线程(Per-chat-type threading)
您可以通过设置 channels.slack.replyToModeByChatType 为每种聊天类型配置不同的线程行为:
{
channels: {
slack: {
replyToMode: "off", // 频道的默认值
replyToModeByChatType: {
direct: "all", // 私信始终使用线程
group: "first" // 群组私信/MPIM 第一条回复使用线程
},
}
}
}
支持的聊天类型:
- direct:1 对 1 私信(Slack im)
- group:群组私信 / MPIM(Slack mpim)
- channel:标准频道(公共/私有)
优先级:
- replyToModeByChatType.<chatType>
- replyToMode
- 提供商默认值(off)
旧版 channels.slack.dm.replyToMode 在未设置聊天类型覆盖时仍被接受作为 direct 的回退。
示例:
仅私信使用线程:
{
channels: {
slack: {
replyToMode: "off",
replyToModeByChatType: { direct: "all" }
}
}
}
群组私信使用线程,但频道保持在根级别:
{
channels: {
slack: {
replyToMode: "off",
replyToModeByChatType: { group: "first" }
}
}
}
频道使用线程,私信保持在根级别:
{
channels: {
slack: {
replyToMode: "first",
replyToModeByChatType: { direct: "off", group: "off" }
}
}
}
手动线程标签(Manual threading tags)
为了精细控制,在代理响应中使用这些标签:
- [[reply_to_current]] — 回复触发消息(开始/继续线程)。
- [[reply_to:<id>]] — 回复特定消息 ID。
会话 + 路由(Sessions + routing)
- 私信共享 main 会话(类似 WhatsApp/Telegram)。
- 频道映射到 agent:<agentId>:slack:channel:<channelId> 会话。
- 斜杠命令使用 agent:<agentId>:slack:slash:<userId> 会话(前缀可通过 channels.slack.slashCommand.sessionPrefix 配置)。
- 如果 Slack 未提供 channel_type,OpenClaw 从频道 ID 前缀(D、C、G)推断,默认为 channel 以保持会话键稳定。
- 原生命令注册使用 commands.native(全局默认 "auto" → Slack 关闭),可以通过 channels.slack.commands.native 为每个工作区覆盖。文本命令需要独立的 /... 消息,可以通过 commands.text: false 禁用。Slack 斜杠命令在 Slack 应用中管理,不会自动删除。使用 commands.useAccessGroups: false 绕过命令的访问组检查。
- 完整命令列表 + 配置:斜杠命令(Slash commands)
私信安全(DM security)(配对)
- 默认:channels.slack.dm.policy="pairing" — 未知私信发送者获得配对代码(1 小时后过期)。
- 批准方式:openclaw pairing approve slack <code>。
- 允许任何人:设置 channels.slack.dm.policy="open" 和 channels.slack.dm.allowFrom=["*"]。
- channels.slack.dm.allowFrom 接受用户 ID、@handles 或电子邮件(在令牌允许时在启动时解析)。向导在设置期间接受用户名,并在令牌允许时将其解析为 ID。
群组策略(Group policy)
- channels.slack.groupPolicy 控制频道处理(open|disabled|allowlist)。
- allowlist 要求频道在 channels.slack.channels 中列出。
- 如果您仅设置 SLACK_BOT_TOKEN/SLACK_APP_TOKEN 且从未创建 channels.slack 部分, 运行时默认将 groupPolicy 设置为 open。添加 channels.slack.groupPolicy、 channels.defaults.groupPolicy 或频道允许列表以锁定它。
- 配置向导接受 #channel 名称,并在可能时将其解析为 ID (公共 + 私有);如果存在多个匹配项,它优先选择活动频道。
- 在启动时,OpenClaw 将允许列表中的频道/用户名解析为 ID(当令牌允许时) 并记录映射;未解析的条目保持键入状态。
- 要 不允许频道,设置 channels.slack.groupPolicy: "disabled"(或保持空允许列表)。
频道选项(channels.slack.channels.<id> 或 channels.slack.channels.<name>):
- allow:当 groupPolicy="allowlist" 时允许/拒绝频道。
- requireMention:频道的提及门控。
- tools:可选的每个频道工具策略覆盖(allow/deny/alsoAllow)。
- toolsBySender:频道内可选的每个发送者工具策略覆盖(键是发送者 ID/@handles/电子邮件;支持 "*" 通配符)。
- allowBots:允许此频道中的机器人作者消息(默认:false)。
- users:可选的每个频道用户允许列表。
- skills:技能过滤器(省略 = 所有技能,空 = 无)。
- systemPrompt:频道的额外系统提示(与主题/目的结合)。
- enabled:设置 false 以禁用频道。
发送目标(Delivery targets)
与 cron/CLI 发送一起使用:
- user:<id> 用于私信
- channel:<id> 用于频道
工具操作(Tool actions)
Slack 工具操作可以通过 channels.slack.actions.* 进行门控:
| 操作组 | 默认 | 注释 |
|---|---|---|
| reactions | 启用 | 反应 + 列出反应 |
| messages | 启用 | 读取/发送/编辑/删除 |
| pins | 启用 | 固定/取消固定/列出 |
| memberInfo | 启用 | 成员信息 |
| emojiList | 启用 | 自定义表情符号列表 |
安全注意事项(Security notes)
- 写入默认使用机器人令牌,因此状态更改操作保持在应用的机器人权限和身份范围内。
- 设置 userTokenReadOnly: false 允许在机器人令牌不可用时使用用户令牌进行写入操作,这意味着操作以安装用户的访问权限运行。将用户令牌视为高特权并保持操作门和允许列表严格。
- 如果启用用户令牌写入,请确保用户令牌包含您期望的写入作用域(chat:write、reactions:write、pins:write、files:write),否则这些操作将失败。
注意事项(Notes)
- 提及门控通过 channels.slack.channels 控制(将 requireMention 设置为 true);agents.list[].groupChat.mentionPatterns(或 messages.groupChat.mentionPatterns)也算作提及。
- 多代理覆盖:在 agents.list[].groupChat.mentionPatterns 上设置每个代理的模式。
- 反应通知遵循 channels.slack.reactionNotifications(使用 reactionAllowlist 与模式 allowlist)。
- 默认情况下忽略机器人作者的消息;通过 channels.slack.allowBots 或 channels.slack.channels.<id>.allowBots 启用。
- 警告:如果您允许回复其他机器人(channels.slack.allowBots=true 或 channels.slack.channels.<id>.allowBots=true),请使用 requireMention、channels.slack.channels.<id>.users 允许列表和/或 AGENTS.md 和 SOUL.md 中的清晰防护措施来防止机器人到机器人的回复循环。
- 对于 Slack 工具,反应移除语义在 /tools/reactions 中。
- 当允许且在大小限制内时,附件将下载到媒体存储。