OpenClaw 中文社区版 Zalo 渠道接入实战指南:Bot API 插件安装、DM 配对控制与长轮询/Webhook 双模式详解

原创2026-10-03 18:12:011,938 阅读
文章标签:人工智能AI Agent即时通讯后端本地部署语音

OpenClaw 中文社区版 Zalo 渠道接入实战指南:Bot API 插件安装、DM 配对控制与长轮询/Webhook 双模式详解

Zalo 是越南主流的即时通讯应用,其 Bot API 允许第三方机器人以 1:1 会话的方式接入用户。OpenClaw 中文社区版(openclaw-cn)通过独立的 @clawdbot/zalo 插件把 Zalo 变成 Gateway 的可路由渠道:入站消息统一归一化进共享的消息通道,回复则确定性地回到同一个 Zalo 会话,模型无需自行选择渠道。本文基于仓库中的 Zalo 渠道文档 与 extensions/zalo 插件源码,完整讲解插件安装、Token 配置、多账号、DM 访问控制、长轮询与 Webhook 双模式、消息类型处理及故障排查,读完即可把 Zalo 机器人接入你的个人 AI 助手。

当前功能定位与能力边界

Zalo 渠道目前的定位是 experimental(实验性):只支持私聊(direct messages),群聊按 Zalo 官方文档说明为 "coming soon",尚未开放。它是支撑类(support)或通知类场景的合适选择——因为路由是确定性的:回复永远发回 Zalo,模型永远不参与"选择渠道"。

从插件元数据可以看到该渠道的完整画像(见 extensions/zalo/src/channel.ts 与 package.json):

  • 渠道 ID:zalo,别名为 zl;
  • 展示名:Zalo (Bot API);
  • 简介:"Vietnam-focused messaging platform with Bot API";
  • 能力声明:chatTypes: ["direct"]、media: true、blockStreaming: true,且 reactions / threads / polls / nativeCommands 均为 false。

能力矩阵如下(与官方文档一致):

Feature Status
Direct messages ✅ Supported
Groups ❌ Coming soon (per Zalo docs)
Media (images) ✅ Supported
Reactions ❌ Not supported
Threads ❌ Not supported
Polls ❌ Not supported
Native commands ❌ Not supported
Streaming ⚠️ Blocked (2000 char limit)

安装 Zalo 插件

Zalo 以插件形式随仓库分发,不内置在核心安装包中。安装方式有三种:

  1. 通过 CLI 安装 npm 包:
    openclaw-cn plugins install @clawdbot/zalo
    
  2. 从源码 checkout 直接安装本地插件目录:
    openclaw-cn plugins install ./extensions/zalo
    
  3. 在 onboarding 向导中选择 Zalo 并确认安装提示,插件会被自动拉取(extensions/zalo/README.md 也记录了相同流程)。

插件本身是一个标准的 OpenClaw 插件,入口 extensions/zalo/index.ts 通过 Plugin SDK 做了三件事:注册 Zalo 渠道(registerChannel)、注册 Webhook HTTP 处理器(registerHttpHandler)、把运行时注入全局单例(setZaloRuntime)。关于插件机制可参考 插件文档。

快速配置入门

安装插件后,最快跑通的路径只有四步:

  1. 安装插件(见上节);
  2. 设置 Token:
    • 环境变量方式:ZALO_BOT_TOKEN=...
    • 配置文件方式:channels.zalo.botToken: "..."
  3. 重启 Gateway(或完成 onboarding);
  4. 私聊默认走 pairing 流程:机器人首次被联系时,需要先批准配对码。

最小可用配置如下(JSON5 格式,可复制到你的配置文件):

{
  channels: {
    zalo: {
      enabled: true,
      botToken: "12345689:abc-xyz",
      dmPolicy: "pairing"
    }
  }
}

创建 Bot Token(Zalo Bot Platform)

  1. 打开 https://bot.zaloplatforms.com 并登录;
  2. 创建一个新 bot 并配置其设置;
  3. 复制 bot token(格式形如 12345689:abc-xyz,即 "bot id : secret")。

Token 的有效性可以在接入前直接验证。源码层面,插件通过 getMe 接口校验 Token 并拉取 bot 信息(见 extensions/zalo/src/api.ts),其 API 基础地址为 https://bot-api.zaloplatforms.com。Gateway 启动账号时还会先做一次 2.5 秒的快速探测,拿到 bot 名称后写入启动日志 <a href="https://link.gitcode.com/i/d4e8ca85e131a028f8287e81741cfcbf" target="_blank">accountId] starting provider (name)(见 [channel.ts 的 startAccount)。

Token 的三种来源与解析优先级

插件支持从环境变量、配置项、Token 文件三种途径读取 Token。解析逻辑位于 extensions/zalo/src/token.ts,对默认账号(default)而言优先级是:

  1. 账号级配置 accounts.<id>.botToken;
  2. 账号级配置 accounts.<id>.tokenFile(从文件读取并 trim);
  3. 顶层配置 channels.zalo.botToken;
  4. 顶层配置 channels.zalo.tokenFile;
  5. 环境变量 ZALO_BOT_TOKEN(仅默认账号可用)。

