访问控制
谁会被允许接入,消息如何路由到会话,以及哪些聊天可以写入配置。
访问控制与路由¶
channels.imessage.dmPolicy 控制私信:
pairing(默认)allowlist(至少需要一个allowFrom条目)open(要求allowFrom包含"*")disabled
允许列表字段:channels.imessage.allowFrom。
允许列表条目必须标识发送者:句柄或静态发送者访问组(accessGroup:<name>)。对于聊天目标,例如 chat_id:*、chat_guid:* 或 chat_identifier:*,请使用 channels.imessage.groupAllowFrom;对于数字 chat_id 注册表键,请使用 channels.imessage.groups。
`channels.imessage.groupPolicy` 控制群组处理:
- `allowlist`(默认)
- `open`
- `disabled`
群组发送者允许列表:`channels.imessage.groupAllowFrom`。
`groupAllowFrom` 条目也可以引用静态发送者访问组(`accessGroup:<name>`)。
运行时回退:如果未设置 `groupAllowFrom`,iMessage 群组发送者检查会使用 `allowFrom`;当私信和群组准入应不同时,请设置 `groupAllowFrom`。显式空值 `groupAllowFrom: []` 不会回退——在 `allowlist` 下它会阻止所有群组发送者。
运行时说明:如果 `channels.imessage` 完全缺失,运行时将回退到 `groupPolicy="allowlist"` 并记录警告(即使已设置 `channels.defaults.groupPolicy`)。
Warning
在 groupPolicy: "allowlist" 下,群组路由会连续执行两个关卡:
- 发送者允许列表(
channels.imessage.groupAllowFrom)——句柄、accessGroup:<name>、chat_guid、chat_identifier或chat_id。空的有效列表(没有groupAllowFrom,也没有allowFrom回退)会阻止所有群组发送者。 - 群组注册表(
channels.imessage.groups)——一旦映射中存在条目即强制执行:聊天必须匹配显式的按chat_id条目,或groups: { "*": { ... } }通配符。当groups为空或缺失时,仅由发送者允许列表决定准入。
如果未配置有效的群组发送者允许列表,所有群组消息都会在注册表关卡之前被丢弃。每个关卡在默认日志级别下都有自己的 warn 级别信号,并且各自指明不同的修复方式:
- 启动时每个账号一次性出现,当有效的群组发送者允许列表为空时:
imessage: groupPolicy="allowlist" for account "<id>" but no group sender allowlist is configured ...—— 通过设置channels.imessage.groupAllowFrom(或allowFrom)修复;仅添加groups条目仍会让关卡 1 阻止所有发送者。 - 运行时每个
chat_id一次性出现,当发送者通过了关卡 1,但该聊天缺失于已填充的groups注册表时:imessage: dropping group message from chat_id=<id> ...—— 通过将该chat_id(或"*")添加到channels.imessage.groups下修复。
私信不受影响——它们走不同的代码路径。
在 groupPolicy: "allowlist" 下,群组流程的推荐配置:
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: { "*": { "requireMention": true } },
},
},
}
仅 groupAllowFrom 即可允许这些发送者在任意群组中接入;添加 groups 块可限定允许哪些聊天(并设置每个聊天的选项,例如 requireMention)。
群组的提及门控:
- iMessage 没有原生的提及元数据
- 提及检测使用
agents.entries.*.groupChat.mentionPatterns,然后是messages.groupChat.mentionPatterns;当两者都未设置时,模式会从被路由代理的identity.name和identity.emoji派生 - 群组默认要求提及,即使未显式配置模式;因此,允许列表中的发送者消息可能会被跳过,除非其中包含代理的名称或表情符号
- 在所选代理或全局级别显式设置
mentionPatterns: []会抑制基于身份派生的模式;当没有可用模式时,iMessage 无法执行提及门控 - 来自授权发送者的控制命令会绕过提及门控
要处理某个群组中来自允许发送者的所有消息,请将该聊天的 requireMention 设置为 false:
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123", "+15555550124"],
groups: {
"*": {},
"123": { requireMention: false },
},
},
},
}
将 123 替换为 imsg chats --limit 20 --json 中的数字聊天 ID。编辑已经提供该账号群组策略的映射:channels.imessage.groups,或者当它覆盖根映射时使用 channels.imessage.accounts.<account-id>.groups。这也适用于 accounts.default.groups;仅仅存在一个账号条目并不意味着需要它自己的 groups 映射。只有当最多配置了一个账号时,空的账号映射才会继承根映射。
要仅允许在由 OpenClaw 启动的原生回复线程中进行未提及的后续消息,请在该群组条目中将 requireMentionInBotThreads: false 与 requireMention: true 一起设置。精确的群组设置会覆盖 groups["*"].requireMentionInBotThreads。将其设置为 true 可在这些线程中要求提及,或省略它以保留正常的提及行为。发送者和群组限制仍然适用。
当提及模式被禁用时,显式的 requireMentionInBotThreads: true 仍会强制执行。配置可用的提及模式以在这些线程中提及机器人;否则,除了授权的控制命令外,它们将保持静默。
线程所有权来自原生线程根 GUID 和 OpenClaw 的按账号和会话范围的已发送消息缓存。该缓存最多保留 2,000 条消息,持续六小时,并可在该时间窗口内重启后保留。未知或被清除的根仍保持正常的提及要求。在别人的线程中回复机器人消息不会使该线程成为机器人所有。
Preserve the existing wildcard and every per-group setting, changing only the target chat's requireMention. Account maps replace the whole inherited map, so if you intentionally create an account-specific override, first copy the complete inherited map, including all wildcard and per-group policies. When no map previously applied, "*": {} preserves admission to other groups while keeping their default mention requirement. Keep a restricted map restricted. groupAllowFrom still controls sender access.
保留现有的通配符以及每个分组的设置,仅修改目标聊天的 `requireMention`。账户映射会替换整个继承的映射,因此如果你有意创建账户特定的覆盖,请先复制完整的继承映射,包括所有通配符和分组策略。如果之前没有应用任何映射,`"*": {}` 会保留对其他分组的准入,同时保持它们的默认提及要求。保持受限映射的受限状态。`groupAllowFrom` 仍然控制发送者访问。
一条未提及而被跳过的消息会在默认日志级别产生警告,其中包含聊天 ID 以及 `requireMention: false` 修复建议。同一聊天的重复警告会被一个有界的内存缓存抑制;重启通道或驱逐缓存条目后,警告会再次出现。
分组级 `systemPrompt`:
`channels.imessage.groups.*` 下的每个条目都接受一个可选的 `systemPrompt` 字符串,它会被注入到代理的系统提示中,用于处理该分组中消息的每一轮。解析方式与 `channels.whatsapp.groups` 相同:
1. **分组特定系统提示**(`groups["<chat_id>"].systemPrompt`):当映射中存在该特定分组条目 **且** 定义了其 `systemPrompt` 键时使用。如果 `systemPrompt` 是空字符串(`""`),则通配符被抑制,并且不会向该分组应用任何系统提示。
2. **分组通配符系统提示**(`groups["*"].systemPrompt`):当映射中完全不存在该特定分组条目,或者条目存在但未定义 `systemPrompt` 键时使用。
```json5
{
channels: {
imessage: {
groupPolicy: "allowlist",
groupAllowFrom: ["+15555550123"],
groups: {
"*": { systemPrompt: "Use British spelling." },
"8421": {
requireMention: true,
systemPrompt: "This is the on-call rotation chat. Keep replies under 3 sentences.",
},
"9907": {
// explicit suppression: the wildcard "Use British spelling." does not apply here
systemPrompt: "",
},
},
},
},
}
```
分组级提示仅适用于分组消息——直接消息不受影响。
- 直接消息使用直接路由;分组使用分组路由。
- 在默认
session.dmScope=main下,iMessage 直接消息会合并到代理主会话中。 - 分组会话是隔离的(
agent:<agentId>:imessage:group:<chat_id>)。 - 回复会使用来源通道/目标元数据路由回 iMessage。
类分组线程行为:
一些多参与者 iMessage 线程可能以 is_group=false 到达。
如果该 chat_id 已在 channels.imessage.groups 下显式配置,OpenClaw 会将其视为分组流量(分组门控 + 分组会话隔离)。
ACP 会话绑定¶
iMessage 聊天可以绑定到 ACP 会话。
快速操作员流程:
- 在直接消息或允许的分组聊天中运行
/acp spawn codex --bind here。 - 该同一 iMessage 对话中的后续消息会路由到已生成的 ACP 会话。
/new和/reset会就地重置同一个已绑定的 ACP 会话。/acp close会关闭 ACP 会话并移除绑定。
已配置的持久绑定使用顶层 bindings[] 条目,其中 type: "acp" 且 match.channel: "imessage"。
match.peer.id 可以使用:
- 规范化后的直接消息句柄,例如
+15555550123或user@example.com chat_id:<id>(推荐用于稳定的分组绑定)chat_guid:<guid>chat_identifier:<identifier>
示例:
{
agents: {
entries: {
codex: {
default: true,
runtime: {
type: "acp",
acp: { agent: "codex", backend: "acpx", mode: "persistent" },
},
},
},
},
bindings: [
{
type: "acp",
agentId: "codex",
match: {
channel: "imessage",
accountId: "default",
peer: { kind: "group", id: "chat_id:123" },
},
acp: { label: "codex-group" },
},
],
}
请参阅 ACP Agents 了解共享的 ACP 绑定行为。
配置写入¶
iMessage 默认允许通道发起的配置写入(当 commands.config: true 时,用于 /config set|unset)。
禁用:
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw