Status: experimental. Direct messages and group chats are both implemented. The Capabilities table below reflects verified behavior on Zalo Bot Creator / Marketplace bots.

Bundled plugin

Zalo ships as a bundled plugin in current Apus releases, so packaged builds do not need a separate install.

On an older build or a custom install that excludes Zalo, install the npm package directly:

Quick setup

  1. Create a bot token at https://bot.zaloplatforms.com (sign in, create a bot, configure settings). The token is numeric_id:secret. For Marketplace bots the usable runtime token may appear in the bot's welcome message.
  2. Set the token, either as env ZALO_BOT_TOKEN=... (default account only) or in config.
  3. Check apus channels status --probe; start the Gateway if it is offline. Config changes follow hot reload. If you changed the service environment, restart the Gateway to load it.
  4. Approve the pairing code on first DM contact (default DM policy is pairing).

Minimal config:

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

Multi-account: add more entries under channels.zalo.accounts.<id>, each with its own botToken/name. channels.zalo.botToken (flat, no accounts) is a legacy single-account shorthand. Prefer accounts.<id>.* for new configs.

What it is

Zalo is a Vietnam-focused messaging app. Its Bot API lets the Gateway run a bot for both 1:1 conversations and group chats. Routing back to Zalo is deterministic. The model never chooses channels.

This page covers Zalo Bot Creator / Marketplace bots. Zalo Official Account (OA) bots are a different product surface and may behave differently. This page does not cover them.

How it works

Limits

Limit Value
Outbound text chunk size 2000 characters (Zalo API limit)
Media size (inbound/outbound) channels.zalo.mediaMaxMb, default 5 MB
Webhook request body 1 MB, 30s read timeout
Webhook rate limit 120 requests / 60s per path+client IP, then HTTP 429
Webhook replay tombstones 30 days, up to 20,000 completed events per account (keyed by message id)

Access control

Direct messages

Groups

Group chats are supported by the plugin (chatTypes: ["direct", "group"]) and gated by mention plus group policy:

Long-polling vs webhook

Supported message types

Capabilities

Feature Status
Direct messages Supported
Groups Supported (mention-gated)
Media (inbound/outbound) Supported, capped by mediaMaxMb
Reactions Not supported
Threads Not supported
Polls Not supported
Native commands Not supported
Reply-to / quote Not used (fixed off)

Delivery targets (CLI/cron)

Use a chat ID as the target:

apus message send --channel zalo --target 123456789 --message "hi"

Troubleshooting

Bot does not respond:

Webhook not receiving events:

Configuration reference

Full configuration: Configuration

Setting Description Default
channels.zalo.enabled Enable/disable channel startup true
channels.zalo.accounts.<id>.botToken Bot token from Zalo Bot Platform -
channels.zalo.accounts.<id>.tokenFile Read token from a file (symlinks rejected) -
channels.zalo.accounts.<id>.name Display name -
channels.zalo.accounts.<id>.enabled Enable/disable this account true
channels.zalo.accounts.<id>.dmPolicy Per-account DM policy pairing
channels.zalo.accounts.<id>.allowFrom DM allowlist (user IDs) -
channels.zalo.accounts.<id>.groupPolicy Per-account group policy see Groups
channels.zalo.accounts.<id>.groupAllowFrom Group sender allowlist; falls back to allowFrom -
channels.zalo.accounts.<id>.mediaMaxMb Inbound/outbound media cap (MB) 5
channels.zalo.accounts.<id>.webhookUrl Enable webhook mode (HTTPS required) -
channels.zalo.accounts.<id>.webhookSecret Webhook secret (8-256 chars) -
channels.zalo.accounts.<id>.webhookPath Webhook path on the gateway HTTP server webhook URL path
channels.zalo.accounts.<id>.proxy Proxy URL for API requests -
channels.zalo.accounts.<id>.responsePrefix Outbound response prefix override -
channels.zalo.defaultAccount Default account when multiple are configured default

channels.zalo.botToken, channels.zalo.dmPolicy, and other flat top-level keys are the legacy single-account shorthand for the fields above. Both forms are supported.

Env option: ZALO_BOT_TOKEN=... resolves the default account's token only.

Related