重要限制:环境变量 ZALO_BOT_TOKEN 只对默认账号生效。这一约束在插件层面被强制校验——配置向导中,若 input.useEnv 且账号不是默认账号,会直接返回错误 "ZALO_BOT_TOKEN can only be used for the default account"(见 channel.ts)。

多账号支持

需要同时跑多个 Zalo 机器人时,使用 channels.zalo.accounts 声明每个账号,每个账号可独立配置 Token、开关、DM 策略与 Webhook:

{
  channels: {
    zalo: {
      enabled: true,
      accounts: {
        support: {
          botToken: "111111:aaa",
          name: "Support Bot",
          enabled: true
        },
        notify: {
          botToken: "222222:bbb",
          dmPolicy: "allowlist",
          allowFrom: [123456789]
        }
      }
    }
  }
}

账号解析逻辑见 extensions/zalo/src/accounts.ts:账号级配置会与顶层配置合并(账号字段覆盖顶层),defaultAccount 可指定默认账号;账号的启用状态是顶层 enabled 与账号级 enabled 的"与"关系。配置结构本身由 config-schema.ts 中的 Zod schema 约束,accounts 是一个 catchall 映射,每个账号键的字段与顶层一致。

DM 访问控制:配对、白名单与开放模式

私聊消息的访问控制由 channels.zalo.dmPolicy 决定,可选值为 pairing | allowlist | open | disabled,默认 pairing。底层实现在 monitor.ts 的消息流水线中:

  • pairing(默认):未知发送者会收到一个配对码,其消息在批准前被忽略;配对码 1 小时后过期。机器人首次被私聊时,会自动通过 sendMessage 回发一段包含"你的 Zalo user id"与配对码的说明(buildPairingReply)。
  • allowlist:只有 allowFrom 中列出的数字用户 ID 才能触发会话,其余发送者被静默忽略。
  • open:放开所有私聊,但配置 open 时 allowFrom 必须包含 "*"(向导也会引导填写)。
  • disabled:完全拒绝所有私聊入站。

批准配对的操作命令:

openclaw-cn pairing list zalo
openclaw-cn pairing approve zalo <CODE>

注意:Zalo 没有用户名查询能力,channels.zalo.allowFrom 只接受数字用户 ID(见 onboarding.ts 的校验逻辑,非纯数字会提示 "Use a numeric Zalo user id")。用户 ID 支持 zalo: / zl: 前缀写法,解析时会自动剥离归一化(见 channel.ts)。更完整的配对机制可参考 配对指南。

长轮询 vs Webhook:两种事件接收模式

长轮询(默认,无需公网地址)

默认使用长轮询接收事件:getUpdates 以 30 秒超时发起请求,Zalo API 单次调用返回单个 update(与 Telegram 返回数组不同,见 api.ts 的注释);HTTP 408 被识别为轮询超时(无新消息)而非错误;出现真实错误时等待 5 秒重试(见 monitor.ts)。由于轮询模式下 Gateway 主动向外拉取,不需要公网 URL,适合内网或难以暴露端点的场景。

Webhook 模式

