Skip to content

本页介绍如何将 Slack 接入 OpenClaw 龙虾。支持 Socket Mode(默认)和 HTTP Request URLs 两种接入方式。涵盖 Slack App 创建、Token 配置、DM/频道访问策略、@mention 控制、斜杠命令、文本流式输出、执行审批集成及常见故障排查。

Slack 接入配置

生产就绪,支持通过 Slack App 集成的私信和频道。默认模式为 Socket Mode,也支持 HTTP Request URLs。

快速配置

Socket Mode(默认)

  1. 创建 Slack App 并获取 Token

    在 Slack App 设置中:

    • 启用 Socket Mode
    • 创建 App Tokenxapp-...),权限包含 connections:write
    • 安装 App 并复制 Bot Tokenxoxb-...
  2. 配置 OpenClaw

json5
{
  channels: {
    slack: {
      enabled: true,
      mode: "socket",
      appToken: "xapp-...",
      botToken: "xoxb-...",
    },
  },
}

环境变量回退(仅默认账号):

bash
SLACK_APP_TOKEN=xapp-...
SLACK_BOT_TOKEN=xoxb-...
  1. 订阅 App 事件

    订阅以下 Bot 事件:

    • app_mention
    • message.channelsmessage.groupsmessage.immessage.mpim
    • reaction_addedreaction_removed
    • member_joined_channelmember_left_channel
    • channel_rename
    • pin_addedpin_removed

    同时在 App Home 中启用 Messages Tab 以支持私信。

  2. 启动 Gateway

bash
openclaw gateway

HTTP Request URLs 模式

  1. 设置模式为 HTTP(channels.slack.mode="http"),复制 Slack Signing Secret,将 Event Subscriptions + Interactivity + Slash Command 的 Request URL 统一指向 webhook 路径(默认 /slack/events)。

  2. 配置:

json5
{
  channels: {
    slack: {
      enabled: true,
      mode: "http",
      botToken: "xoxb-...",
      signingSecret: "your-signing-secret",
      webhookPath: "/slack/events",
    },
  },
}
  1. 多账号 HTTP 模式时,每个账号使用不同的 webhookPath,避免路由冲突。

App Manifest 和权限清单

Slack App Manifest 示例(展开查看)
json
{
  "display_information": {
    "name": "OpenClaw",
    "description": "Slack connector for OpenClaw"
  },
  "features": {
    "bot_user": {
      "display_name": "OpenClaw",
      "always_online": true
    },
    "app_home": {
      "messages_tab_enabled": true,
      "messages_tab_read_only_enabled": false
    },
    "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",
        "users:read"
      ]
    }
  },
  "settings": {
    "socket_mode_enabled": true,
    "event_subscriptions": {
      "bot_events": [
        "app_mention",
        "channel_rename",
        "member_joined_channel",
        "member_left_channel",
        "message.channels",
        "message.groups",
        "message.im",
        "message.mpim",
        "pin_added",
        "pin_removed",
        "reaction_added",
        "reaction_removed"
      ]
    }
  }
}

可选用户 Token 权限(读操作):channels:historygroups:historyim:historympim:historychannels:readgroups:readim:readmpim:readusers:readreactions:readpins:reademoji:readsearch:read

Token 模型

  • Socket Mode 需要 botToken + appToken
  • HTTP 模式需要 botToken + signingSecret
  • botTokenappTokensigningSecretuserToken 均可接受明文字符串或 SecretRef 对象。
  • 配置中的 Token 优先于环境变量。
  • SLACK_BOT_TOKEN / SLACK_APP_TOKEN 环境变量回退仅适用于默认账号。
  • userTokenxoxp-...)仅支持配置,无环境变量回退,默认为只读模式(userTokenReadOnly: true)。
  • 可选:添加 chat:write.customize 使出站消息使用当前 agent 身份(自定义 username 和图标)。

账号状态检查:账号检查会追踪每个凭证的 *Source*Status 字段(botTokenappTokensigningSecretuserToken)。状态为 availableconfigured_unavailablemissingconfigured_unavailable 表示账号通过 SecretRef 或其他非内联密钥来源配置,但当前命令/运行时路径无法解析实际值。

