群组

OpenClaw 在各个平台上对群聊的处理方式是一致的:WhatsApp、Telegram、Discord、Slack、Signal、iMessage、Microsoft Teams。

新手入门(2 分钟)

OpenClaw “运行”在你自己的消息账号上。不存在单独的 WhatsApp 机器人用户。 如果在一个群组里,OpenClaw 就能看到这个群组并在里面回复。

默认行为:

  • 群组是受限的(groupPolicy: "allowlist")。
  • 回复需要提及(mention),除非你明确禁用提及门控。

翻译一下:白名单中的发送者可以通过提及 OpenClaw 来触发它。

TL;DR

  • DM 访问*.allowFrom 控制。
  • 群组访问*.groupPolicy + 白名单(*.groups*.groupAllowFrom)控制。
  • 回复触发由提及门控(requireMention/activation)控制。

快速流程(群组消息会发生什么):

groupPolicy? disabled -> 丢弃
groupPolicy? allowlist -> 群组允许? no -> 丢弃
requireMention? yes -> 被提及? no -> 仅存储为上下文
otherwise -> 回复

群组消息流程

如果你想…

目标要设置什么
允许所有群组但只在 @提及时回复groups: { "*": { requireMention: true } }
禁用所有群组回复groupPolicy: "disabled"
只允许特定群组groups: { "<group-id>": { ... } } (没有 "*" 键)
只有你能在群组中触发groupPolicy: "allowlist", groupAllowFrom: ["+1555..."]

Session 键

  • 群组 Session 使用 agent:<agentId>:<channel>:group:<id> Session 键(房间/频道使用 agent:<agentId>:<channel>:channel:<id>)。
  • Telegram 论坛主题会在群组 id 后添加 :topic:<threadId>,这样每个主题都有自己的 Session。
  • 私聊使用主 Session(或按发送者配置的 Session)。
  • 群组 Session 会跳过 Heartbeat。

模式:个人 DM + 公共群组(单 Agent)

可以 — 如果你的”个人”流量是 DM,“公共”流量是群组,这种方式效果很好。

为什么:在单 Agent 模式下,DM 通常落在 Session 键(agent:main:main)中,而群组总是使用非主 Session 键(agent:main:<channel>:group:<id>)。如果你启用 mode: "non-main" 的沙箱,这些群组 Session 会在 Docker 中运行,而你的主 DM Session 保持在宿主机上。

这给你一个 Agent “大脑”(共享 Workspace + 内存),但两种执行姿态:

  • DM:完整工具(宿主机)
  • 群组:Sandbox + 受限工具(Docker)

如果你需要真正独立的 Workspace/角色(“个人”和”公共”绝不能混合),使用第二个 Agent + 绑定。参见 Multi-Agent Routing

示例(DM 在宿主机,群组沙箱化 + 仅消息工具):

{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main", // groups/channels are non-main -> sandboxed
        scope: "session", // strongest isolation (one container per group/channel)
        workspaceAccess: "none",
      },
    },
  },
  tools: {
    sandbox: {
      tools: {
        // If allow is non-empty, everything else is blocked (deny still wins).
        allow: ["group:messaging", "group:sessions"],
        deny: ["group:runtime", "group:fs", "group:ui", "nodes", "cron", "gateway"],
      },
    },
  },
}

想要”群组只能看到文件夹 X”而不是”无宿主机访问”?保持 workspaceAccess: "none" 并只挂载白名单路径到 Sandbox:

{
  agents: {
    defaults: {
      sandbox: {
        mode: "non-main",
        scope: "session",
        workspaceAccess: "none",
        docker: {
          binds: [
            // hostPath:containerPath:mode
            "~/FriendsShared:/data:ro",
          ],
        },
      },
    },
  },
}

相关:

显示标签

  • UI 标签在可用时使用 displayName,格式为 <channel>:<token>
  • #room 保留给房间/频道;群聊使用 g-<slug>(小写,空格 -> -,保留 #@+._-)。

群组策略

控制每个 Channel 如何处理群组/房间消息:

{
  channels: {
    whatsapp: {
      groupPolicy: "disabled", // "open" | "disabled" | "allowlist"
      groupAllowFrom: ["+15551234567"],
    },
    telegram: {
      groupPolicy: "disabled",
      groupAllowFrom: ["123456789", "@username"],
    },
    signal: {
      groupPolicy: "disabled",
      groupAllowFrom: ["+15551234567"],
    },
    imessage: {
      groupPolicy: "disabled",
      groupAllowFrom: ["chat_id:123"],
    },
    msteams: {
      groupPolicy: "disabled",
      groupAllowFrom: ["[email protected]"],
    },
    discord: {
      groupPolicy: "allowlist",
      guilds: {
        GUILD_ID: { channels: { help: { allow: true } } },
      },
    },
    slack: {
      groupPolicy: "allowlist",
      channels: { "#general": { allow: true } },
    },
    matrix: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["@owner:example.org"],
      groups: {
        "!roomId:example.org": { allow: true },
        "#alias:example.org": { allow: true },
      },
    },
  },
}
策略行为
"open"群组绕过白名单;提及门控仍然适用。
"disabled"完全阻止所有群组消息。
"allowlist"只允许匹配配置白名单的群组/房间。

