对于 OpenClaw iMessage 部署,请在已登录的 macOS Messages 主机上使用
imsg。如果你的 Gateway 运行在 Linux 或 Windows 上,请将 channels.imessage.cliPath 指向一个通过 SSH 在 Mac 上运行 imsg 的包装器。入站恢复是自动的。 在桥接或网关重启后,iMessage 会重放停机期间遗漏的消息,并抑制 Apple 在 Push 恢复后可能刷出的过时“积压炸弹”,通过去重确保不会重复分发任何内容。无需启用任何配置——请参见桥接或网关重启后的入站恢复。imsg rpc,并通过 stdio 上的 JSON-RPC 通信(没有单独的守护进程/端口)。高级操作需要 imsg launch 以及成功的私有 API 探测。
私有 API 操作
回复、tapback、效果、附件和群组管理。
配对
iMessage 私信默认使用配对模式。
远程 Mac
当 Gateway 不在 Messages 所在的 Mac 上运行时,请使用 SSH 包装器。
配置参考
iMessage 字段完整参考。
快速设置
要求和权限(macOS)
- Messages 必须在运行
imsg的 Mac 上已登录。 - 运行 OpenClaw/
imsg的进程上下文需要完全磁盘访问权限(用于访问 Messages 数据库)。 - 通过 Messages.app 发送消息需要自动化权限。
- 对于高级操作(react / edit / unsend / threaded reply / effects / group ops),必须禁用系统完整性保护(SIP)——见下方 启用 imsg 私有 API。基础文本和媒体收发在不禁用 SIP 的情况下也能工作。
SSH wrapper sends fail with AppleEvents -1743
SSH wrapper sends fail with AppleEvents -1743
远程 SSH 设置可以读取聊天、通过 检查已登录 Mac 用户的 TCC 数据库或“系统设置” > “隐私与安全性” > “自动化”。如果自动化条目记录在 在这种状态下,重复执行
channels status --probe,并处理入站消息,但外发发送仍会因 AppleEvents 授权错误而失败:/usr/libexec/sshd-keygen-wrapper 而不是 imsg 或本地 shell 进程上,macOS 可能不会为该 SSH 服务端客户端暴露可用的 Messages 开关:tccutil reset AppleEvents 或通过同一个 SSH 包装器重新运行 imsg send 可能仍会失败,因为需要 Messages Automation 的进程上下文是 SSH 包装器,而不是 UI 可以授予权限的某个应用。请改用受支持的 imsg 进程上下文之一:- 在已登录的 Messages 用户本地会话中运行 Gateway,或至少运行
imsgbridge。 - 在授予同一会话中的完全磁盘访问权限和自动化权限后,使用该用户的 LaunchAgent 启动 Gateway。
- 如果你保留双用户 SSH 拓扑,请在启用通道之前,验证一次真实的外发
imsg send是否能通过确切的包装器成功。如果无法授予 Automation,请改为单用户imsg设置,而不要依赖 SSH 包装器来发送消息。
启用 imsg 私有 API
imsg 提供两种运行模式:
- 基础模式(默认,不需要更改 SIP):通过
send发送外发文本和媒体、入站监控/历史、聊天列表。这就是在全新安装brew install steipete/tap/imsg并授予上面列出的标准 macOS 权限后可直接获得的能力。 - 私有 API 模式:
imsg会将一个 helper dylib 注入Messages.app,以调用内部IMCore函数。这会解锁react、edit、unsend、reply(线程式)、sendWithEffect、renameGroup、setGroupIcon、addParticipant、removeParticipant、leaveGroup,以及输入状态指示和已读回执。
imsg 的 README 明确说明了这一点:
诸如这种 helper 注入技术使用的是read、typing、launch、基于桥接的富发送、消息变更和聊天管理等高级功能都是可选的。它们需要禁用 SIP,并将一个 helper dylib 注入到Messages.app中。启用 SIP 时,imsg launch会拒绝注入。
imsg 自己的 dylib 来访问 Messages 的私有 API。在 OpenClaw 的 iMessage 路径中,没有第三方服务器或 BlueBubbles 运行时。
设置
-
在运行 Messages.app 的 Mac 上安装(或升级)
imsg:imsg status --json的输出会报告bridge_version、rpc_methods以及每个方法的selectors,这样你就能在开始之前看到当前构建支持哪些能力。 -
禁用系统完整性保护,并且(在现代 macOS 上)禁用 Library Validation。 将非 Apple 的 helper dylib 注入到 Apple 签名的
Messages.app需要关闭 SIP 并且放宽 library validation。Recovery 模式下的 SIP 步骤取决于 macOS 版本:- macOS 10.13-10.15(Sierra-Catalina): 通过 Terminal 禁用 Library Validation,重启进入 Recovery Mode,运行
csrutil disable,然后重启。 - macOS 11+(Big Sur 及更高版本),Intel: 进入 Recovery Mode(或 Internet Recovery),运行
csrutil disable,然后重启。 - macOS 11+,Apple Silicon: 使用电源键启动流程进入 Recovery;在较新的 macOS 版本上,点击 Continue 时按住 Left Shift 键,然后运行
csrutil disable。虚拟机环境遵循单独流程,因此请先拍摄 VM 快照。
csrutil disable通常还不够。 Apple 仍然会将Messages.app作为平台二进制文件执行 library validation,因此即使关闭 SIP,adhoc 签名的 helper 也会被拒绝(Library Validation failed: ... platform binary, but mapped file is not)。在禁用 SIP 之后,还要禁用 library validation 并重启:macOS 26(Tahoe),已在 26.5.1 上验证: 关闭 SIP 再加上上面的DisableLibraryValidation命令,就足以在 26.0 到 26.5.x 之间注入 helper。不需要 boot-args。 当注入失败时,plist 是决定性因素,也是 Tahoe 上最常见的遗漏步骤:- 有 plist:
imsg launch会注入,且imsg status会报告advanced_features: true。 - 没有 plist(即使关闭了 SIP):
imsg launch会失败并报出Failed to launch: Timeout waiting for Messages.app to initialize。AMFI 在加载时拒绝该 adhoc helper,因此 bridge 永远无法就绪,启动也会超时。这个超时是 Tahoe 上大多数人遇到的症状,修复方法就是上面的 plist,而不是采取更激进的措施。
Messages.app,bridge 会启动;移除 plist 并重启后,imsg launch会产生上面的超时失败,并且 dylib 不会被映射。 如果在 macOS 升级后,imsg launch注入或某些特定selectors开始返回 false,通常就是这个门槛导致的。在假设 SIP 步骤本身失败之前,请先检查你的 SIP 和 library-validation 状态。如果这些设置都正确,但 bridge 仍然无法注入,请收集imsg status --json和imsg launch的输出并反馈给imsg项目,而不是进一步削弱系统级安全控制。 在运行imsg launch之前,请按照 Apple 针对你的 Mac 的恢复模式流程禁用 SIP。 - macOS 10.13-10.15(Sierra-Catalina): 通过 Terminal 禁用 Library Validation,重启进入 Recovery Mode,运行
-
注入 helper。 在 SIP 已禁用且 Messages.app 已登录的情况下:
当 SIP 仍启用时,
imsg launch会拒绝注入,因此这也可作为第 2 步是否生效的确认。 -
从 OpenClaw 验证桥接:
iMessage 条目应报告为
works,并且imsg status --json | jq '.selectors'应显示retractMessagePart: true,以及你的 macOS 构建所暴露的编辑 / 输入状态 / 已读等选择器。OpenClaw 插件在actions.ts中按方法进行的能力门控,只会公开其底层 selector 为true的操作,因此你在代理工具列表中看到的动作范围,反映了该主机上的桥接实际能做什么。
openclaw channels status --probe 将该通道报告为 works,但在分发时某些特定操作抛出 “iMessage <action> requires the imsg private API bridge”,请再次运行 imsg launch——helper 可能会脱落(Messages.app 重启、系统更新等),而缓存的 available: true 状态会继续宣告这些操作,直到下一次探测刷新它为止。
当你无法禁用 SIP 时
如果你的威胁模型不接受禁用 SIP:imsg会回退到基础模式——仅文本 + 媒体 + 接收。- OpenClaw 插件仍会公开文本/媒体发送和入站监控;只是会根据按方法的能力门控,在动作面上隐藏
react、edit、unsend、reply、sendWithEffect和群组操作。 - 你可以在另一台非 Apple Silicon Mac(或一台专用 bot Mac)上关闭 SIP 来承担 iMessage 工作负载,同时在你的主设备上保持 SIP 启用。见下方 专用 bot macOS 用户(独立 iMessage 身份)。
访问控制和路由
- DM 策略
- 群组策略 + 提及
- 会话和确定性回复
channels.imessage.dmPolicy 控制私信:pairing(默认)allowlistopen(要求allowFrom包含"*")disabled
channels.imessage.allowFrom。Allowlist 条目必须标识发送者:handle 或静态发送者访问组(accessGroup:<name>)。针对诸如 chat_id:*、chat_guid:* 或 chat_identifier:* 之类的聊天目标,请使用 channels.imessage.groupAllowFrom;针对数字 chat_id 注册表键,请使用 channels.imessage.groups。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 可以使用:
- 规范化的 DM handle,例如
+15555550123或[email protected] chat_id:<id>(推荐用于稳定的群组绑定)chat_guid:<guid>chat_identifier:<identifier>
部署模式
专用 bot macOS 用户(独立 iMessage 身份)
专用 bot macOS 用户(独立 iMessage 身份)
使用专用 Apple ID 和 macOS 用户,这样 bot 流量就会与个人 Messages 配置文件隔离开来。典型流程:
- 创建/登录一个专用的 macOS 用户。
- 在该用户中使用 bot Apple ID 登录 Messages。
- 在该用户中安装
imsg。 - 创建 SSH 包装脚本,以便 OpenClaw 可以在该用户上下文中运行
imsg。 - 将
channels.imessage.accounts.<id>.cliPath和.dbPath指向该用户配置文件。
通过 Tailscale 连接远程 Mac(示例)
通过 Tailscale 连接远程 Mac(示例)
常见拓扑:使用 SSH 密钥,以便 SSH 和 SCP 都是非交互式的。
先确保主机密钥是受信任的(例如
- gateway 运行在 Linux/VM 上
- iMessage +
imsg运行在你 tailnet 中的一台 Mac 上 cliPath包装脚本使用 SSH 运行imsgremoteHost启用通过 SCP 拉取附件
ssh [email protected]),以便填充 known_hosts。多账号模式
多账号模式
iMessage 支持在
channels.imessage.accounts 下为每个账号进行配置。每个账号都可以覆盖诸如 cliPath、dbPath、allowFrom、groupPolicy、mediaMaxMb、历史设置以及附件根目录允许列表等字段。直接消息历史
直接消息历史
将
channels.imessage.dmHistoryLimit 设为一个值,可使用该会话最近解码过的 imsg 历史为新的直接消息会话播种。使用 channels.imessage.dms["<sender>"].historyLimit 可按发送者覆盖,包括设置为 0 以禁用该发送者的历史。iMessage DM 历史会按需从 imsg 获取。保持未设置 dmHistoryLimit 会禁用全局 DM 历史播种,但为某个发送者设置正值的 channels.imessage.dms["<sender>"].historyLimit 仍会为该发送者启用播种。媒体、分块和投递目标
附件和媒体
附件和媒体
- 入站附件摄取默认关闭——将
channels.imessage.includeAttachments: true设为开启后,才会把照片、语音备忘录、视频及其他附件转发给代理。若保持关闭,仅包含附件的 iMessage 会在到达代理之前被丢弃,并且可能根本不会生成任何Inbound message日志行。 - 当设置了
remoteHost时,可通过 SCP 拉取远程附件路径 - 附件路径必须匹配允许的根目录:
channels.imessage.attachmentRoots(本地)channels.imessage.remoteAttachmentRoots(远程 SCP 模式)- 默认根路径模式:
/Users/*/Library/Messages/Attachments
- SCP 使用严格的主机密钥检查(
StrictHostKeyChecking=yes) - 出站媒体大小使用
channels.imessage.mediaMaxMb(默认 16 MB)
出站分块
出站分块
- 文本分块限制:
channels.imessage.textChunkLimit(默认 4000) - 分块模式:
channels.imessage.chunkModelength(默认)newline(优先按段落拆分)
寻址格式
寻址格式
推荐的显式目标:
chat_id:123(推荐用于稳定路由)chat_guid:...chat_identifier:...
imessage:+1555...sms:+1555...[email protected]
私有 API 动作
当imsg launch 正在运行,并且 openclaw channels status --probe 报告 privateApi.available: true 时,消息工具除了正常文本发送之外,还可以使用 iMessage 原生动作。
可用动作
可用动作
- react:添加/移除 iMessage tapback(
messageId、emoji、remove)。支持的 tapback 映射到 love、like、dislike、laugh、emphasize 和 question。 - reply:对现有消息发送线程式回复(
messageId、text或message,以及chatGuid、chatId、chatIdentifier或to)。 - sendWithEffect:发送带有 iMessage 效果的文本(
text或message、effect或effectId)。 - edit:在支持的 macOS/私有 API 版本上编辑已发送消息(
messageId、text或newText)。 - unsend:在支持的 macOS/私有 API 版本上撤回已发送消息(
messageId)。 - upload-file:发送媒体/文件(
buffer为 base64,或已加载的media/path/filePath,filename,可选asVoice)。旧别名:sendAttachment。 - renameGroup、setGroupIcon、addParticipant、removeParticipant、leaveGroup:当当前目标是群聊时,管理群聊。
Message IDs
Message IDs
入站 iMessage 上下文在可用时会同时包含简短的
MessageSid 值和完整的消息 GUID。简短 ID 的作用域限定在最近的 SQLite 后端回复缓存中,并且在使用前会先检查当前聊天。如果简短 ID 已过期或属于其他聊天,请改用完整的 MessageSidFull 重试。能力检测
能力检测
只有当缓存的探测状态显示桥接不可用时,OpenClaw 才会隐藏私有 API 动作。如果状态未知,动作仍会显示,并且探测会延迟触发,因此在
imsg launch 之后,首个动作无需单独手动刷新状态也可能成功。已读回执和输入状态
已读回执和输入状态
当私有 API 桥接可用时,接受到的入站聊天会在分发前被标记为已读,并且在代理生成回复时会向发送者显示输入状态气泡。可通过以下方式禁用已读标记:早于按方法级别能力列表的旧版
imsg 构建会静默关闭输入状态/已读;OpenClaw 每次重启只会记录一次警告,因此缺失回执的原因可以追溯。入站 tapback
入站 tapback
OpenClaw 会订阅 iMessage tapback,并将接受到的反应作为系统事件路由,而不是普通消息文本,因此用户的 tapback 不会触发普通回复循环。通知模式由
channels.imessage.reactionNotifications 控制:"own"(默认):仅在用户对机器人生成的消息作出反应时通知。"all":对所有来自授权发送者的入站 tapback 通知。"off":忽略入站 tapback。
channels.imessage.accounts.<id>.reactionNotifications。审批反应(👍 / 👎)
审批反应(👍 / 👎)
当
approvals.exec.enabled 或 approvals.plugin.enabled 为 true 且请求路由到 iMessage 时,网关会原生投递批准请求并接受 tapback 来解决它:👍(Like tapback)→allow-once👎(Dislike tapback)→denyallow-always仍然是手动回退方式:作为普通回复发送/approve <id> allow-always。
channels.imessage.allowFrom(或 channels.imessage.accounts.<id>.allowFrom)读取;请添加用户的 E.164 格式电话号码或其 Apple ID 电子邮件。通配符条目 "*" 会被接受,但会允许任何发送者进行批准。该反应快捷方式会刻意绕过 reactionNotifications、dmPolicy 和 groupAllowFrom,因为显式审批人允许列表才是批准解析真正需要的唯一门槛。此版本的行为变化: 当 channels.imessage.allowFrom 非空时,/approve <id> <decision> 文本命令现在会依据该审批人列表进行授权(而不是更宽泛的 DM 允许列表)。虽然在 DM 允许列表中获准但不在 allowFrom 中的发送者将收到明确拒绝。请将所有应该能够通过 /approve(以及通过反应)进行批准的操作员添加到 allowFrom 中,以保留先前行为。当 allowFrom 为空时,旧的“同聊天回退”仍然生效,且 /approve 继续授权任何 DM 允许列表所允许的用户。操作员说明:- 该反应绑定会同时存储在内存中(TTL 与批准过期时间匹配)以及网关的持久键值存储中,因此在网关重启后不久到达的 tapback 仍可解析为该批准。
- 来自其他设备的
is_from_me=truetapback(操作者在已配对 Apple 设备上的自身反应)会被刻意忽略,因此机器人不能自我批准。 - 旧式文本风格 tapback(非常老旧 Apple 客户端发出的纯文本
Liked "…")无法解析批准,因为它们不携带消息 GUID;反应解析需要当前 macOS / iOS 客户端发出的结构化 tapback 元数据。
配置写入
iMessage 默认允许由频道发起的配置写入(用于/config set|unset,当 commands.config: true 时)。
禁用:
合并拆分发送的 DM(命令 + URL 在同一条输入中)
当用户把命令和 URL 一起输入时——例如Dump https://example.com/article——Apple 的 Messages 应用会把发送拆分成两条独立的 chat.db 记录:
- 一条文本消息(
"Dump")。 - 一条 URL 预览气泡(
"https://..."),并附带 OG 预览图片作为附件。
imsg 引入的行为。
channels.imessage.coalesceSameSenderDms 会将 DM 纳入对同一发送者连续行的缓冲。当 imsg 在某条源记录上暴露结构化的 URL 预览标记 balloon_bundle_id: "com.apple.messages.URLBalloonProvider" 时,OpenClaw 只合并那次真实的拆分发送,并保持其他缓冲记录作为独立轮次。在较旧、完全不输出 balloon 元数据的 imsg 版本上,OpenClaw 无法区分拆分发送和独立发送,因此会回退为合并整个缓冲桶。这样可以保留元数据引入前的行为,而不是把 Dump <url> 的拆分发送退化成两轮。群聊仍按每条消息分发,以保留多用户轮次结构。
- 何时启用
- 启用方式
- 取舍
在以下情况下启用:
- 你提供的技能期望在同一条消息里同时包含
command + payload(dump、paste、save、queue 等)。 - 你的用户会把 URL 和命令一起粘贴。
- 你可以接受额外的 DM 轮次延迟(见下文)。
- 你需要单词 DM 触发器的最低命令延迟。
- 所有流程都是不带后续负载的单次命令。
场景以及代理看到的内容
“启用标志”列显示的是在会输出balloon_bundle_id 的 imsg 构建版本上的行为。在更旧、完全不输出 balloon 元数据的 imsg 构建上,下方标记为“两轮”/“N 轮”的行会回退为旧式合并(1 轮):OpenClaw 无法从结构上区分拆分发送和独立发送,因此会保留元数据引入前的合并行为。只有当构建版本开始输出 balloon 元数据后,精确分离才会启用。
| 用户输入内容 | chat.db 产出 | 关闭标志(默认) | 启用标志 + 窗口(imsg 输出 balloon 元数据) |
|---|---|---|---|
Dump https://example.com(一次发送) | 约 1 秒内产生 2 行 | 两轮代理交互:先单独收到 “Dump”,再收到 URL | 一轮:合并后的文本 Dump https://example.com |
Save this 📎image.jpg caption(附件 + 文本) | 2 行,且没有 URL balloon 元数据 | 两轮 | 两轮(在无元数据构建上采用旧式合并) |
/status(独立命令) | 1 行 | 立即分发 | 最多等待一个窗口,然后分发 |
| 单独粘贴的 URL | 1 行 | 立即分发 | 最多等待一个窗口,然后分发 |
| 文本 + URL 被刻意拆成两条独立消息发送,且相隔几分钟 | 窗口外的 2 行 | 两轮 | 两轮(窗口在它们之间过期) |
| 在窗口内快速突发发送超过 10 条小 DM | 2 行,没有 URL balloon 元数据 | N 轮 | N 轮(在无元数据构建上采用旧式合并) |
| 群聊里有两个人同时输入 | 来自 M 个发送者的 N 行 | M+ 轮(每个发送者桶一轮) | M+ 轮——群聊不会被合并 |
桥接器或网关重启后的入站恢复
iMessage 会恢复网关停机期间遗漏的消息,同时抑制 Apple 在 Push 恢复后可能一次性刷出的陈旧“积压爆发”。默认行为始终开启,建立在入站去重之上。- 重放去重。 每条已分发的入站消息都会通过其 Apple GUID 记录到持久化插件状态(
imessage.inbound-dedupe)中,在接收时认领,并在处理完成后提交(若发生临时失败则释放,以便重试)。任何已经处理过的内容都会被丢弃,而不会重复分发。这使得恢复可以激进地重放,而无需逐条记录状态。 - 停机恢复。 启动时,监控会记住最后一次分发的
chat.db行号(每个账户持久化的游标),并将其作为since_rowid传给imsg watch.subscribe,这样imsg就会重放网关停机期间到达的那些行,然后继续追踪实时流。重放范围限制在最近的若干行以及约 2 小时内的消息,去重机制会丢弃任何已经处理过的内容。 - 陈旧积压年龄防线。 启动边界之上的行是真正实时的;其中发送时间比到达时间早超过约 15 分钟的,则是 Push 刷出的积压消息,会被抑制。重放的行(处于边界之上或之下)则使用更宽的恢复窗口,因此最近遗漏的消息会被投递,而更早的历史消息不会。
cliPath,因为 since_rowid 重放通过同一个 imsg RPC 连接运行。区别在于窗口:当网关能够读取 chat.db(本地)时,它会锚定启动时的行号边界,限制重放跨度,并投递最多几小时前遗漏的消息;通过远程 SSH cliPath 时则无法读取数据库,因此重放不设上限,所有行都使用实时年龄防线——它仍会恢复最近遗漏的消息,也仍会抑制旧积压,只是使用更窄的实时窗口。要获得更宽的恢复窗口,请在 Messages 所在的 Mac 上运行网关。
运维可见信号
被抑制的积压会按默认级别记录日志,不会静默丢弃(recovery 标志会显示当前使用了哪个窗口):
迁移
channels.imessage.catchup.* 已弃用——现在停机恢复已自动开启,新配置无需任何设置。现有配置中 catchup.enabled: true 仍会作为兼容性配置文件,保留用于恢复重放窗口。已禁用的 catchup 块(enabled: false 或未设置 enabled: true)已退役;openclaw doctor --fix 会将其移除。
故障排查
未找到 imsg 或不支持 RPC
未找到 imsg 或不支持 RPC
验证二进制文件和 RPC 支持:如果探测报告不支持 RPC,请更新
imsg。如果私有 API 操作不可用,请在已登录的 macOS 用户会话中运行 imsg launch,然后再次探测。如果 Gateway 没有在 macOS 上运行,请改用上面的通过 SSH 连接远程 Mac 的设置,而不是默认的本地 imsg 路径。Gateway 未在 macOS 上运行
Gateway 未在 macOS 上运行
默认的 然后运行:
cliPath: "imsg" 必须在登录到 Messages 的 Mac 上运行。在 Linux 或 Windows 上,将 channels.imessage.cliPath 设置为一个包装脚本,通过 SSH 连接到那台 Mac 并运行 imsg "$@"。DM 被忽略
DM 被忽略
检查:
channels.imessage.dmPolicychannels.imessage.allowFrom- 配对批准(
openclaw pairing list imessage)
群消息被忽略
群消息被忽略
检查:
channels.imessage.groupPolicychannels.imessage.groupAllowFromchannels.imessage.groups白名单行为- 提及模式配置(
agents.list[].groupChat.mentionPatterns)
远程附件失败
远程附件失败
检查:
channels.imessage.remoteHostchannels.imessage.remoteAttachmentRoots- 网关主机上的 SSH/SCP 密钥认证
- 网关主机的
~/.ssh/known_hosts中是否存在主机密钥 - 运行 Messages 的 Mac 上远程路径是否可读
macOS 权限提示被错过
macOS 权限提示被错过
在相同用户/会话上下文中的交互式 GUI 终端里重新运行并批准提示:确认运行 OpenClaw/
imsg 的进程上下文已授予完全磁盘访问和自动化权限。配置参考指针
相关内容
- 通道概览 — 所有受支持的通道
- BlueBubbles 移除与 imsg iMessage 路径 — 公告与迁移摘要
- 从 BlueBubbles 迁移过来 — 配置转换表与逐步切换
- 配对 — DM 认证与配对流程
- 群组 — 群聊行为与提及门控
- 通道路由 — 消息会话路由
- 安全性 — 访问模型与加固