Skip to main content
通过 Slack 应用集成,为 DM 和频道提供可用于生产环境的支持。默认模式为 Socket Mode;也支持 HTTP Request URLs。

配对

Slack DM 默认使用配对模式。

斜杠命令

原生命令行为与命令目录。

频道故障排查

跨频道诊断与修复操作手册。

选择 Socket Mode 或 HTTP Request URLs

这两种传输方式都已可用于生产环境,并且在消息、斜杠命令、App Home 和交互功能上具有同等能力。请选择部署形态,而不是功能。
关注点Socket Mode(默认)HTTP Request URLs
公共 Gateway URL不需要需要(DNS、TLS、反向代理或隧道)
出站网络必须能够出站 WSS 到 wss-primary.slack.com不需要出站 WS;仅需入站 HTTPS
所需令牌Bot token + 带有 connections:write 的 App-Level TokenBot token + Signing Secret
开发笔记本 / 防火墙后面可直接工作需要公共隧道(ngrok、Cloudflare Tunnel、Tailscale Funnel)或预发布 Gateway
横向扩展每台主机、每个 app 一个 Socket Mode 会话;多个 Gateway 需要不同的 Slack 应用无状态 POST 处理器;多个 Gateway 副本可通过负载均衡器共享同一个应用
单个 Gateway 上的多账号支持;每个账号都会打开各自的 WS支持;每个账号都需要唯一的 webhookPath(默认 /slack/events),以免注册冲突
斜杠命令传输通过 WS 连接传递;slash_commands[].url 会被忽略Slack 会 POST 到 slash_commands[].url;该字段是命令分发所必需的
请求签名不使用(认证方式是 App-Level Token)Slack 会对每个请求签名;OpenClaw 使用 signingSecret 进行校验
连接断开后的恢复已启用 Slack SDK 自动重连;OpenClaw 也会以受限退避方式重启失败的 Socket Mode 会话。适用 pong 超时的传输调优。没有持久连接可断开;重试由 Slack 按请求进行
选择 Socket Mode 适用于单 Gateway 主机、开发笔记本,以及能够向外访问 *.slack.com 但不能接受入站 HTTPS 的本地/内网环境。选择 HTTP Request URLs 适用于在负载均衡器后运行多个 Gateway 副本、出站 WSS 被阻止但允许入站 HTTPS、或者你已经在反向代理处终结 Slack webhook 的场景。

安装

在配置 channel 之前先安装 Slack:
openclaw plugins install @openclaw/slack
plugins install 会注册并启用该插件。在你配置好下面的 Slack app 和 channel 设置之前,该插件不会实际执行任何操作。有关通用插件行为和安装规则,请参见 Plugins

快速设置

1

创建新的 Slack 应用

打开 api.slack.com/appsCreate New AppFrom a manifest → 选择你的 workspace → 粘贴下面任一 manifest → NextCreate
{
  "display_information": {
    "name": "OpenClaw",
    "description": "Slack connector for OpenClaw"
  },
  "features": {
    "bot_user": { "display_name": "OpenClaw", "always_online": true },
    "app_home": {
      "home_tab_enabled": true,
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    },
    "assistant_view": {
      "assistant_description": "OpenClaw connects Slack assistant threads to OpenClaw agents.",
      "suggested_prompts": [
        { "title": "What can you do?", "message": "你能帮我做什么?" },
        {
          "title": "Summarize this channel",
          "message": "总结这个频道最近的活动。"
        },
        { "title": "Draft a reply", "message": "帮我起草一条回复。" }
      ]
    },
    "slash_commands": [
      {
        "command": "/openclaw",
        "description": "发送消息给 OpenClaw",
        "should_escape": false
      }
    ]
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "app_mentions:read",
        "assistant:write",
        "channels:history",
        "channels:read",
        "chat:write",
        "commands",
        "emoji:read",
        "files:read",
        "files:write",
        "groups:history",
        "groups:read",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "pins:read",
        "pins:write",
        "reactions:read",
        "reactions:write",
        "usergroups:read",
        "users:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_home_opened",
        "app_mention",
        "assistant_thread_context_changed",
        "assistant_thread_started",
        "channel_rename",
        "member_joined_channel",
        "member_left_channel",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "pin_added",
        "pin_removed",
        "reaction_added",
        "reaction_removed"
      ]
    }
  }
}
推荐 与 Slack 插件的完整功能集一致:App Home、斜杠命令、文件、表情反应、置顶、群组 DM,以及 emoji/usergroup 读取。若 workspace 策略限制 scope,则选择 Minimal —— 它覆盖 DM、频道/群组历史、提及和斜杠命令,但会移除文件、reaction、pin、群组 DM(mpim:*)、emoji:readusergroups:read。有关每个 scope 的原因以及附加选项(例如额外斜杠命令),请参见 Manifest and scope checklist
Slack 创建应用后:
  • Basic Information -> App-Level Tokens -> Generate Token and Scopes: 添加 connections:write,保存,并复制 App-Level Token。
  • Install App -> Install to Workspace: 复制 Bot User OAuth Token。
2

配置 OpenClaw

推荐的 SecretRef 设置:
export SLACK_APP_TOKEN=slack-app-token-example
export SLACK_BOT_TOKEN=slack-bot-token-example
cat > slack.socket.patch.json5 <<'JSON5'
{
  channels: {
    slack: {
      enabled: true,
      mode: "socket",
      appToken: { source: "env", provider: "default", id: "SLACK_APP_TOKEN" },
      botToken: { source: "env", provider: "default", id: "SLACK_BOT_TOKEN" },
    },
  },
}
JSON5
openclaw config patch --file ./slack.socket.patch.json5 --dry-run
openclaw config patch --file ./slack.socket.patch.json5
环境变量回退(仅默认账号):
SLACK_APP_TOKEN=slack-app-token-example
SLACK_BOT_TOKEN=slack-bot-token-example
3

启动网关

openclaw gateway

Socket Mode 传输调优

OpenClaw 默认将 Slack SDK 客户端的 pong 超时设置为 15 秒,适用于 Socket Mode。仅当你需要针对工作区或主机进行特定调优时,才覆盖传输设置:
{
  channels: {
    slack: {
      mode: "socket",
      socketMode: {
        clientPingTimeout: 20000,
        serverPingTimeout: 30000,
        pingPongLoggingEnabled: false,
      },
    },
  },
}
仅当 Socket Mode 工作区记录了 Slack websocket pong/server-ping 超时,或运行在已知事件循环饥饿的主机上时才使用此设置。clientPingTimeout 是 SDK 发送客户端 ping 后等待 pong 的时间;serverPingTimeout 是等待 Slack 服务器 ping 的时间。应用消息和事件仍然是应用状态,而不是传输层存活信号。 注意:
  • socketMode 在 HTTP Request URL 模式中会被忽略。
  • 基础 channels.slack.socketMode 设置适用于所有 Slack 账号,除非被覆盖。按账号覆盖使用 channels.slack.accounts.<accountId>.socketMode;由于这是对象覆盖,请包含该账号所需的每一项 socket 调优字段。
  • 只有 clientPingTimeout 有 OpenClaw 默认值(15000)。serverPingTimeoutpingPongLoggingEnabled 仅在配置后才会传递给 Slack SDK。
  • Socket Mode 重启退避时间从约 2 秒开始,最高约 30 秒。连续的可恢复启动/启动等待失败会在 12 次尝试后停止;在成功连接后,后续可恢复断开会开启新的重试周期。不可恢复的 Slack 认证错误,例如 invalid_auth、已撤销的 token 或缺少作用域,会快速失败,而不是永远重试。

Manifest 和作用域清单

基础 Slack 应用 manifest 在 Socket Mode 和 HTTP Request URLs 中是相同的。只有 settings 块(以及斜杠命令的 url)不同。 基础 manifest(Socket Mode 默认):
{
  "display_information": {
    "name": "OpenClaw",
    "description": "OpenClaw 的 Slack 连接器"
  },
  "features": {
    "bot_user": { "display_name": "OpenClaw", "always_online": true },
    "app_home": {
      "home_tab_enabled": true,
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    },
    "assistant_view": {
      "assistant_description": "OpenClaw 将 Slack assistant threads 连接到 OpenClaw 代理。",
      "suggested_prompts": [
        { "title": "What can you do?", "message": "What can you help me with?" },
        {
          "title": "Summarize this channel",
          "message": "Summarize the recent activity in this channel."
        },
        { "title": "Draft a reply", "message": "Help me draft a reply." }
      ]
    },
    "slash_commands": [
      {
        "command": "/openclaw",
        "description": "向 OpenClaw 发送消息",
        "should_escape": false
      }
    ]
  },
  "oauth_config": {
    "scopes": {
      "bot": [
        "app_mentions:read",
        "assistant:write",
        "channels:history",
        "channels:read",
        "chat:write",
        "commands",
        "emoji:read",
        "files:read",
        "files:write",
        "groups:history",
        "groups:read",
        "im:history",
        "im:read",
        "im:write",
        "mpim:history",
        "mpim:read",
        "mpim:write",
        "pins:read",
        "pins:write",
        "reactions:read",
        "reactions:write",
        "usergroups:read",
        "users:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_home_opened",
        "app_mention",
        "assistant_thread_context_changed",
        "assistant_thread_started",
        "channel_rename",
        "member_joined_channel",
        "member_left_channel",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "pin_added",
        "pin_removed",
        "reaction_added",
        "reaction_removed"
      ]
    }
  }
}
对于 HTTP Request URLs 模式,将 settings 替换为 HTTP 变体,并为每个斜杠命令添加 url。需要公开 URL:
{
  "features": {
    "slash_commands": [
      {
        "command": "/openclaw",
        "description": "向 OpenClaw 发送消息",
        "should_escape": false,
        "url": "https://gateway-host.example.com/slack/events"
      }
    ]
  },
  "settings": {
    "event_subscriptions": {
      "request_url": "https://gateway-host.example.com/slack/events",
      "bot_events": [
        "app_home_opened",
        "app_mention",
        "assistant_thread_context_changed",
        "assistant_thread_started",
        "channel_rename",
        "member_joined_channel",
        "member_left_channel",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "pin_added",
        "pin_removed",
        "reaction_added",
        "reaction_removed"
      ]
    },
    "interactivity": {
      "is_enabled": true,
      "request_url": "https://gateway-host.example.com/slack/events",
      "message_menu_options_url": "https://gateway-host.example.com/slack/events"
    }
  }
}

其他 manifest 设置