操作权限控制

Slack 操作通过 channels.slack.actions.* 控制。

操作组默认状态
messages启用
reactions启用
pins启用
memberInfo启用
emojiList启用

当前 Slack 消息操作包括 sendupload-filedownload-filereadeditdeletepinunpinlist-pinsmember-infoemoji-list

访问控制与路由

私信(DM)策略

channels.slack.dmPolicy(旧版:channels.slack.dm.policy)控制 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

DM 配对使用 openclaw pairing approve slack <code>

频道策略

channels.slack.groupPolicy 控制频道处理:

  • open
  • allowlist
  • disabled

频道白名单在 channels.slack.channels 下,应使用稳定的频道 ID。

运行时说明:如果 channels.slack 完全缺失(仅环境变量配置),运行时回退到 groupPolicy="allowlist" 并记录警告(即使设置了 channels.defaults.groupPolicy)。

名称/ID 解析:

  • 频道和 DM 白名单条目在启动时解析(Token 权限允许的情况下)
  • 未解析的频道名称条目保留在配置中但默认被路由忽略
  • 入站授权和频道路由默认以 ID 优先;直接用户名/slug 匹配需要 channels.slack.dangerouslyAllowNameMatching: true

@mention 和频道用户

频道消息默认需要 @mention 才会响应。

