Slack
状态:生产就绪,支持通过 Slack 应用集成进行私信和频道通信。默认模式为 Socket Mode;也支持 HTTP Events API 模式。
快速设置
Socket Mode(默认)
### 步骤 1:创建 Slack 应用和 Token
在 Slack 应用设置中:
- 启用 **Socket Mode**
- 创建 **App Token**(`xapp-...`),权限为 `connections:write`
- 安装应用并复制 **Bot Token**(`xoxb-...`)
### 步骤 2:配置 OpenClaw
{
channels: {
slack: {
enabled: true,
mode: "socket",
appToken: "xapp-...",
botToken: "xoxb-...",
},
},
}
环境变量备选(仅默认账户):
SLACK_APP_TOKEN=xapp-...
SLACK_BOT_TOKEN=xoxb-...
### 步骤 3:订阅应用事件
订阅 Bot 事件:
- `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`
同时启用 App Home **Messages Tab** 以支持私信。
### 步骤 4:启动 Gateway
openclaw gateway
HTTP Events API 模式
### 步骤 1:为 HTTP 配置 Slack 应用
- 将模式设为 HTTP(`channels.slack.mode="http"`)
- 复制 Slack **Signing Secret**
- 将 Event Subscriptions + Interactivity + Slash command Request URL 设为同一 webhook 路径(默认 `/slack/events`)
### 步骤 2:配置 OpenClaw HTTP 模式
{
channels: {
slack: {
enabled: true,
mode: "http",
botToken: "xoxb-...",
signingSecret: "your-signing-secret",
webhookPath: "/slack/events",
},
},
}
### 步骤 3:多账户 HTTP 使用唯一 webhook 路径
支持按账户的 HTTP 模式。
为每个账户设置不同的 `webhookPath` 以避免注册冲突。
Token 模型
- Socket Mode 需要
botToken+appToken。 - HTTP 模式需要
botToken+signingSecret。 - 配置中的 Token 优先于环境变量备选。
SLACK_BOT_TOKEN/SLACK_APP_TOKEN环境变量备选仅适用于默认账户。userToken(xoxp-...)仅支持配置(无环境变量备选),默认为只读行为(userTokenReadOnly: true)。- 可选:添加
chat:write.customize权限,使出站消息使用活跃 Agent 身份(自定义username和图标)。icon_emoji使用:emoji_name:语法。
提示: 对于操作/目录读取,配置后会优先使用 user token。对于写入操作,bot token 仍然优先;仅当
userTokenReadOnly: false且 bot token 不可用时才允许 user token 写入。
访问控制与路由
私信策略
`channels.slack.dmPolicy` 控制私信访问(旧版:`channels.slack.dm.policy`):
- `pairing`(默认)
- `allowlist`
- `open`(需要 `channels.slack.allowFrom` 包含 `"*"`;旧版:`channels.slack.dm.allowFrom`)
- `disabled`
私信标志:
- `dm.enabled`(默认 true)
- `channels.slack.allowFrom`(首选)
- `dm.allowFrom`(旧版)
- `dm.groupEnabled`(群组私信默认 false)
- `dm.groupChannels`(可选 MPIM 白名单)
多账户优先级:
- `channels.slack.accounts.default.allowFrom` 仅适用于 `default` 账户。
- 命名账户在其自身 `allowFrom` 未设置时继承 `channels.slack.allowFrom`。
- 命名账户不继承 `channels.slack.accounts.default.allowFrom`。
私信配对使用 `openclaw pairing approve slack <code>`。
频道策略
`channels.slack.groupPolicy` 控制频道处理:
- `open`
- `allowlist`
- `disabled`
频道白名单位于 `channels.slack.channels`,应使用稳定的频道 ID。
运行时注意:如果 `channels.slack` 完全缺失(仅使用环境变量),运行时会回退到 `groupPolicy="allowlist"` 并记录警告(即使 `channels.defaults.groupPolicy` 已设置)。
名称/ID 解析:
- 频道白名单条目和私信白名单条目在 Token 访问允许时启动时解析
- 未解析的频道名称条目保持配置但默认不参与路由
- 入站授权和频道路由默认以 ID 优先;直接用户名/slug 匹配需要 `channels.slack.dangerouslyAllowNameMatching: true`
提及与频道用户
频道消息默认需要提及。
提及来源:
- 显式的应用提及(`<@botId>`)
- 提及正则模式(`agents.list[].groupChat.mentionPatterns`,备选 `messages.groupChat.mentionPatterns`)
- 隐式的线程中回复 Bot 行为
按频道控制(`channels.slack.channels.<id>`;名称仅通过启动时解析或 `dangerouslyAllowNameMatching`):
- `requireMention`
- `users`(白名单)
- `allowBots`
- `skills`
- `systemPrompt`
- `tools`、`toolsBySender`
- `toolsBySender` 键格式:`id:`、`e164:`、`username:`、`name:` 或 `"*"` 通配符(旧版无前缀键仍映射为 `id:`)
命令和斜杠行为
- Slack 的原生命令自动模式关闭(
commands.native: "auto"不会启用 Slack 原生命令)。 - 通过
channels.slack.commands.native: true(或全局commands.native: true)启用原生 Slack 命令处理器。 - 启用原生命令后,在 Slack 中注册匹配的斜杠命令(
/<command>名称),有一个例外:- 为 status 命令注册
/agentstatus(Slack 保留了/status)
- 为 status 命令注册
- 如果未启用原生命令,可以通过
channels.slack.slashCommand运行单个配置的斜杠命令。 - 原生参数菜单现在会自适应渲染策略:
- 最多 5 个选项:按钮区块
- 6-100 个选项:静态选择菜单
- 超过 100 个选项:在交互性选项处理器可用时使用异步选项过滤的外部选择
- 如果编码的选项值超过 Slack 限制,流程会回退到按钮
- 对于长选项 payload,斜杠命令参数菜单在分派选定值前使用确认对话框。
交互式回复
Slack 可以渲染 Agent 创作的交互式回复控件,但此功能默认禁用。
全局启用:
{
channels: {
slack: {
capabilities: {
interactiveReplies: true,
},
},
},
}
或仅为一个 Slack 账户启用:
{
channels: {
slack: {
accounts: {
ops: {
capabilities: {
interactiveReplies: true,
},
},
},
},
},
}
启用后,Agent 可以发出 Slack 专属的回复指令:
[[slack_buttons: Approve:approve, Reject:reject]][[slack_select: Choose a target | Canary:canary, Production:production]]
这些指令会编译为 Slack Block Kit,点击或选择会通过现有的 Slack 交互事件路径路由回来。
说明:
- 这是 Slack 专属 UI。其他频道不会将 Slack Block Kit 指令翻译为自己的按钮系统。
- 交互式回调值是 OpenClaw 生成的不透明 Token,而非 Agent 创作的原始值。
- 如果生成的交互式区块超过 Slack Block Kit 限制,OpenClaw 会回退到原始文本回复,而非发送无效的区块 payload。
默认斜杠命令设置:
enabled: falsename: "openclaw"sessionPrefix: "slack:slash"ephemeral: true
斜杠会话使用隔离的键:
agent:<agentId>:slack:slash:<userId>
并且仍然将命令执行路由到目标对话会话(CommandTargetSessionKey)。
线程、会话和回复标签
- 私信路由为
direct;频道为channel;MPIM 为group。 - 默认
session.dmScope=main下,Slack 私信合并到 Agent 主会话。 - 频道会话:
agent:<agentId>:slack:channel:<channelId>。 - 线程回复可在适用时创建线程会话后缀(
:thread:<threadTs>)。 channels.slack.thread.historyScope默认为thread;thread.inheritParent默认为false。channels.slack.thread.initialHistoryLimit控制新线程会话开始时获取的现有线程消息数(默认20;设为0禁用)。
回复线程控制:
channels.slack.replyToMode:off|first|all(默认off)channels.slack.replyToModeByChatType:按direct|group|channel- 旧版私信备选:
channels.slack.dm.replyToMode
支持手动回复标签:
[[reply_to_current]][[reply_to:<id>]]
注意:replyToMode="off" 会禁用 Slack 中的所有回复线程,包括显式的 [[reply_to_*]] 标签。这与 Telegram 不同——Telegram 在 "off" 模式下仍会处理显式标签。差异反映了平台线程模型的不同:Slack 线程会将消息从频道中隐藏,而 Telegram 回复在主聊天流中仍然可见。
媒体、分块和投递
入站附件
Slack 文件附件从 Slack 托管的私有 URL(Token 认证请求流程)下载,当获取成功且大小限制允许时写入媒体存储。
运行时入站大小上限默认为 `20MB`,除非通过 `channels.slack.mediaMaxMb` 覆盖。
出站文本和文件
- 文本分块使用 `channels.slack.textChunkLimit`(默认 4000)
- `channels.slack.chunkMode="newline"` 启用段落优先分割
- 文件发送使用 Slack 上传 API,可包含线程回复(`thread_ts`)
- 出站媒体上限遵循 `channels.slack.mediaMaxMb`(如已配置);否则频道发送使用媒体管道的 MIME 类型默认值
投递目标
首选显式目标:
- `user:<id>` 用于私信
- `channel:<id>` 用于频道
向用户目标发送私信时,通过 Slack 对话 API 打开私信。
操作和门控
Slack 操作由 channels.slack.actions.* 控制。
当前 Slack 工具中的可用操作组:
| 组 | 默认 |
|---|---|
| messages | 启用 |
| reactions | 启用 |
| pins | 启用 |
| memberInfo | 启用 |
| emojiList | 启用 |
事件和运维行为
- 消息编辑/删除/线程广播映射为系统事件。
- 表情回应添加/移除事件映射为系统事件。
- 成员加入/离开、频道创建/重命名、pin 添加/移除事件映射为系统事件。
- 助理线程状态更新(用于线程中的 “正在输入…” 指示器)使用
assistant.threads.setStatus,需要 Bot 权限assistant:write。 channel_id_changed在configWrites启用时可迁移频道配置键。- 频道主题/用途元数据被视为不受信任的上下文,可注入路由上下文。
- 区块操作和模态交互发出结构化的
Slack interaction: ...系统事件,包含丰富的 payload 字段:- 区块操作:选定值、标签、选择器值和
workflow_*元数据 - 模态
view_submission和view_closed事件,包含路由的频道元数据和表单输入
- 区块操作:选定值、标签、选择器值和
确认回应
ackReaction 在 OpenClaw 处理入站消息时发送确认 emoji。
解析顺序:
channels.slack.accounts.<accountId>.ackReactionchannels.slack.ackReactionmessages.ackReaction- Agent 身份 emoji 备选(
agents.list[].identity.emoji,否则 ”👀”)
说明:
- Slack 使用短代码(例如
"eyes")。 - 使用
""禁用 Slack 账户或全局的回应。
输入反馈回应备选
typingReaction 在 OpenClaw 处理回复时向入站 Slack 消息添加临时回应,完成后移除。这在 Slack 原生助理输入功能不可用时特别有用,尤其是在私信中。
解析顺序:
channels.slack.accounts.<accountId>.typingReactionchannels.slack.typingReaction
说明:
- Slack 使用短代码(例如
"hourglass_flowing_sand")。 - 回应是尽力而为的,回复完成或失败后会自动尝试清理。
Manifest 和权限检查清单
Slack 应用 manifest 示例
{
"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",
"im:history",
"im:read",
"im:write",
"mpim:history",
"mpim:read",
"mpim:write",
"users:read",
"app_mentions:read",
"assistant:write",
"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"
]
}
}
}
可选的 user-token 权限(读操作)
如果你配置了 `channels.slack.userToken`,典型的读权限包括:
- `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`(如果你依赖 Slack 搜索读取)
故障排查
频道无回复
按顺序检查:
- `groupPolicy`
- 频道白名单(`channels.slack.channels`)
- `requireMention`
- 按频道的 `users` 白名单
有用的命令:
openclaw channels status --probe
openclaw logs --follow
openclaw doctor
私信消息被忽略
检查:
- `channels.slack.dm.enabled`
- `channels.slack.dmPolicy`(或旧版 `channels.slack.dm.policy`)
- 配对批准/白名单条目
openclaw pairing list slack
Socket Mode 无法连接
验证 Bot + App Token 以及 Slack 应用设置中的 Socket Mode 启用状态。
HTTP 模式未收到事件
验证:
- signing secret
- webhook 路径
- Slack Request URL(Events + Interactivity + Slash Commands)
- 每个 HTTP 账户使用唯一的 `webhookPath`
原生/斜杠命令未触发
确认你的预期是:
- 原生命令模式(`channels.slack.commands.native: true`),且在 Slack 中注册了匹配的斜杠命令
- 还是单斜杠命令模式(`channels.slack.slashCommand.enabled: true`)
同时检查 `commands.useAccessGroups` 和频道/用户白名单。
文本流式传输
OpenClaw 支持通过 Agents and AI Apps API 实现 Slack 原生文本流式传输。
channels.slack.streaming 控制实时预览行为:
off:禁用实时预览流式传输。partial(默认):用最新的部分输出替换预览文本。block:追加分块预览更新。progress:生成时显示进度状态文本,然后发送最终文本。
channels.slack.nativeStreaming 在 streaming 为 partial 时控制 Slack 原生流式 API(chat.startStream / chat.appendStream / chat.stopStream)(默认:true)。
禁用原生 Slack 流式传输(保留草稿预览行为):
channels:
slack:
streaming: partial
nativeStreaming: false
旧版键:
channels.slack.streamMode(replace | status_final | append)自动迁移为channels.slack.streaming。- 布尔值
channels.slack.streaming自动迁移为channels.slack.nativeStreaming。
要求
- 在 Slack 应用设置中启用 Agents and AI Apps。
- 确保应用拥有
assistant:write权限。 - 该消息需要有一个可用的回复线程。线程选择仍遵循
replyToMode。
行为
- 第一个文本分块启动流(
chat.startStream)。 - 后续文本分块追加到同一流(
chat.appendStream)。 - 回复结束时终结流(
chat.stopStream)。 - 媒体和非文本 payload 回退到正常投递。
- 如果流式传输在回复途中失败,OpenClaw 对剩余 payload 回退到正常投递。
配置参考指引
主要参考:
-
Slack 重要字段:
- 模式/认证:
mode、botToken、appToken、signingSecret、webhookPath、accounts.* - 私信访问:
dm.enabled、dmPolicy、allowFrom(旧版:dm.policy、dm.allowFrom)、dm.groupEnabled、dm.groupChannels - 兼容性开关:
dangerouslyAllowNameMatching(紧急开关;除非必要否则保持关闭) - 频道访问:
groupPolicy、channels.*、channels.*.users、channels.*.requireMention - 线程/历史:
replyToMode、replyToModeByChatType、thread.*、historyLimit、dmHistoryLimit、dms.*.historyLimit - 投递:
textChunkLimit、chunkMode、mediaMaxMb、streaming、nativeStreaming - 运维/功能:
configWrites、commands.native、slashCommand.*、actions.*、userToken、userTokenReadOnly
- 模式/认证: