Skip to content

Groups

Moltbot 会在各消息表面上一致地处理群聊:WhatsApp、Telegram、Discord、Slack、Signal、iMessage、Microsoft Teams。

新手简介(2 分钟)

Moltbot “寄居”在你自己的消息账号上,并不存在一个独立的 WhatsApp bot 用户。 如果 在某个群里,Moltbot 就能看到该群并在那里回复。

默认行为:

  • 群是受限的(groupPolicy: "allowlist")。
  • 除非你显式关闭 mention gating,否则回复需要被提及(@)。

翻译一下:在 allowlist 里的发送者可以通过 @ 它来触发 Moltbot。

TL;DR

  • DM 访问控制:由 *.allowFrom 控制。
  • 群访问控制:由 *.groupPolicy + allowlists(*.groups*.groupAllowFrom)控制。
  • 是否触发回复:由 mention gating(requireMention/activation)控制。

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

groupPolicy? disabled -> 丢弃
groupPolicy? allowlist -> 群允许?否 -> 丢弃
requireMention? 是 -> 是否提及?否 -> 只存为上下文
否则 -> 回复

群消息流程

如果你想要……

目标需要设置
允许所有群,但只在 @mentions 时回复groups: { "*": { requireMention: true } }
禁用所有群回复groupPolicy: "disabled"
只允许特定群groups: { "<group-id>": { ... } }(不使用 "*"
只有你能在群里触发groupPolicy: "allowlist"groupAllowFrom: ["+1555..."]

Session keys

  • 群 session 使用 agent:<agentId>:<channel>:group:<id>(rooms/channels 使用 agent:<agentId>:<channel>:channel:<id>)。
  • Telegram forum topics 会在 group id 末尾加 :topic:<threadId>,使每个 topic 都有独立 session。
  • 私聊使用 main session(或按发送者隔离,如果已配置)。
  • 群 session 会跳过 heartbeats。

模式:个人私信 + 公共群(单 agent)

可以——如果你的“个人”流量主要是 私信(DMs),而“公共”流量主要是 群聊(groups),这种模式很好用。

原因:在单 agent 模式下,DM 通常落到 main session key(agent:main:main),而群总是使用 non-main session keys(agent:main:<channel>:group:<id>)。如果你启用 sandboxing 并设置 mode: "non-main",这些群 sessions 会在 Docker 中运行,而 main DM session 仍留在主机上。

这样你拥有一个共享 workspace + memory 的 agent “大脑”,但有两种执行姿态:

  • DMs:全工具(host)
  • Groups:sandbox + 受限工具(Docker)

如果你需要真正隔离的 workspaces/personas(“个人”和“公共”绝不能混),请用第二个 agent + bindings。参见 Multi-Agent Routing

示例(DMs 在 host,groups sandboxed + 仅消息相关 tools):

json5
{
  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"]
      }
    }
  }
}

想要“groups 只能看到文件夹 X”而不是“无 host 访问”?保持 workspaceAccess: "none" 并只把 allowlisted paths 挂载到 sandbox:

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

相关:

显示标签(Display labels)

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

群策略(Group policy)

按渠道控制群/房间消息如何处理:

json5
{
  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: ["user@org.com"]
    },
    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 }
      }
    }
  }
}
Policy行为
"open"群会绕过 allowlists;mention-gating 仍生效。
"disabled"完全阻止所有群消息。
"allowlist"只允许匹配配置 allowlist 的群/房间。

备注:

  • groupPolicy 与 mention-gating 是两条独立机制(后者要求 @mentions)。
  • WhatsApp/Telegram/Signal/iMessage/Microsoft Teams:使用 groupAllowFrom(fallback:显式 allowFrom)。
  • Discord:allowlist 使用 channels.discord.guilds.<id>.channels
  • Slack:allowlist 使用 channels.slack.channels
  • Matrix:allowlist 使用 channels.matrix.groups(room IDs、aliases 或 names)。用 channels.matrix.groupAllowFrom 限制发送者;也支持每 room 的 users allowlists。
  • Group DMs 单独控制(channels.discord.dm.*channels.slack.dm.*)。
  • Telegram allowlist 可匹配 user IDs("123456789""telegram:123456789""tg:123456789")或 usernames("@alice""alice");前缀不区分大小写。
  • 默认是 groupPolicy: "allowlist";如果 group allowlist 为空,则群消息会被阻止。

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

  1. groupPolicy(open/disabled/allowlist)
  2. group allowlists(*.groups*.groupAllowFrom、渠道特定 allowlist)
  3. mention gating(requireMention/activation

Mention gating(默认)

除非按群覆盖,否则群消息需要被提及。默认值按子系统存放在 *.groups."*" 下。

当渠道支持 reply 元数据时,“回复 bot 的消息”会被视为隐式提及。这适用于 Telegram、WhatsApp、Slack、Discord 与 Microsoft Teams。

json5
{
  channels: {
    whatsapp: {
      groups: {
        "*": { requireMention: true },
        "123@g.us": { requireMention: false }
      }
    },
    telegram: {
      groups: {
        "*": { requireMention: true },
        "123456789": { requireMention: false }
      }
    },
    imessage: {
      groups: {
        "*": { requireMention: true },
        "123": { requireMention: false }
      }
    }
  },
  agents: {
    list: [
      {
        id: "main",
        groupChat: {
          mentionPatterns: ["@clawd", "moltbot", "\\+15555550123"],
          historyLimit: 50
        }
      }
    ]
  }
}

备注:

  • mentionPatterns 是大小写不敏感的正则。
  • 有原生 mentions 的表面仍会通过;patterns 是兜底。
  • 按 agent 覆盖:agents.list[].groupChat.mentionPatterns(多个 agents 共享同一群时很有用)。
  • mention gating 只在可进行 mention 检测时才强制执行(原生 mentions 或配置了 mentionPatterns)。
  • Discord 默认值在 channels.discord.guilds."*"(可按 guild/channel 覆盖)。
  • 群历史上下文在各渠道间统一包装,并且是 pending-only(因 mention gating 而跳过的消息)。全局默认用 messages.groupChat.historyLimit,按渠道覆盖用 channels.<channel>.historyLimit(或 channels.<channel>.accounts.*.historyLimit)。设为 0 可禁用。

群/频道的工具限制(可选)

部分渠道配置支持在特定群/房间/频道内限制可用 tools:

  • tools:对整个群的 allow/deny。
  • toolsBySender:群内按发送者覆盖(keys 是 sender IDs/usernames/emails/phone numbers,取决于渠道)。用 "*" 作为通配符。

解析顺序(越具体越优先):

  1. 群/频道的 toolsBySender 命中
  2. 群/频道的 tools
  3. 默认("*"toolsBySender 命中
  4. 默认("*"tools

示例(Telegram):

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

备注:

  • 群/频道工具限制会叠加到全局/按 agent 的 tool policy 之上(deny 仍优先)。
  • 某些渠道对 rooms/channels 的嵌套层级不同(例如 Discord guilds.*.channels.*、Slack channels.*、MS Teams teams.*.channels.*)。

群 allowlists

当配置了 channels.whatsapp.groupschannels.telegram.groupschannels.imessage.groups 时,其 keys 充当群 allowlist。使用 "*" 可允许所有群,同时仍设置默认 mention 行为。

常见意图(复制/粘贴):

  1. 禁用所有群回复
json5
{
  channels: { whatsapp: { groupPolicy: "disabled" } }
}
  1. 只允许特定群(WhatsApp)
json5
{
  channels: {
    whatsapp: {
      groups: {
        "123@g.us": { requireMention: true },
        "456@g.us": { requireMention: false }
      }
    }
  }
}
  1. 允许所有群但要求 mention(显式)
json5
{
  channels: {
    whatsapp: {
      groups: { "*": { requireMention: true } }
    }
  }
}
  1. 只有 owner 能在群里触发(WhatsApp)
json5
{
  channels: {
    whatsapp: {
      groupPolicy: "allowlist",
      groupAllowFrom: ["+15551234567"],
      groups: { "*": { requireMention: true } }
    }
  }
}

Activation(仅 owner)

群 owner 可以切换按群激活:

  • /activation mention
  • /activation always

owner 由 channels.whatsapp.allowFrom 决定(未设置时用 bot 自身 E.164)。把命令作为独立消息发送。其他表面目前会忽略 /activation

Context 字段

群入站 payload 会设置:

  • ChatType=group
  • GroupSubject(若可用)
  • GroupMembers(若可用)
  • WasMentioned(mention gating 结果)
  • Telegram forum topics 还会包含 MessageThreadIdIsForum

agent 的 system prompt 会在新群 session 的第一回合包含一段群聊简介,提醒模型像人一样回复、避免 Markdown 表格、并避免输出字面量 \n 序列。

iMessage 细节

  • 路由或 allowlist 时优先使用 chat_id:<id>
  • 列出 chats:imsg chats --limit 20
  • 群回复总是回到同一个 chat_id

WhatsApp 细节

WhatsApp 专属行为(history injection、mention handling 细节)参见 Group messages