@mention 来源:

  • 显式 App mention(<@botId>
  • mention 正则模式(agents.list[].groupChat.mentionPatterns,回退 messages.groupChat.mentionPatterns
  • 隐式回复 bot 线程行为

每频道控制(channels.slack.channels.<id>):

  • requireMention
  • users(白名单)
  • allowBots
  • skills
  • systemPrompt
  • toolstoolsBySender
  • toolsBySender key 格式:id:e164:username:name:"*" 通配符(旧版无前缀 key 仍映射到 id:

线程、Session 和回复标签

  • DM 路由为 direct;频道为 channel;MPIM 为 group
  • 默认 session.dmScope=main 时,Slack DM 折叠到 agent 主 session。
  • 频道 session:agent:<agentId>:slack:channel:<channelId>
  • 线程回复可创建线程 session 后缀(:thread:<threadTs>)。
  • channels.slack.thread.historyScope 默认为 threadthread.inheritParent 默认为 false
  • channels.slack.thread.initialHistoryLimit 控制新线程 session 启动时获取的历史消息数量(默认 20;设为 0 禁用)。

回复线程控制:

  • channels.slack.replyToModeoff|first|all|batched(默认 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 回复在主聊天流中仍然可见。

确认 Reaction

ackReaction 在 OpenClaw 处理入站消息时发送确认 emoji。

解析顺序:

  1. channels.slack.accounts.<accountId>.ackReaction
  2. channels.slack.ackReaction
  3. messages.ackReaction
  4. agent 身份 emoji 回退(agents.list[].identity.emoji,否则 "👀")

说明:

  • Slack 使用简码(如 "eyes")。
  • 使用 "" 可禁用该 Slack 账号或全局的 reaction。

文本流式输出

channels.slack.streaming 控制实时预览行为:

  • off:禁用实时预览流式输出。
  • partial(默认):用最新部分输出替换预览文本。
  • block:追加分块预览更新。
  • progress:生成时显示进度状态文本,完成后发送最终文本。

channels.slack.nativeStreaming 控制 Slack 原生文本流式输出(streamingpartial 时,默认 true)。

  • 原生文本流式输出需要可用的回复线程。线程选择仍遵循 replyToMode。没有线程时使用普通草稿预览。
  • 媒体和非文本负载回退到普通交付。
  • 流式输出中途失败时,OpenClaw 对剩余负载回退到普通交付。

使用草稿预览代替 Slack 原生文本流式输出:

json5
{
  channels: {
    slack: {
      streaming: "partial",
      nativeStreaming: false,
    },
  },
}

旧版 key:

  • channels.slack.streamModereplace | status_final | append)自动迁移到 channels.slack.streaming
  • 布尔值 channels.slack.streaming 自动迁移到 channels.slack.nativeStreaming

打字 Reaction 回退

typingReaction 在 OpenClaw 处理回复时向入站 Slack 消息添加临时 reaction,运行完成时移除。在线程回复之外最有用(线程回复默认显示 "is typing..." 状态指示器)。

解析顺序:

  1. channels.slack.accounts.<accountId>.typingReaction
  2. channels.slack.typingReaction

说明:

  • Slack 使用简码(如 "hourglass_flowing_sand")。
  • reaction 是尽力而为的,回复或失败路径完成后自动清理。

媒体、分块和交付

入站附件:Slack 文件附件从 Slack 托管的私有 URL 下载(Token 认证请求流),获取成功且在大小限制内时写入媒体存储。运行时入站大小上限默认 20MB,可通过 channels.slack.mediaMaxMb 覆盖。

出站文本和文件

  • 文本块使用 channels.slack.textChunkLimit(默认 4000)
  • channels.slack.chunkMode="newline" 启用段落优先分割
  • 文件发送使用 Slack upload API,可包含线程回复(thread_ts
  • 出站媒体上限遵循 channels.slack.mediaMaxMb(已配置时);否则频道发送使用媒体管道中的 MIME 类型默认值

交付目标

  • user:<id> 用于私信
  • channel:<id> 用于频道

命令和斜杠行为

  • Slack 的原生命令自动模式默认关闭commands.native: "auto" 不会启用 Slack 原生命令)。
  • channels.slack.commands.native: true(或全局 commands.native: true)启用原生 Slack 命令处理器。
  • 启用原生命令时,在 Slack 注册对应的斜杠命令,有一个例外:注册 /agentstatus 用于状态命令(Slack 保留了 /status)。
  • 如果不启用原生命令,可通过 channels.slack.slashCommand 配置单个斜杠命令。
  • 原生参数菜单根据选项数量自适应渲染策略:最多 5 个选项用按钮块,6-100 个选项用静态选择菜单,超过 100 个选项用带异步过滤的外部选择(需要 interactivity 选项处理器),编码后选项值超出 Slack 限制时回退到按钮。

默认斜杠命令配置:

  • enabled: false
  • name: "openclaw"
  • sessionPrefix: "slack:slash"
  • ephemeral: true

斜杠 session 使用隔离 key:agent:<agentId>:slack:slash:<userId>,但仍针对目标会话 session 路由命令执行。

交互式回复

Slack 可以渲染 agent 编写的交互式回复控件,但此功能默认禁用。

全局启用:

json5
{
  channels: {
    slack: {
      capabilities: {
        interactiveReplies: true,
      },
    },
  },
}

或仅对某个 Slack 账号启用:

json5
{
  channels: {
    slack: {
      accounts: {
        ops: {
          capabilities: {
            interactiveReplies: true,
          },
        },
      },
    },
  },
}

启用后,agent 可以发出 Slack 专用回复指令:

  • [[slack_buttons: 批准:approve, 拒绝:reject]]
  • [[slack_select: 选择目标 | 金丝雀:canary, 生产:production]]

这些指令会编译成 Slack Block Kit,通过现有的 Slack 交互事件路径路由点击或选择。

注意:

  • 这是 Slack 专用 UI,其他频道不会将 Slack Block Kit 指令翻译成自己的按钮系统。
  • 交互回调值是 OpenClaw 生成的不透明 token,不是 agent 编写的原始值。
  • 如果生成的交互块超出 Slack Block Kit 限制,OpenClaw 回退到原始文本回复。

Slack 中的执行审批

Slack 可作为原生审批客户端,使用交互式按钮,而不是回退到 Web UI 或终端。

  • 执行审批使用 channels.slack.execApprovals.* 进行原生 DM/频道路由。
  • 插件审批也可以通过相同的 Slack 原生按钮界面解决(当请求已经在 Slack 中且审批 id 类型为 plugin:)。
  • 审批者授权仍然强制执行:只有被标识为审批者的用户才能通过 Slack 批准或拒绝请求。

当 Slack App 设置中启用了 interactivity 时,审批提示直接在对话中渲染为 Block Kit 按钮。这些按钮存在时是主要审批 UX;只有当工具结果说明聊天审批不可用或手动审批是唯一路径时,才应包含手动 /approve 命令。

配置:

  • channels.slack.execApprovals.enabled
  • channels.slack.execApprovals.approvers(可选;无时回退到 commands.ownerAllowFrom
  • channels.slack.execApprovals.targetdm | channel | both,默认 dm
  • agentFiltersessionFilter

enabled 未设置或为 "auto" 且至少一个审批者解析成功时,Slack 自动启用原生执行审批。

默认行为(无显式 Slack 执行审批配置):

json5
{
  commands: {
    ownerAllowFrom: ["slack:U12345678"],
  },
}

只有需要覆盖审批者、添加过滤器或选择来源聊天交付时,才需要显式 Slack 原生配置:

json5
{
  channels: {
    slack: {
      execApprovals: {
        enabled: true,
        approvers: ["U12345678"],
        target: "both",
      },
    },
  },
}

事件和运行行为

  • 消息编辑/删除/线程广播映射为系统事件。
  • Reaction 添加/删除事件映射为系统事件。
  • 成员加入/离开、频道创建/重命名、pin 添加/删除事件映射为系统事件。
  • channel_id_changed 在启用 configWrites 时可迁移频道配置 key。
  • 频道话题/目的元数据视为不可信上下文,可注入路由上下文。
  • 线程起始者和初始线程历史上下文种子在适用时由配置的发送者白名单过滤。
  • Block actions 和 modal 交互触发结构化 Slack interaction: ... 系统事件,包含丰富的 payload 字段:block actions(选中值、标签、选择器值和 workflow_* 元数据);modal view_submissionview_closed 事件(含路由频道元数据和表单输入)。

故障排查

频道无回复

按顺序检查:

  1. groupPolicy
  2. 频道白名单(channels.slack.channels
  3. requireMention
  4. 每频道 users 白名单
bash
openclaw channels status --probe
openclaw logs --follow
openclaw doctor

DM 消息被忽略

检查:

  • channels.slack.dm.enabled
  • channels.slack.dmPolicy(或旧版 channels.slack.dm.policy
  • 配对审批 / 白名单条目
bash
openclaw pairing list slack

Socket Mode 无法连接

验证 bot token + app token 及 Slack App 设置中的 Socket Mode 启用状态。

如果 openclaw channels status --probe --json 显示 botTokenStatusappTokenStatus: "configured_unavailable",说明 Slack 账号已配置但当前运行时无法解析 SecretRef 后端的值。

HTTP 模式未收到事件

验证:

  • signing secret
  • webhook 路径
  • Slack Request URLs(Events + Interactivity + Slash Commands)
  • 每个 HTTP 账号使用唯一 webhookPath

如果账号快照中出现 signingSecretStatus: "configured_unavailable",说明 HTTP 账号已配置但当前运行时无法解析 SecretRef 后端的 signing secret。

原生/斜杠命令不触发

检查是否使用了正确的模式:

  • 原生命令模式(channels.slack.commands.native: true)+ 在 Slack 中注册对应斜杠命令
  • 或单斜杠命令模式(channels.slack.slashCommand.enabled: true

同时检查 commands.useAccessGroups 和频道/用户白名单。

常见问题

Q: Socket Mode 和 HTTP Request URLs 模式该选哪个?

A: 个人项目或公司内网环境推荐 Socket Mode,龙虾主动连接 Slack 不需要公网地址。HTTP 模式适合有公网可访问地址的服务器,Slack 会主动推事件过来,延迟更低,稳定性更好。

Q: 如何限制只有特定用户可以和龙虾在 Slack 里聊天?

A: 使用 dmPolicy: "allowlist" + allowFrom: ["U12345678", "U87654321"] 来白名单控制私信权限。频道内可以在 channels.slack.channels.<channelId>.users 里设置每频道用户白名单。

Q: 为什么频道里 @ 了龙虾没有响应?

A: 最常见的原因是 groupPolicy 设置为 allowlist 但该频道不在白名单里,或者 requireMention 设置但没有订阅 app_mention 事件。用 openclaw channels status --probeopenclaw logs --follow 来诊断。

相关链接