Skip to content

Zalo setup

Bestie includes a first Zalo adapter for running the local runtime through a Zalo bot-style API. This adapter is intentionally narrow: text messages only, owner-only access, local polling, memory controls, and approval prompts.

Use Telegram when you need attachments or voice workflows today. Use Zalo when you want the same Bestie runtime in a Zalo chat and are comfortable with the current text-only adapter.

The Zalo adapter currently supports:

  • Local polling with bestie channels zalo or one-shot polling with bestie channels zalo --once.
  • Setup via bestie channels zalo setup.
  • Owner-only filtering through channels.zalo.ownerUserId.
  • Text messages and text captions.
  • Typing indicators when the platform call succeeds.
  • Long replies split into 2,000-character chunks.
  • Memory recall and memory reasoning for the zalo channel.
  • Tool activity progress messages and pending action approvals.
  • Slash commands: /help, /status, /providers, /approvals, /approve <id>, /deny <id>, /memory, /memory pending, /memory pause, and /memory resume.
  • Transcript logging for debugging Zalo interactions.
  • Flexible sender/chat ID extraction for various Zalo API response formats.

Not yet supported:

  • Attachments, images, files, audio, or voice workflows.
  • Rich Zalo message templates.
  • Group access policies beyond the configured owner id.
  • Webhook hosting; the current adapter polls from the local process.
  • A working Bestie local setup with bestie doctor passing for your LLM provider.
  • A Zalo bot token compatible with Bestie’s Zalo Bot API calls.
  • Your Zalo owner user id.

Secrets stay in .bestie/.env; non-secret channel settings stay in .bestie/config.json.

Terminal window
bestie channels zalo setup

The setup wizard asks for:

  1. Owner Zalo user id.
  2. Zalo bot token.

It writes the owner id and token environment variable name to config:

{
"channels": {
"zalo": {
"enabled": true,
"botTokenEnv": "BESTIE_ZALO_BOT_TOKEN",
"ownerUserId": "zalo-owner-1"
}
}
}

It stores the token value in .bestie/.env:

Terminal window
BESTIE_ZALO_BOT_TOKEN=your-zalo-token

Start the local polling loop:

Terminal window
bestie channels zalo

For a smoke check, process one polling batch and exit:

Terminal window
bestie channels zalo --once

Bestie only replies when the incoming sender id matches channels.zalo.ownerUserId. Non-owner messages are ignored.

For debugging Zalo interactions, you can enable transcript logging:

Terminal window
bestie channels zalo --transcript ./logs/zalo-smoke.jsonl

This writes a JSONL file with:

  • zalo_get_updates_start / zalo_get_updates_finish events for each polling cycle.
  • zalo_send_message events for outbound messages.
  • zalo_send_chat_action events for typing indicators.

Each entry includes timestamps and hashed identifiers for privacy.

To debug unexpected Zalo API response formats:

Terminal window
bestie channels zalo --transcript ./logs/zalo-smoke.jsonl --capture-shape

This captures the structure of getUpdates responses, useful when integrating with different Zalo Bot API versions.

Use these commands from the configured owner account:

/help
/status
/providers
/memory
/memory pending
/memory pause
/memory resume
/approvals
/approve <id>
/deny <id>

Approval requests are queued locally. When Bestie needs permission for a gated action, it sends an approval id in Zalo. Reply with /approve <id> or /deny <id> to resolve it.

  • Zalo is not enabled: run bestie channels zalo setup first.
  • Zalo bot token env ... is missing: add BESTIE_ZALO_BOT_TOKEN to .bestie/.env or rerun setup.
  • Zalo owner user id is missing: set channels.zalo.ownerUserId in .bestie/config.json.
  • No reply from Bestie: confirm the sender id exactly matches ownerUserId; non-owner messages are ignored by design.
  • Provider timeout while handling Zalo: run bestie doctor, ask a narrower question, or increase llm.timeoutMs.
  • Polling failures: check token validity, network access, and whether the Zalo Bot API endpoint is reachable from your machine.
  • Unexpected response shape errors: run with --capture-shape flag to log the API response structure for debugging.

For core runtime checks, run:

Terminal window
bestie doctor
bestie status

When working from the Bestie source repository, these checks cover the Zalo setup path:

Terminal window
npm run smoke:zalo:setup
npm test