首页
/ OpenClaw zalouser 插件实战:用 zca-js 进程内集成驱动 Zalo 个人账户消息通道

OpenClaw zalouser 插件实战:用 zca-js 进程内集成驱动 Zalo 个人账户消息通道

2026-09-06 14:01:02作者:咎竹峻Karen

本篇基于 extensions/zalouser/README.md 展开,讲清 OpenClaw 的 Zalo 个人账号(Zalo Personal Account)通道插件 @openclaw/zalouser 的安装、QR 扫码登录、多账号配置、访问策略与 Agent 工具集成。读完你可以独立完成该插件的部署与日常运维,并理解其"无外部 CLI、进程内 zca-js 集成"的架构选型在多账号场景下是如何落地的。

风险提示(原文档警告): 对 Zalo 个人账号做自动化可能导致账号被停用或封禁。这是非官方集成,风险自担。

一、插件定位:为什么叫 zalouser

zalouser 通道的命名刻意强调它自动化的是个人 Zalo 用户账号(非官方途径),与潜在的官方 Zalo Bot API 集成(保留给 zalo 通道)区分开。从 extensions/zalouser/package.json 可以看到插件以 @openclaw/zalouser 发布,核心依赖只有 zca-jstypeboxzod,并且声明 openclaw 为可选的 peer 依赖(>=2026.8.1)。

它解决的核心问题是:在 Zalo Bot API 不可用的场景下,让 OpenClaw 的 AI Agent 通过个人账户收发 Zalo 消息。README 给出的特性清单如下:

  • 通道插件集成,带配置向导(setup wizard)+ QR 扫码登录;
  • 通过 zca-js 在进程内实现监听器/发送器,无需外部 zcaopenzcazca-cli 二进制
  • 多账号支持;
  • Agent 工具集成(工具名 zalouser);
  • 支持 DM/群组策略(pairing、allowlist 等)。

前置要求仅有两项:一个运行中的 OpenClaw Gateway,以及手机上的 Zalo App(用于扫码登录)。

extensions/zalouser/openclaw.plugin.json 的插件元数据可以进一步确认其契约:声明了 channels: ["zalouser"]、工具契约 contracts.tools: ["zalouser"],并启用 doctor 契约(configRepairstateMigrations 均为 true),意味着 openclaw doctor --fix 会参与该插件的配置修复与状态迁移。此外 package.json 中通道别名包含 zlu,频道排序 order: 85,文档路径为 /channels/zalouser(对应 docs/channels/zalouser.md)。

二、安装:npm 与本地源码两种方式

方式 A:npm 安装(默认)

openclaw plugins install @openclaw/zalouser

方式 B:本地源码检出

PLUGIN_SRC=./path/to/local/zalouser-plugin
openclaw plugins install "$PLUGIN_SRC"
cd "$PLUGIN_SRC" && pnpm install

两种方式安装后都需重启 Gateway 生效。

从源码结构看,插件通过 createLazyRuntimeModule 懒加载运行时模块(见 extensions/zalouser/src/channel.ts 第 32 行的 loadZalouserChannelRuntime),即 zca-js 相关的重模块只在真正需要监听、登录或探测时才被 import,这解释了 openclaw.plugin.jsonactivation.onStartup: false 的设计——插件不会在 Gateway 启动时立即拉起完整运行时。

三、快速上手:QR 登录、启用通道、发送消息

3.1 QR 扫码登录

openclaw channels login --channel zalouser

用手机上 Zalo App 扫描终端输出的二维码完成登录。多账号场景下可以指定账号:

openclaw channels login --channel zalouser --account work

QR 登录的底层由 Gateway 侧的 loginWithQrStart / loginWithQrWait 两个回调实现(extensions/zalouser/src/channel.ts 第 165-181 行):先按账号解析 credential profile(resolveZalouserQrProfile),再调用运行时中的 startZaloQrLogin 发起登录并等待扫码结果。凭证以"profile"为单位保存在 OpenClaw 状态中,而不是外部进程的文件里。

3.2 启用通道

在 OpenClaw 配置中开启通道并设定 DM 策略:

channels:
  zalouser:
    enabled: true
    dmPolicy: pairing # pairing | allowlist | open | disabled

dmPolicy 默认值为 pairing(配对码模式):首次 DM 收到配对请求后,在 Gateway 侧批准配对码即可。从 extensions/zalouser/src/channel.ts 第 130 行的状态适配器可以看到,状态快照中展示的 dmPolicy 在缺省时即回退为 "pairing",与文档一致。

3.3 发送一条消息

openclaw message send --channel zalouser --target <threadId> --message "Hello from OpenClaw"

从实现细节看,出站文本在发送前会经过 Markdown 分块处理:extensions/zalouser/src/channel.adapters.ts 中定义了 ZALOUSER_TEXT_CHUNK_LIMIT = 2000,并以 chunkTextForOutbound(markdown 模式)作为 chunker——即出站长文本会被按 2000 字符的 Zalo 客户端限制切分。测试用例 extensions/zalouser/src/channel.sendpayload.test.ts 验证了"先做 Markdown 格式化、再分块"的顺序以及内部分块进度会透传给出站适配器。

四、配置详解

4.1 基础配置

channels:
  zalouser:
    enabled: true
    dmPolicy: pairing

4.2 多账号配置

channels:
  zalouser:
    enabled: true
    defaultAccount: default
    accounts:
      default:
        enabled: true
        profile: default
      work:
        enabled: true
        profile: work

这里的关键概念是 account 与 profile 的分离

  • account 是 OpenClaw 通道侧的逻辑账号(决定路由、策略、状态归属);
  • profilezca-js 侧的凭证档案名,决定实际用哪一套已登录的 Zalo 会话。