注意:

  • groupPolicy 与提及门控(需要 @提及)是分开的。
  • WhatsApp/Telegram/Signal/iMessage/Microsoft Teams:使用 groupAllowFrom(回退:显式 allowFrom)。
  • Discord:白名单使用 channels.discord.guilds.<id>.channels
  • Slack:白名单使用 channels.slack.channels
  • Matrix:白名单使用 channels.matrix.groups(房间 ID、别名或名称)。使用 channels.matrix.groupAllowFrom 限制发送者;也支持每个房间的 users 白名单。
  • 群组 DM 单独控制(channels.discord.dm.*channels.slack.dm.*)。
  • Telegram 白名单可以匹配用户 ID("123456789""telegram:123456789""tg:123456789")或用户名("@alice""alice");前缀不区分大小写。
  • 默认是 groupPolicy: "allowlist";如果你的群组白名单为空,群组消息会被阻止。

快速心智模型(群组消息的评估顺序):

  1. groupPolicy(open/disabled/allowlist)
  2. 群组白名单(*.groups*.groupAllowFrom、Channel 特定白名单)
  3. 提及门控(requireMention/activation

提及门控(默认)

群组消息需要提及,除非按群组覆盖。默认值位于 *.groups."*" 下的每个子系统中。

回复机器人消息算作隐式提及(当 Channel 支持回复元数据时)。这适用于 Telegram、WhatsApp、Slack、Discord 和 Microsoft Teams。

{
  channels: {
    whatsapp: {
      groups: {
        "*": { requireMention: true },
        "[email protected]": { requireMention: false },
      },
    },
    telegram: {
      groups: {
        "*": { requireMention: true },
        "123456789": { requireMention: false },
      },
    },
    imessage: {
      groups: {
        "*": { requireMention: true },
        "123": { requireMention: false },
      },
    },
  },
  agents: {
    list: [
      {
        id: "main",
        groupChat: {
          mentionPatterns: ["@openclaw", "openclaw", "\\+15555550123"],
          historyLimit: 50,
        },
      },
    ],
  },
}

注意:

  • mentionPatterns 是不区分大小写的正则表达式。
  • 提供显式提及的平台仍然通过;模式是回退方案。
  • 每个 Agent 覆盖:agents.list[].groupChat.mentionPatterns(当多个 Agent 共享一个群组时很有用)。
  • 只有在提及检测可能时才强制执行提及门控(原生提及或配置了 mentionPatterns)。
  • Discord 默认值位于 channels.discord.guilds."*" 中(可按 guild/channel 覆盖)。
  • 群组历史上下文在各个 Channel 中统一包装,并且是仅待处理(由于提及门控而跳过的消息);使用 messages.groupChat.historyLimit 作为全局默认值,使用 channels.<channel>.historyLimit(或 channels.<channel>.accounts.*.historyLimit)进行覆盖。设置 0 以禁用。

群组/Channel 工具限制(可选)

某些 Channel 配置支持限制特定群组/房间/频道内可用的工具。

  • tools:允许/拒绝整个群组的工具。
  • toolsBySender:群组内按发送者覆盖(键是发送者 ID/用户名/电子邮件/电话号码,取决于 Channel)。使用 "*" 作为通配符。

解析顺序(最具体的获胜):

  1. 群组/Channel toolsBySender 匹配
  2. 群组/Channel tools
  3. 默认("*"toolsBySender 匹配
  4. 默认("*"tools

示例(Telegram):

{
  channels: {
    telegram: {
      groups: {
        "*": { tools: { deny: ["exec"] } },
        "-1001234567890": {
          tools: { deny: ["exec", "read", "write"] },
          toolsBySender: {
            "123456789": { alsoAllow: ["exec"] },
          },
        },
      },
    },
  },
}

注意:

  • 群组/Channel 工具限制是在全局/Agent 工具策略之外应用的(deny 仍然获胜)。
  • 某些 Channel 对房间/频道使用不同的嵌套(例如,Discord guilds.*.channels.*、Slack channels.*、MS Teams teams.*.channels.*)。

群组白名单

当配置了 channels.whatsapp.groupschannels.telegram.groupschannels.imessage.groups 时,键充当群组白名单。使用 "*" 允许所有群组,同时仍设置默认提及行为。

常见意图(复制粘贴):

  1. 禁用所有群组回复
{
  channels: { whatsapp: { groupPolicy: "disabled" } },
}
  1. 只允许特定群组(WhatsApp)
{
  channels: {
    whatsapp: {
      groups: {
        "[email protected]": { requireMention: true },
        "[email protected]": { requireMention: false },
      },
    },
  },
}
  1. 允许所有群组但需要提及(显式)
{
  channels: {
    whatsapp: {
      groups: { "*": { requireMention: true } },
    },
  },
}
  1. 只有所有者可以在群组中触发(WhatsApp)
{
  channels: {
    whatsapp: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
      groups: { "*": { requireMention: true } },
    },
  },
}

激活(仅所有者)

群组所有者可以切换每个群组的激活:

  • /activation mention
  • /activation always

所有者由 channels.whatsapp.allowFrom 确定(或未设置时使用机器人自己的 E.164)。将命令作为独立消息发送。其他平台目前忽略 /activation

Context 字段

群组入站 payload 设置:

  • ChatType=group
  • GroupSubject(如果已知)
  • GroupMembers(如果已知)
  • WasMentioned(提及门控结果)
  • Telegram 论坛主题还包括 MessageThreadIdIsForum

Agent 系统 Prompt 在新群组 Session 的第一轮中包含群组介绍。它提醒模型像人类一样回应,避免 Markdown 表格,并避免输入字面的 \n 序列。

iMessage 特定

  • 路由或白名单时优先使用 chat_id:<id>
  • 列出聊天:imsg chats --limit 20
  • 群组回复总是返回到相同的 chat_id

WhatsApp 特定

参见 群组消息 了解 WhatsApp 专属行为(历史注入、提及处理详情)。