zca-js、在进程内、且无需外部 CLI 二进制文件来自动化一个 Zalo 个人账号。
安装
Zalo Personal 是一个官方外部插件,不包含在核心中。请先安装后再使用:- 固定版本:
openclaw plugins install @openclaw/zalouser@<version> - 从源代码检出安装:
openclaw plugins install ./path/to/local/zalouser-plugin - 详情:插件。
快速设置
- 安装插件(见上文)。
- 登录(QR,在 Gateway 机器上):
openclaw channels login --channel zalouser- 使用 Zalo 手机应用扫描二维码。
- 启用该通道:
- 重启 Gateway(或完成设置)。
- DM 访问默认是 pairing;首次联系时请在配对码上批准。
它是什么
- 完全通过
zca-js库在进程内运行(不需要外部zca/openzca二进制文件)。 - 使用原生事件监听器(
message、error)接收传入消息。 - 直接通过 JS API 发送回复(文本/媒体/链接)。
- 面向“个人账号”使用场景设计,在这些场景中无法使用 Zalo Bot API。
命名
Channel id 是zalouser,以明确表示这会自动化一个个人 Zalo 用户账号(非官方)。zalo 保留给未来可能的官方 Zalo API 集成。
查找 ID(目录)
限制
- 出站文本按 2000 个字符分块(Zalo 客户端限制)。
- 不支持流式传输。
- 已完成的入站消息 ID 保留 30 天,每个账户最多保留最近的 1000 条记录。
入站持久性
OpenClaw 会在处理每个原始zca-js 消息回调之前先将其存储起来。待处理消息会在 Gateway 重启后从账户队列中恢复,并且对于每个私聊或群聊,处理过程都会保持串行化。
zca-js 套接字监听器不会提供投递确认,也不会在重新连接后自动重放旧消息。因此,持久化队列保护的是回调到达 OpenClaw 之后的本地崩溃窗口;对于套接字从未投递到的消息,它无法进行恢复。重放墓碑记录主要用于防止同一条 Zalo 消息 ID 的重复回调。
访问控制(私信)
channels.zalouser.dmPolicy:pairing | allowlist | open | disabled(默认:pairing)。
channels.zalouser.allowFrom 应使用稳定的 Zalo 用户 ID。它也可以引用静态发送者访问组(accessGroup:<name>)。在交互式设置期间,输入的名称可以通过插件的进程内联系人查找解析为 ID。
如果原始名称仍保留在配置中,仅当启用 channels.zalouser.dangerouslyAllowNameMatching: true 时,启动才会解析它。若不启用该选项,运行时发送者检查仅基于 ID,原始名称会被忽略,不用于授权。
通过以下方式批准:
openclaw pairing list zalouseropenclaw pairing approve zalouser <code>
群组访问(可选)
- 默认:
channels.zalouser.groupPolicy = "allowlist"(群组需要显式的 allowlist 条目)。 - 打开所有群组:
channels.zalouser.groupPolicy = "open"。 - 屏蔽所有群组:
channels.zalouser.groupPolicy = "disabled"。 - 当
groupPolicy = "allowlist"时:channels.zalouser.groups的键应为稳定的群组 ID;仅当启用channels.zalouser.dangerouslyAllowNameMatching: true时,名称才会在启动时解析为 ID。channels.zalouser.groupAllowFrom控制允许的群组中哪些发送者可以触发机器人;静态发送者访问组可通过accessGroup:<name>引用。
- 配置向导可以提示输入群组 allowlist。
- 群组 allowlist 的匹配默认仅按 ID 进行。除非启用
channels.zalouser.dangerouslyAllowNameMatching: true,否则无法解析的名称会在认证时被忽略。 channels.zalouser.dangerouslyAllowNameMatching: true是一种破窗兼容模式,会重新启用可变的启动时名称解析和运行时群组名匹配。- 对于普通群组消息,
groupAllowFrom不会 回退到allowFrom:如果在一个已列入 allowlist 的群组中将其留空,则该群组对任意发送者开放。已授权的控制命令(例如/new)是例外;当groupAllowFrom为空时,命令发送者检查会回退到allowFrom。
channels.zalouser.groups.<id>.allow 是一个旧字段名;当前配置使用 enabled。openclaw doctor --fix 会自动将 allow 迁移为 enabled。群组提及门控
channels.zalouser.groups.<group>.requireMention控制群组回复是否需要提及。- 解析顺序:group id ->
group:<id>别名 -> 群组名称/slug(基于名称的候选项仅在dangerouslyAllowNameMatching: true时适用)->*-> 默认值(true)。 - 同时适用于 allowlist 群组和开放群组模式。
- 引用机器人的消息会被视为对群组激活的隐式提及。
- 已授权的控制命令(例如
/new)可以绕过提及门控。 - 当群组消息因需要提及而被跳过时,OpenClaw 会将其作为待处理的群组历史保存,并在下一条已处理的群组消息中包含它。
- 群组历史上限:
channels.zalouser.historyLimit,然后是messages.groupChat.historyLimit,最后的回退值为50。
多账户
该账户在 OpenClaw 状态中映射到zalouser 配置文件。示例:
环境变量
配置文件中的 profile 选择也可以来自环境变量:
Profile 名称用于选择 OpenClaw 状态中保存的 Zalo 登录凭据。解析顺序如下:
- 配置中的显式
profile。 ZALOUSER_PROFILE。ZCA_PROFILE。- 非默认账号使用账号 id,默认账号使用
default。
profile,这样一个环境变量不会让多个账号共享同一个登录会话。
打字、反应与送达确认
- OpenClaw 会在发送回复前先发送一个输入中事件(尽力而为)。
- 通道操作中支持
zalouser的消息反应动作react。- 使用
remove: true可从消息中移除特定反应表情。 - 反应语义:反应
- 使用
- 对于包含事件元数据的入站消息,OpenClaw 会发送已送达 + 已查看确认(尽力而为)。
故障排除
登录无法保持:openclaw channels status --probe- 重新登录:
openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser
- 在
allowFrom/groupAllowFrom中使用数字 ID,并在groups中使用稳定的群组 ID。如果你有意需要精确的好友/群组名称,请启用channels.zalouser.dangerouslyAllowNameMatching: true。
zca/基于 CLI 的设置升级:
- 移除任何对外部
zca进程的假设;该通道现在通过zca-js完全在进程内运行,不再需要外部 CLI 二进制文件。
相关内容
- Channels 概览 - 所有支持的渠道
- 配对 - DM 认证和配对流程
- 群组 - 群聊行为和提及门控
- 渠道路由 - 消息的会话路由
- 安全 - 访问模型和加固。