账号解析逻辑在 extensions/zalouser/src/accounts.ts 中,profile 的解析优先级为(resolveProfile,第 36-50 行):

  1. 配置中显式声明的 profile
  2. 环境变量 ZALOUSER_PROFILE
  3. 环境变量 ZCA_PROFILE(遗留兼容);
  4. 非默认账号回退到账号 id 本身;默认账号回退到 "default"

因此官方建议:多账号场景下务必在每个 account 上显式写 profile,避免一个环境变量让多个账号共享同一登录会话。ZALOUSER_PROFILE / ZCA_PROFILE 同时也是该通道"已配置"状态的探测依据(package.jsonchannel.configuredState.env.anyOf)。

另外两个值得注意的默认行为(均可在 accounts.ts 中找到实现):

  • groupPolicy 缺省为 "allowlist"(第 32 行注释明确"与 Telegram 的安全默认保持一致")——群组默认需要显式 allowlist 条目才会被处理;
  • 账号 enabled 是通道级 enabled 与账号级 enabled 的"与"关系,任一层关闭都会禁用该账号。

官方文档 docs/channels/zalouser.md 对群组侧有更完整的说明,包括 groups.<id>.requireMention 的 @提及门控、groupAllowFrom 的发送者限制、dangerouslyAllowNameMatching 这一"破玻璃"兼容模式(重新启用启动期名称解析与运行时群名匹配),以及 mediaMaxMb 的账号级 → 通道根级 → agents.defaults.mediaMaxMb 的三级回退,可延伸阅读。

五、常用运维命令

# 登录 / 登出 / 状态探测
openclaw channels login --channel zalouser
openclaw channels login --channel zalouser --account work
openclaw channels status --probe
openclaw channels logout --channel zalouser

# 目录查询:查自己、搜好友、查群组、查群成员
openclaw directory self --channel zalouser
openclaw directory peers list --channel zalouser --query "name"
openclaw directory groups list --channel zalouser --query "work"
openclaw directory groups members --channel zalouser --group-id <id>

这些命令并非空壳:channel.ts 中的 directory 适配器(第 60-114 行)实现了 self / listPeers / listGroups / listGroupMembers 四个目录接口,底层调用 getZaloUserInfolistZaloFriendsMatchinglistZaloGroupsMatchinglistZaloGroupMembers。群组 id 会以 group:<groupId> 前缀规范化,供会话路由使用。channels status --probe 则走 probeAccount(第 122-123 行)调用 probeZalouser 对凭证 profile 做连通性探测,用于判断登录态是否有效。

六、Agent 工具 zalouser

该插件为 AI Agent 注册了名为 zalouser 的工具(在 openclaw.plugin.json 中以 contracts.tools 声明)。可用动作共 7 个:

action 作用 关键参数
send 发送文本消息 threadIdmessageisGroup
image 发送图片 threadIdurl(图片 URL)
link 发送链接 threadIdurl
friends 列出/搜索好友 queryprofile
groups 列出群组 queryprofile
me 获取当前登录资料 profile
status 检查认证状态 profile

extensions/zalouser/src/tool.ts 的 Tool Schema(第 22-33 行)可以确认全部参数集:actionthreadIdmessageisGroupprofilequeryurl,且 additionalProperties: false(不接收未声明参数)。实现上有两个值得了解的细节:

  1. 环境上下文回退resolveZalouserSendTarget(第 100-107 行)表明 threadId/isGroup 可以省略——当投递上下文(deliveryContext)本身就在 zalouser 通道上时,工具会自动从当前会话解析目标线程,Agent 不必重复传入;显式参数永远优先。
  2. profile 选的是凭证档案,不是通道账号resolveToolMediaMaxBytes(第 50-68 行)注释明确"Profiles are credentials, not account IDs"。只有当当前投递路由所在账号使用的 profile 与工具传入的 profile 一致时,才会套用该账号的 mediaMaxMb 上限;否则回退到通道根级/代理级媒体上限,且不会去搜索其他恰好共享该 profile 的账号。

七、故障排查

README 给出的三条排查路径:

  • 登录态未持久化:先登出再重新登录——
    openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser
    
    登出会调用运行时的 logoutZaloProfile 清理对应 profile 的会话(channel.ts 第 182-185 行 logoutAccount)。
  • 状态探测openclaw channels status --probe,确认凭证 profile 是否仍处于认证态。
  • 名称解析问题(allowlist/群组):优先使用数字型 Zalo ID 或精确的 Zalo 名称,避免依赖可变的群名/昵称做匹配。

官方文档还补充了两类问题(见 docs/channels/zalouser.md):allowlist/群名未解析时改用数字 ID 或显式开启 dangerouslyAllowNameMatching;从旧的外部 zca/CLI 方案升级后需移除对外部 zca 进程的一切假设,因为新通道完全进程内运行。

八、小结

@openclaw/zalouser 是 OpenClaw 面向 Zalo 个人账户的通道插件:它以 zca-js 为唯一运行时依赖,把监听、发送、QR 登录全部收敛到 Gateway 进程内,通过 account/profile 双层模型支持多账号,并以 zalouser 工具向 Agent 暴露 sendimagelinkfriendsgroupsmestatus 七类动作。对需要在无官方 Bot API 条件下接入 Zalo 的团队,它的配置面(dmPolicygroupPolicyaccountsprofile)与运维命令(login/logout/status/directory)都已按 OpenClaw 通道插件的标准契约实现,可直接套用上述安装与配置流程;同时请牢记其非官方属性与账号风控风险。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
858
1.35 K
docsdocs
暂无描述
Markdown
899
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
923
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.83 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
532
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
524
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
393