启用不同功能以扩展上述默认配置。 默认 manifest 启用 Slack App Home 的 Home 选项卡,并订阅 app_home_opened。当工作区成员打开 Home 选项卡时,OpenClaw 会通过 views.publish 发布一个安全的默认 Home 视图;其中不包含会话负载或私有配置。Messages 选项卡仍对 Slack 私信启用。该 manifest 还通过 features.assistant_viewassistant:writeassistant_thread_startedassistant_thread_context_changed 启用 Slack assistant threads;assistant threads 会路由到各自的 OpenClaw 线程会话,并让 Slack 提供的线程上下文可供代理使用。
可以使用多个 原生斜杠命令 代替单个配置命令,并带来一些细微差异:
  • 使用 /agentstatus 而不是 /status,因为 /status 命令已被保留。
  • 同时可用的斜杠命令不超过 25 个。
将现有的 features.slash_commands 部分替换为 可用命令 的子集:
{
  "slash_commands": [
    {
      "command": "/new",
      "description": "开始一个新会话",
      "usage_hint": "[model]"
    },
    {
      "command": "/reset",
      "description": "重置当前会话"
    },
    {
      "command": "/compact",
      "description": "压缩会话上下文",
      "usage_hint": "[instructions]"
    },
    {
      "command": "/stop",
      "description": "停止当前运行"
    },
    {
      "command": "/session",
      "description": "管理线程绑定过期时间",
      "usage_hint": "idle <duration|off> or max-age <duration|off>"
    },
    {
      "command": "/think",
      "description": "设置思考级别",
      "usage_hint": "<level>"
    },
    {
      "command": "/verbose",
      "description": "切换详细输出",
      "usage_hint": "on|off|full"
    },
    {
      "command": "/fast",
      "description": "显示或设置快速模式",
      "usage_hint": "[status|on|off]"
    },
    {
      "command": "/reasoning",
      "description": "切换推理可见性",
      "usage_hint": "[on|off|stream]"
    },
    {
      "command": "/elevated",
      "description": "切换提升模式",
      "usage_hint": "[on|off|ask|full]"
    },
    {
      "command": "/exec",
      "description": "显示或设置 exec 默认值",
      "usage_hint": "host=<auto|sandbox|gateway|node> security=<deny|allowlist|full> ask=<off|on-miss|always> node=<id>"
    },
    {
      "command": "/approve",
      "description": "批准或拒绝待处理的批准请求",
      "usage_hint": "<id> <decision>"
    },
    {
      "command": "/model",
      "description": "显示或设置模型",
      "usage_hint": "[name|#|status]"
    },
    {
      "command": "/models",
      "description": "列出提供方/模型",
      "usage_hint": "[provider] [page] [limit=<n>|size=<n>|all]"
    },
    {
      "command": "/help",
      "description": "显示简短帮助摘要"
    },
    {
      "command": "/commands",
      "description": "显示生成的命令目录"
    },
    {
      "command": "/tools",
      "description": "显示当前代理此刻可使用的内容",
      "usage_hint": "[compact|verbose]"
    },
    {
      "command": "/agentstatus",
      "description": "显示运行时状态,包括可用时的提供方使用情况/配额"
    },
    {
      "command": "/tasks",
      "description": "列出当前会话的活动/最近后台任务"
    },
    {
      "command": "/context",
      "description": "解释上下文是如何组装的",
      "usage_hint": "[list|detail|json]"
    },
    {
      "command": "/whoami",
      "description": "显示你的发送者身份"
    },
    {
      "command": "/skill",
      "description": "按名称运行一个技能",
      "usage_hint": "<name> [input]"
    },
    {
      "command": "/btw",
      "description": "在不更改会话上下文的情况下提出一个旁支问题",
      "usage_hint": "<question>"
    },
    {
      "command": "/side",
      "description": "在不更改会话上下文的情况下提出一个旁支问题",
      "usage_hint": "<question>"
    },
    {
      "command": "/usage",
      "description": "控制使用情况页脚或显示费用摘要",
      "usage_hint": "off|tokens|full|cost"
    }
  ]
}
如果你希望发出的消息使用当前代理身份(自定义用户名和图标),而不是默认的 Slack 应用身份,请添加 chat:write.customize bot scope。如果你使用表情符号图标,Slack 期望使用 :emoji_name: 语法。
如果你配置了 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 搜索读取)

Token 模型

  • botToken + appToken 是 Socket Mode 所必需的。
  • HTTP 模式需要 botToken + signingSecret
  • botToken, appToken, signingSecret, 和 userToken 接受明文字符串或 SecretRef 对象。
  • 配置中的 token 会覆盖环境变量回退。
  • SLACK_BOT_TOKEN / SLACK_APP_TOKEN 环境变量回退仅适用于默认账号。
  • userToken 仅可在配置中设置(没有环境变量回退),并默认采用只读行为(userTokenReadOnly: true)。
状态快照行为:
  • Slack 账号检查会跟踪每个凭据的 *Source*Status 字段(botTokenappTokensigningSecretuserToken)。
  • 状态可以是 availableconfigured_unavailablemissing
  • configured_unavailable 表示该账号通过 SecretRef 或其他非内联密钥来源进行了配置,但当前命令/运行时路径 无法解析出实际值。
  • 在 HTTP 模式下会包含 signingSecretStatus;在 Socket Mode 下, 所需配对为 botTokenStatus + appTokenStatus
对于操作/目录读取,如果已配置,user token 可以优先使用。对于写入,仍优先使用 bot token;只有在 userTokenReadOnly: false 且 bot token 不可用时,才允许使用 user-token 写入。

