Auth model
Installed plugin + Zalo Bot API credentials
A regional bot lane where local platform conventions matter more than generic bot patterns.
Zalo Bot API support for OpenClaw covers plugin-backed setup, bot credentials, local rollout conventions, and verification tuned for Vietnam-focused deployments.
Auth model
Installed plugin + Zalo Bot API credentials
Safety stance
Regional platform rules and account expectations should be documented alongside the technical setup.
Verification ritual
Test credential validity, one direct bot interaction, and one intended production-like context before scaling use.
Rollout mode
25–40 min setup
Experimental · Zalo bot channel
Zalo stays intentionally narrow: experimental Bot API integration, deterministic replies back to Zalo, and operator-controlled DM or group policy.
Policy watch
If the guide imports assumptions from Telegram or WhatsApp without adjustment, operators will miss the platform-specific constraints that matter.
Zalo is an experimental Bot API lane for operators serving Zalo-first audiences. The important distinction is not just the token; it is the operating model around pairing by default, fail-closed group behavior, and a deliberate choice between long-polling and webhook delivery.
Zalo matters when the user base is already there.
The official OpenClaw docs position it as a plugin-backed bot integration that is well suited to deterministic routing for direct conversations and support-style traffic. That gives it a practical place in the channel mix:
This is not the lane to treat as a Telegram clone. The official docs emphasize different defaults and a narrower capability surface.
Use this dossier when you need to decide:
The official docs support two transport modes:
webhookUrl and webhookSecretIf you do not need public inbound delivery, long-polling is the easier baseline. If you do need webhooks, HTTPS and secret handling become part of the operating surface immediately.
Zalo can be connected and still stay silent by policy.
The main controls are:
dmPolicyallowFromgroupPolicygroupAllowFromThe upstream docs are explicit that:
pairingallowlistgroupAllowFrom falls back to allowFrom if unsetgroupPolicy: "open" allows any group member, but remains mention-gatedThat means “bot is online” and “bot is supposed to answer here” are separate questions.
For most first deployments, the safest starting posture is:
pairing,{
channels: {
zalo: {
enabled: true,
botToken: '12345689:abc-xyz',
dmPolicy: 'pairing',
},
},
}
Why this is a good first shape:
Zalo is not bundled with core OpenClaw.
Install it first:
openclaw plugins install @openclaw/zalo
From source checkout, the docs also allow:
openclaw plugins install ./extensions/zalo
Then create a bot token through the official Zalo Bot Platform:
The docs describe the token format as something like 12345689:abc-xyz.
The official docs support both env and config:
ZALO_BOT_TOKEN=...channels.zalo.botTokenFor steady-state operation, config is usually easier to audit than shell state:
{
channels: {
zalo: {
enabled: true,
botToken: '12345689:abc-xyz',
dmPolicy: 'pairing',
},
},
}
The docs also note that env works only for the default account, which is another reason to prefer config once the lane matters.
pairingThe official docs make pairing the default for a reason.
Unknown senders do not become trusted automatically. Instead they receive a pairing code, and their messages are ignored until approved.
Approve with:
openclaw pairing list zalo
openclaw pairing approve zalo <CODE>
The docs also note that pairing codes expire after one hour.
allowlistIf the sender set is already fixed, use allowFrom with numeric Zalo user IDs.
Be careful here: the official docs are explicit that Zalo does not support username lookup for this field.
open means truly openThe config reference notes that open requires "*" in allowFrom. Only use that when you really mean to accept broad inbound DM traffic.
Zalo group support exists, but the docs clearly frame it as policy-driven, not something to enable casually.
If you do nothing, groups default to allowlist behavior.
That is the right baseline for an experimental channel.
If you need groups, start by deciding which sender IDs are allowed to trigger the bot:
{
channels: {
zalo: {
dmPolicy: 'pairing',
groupPolicy: 'allowlist',
groupAllowFrom: ['123456789'],
},
},
}
If groupAllowFrom is omitted, runtime falls back to allowFrom, which can be useful when the same small set of known people is allowed in both DMs and groups.
The official docs explicitly say that groupPolicy: 'open' allows any group member, but only in a mention-gated way.
That makes open less reckless than “reply to everything,” but it is still broader than most first rollouts need.
Long-polling is the default, and it avoids public ingress.
Use webhook mode when you specifically need it, and then satisfy the upstream requirements exactly:
channels.zalo.webhookUrlchannels.zalo.webhookSecretwebhookPath behaviorThe docs also call out a hard constraint: polling and webhook mode are mutually exclusive per the Zalo API.
Start with:
openclaw channels status --probe
openclaw logs --follow
The official troubleshooting section points here first when the bot stays silent.
This verifies the real default: pairing should happen, not silent broad access.
Approve the pairing code, then confirm the bot responds in the same DM thread.
Do not just add the bot to a chat and assume the result proves anything.
Validate one message from an allowed sender under the chosen groupPolicy, or one mention in open mode if that is the posture you selected.
Because polling and webhooks are mutually exclusive, a webhook validation should include one clean end-to-end event with the expected HTTPS endpoint and secret handling.
The official docs support a narrower feature set than some mainstream bot ecosystems:
If your workflow depends heavily on threaded moderation, reactions, or streaming-heavy UX, document that constraint before rollout rather than after user disappointment.
The official troubleshooting sequence starts with token validity, sender approval, and gateway logs.
That is often policy, not transport. Check dmPolicy, allowFrom, and whether pairing approval actually happened.
The upstream docs call out three common causes first:
Make sure polling is not still assumed somewhere. The docs are explicit that polling and webhook mode cannot run together.
A restrained Zalo rollout usually looks like this:
pairing first,That is a better fit for the current channel than trying to import Slack or Telegram habits unchanged.
If you need the raw configuration surface, continue with:
Verification & references
References