需要实时推送时,配置 channels.zalo.webhookUrl 与 channels.zalo.webhookSecret。源码层面的强约束如下(见 monitor.ts):

  • Webhook URL 必须使用 HTTPS(非 https:// 前缀直接抛错);
  • Webhook secret 长度必须在 8–256 字符之间;
  • Zalo 会以 X-Bot-Api-Secret-Token 请求头携带 secret 用于校验,插件用 timingSafeEqual 做恒定时间比较(monitor.ts);
  • Gateway HTTP 服务在 channels.zalo.webhookPath 上处理请求,缺省时自动取 webhookUrl 的路径(monitor.ts);
  • 仅接受 POST 与 JSON Content-Type,请求体上限 1 MB;
  • 内置防护:按"路径+来源 IP"做 60 秒窗口 120 次限流,5 分钟内的重复事件(按 event_name:message_id)会被去重,避免推送重放(monitor.ts)。

Webhook 配置示例:

{
  channels: {
    zalo: {
      webhookUrl: "https://example.com/zalo-webhook",
      webhookSecret: "your-secret-8-plus-chars",
      webhookPath: "/zalo-webhook"
    }
  }
}

关键约束:getUpdates(轮询)与 Webhook 在 Zalo API 层面是互斥的。插件在启用轮询前会先调用 deleteWebhook 清理残留的 webhook 注册,启用 Webhook 时则调用 setWebhook 注册(并在 Gateway 停止时通过 abort 监听自动注销,monitor.ts)。因此不要同时启用两种模式,否则会互相干扰。

支持的消息类型与媒体处理

入站事件按 event_name 分发(monitor.ts):

事件 处理方式
message.text.received 完整处理:进入 Agent 流水线
message.image.received 下载图片(受 mediaMaxMb 限制)后连同 caption 一并进入流水线
message.sticker.received 仅记录日志,不触发 Agent 回复
message.unsupported.received 仅记录日志(例如来自受保护用户的消息)

图片入站链路(monitor.ts):先 fetchRemoteMedia 拉取 URL,再经 saveMediaBuffer 以 mediaMaxMb * 1024 * 1024 为上限落盘,失败则降级为纯文本处理。出站图片通过 sendPhoto 发送,多条媒体时第一条附带文字说明(monitor.ts)。

所有入站消息都会归一化进共享的 channel envelope(含媒体占位符),最终会话上下文里携带 From: zalo:<userId>、To: zalo:<chatId>、SessionKey、Provider: zalo、MediaPath 等字段(monitor.ts),与其余渠道完全一致,因此 Zalo 私聊会话与 Agent 的主会话共享上下文。

限制:2000 字符分块、媒体上限与流式屏蔽

  • 出站文本按 2000 字符分块:textChunkLimit: 2000 是 Zalo API 的硬限制。插件内置按换行/空格边界断行的 chunker(channel.ts),出站时还会先做 Markdown 表格转换(convertMarkdownTables),再按 2000 字符分块逐条发送(monitor.ts)。
  • 媒体大小上限:channels.zalo.mediaMaxMb 同时约束入站下载与出站媒体,默认 5 MB(常量 DEFAULT_MEDIA_MAX_MB)。
  • 流式输出被默认屏蔽:blockStreaming: true。原因是 2000 字符限制会让流式逐段输出的意义大打折扣,插件干脆在能力声明中禁用流式。

投递目标:CLI 与定时任务

Zalo 作为投递渠道时,目标直接使用聊天 ID(chat id)。示例:

openclaw-cn message send --channel zalo --target 123456789 --message "hi"

出站目标会经过 normalizeZaloMessagingTarget 归一化(剥离 zalo: / zl: 前缀,channel.ts),targetResolver 用 /^\d{3,}$/ 判断是否形如 ID 并给出 <chatId> 提示,因此 cron 任务、定时通知等场景可以直接把 Zalo chat id 当作目标使用。

故障排查

机器人不响应:

  • 用探测命令确认 Token 有效:openclaw-cn channels status --probe(该命令会调用 getMe 实时探测,见 probe.ts);
  • 确认发送者已获批准(pairing 批准或已加入 allowFrom);
  • 查看 Gateway 日志:clawdbot logs --follow。

Webhook 收不到事件:

  • 确认 Webhook URL 是 HTTPS;
  • 确认 secret 长度在 8–256 字符之间;
  • 确认 Gateway HTTP 端点能在配置的路径上被外部访问;
  • 确认没有同时运行 getUpdates 轮询(两者互斥)。

配置参考(Zalo)

完整配置总览见 配置文档。以下是 Zalo 渠道的全部配置项:

Provider 选项:

  • channels.zalo.enabled:启用/禁用渠道启动。
  • channels.zalo.botToken:Zalo Bot Platform 的 bot token。
  • channels.zalo.tokenFile:从文件路径读取 token。
  • channels.zalo.dmPolicy:pairing | allowlist | open | disabled(默认 pairing)。
  • channels.zalo.allowFrom:DM 白名单(用户 ID)。open 模式必须包含 "*";向导会要求填写数字 ID。
  • channels.zalo.mediaMaxMb:入站/出站媒体上限(MB,默认 5)。
  • channels.zalo.webhookUrl:启用 Webhook 模式(必须 HTTPS)。
  • channels.zalo.webhookSecret:Webhook secret(8–256 字符)。
  • channels.zalo.webhookPath:Gateway HTTP 服务器上的 Webhook 路径。
  • channels.zalo.proxy:API 请求使用的代理 URL。

多账号选项(channels.zalo.accounts.<id>.*):

  • accounts.<id>.botToken:账号级 token。
  • accounts.<id>.tokenFile:账号级 token 文件。
  • accounts.<id>.name:显示名称。
  • accounts.<id>.enabled:账号级开关。
  • accounts.<id>.dmPolicy:账号级 DM 策略。
  • accounts.<id>.allowFrom:账号级白名单。
  • accounts.<id>.webhookUrl:账号级 Webhook URL。
  • accounts.<id>.webhookSecret:账号级 Webhook secret。
  • accounts.<id>.webhookPath:账号级 Webhook 路径。
  • accounts.<id>.proxy:账号级代理 URL。

此外 schema 还支持 channels.zalo.defaultAccount(指定默认账号 ID)与账号级 markdown、responsePrefix 等扩展字段(见 config-schema.ts)。所有配置修改后均需重启 Gateway 生效(插件的 reload.configPrefixes 仅覆盖 channels.zalo 前缀)。排查 Zalo 渠道问题时,可结合 插件 README、API 客户端实现 与 监控/Webhook 实现 进一步定位。

登录后查看全文
openclaw-cn