操作与门控

Slack 操作由 channels.slack.actions.* 控制。 当前 Slack 工具中可用的操作组:
默认
messages已启用
reactions已启用
pins已启用
memberInfo已启用
emojiList已启用
当前 Slack 消息操作包括 sendupload-filedownload-filereadeditdeletepinunpinlist-pinsmember-infoemoji-listdownload-file 接受入站文件占位符中显示的 Slack 文件 ID,并会针对图片返回图片预览,针对其他文件类型返回本地文件元数据。

访问控制与路由

channels.slack.dmPolicy 控制 DM 访问。channels.slack.allowFrom 是规范的 DM 允许列表。
  • pairing(默认)
  • allowlist
  • open(需要 channels.slack.allowFrom 包含 "*"
  • disabled
DM 标志:
  • dm.enabled(默认 true)
  • channels.slack.allowFrom
  • dm.allowFrom(旧版)
  • dm.groupEnabled(群组 DM 默认 false)
  • dm.groupChannels(可选的 MPIM 允许列表)
多账号优先级:
  • channels.slack.accounts.default.allowFrom 仅适用于 default 账号。
  • 当命名账号自身的 allowFrom 未设置时,会继承 channels.slack.allowFrom
  • 命名账号不会继承 channels.slack.accounts.default.allowFrom
旧版 channels.slack.dm.policychannels.slack.dm.allowFrom 仍会为兼容性读取。openclaw doctor --fix 会在不改变访问权限的前提下,将它们迁移到 dmPolicyallowFromDMs 中的配对使用 openclaw pairing approve slack <code>

线程、会话和回复标签

  • DMs 路由为 direct;channels 为 channel;MPIMs 为 group
  • Slack 路由绑定接受原始 peer IDs,以及 Slack 目标形式,例如 channel:C12345678user:U12345678<@U12345678>
  • 在默认 session.dmScope=main 下,Slack DMs 会折叠到 agent 主会话。
  • 频道会话:agent:<agentId>:slack:channel:<channelId>
  • 普通顶层频道消息会保留在按频道划分的会话中,即使 replyToMode 不是 off 也是如此。
  • Slack 线程回复会使用父 Slack thread_ts 作为会话后缀(:thread:<threadTs>),即使通过 replyToMode="off" 禁用了出站回复线程化也是如此。
  • OpenClaw 会在一个符合条件的顶层频道 root 预期会开启一个可见的 Slack thread 时,将其种子化到 agent:<agentId>:slack:channel:<channelId>:thread:<rootTs>,这样 root 和后续线程回复就共享同一个 OpenClaw 会话。这适用于 app_mention 事件、显式 bot 或已配置的 mention-pattern 匹配,以及 requireMention: falsereplyToModeoff 的频道。
  • channels.slack.thread.historyScope 默认值为 threadthread.inheritParent 默认值为 false
  • channels.slack.thread.initialHistoryLimit 控制新 thread session 启动时会拉取多少已有 thread messages(默认 20;设为 0 可禁用)。
  • channels.slack.thread.requireExplicitMention(默认 false):当为 true 时,会抑制隐式 thread mentions,使 bot 只响应 thread 内显式的 @bot mentions,即使 bot 已经参与过该 thread 也是如此。若不启用此项,已参与 bot thread 中的回复会绕过 requireMention 门控。
回复线程控制:
  • channels.slack.replyToModeoff|first|all|batched(默认 off
  • channels.slack.replyToModeByChatType:按 direct|group|channel 分别设置
  • direct chats 的旧版回退:channels.slack.dm.replyToMode
支持手动回复标签:
  • [[reply_to_current]]
  • [[reply_to:<id>]]
对于来自 message 工具的显式 Slack thread replies,设置 replyBroadcast: true,并配合 action: "send"threadIdreplyTo,以请求 Slack 也将该 thread reply 广播到父频道。这会映射到 Slack 的 chat.postMessage reply_broadcast 标志,并且仅支持文本或 Block Kit 发送,不支持媒体上传。 当一个 message 工具调用在 Slack thread 内运行并且目标是同一个频道时,OpenClaw 通常会根据 replyToMode 继承当前 Slack thread。将 action: "send"action: "upload-file" 上的 topLevel: true 设为真,可强制改为发送新的父频道消息。threadId: null 也可作为同样的顶层退出选项。
replyToMode="off" 会禁用出站 Slack 回复线程化,包括显式的 [[reply_to_*]] 标签。它不会将入站 Slack thread sessions 扁平化:已经发布在 Slack thread 中的消息仍会路由到 :thread:<threadTs> session。这与 Telegram 不同,在 Telegram 中即使在 "off" 模式下显式标签仍会被保留。Slack threads 会在频道中隐藏消息,而 Telegram replies 会以内联方式可见。

确认反应

ackReaction 会在 OpenClaw 处理入站消息期间发送一个确认表情,而 ackReactionScope 决定该表情实际何时发送。

Emoji (ackReaction)

解析顺序:
  • channels.slack.accounts.<accountId>.ackReaction
  • channels.slack.ackReaction
  • messages.ackReaction
  • agent identity emoji 回退(agents.list[].identity.emoji,否则 "eyes" / 👀)
说明:
  • Slack 期望使用简写名(例如 "eyes")。
  • 可使用 "" 来禁用该 Slack 账号或全局的反应。

范围(messages.ackReactionScope

Slack 提供方从 messages.ackReactionScope 读取范围(默认 "group-mentions")。目前没有 Slack 账号级或频道级覆盖;该值对网关全局生效。 取值:
  • "all":在 DMs 和群组中都添加反应。
  • "direct":仅在 DMs 中添加反应。
  • "group-all":对每条群组消息都添加反应(不包括 DMs)。
  • "group-mentions"(默认):在群组中添加反应,但仅在 bot 被提及(或在已选择启用的群组可提及对象中)时才触发。不包括 DMs。
  • "off" / "none":从不添加反应。
默认范围("group-mentions")不会在私聊中触发确认反应。若要在入站 Slack DMs 上看到已配置的 ackReaction(例如 "eyes"),请将 messages.ackReactionScope 设为 "direct""all"messages.ackReactionScope 会在 Slack 提供方启动时读取,因此需要重启网关后更改才会生效。
{
  messages: {
    ackReaction: "eyes",
    ackReactionScope: "all", // 在 DMs 和群组中添加反应
  },
}

文本流式传输

channels.slack.streaming 控制实时预览行为:
  • off:禁用实时预览流式传输。
  • partial(默认):使用最新的部分输出替换预览文本。
  • block:追加分块预览更新。
  • progress:在生成期间显示进度状态文本,然后发送最终文本。
  • streaming.preview.toolProgress:当草稿预览处于活动状态时,将工具/进度更新路由到同一条已编辑的预览消息中(默认:true)。设为 false 可保留单独的工具/进度消息。
  • streaming.preview.commandText / streaming.progress.commandText:设为 status 可在隐藏原始 command/exec 文本的同时保留紧凑的工具进度行(默认:raw)。
隐藏原始 command/exec 文本,同时保留紧凑的进度行:
{
  "channels": {
    "slack": {
      "streaming": {
        "mode": "progress",
        "progress": {
          "toolProgress": true,
          "commandText": "status"
        }
      }
    }
  }
}
channels.slack.streaming.modepartial 时,channels.slack.streaming.nativeTransport 控制 Slack 原生文本流式传输(默认:true)。 Slack 原生进度任务卡片在 progress 模式下为可选启用。将 channels.slack.streaming.progress.nativeTaskCards 设为 true,并将 channels.slack.streaming.mode 设为 "progress",即可在工作进行时发送 Slack 原生计划/任务卡片,然后在完成时更新同一张任务卡片。不启用该标志时,progress 模式会保留可移植的草稿预览行为。
  • 原生文本流式传输和 Slack assistant 线程状态要显示,必须有可用的回复线程。线程选择仍遵循 replyToMode
  • 当原生流式传输不可用或不存在回复线程时,频道、群聊和顶层 DM 仍可使用常规草稿预览。
  • 顶层 Slack DMs 默认保持非线程化,因此不会显示 Slack 的线程式原生流/状态预览;OpenClaw 会改为在 DM 中发布并编辑草稿预览。
  • 媒体和非文本载荷会回退到正常投递。
  • 媒体/错误最终结果会取消待处理的预览编辑;符合条件的文本/Block 最终结果仅在能够就地编辑预览时才会刷新。
  • 如果流式传输在回复中途失败,OpenClaw 会对剩余载荷回退到正常投递。
使用草稿预览而不是 Slack 原生文本流式传输:
{
  channels: {
    slack: {
      streaming: {
        mode: "partial",
        nativeTransport: false,
      },
    },
  },
}
选择启用 Slack 原生进度任务卡片:
{
  channels: {
    slack: {
      streaming: {
        mode: "progress",
        progress: {
          nativeTaskCards: true,
          render: "rich",
        },
      },
    },
  },
}
旧版键:
  • channels.slack.streamMode (replace | status_final | append) 是 channels.slack.streaming.mode 的旧版运行时别名。
  • 布尔值 channels.slack.streamingchannels.slack.streaming.modechannels.slack.streaming.nativeTransport 的旧版运行时别名。
  • 旧版 channels.slack.nativeStreamingchannels.slack.streaming.nativeTransport 的运行时别名。
  • 运行 openclaw doctor --fix 可将持久化的 Slack 流式配置重写为规范键。

输入中 typing 反应回退

typingReaction 会在 OpenClaw 处理回复期间向入站 Slack 消息添加一个临时反应,并在运行结束后将其移除。这在线程回复之外最有用,因为线程回复默认会使用“正在输入…”状态指示器。 解析顺序:
  • channels.slack.accounts.<accountId>.typingReaction
  • channels.slack.typingReaction
说明:
  • Slack 期望使用简写名(例如 "hourglass_flowing_sand")。
  • 该反应尽力而为,回复或失败路径完成后会自动尝试清理。

媒体、分块与投递

Slack 文件附件会从 Slack 托管的私有 URL 下载(使用 token 认证请求流程),并在获取成功且大小限制允许时写入媒体存储。文件占位符包含 Slack fileId,因此 agent 可以使用 download-file 获取原始文件。下载会使用有界的空闲超时和总超时。如果 Slack 文件检索卡住或失败,OpenClaw 会继续处理消息,并回退到文件占位符。运行时入站大小上限默认是 20MB,除非被 channels.slack.mediaMaxMb 覆盖。
  • 文本分块使用 channels.slack.textChunkLimit(默认 4000)
  • channels.slack.chunkMode="newline" 启用优先按段落拆分
  • 文件发送使用 Slack 上传 API,并可包含线程回复(thread_ts
  • 若已配置,出站媒体上限遵循 channels.slack.mediaMaxMb;否则频道发送使用媒体管道中的 MIME 类型默认值
推荐的显式目标:
  • user:<id> 用于 DMs
  • channel:<id> 用于频道
仅文本/分块的 Slack DMs 可以直接发布到 user ID;文件上传和带线程的发送会先通过 Slack conversation API 打开 DM,因为这些路径需要一个具体的 conversation ID。

命令与斜杠行为

Slash 命令在 Slack 中表现为单个已配置命令或多个原生命令。配置 channels.slack.slashCommand 可更改命令默认值:
  • enabled: false
  • name: "openclaw"
  • sessionPrefix: "slack:slash"
  • ephemeral: true
/openclaw /help
原生命令需要在你的 Slack 应用中添加 额外的 manifest 设置,并通过全局配置中的 channels.slack.commands.native: truecommands.native: true 启用。
  • 对于 Slack,原生命令自动模式是 关闭 的,因此 commands.native: "auto" 不会启用 Slack 原生命令。
/help
原生参数菜单使用自适应渲染策略,在发送所选选项值之前会先显示确认模态框:
  • 最多 5 个选项:按钮块
  • 6-100 个选项:静态选择菜单
  • 超过 100 个选项:在可用交互选项处理器时,使用带异步选项过滤的外部选择器
  • 超出 Slack 限制:编码后的选项值会回退为按钮
/think
Slash 会话使用类似 agent:<agentId>:slack:slash:<userId> 的隔离键,并仍然通过 CommandTargetSessionKey 将命令执行路由到目标对话会话。

交互式回复

Slack 可以渲染由 agent 生成的交互式回复控件,但此功能默认是禁用的。对于新的 agent、CLI 和插件输出,建议使用共享的 presentation 按钮或选择块。它们使用相同的 Slack 交互路径,同时在其他渠道上也能优雅降级。 全局启用它:
{
  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 专用的临时方案;新建可移植控件时请使用共享 presentation。 用于指令编译器的 API 对新生产代码也已废弃:
  • compileSlackInteractiveReplies(...)
  • parseSlackOptionsLine(...)
  • isSlackInteractiveRepliesEnabled(...)
  • buildSlackInteractiveBlocks(...)
新建 Slack 渲染控件时,请使用 presentation 负载和 buildSlackPresentationBlocks(...) 注意:
  • 这是 Slack 专用的旧版 UI。其他渠道不会将 Slack Block Kit 指令转换为它们自己的按钮系统。
  • 交互回调值是 OpenClaw 生成的不可读令牌,而不是 agent 直接编写的原始值。
  • 如果生成的交互块超过 Slack Block Kit 限制,OpenClaw 会回退为原始文本回复,而不是发送无效的 blocks 负载。

插件拥有的模态提交

注册了交互处理器的 Slack 插件,也可以在 OpenClaw 为 agent 可见的系统事件压缩负载之前,接收模态框的 view_submissionview_closed 生命周期事件。在打开 Slack 模态框时,请使用以下一种路由模式:
  • callback_id 设为 openclaw:<namespace>:<payload>
  • 或保留现有的 callback_id,并在模态框的 private_metadata 中放入 pluginInteractiveData: "<namespace>:<payload>"
处理器会收到 ctx.interaction.kindview_submissionview_closed,规范化后的 inputs,以及来自 Slack 的完整原始 stateValues 对象。仅使用 callback-id 路由就足以调用插件处理器;当模态框还应该生成一个 agent 可见的系统事件时,请包含现有模态框的 private_metadata 用户/会话路由字段。agent 会收到一个简洁、脱敏的 Slack interaction: ... 系统事件。如果处理器返回 systemEvent.summarysystemEvent.referencesystemEvent.data,这些字段会包含在该简洁事件中,这样 agent 就可以引用 插件拥有的存储,而无需看到完整的表单负载。

Slack 中的原生审批

Slack 可以作为原生审批客户端,通过交互式按钮和交互操作来处理审批,而不是回退到 Web UI 或终端。
  • Exec 和插件审批可以渲染为 Slack 原生的 Block Kit 提示。
  • channels.slack.execApprovals.* 仍然是原生 exec 审批客户端的启用与 DM/频道路由配置。
  • Exec 审批 DM 使用 channels.slack.execApprovals.approverscommands.ownerAllowFrom
  • 当 Slack 被启用为源会话的原生审批客户端时,或者当 approvals.plugin 路由到源 Slack 会话或 Slack 目标时,插件审批会使用 Slack 原生按钮。
  • 插件审批 DM 使用来自 channels.slack.allowFrom、命名账号 allowFrom 或账号默认路由的 Slack 插件审批者。
  • 审批者授权仍然会被强制执行:仅限 exec 的审批者不能批准插件请求,除非他们同时也是插件审批者。
这使用与其他渠道相同的共享审批按钮界面。当你的 Slack 应用设置中启用了 interactivity 时,审批提示会直接在对话中渲染为 Block Kit 按钮。 当这些按钮存在时,它们就是主要的审批体验;只有当工具结果表明聊天审批不可用或手动审批是唯一途径时,OpenClaw 才应包含手动的 /approve 命令。 配置路径:
  • channels.slack.execApprovals.enabled
  • channels.slack.execApprovals.approvers(可选;在可能时回退到 commands.ownerAllowFrom
  • channels.slack.execApprovals.targetdm | channel | both,默认:dm
  • agentFilter, sessionFilter
enabled 未设置或为 "auto" 且至少有一个 exec 审批者可解析时,Slack 会自动启用原生 exec 审批。当 Slack 插件审批者可解析且请求匹配原生客户端过滤器时,Slack 也可以通过这个原生客户端路径处理原生插件审批。将 enabled: false 设为显式禁用 Slack 作为原生审批客户端。将 enabled: true 设为在审批者可解析时强制启用原生审批。禁用 Slack exec 审批不会禁用通过 approvals.plugin 启用的原生 Slack 插件审批投递;插件审批投递会改用 Slack 插件审批者。 未显式配置 Slack 执行审批时的默认行为:
{
  commands: {
    ownerAllowFrom: ["slack:U12345678"],
  },
}
只有当你想覆盖审批者、添加过滤器,或 选择原始聊天投递时,才需要显式的 Slack 原生配置:
{
  channels: {
    slack: {
      execApprovals: {
        enabled: true,
        approvers: ["U12345678"],
        target: "both",
      },
    },
  },
}
共享的 approvals.exec 转发是独立的。仅当 exec 审批提示也必须路由到其他聊天或显式的带外目标时才使用它。共享的 approvals.plugin 转发也同样独立;只有当 Slack 能够原生处理插件审批请求时,Slack 原生投递才会抑制该回退。 同聊 /approve 也可在已经支持命令的 Slack 频道和 DM 中使用。完整的审批转发模型请参见 执行审批

事件与运行行为

  • 消息编辑/删除会映射为系统事件。
  • 线程广播(“也发送到频道”的线程回复)会被当作普通用户消息处理。
  • reaction 的添加/移除事件会映射为系统事件。
  • 成员加入/离开、频道创建/重命名,以及 pin 的添加/移除事件会映射为系统事件。
  • 启用 configWrites 时,channel_id_changed 可迁移频道配置键。
  • 频道 topic/purpose 元数据会被视为不受信任的上下文,并可能被注入到路由上下文中。
  • 线程起始消息和初始线程历史上下文种子在适用时会按配置的发送者白名单过滤。
  • Block actions 和 modal 交互会发出结构化的 Slack interaction: ... 系统事件,并带有丰富的 payload 字段:
    • block actions:所选值、标签、选择器值,以及 workflow_* 元数据
    • modal view_submissionview_closed 事件,包含路由后的频道元数据和表单输入

配置参考

主要参考:/gateway/config-channels#slack
  • mode/auth: mode, botToken, appToken, signingSecret, webhookPath, accounts.*
  • DM 访问: 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, streaming.nativeTransport, streaming.preview.toolProgress
  • 展开预览: unfurlLinks(默认:false),unfurlMedia 用于控制 chat.postMessage 链接/媒体预览;将 unfurlLinks: true 设回以启用链接预览
  • 运维/功能: configWrites, commands.native, slashCommand.*, actions.*, userToken, userTokenReadOnly

故障排查

按以下顺序检查:
  • groupPolicy
  • 频道 allowlist (channels.slack.channels) — 键必须是频道 ID (C12345678),而不是名称 (#channel-name)。基于名称的键在 groupPolicy: "allowlist" 下会静默失败,因为频道路由默认按 ID 优先。查找 ID:在 Slack 中右键点击频道 → 复制链接 — URL 末尾的 C... 值就是频道 ID。
  • requireMention
  • per-channel users allowlist
  • messages.groupChat.visibleReplies: normal group/channel requests default to "automatic". If you opted into "message_tool" and logs show assistant text with no message(action=send) call, the model missed the visible message-tool path. Final text stays private in this mode; inspect the gateway verbose log for suppressed payload metadata, or set it to "automatic" if you want every normal assistant final reply posted through the legacy path.
  • messages.groupChat.unmentionedInbound: if it is "room_event", unmentioned allowed channel chatter is ambient context and stays silent unless the agent calls the message tool. See Ambient room events.
{
  messages: {
    groupChat: {
      visibleReplies: "automatic",
    },
  },
}
有用的命令:
openclaw channels status --probe
openclaw logs --follow
openclaw doctor
检查:
  • channels.slack.dm.enabled
  • channels.slack.dmPolicy(或旧版 channels.slack.dm.policy
  • 配对审批 / allowlist 条目(dmPolicy: "open" 仍然需要 channels.slack.allowFrom: ["*"]
  • 群组 DM 使用 MPIM 处理;启用 channels.slack.dm.groupEnabled,并且如果已配置,请将 MPIM 包含在 channels.slack.dm.groupChannels
  • Slack Assistant DM 事件:提到 drop message_changed 的详细日志 通常意味着 Slack 发送了一个编辑后的 Assistant 线程事件,但在消息元数据中没有可恢复的人类发送者
openclaw pairing list slack
Validate bot + app tokens and Socket Mode enablement in Slack app settings. The App-Level Token needs connections:write, and the Bot User OAuth Token bot token must belong to the same Slack app/workspace as the app token.如果 openclaw channels status --probe --json 显示 botTokenStatusappTokenStatus: "configured_unavailable",说明 Slack 账号已 配置,但当前运行时无法解析基于 SecretRef 的值。类似 slack socket mode failed to start; retry ... 的日志表示可恢复的 启动失败。缺少 scope、令牌被撤销以及无效认证则会立即失败。 slack token mismatch ... 日志意味着 bot token 和 app token 看起来属于不同的 Slack app;请修正 Slack app 凭据。
验证:
  • signing secret
  • webhook path
  • Slack Request URLs(Events + Interactivity + Slash Commands)
  • 每个 HTTP 账号唯一的 webhookPath
  • 公共 URL 终止 TLS 并将请求转发到 Gateway path
  • Slack app 的 request_url 路径必须与 channels.slack.webhookPath 完全匹配(默认 /slack/events
如果账号快照中出现 signingSecretStatus: "configured_unavailable", 说明 HTTP 账号已配置,但当前运行时无法 解析基于 SecretRef 的 signing secret。重复出现的 slack: webhook path ... already registered 日志意味着两个 HTTP 账号使用了相同的 webhookPath;请为每个账号分配不同的路径。
确认你期望的是以下哪种模式:
  • 原生命令模式(channels.slack.commands.native: true),并且 Slack 中注册了匹配的 slash 命令
  • 或单一 slash 命令模式(channels.slack.slashCommand.enabled: true
Slack 不会自动创建或移除 slash 命令。commands.native: "auto" 不会启用 Slack 原生命令;请使用 true 并在 Slack app 中创建匹配的命令。在 HTTP 模式下,每个 Slack slash 命令都必须包含 Gateway URL。在 Socket Mode 中,命令负载通过 websocket 到达,Slack 会忽略 slash_commands[].url另外还要检查 commands.useAccessGroups、DM 授权、channel allowlist 以及每个频道的 users allowlist。Slack 会为被阻止的 slash-command 发送者返回临时错误,包括:
  • This channel is not allowed.
  • You are not authorized to use this command here.

附件视觉参考

当 Slack 文件下载成功且大小限制允许时,Slack 可以将已下载媒体附加到 agent 的轮次中。图片文件可以通过媒体理解路径传递,或直接传递给支持视觉的回复模型;其他文件会作为可下载的文件上下文保留,而不会被当作图像输入处理。

支持的媒体类型

媒体类型来源当前行为备注
JPEG / PNG / GIF / WebP 图片Slack 文件 URL下载并附加到轮次中,以便进行支持视觉的处理单文件上限:channels.slack.mediaMaxMb(默认 20 MB)
PDF 文件Slack 文件 URL下载并作为文件上下文暴露给诸如 download-filepdf 之类的工具Slack 入站不会自动将 PDF 转换为图像视觉输入
其他文件Slack 文件 URL在可能时下载并作为文件上下文暴露二进制文件不被当作图像输入
线程回复线程起始消息文件当回复没有直接媒体时,可将根消息文件作为上下文注入仅文件的起始消息会使用附件占位符
多图消息多个 Slack 文件每个文件独立评估Slack 处理每条消息最多限制为八个文件

入站管道

当带有文件附件的 Slack 消息到达时:
  1. OpenClaw 使用 bot token 从 Slack 的私有 URL 下载文件。
  2. 文件在成功后写入媒体存储。
  3. 下载的媒体路径和内容类型会添加到入站上下文中。
  4. 支持图像的模型/工具路径可以使用该上下文中的图像附件。
  5. 非图像文件仍会作为文件元数据或媒体引用保留,供能够处理它们的工具使用。

线程根附件继承

当消息在某个线程中到达(具有 thread_ts 父级)时:
  • 如果回复本身没有直接媒体,而包含的根消息有文件,Slack 可以将根文件作为线程起始上下文注入。
  • 直接回复附件优先于根消息附件。
  • 只有文件而没有文本的根消息会表示为附件占位符,以便回退机制仍可包含其文件。

多附件处理

当单条 Slack 消息包含多个文件附件时:
  • 每个附件都会通过媒体管道独立处理。
  • 下载后的媒体引用会聚合到消息上下文中。
  • 处理顺序遵循事件负载中 Slack 文件的顺序。
  • 某个附件下载失败不会阻止其他附件处理。

大小、下载与模型限制

  • 大小上限:默认每个文件 20 MB。可通过 channels.slack.mediaMaxMb 配置。
  • 下载失败:Slack 无法提供的文件、过期 URL、无法访问的文件、超大文件,以及 Slack auth/login HTML 响应都会被跳过,而不是报告为不支持的格式。
  • 视觉模型:图像分析会使用当前激活的回复模型(如果它支持视觉),或者使用 agents.defaults.imageModel 中配置的图像模型。

已知限制

场景当前行为解决办法
过期的 Slack 文件 URL文件被跳过;不显示错误在 Slack 中重新上传文件
未配置视觉模型图像附件会作为媒体引用存储,但不会作为图像分析配置 agents.defaults.imageModel,或使用支持视觉的回复模型
非常大的图片(默认 > 20 MB)按大小上限跳过如果 Slack 允许,可增大 channels.slack.mediaMaxMb
转发/共享的附件文本和 Slack 托管的图像/文件媒体按最佳努力处理直接在 OpenClaw 线程中重新分享
PDF 附件作为文件/媒体上下文存储,不会自动通过图像视觉路径处理使用 download-file 获取文件元数据,或使用 pdf 工具分析 PDF

相关文档

相关内容

配对

将 Slack 用户与网关配对。

群组

频道和群组 DM 的行为。

频道路由

将入站消息路由给代理。

安全

威胁模型与加固。

配置

配置布局与优先级。

斜杠命令

命令目录与行为。