Zalo (Bot API)

Status: experimental. DMs são suportadas; tratamento de grupos está disponível com controles explícitos de política de grupo.

Plugin necessário

O Zalo é distribuído como plugin e não vem incluído na instalação padrão.

  • Instalação via CLI: openclaw plugins install @openclaw/zalo
  • Ou selecione Zalo durante o onboarding e confirme o prompt de instalação
  • Detalhes: Plugins

Configuração rápida (iniciante)

  1. Instale o plugin Zalo:
    • A partir de um checkout de código: openclaw plugins install ./extensions/zalo
    • Do npm (se publicado): openclaw plugins install @openclaw/zalo
    • Ou escolha Zalo no onboarding e confirme o prompt de instalação
  2. Defina o token:
    • Env: ZALO_BOT_TOKEN=...
    • Ou config: channels.zalo.botToken: "...".
  3. Reinicie o gateway (ou finalize o onboarding).
  4. O acesso a DM usa pareamento por padrão; aprove o código de pareamento no primeiro contato.

Configuração mínima:

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

O que é

O Zalo é um app de mensagens focado no Vietnã; sua Bot API permite que o Gateway rode um bot para conversas 1:1. É uma boa opção para suporte ou notificações onde você quer roteamento determinístico de volta para o Zalo.

  • Um canal Zalo Bot API controlado pelo Gateway.
  • Roteamento determinístico: respostas voltam para o Zalo; o modelo nunca escolhe canais.
  • DMs compartilham a sessão principal do agente.
  • Grupos são suportados com controles de política (groupPolicy + groupAllowFrom) e por padrão usam comportamento fechado de allowlist.

Configuração (caminho rápido)

1) Criar um token de bot (Zalo Bot Platform)

  1. Acesse https://bot.zaloplatforms.com e faça login.
  2. Crie um novo bot e configure suas opções.
  3. Copie o token do bot (formato: 12345689:abc-xyz).

2) Configurar o token (env ou config)

Exemplo:

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

Opção por env: ZALO_BOT_TOKEN=... (funciona apenas para a conta padrão).

Suporte a múltiplas contas: use channels.zalo.accounts com tokens por conta e name opcional.

  1. Reinicie o gateway. O Zalo inicia quando um token é resolvido (env ou config).
  2. O acesso a DM usa pareamento por padrão. Aprove o código quando o bot for contatado pela primeira vez.

Como funciona (comportamento)

  • Mensagens de entrada são normalizadas no envelope de canal compartilhado com placeholders de mídia.
  • Respostas sempre voltam para o mesmo chat Zalo.
  • Long-polling por padrão; modo webhook disponível com channels.zalo.webhookUrl.

Limites

  • Texto de saída é dividido em 2000 caracteres (limite da API Zalo).
  • Downloads/uploads de mídia são limitados por channels.zalo.mediaMaxMb (padrão 5).
  • Streaming é bloqueado por padrão devido ao limite de 2000 caracteres que torna o streaming menos útil.

Controle de acesso (DMs)

Acesso a DM

  • Padrão: channels.zalo.dmPolicy = "pairing". Remetentes desconhecidos recebem um código de pareamento; mensagens são ignoradas até a aprovação (códigos expiram após 1 hora).
  • Aprove via:
    • openclaw pairing list zalo
    • openclaw pairing approve zalo <CODE>
  • O pareamento é a troca de token padrão. Detalhes: Pareamento
  • channels.zalo.allowFrom aceita IDs numéricos de usuário (sem busca por nome de usuário disponível).

Controle de acesso (Grupos)

  • channels.zalo.groupPolicy controla o tratamento de entrada de grupo: open | allowlist | disabled.
  • O comportamento padrão é fechado: allowlist.
  • channels.zalo.groupAllowFrom restringe quais IDs de remetente podem acionar o bot em grupos.
  • Se groupAllowFrom não está definido, o Zalo faz fallback para allowFrom para verificações de remetente.
  • groupPolicy: "disabled" bloqueia todas as mensagens de grupo.
  • groupPolicy: "open" permite qualquer membro do grupo (com gating de menção).
  • Nota de runtime: se channels.zalo está completamente ausente, o runtime ainda faz fallback para groupPolicy="allowlist" por segurança.

Long-polling vs webhook

  • Padrão: long-polling (sem necessidade de URL pública).
  • Modo webhook: defina channels.zalo.webhookUrl e channels.zalo.webhookSecret.
    • O webhook secret deve ter 8-256 caracteres.
    • A URL do webhook deve usar HTTPS.
    • O Zalo envia eventos com header X-Bot-Api-Secret-Token para verificação.
    • O HTTP do gateway trata requisições de webhook em channels.zalo.webhookPath (padrão é o caminho da URL do webhook).
    • Requisições devem usar Content-Type: application/json (ou media types +json).
    • Eventos duplicados (event_name + message_id) são ignorados por uma janela curta de replay.
    • Tráfego em rajada é limitado por taxa por caminho/origem e pode retornar HTTP 429.

Nota: getUpdates (polling) e webhook são mutuamente exclusivos conforme a documentação da API Zalo.

Tipos de mensagem suportados

  • Mensagens de texto: Suporte completo com divisão em 2000 caracteres.
  • Mensagens de imagem: Download e processamento de imagens de entrada; envio de imagens via sendPhoto.
  • Stickers: Registrados mas não totalmente processados (sem resposta do agente).
  • Tipos não suportados: Registrados (ex: mensagens de usuários protegidos).

Funcionalidades

FuncionalidadeStatus
Mensagens diretasSuportado
GruposSuportado com controles de política (allowlist por padrão)
Mídia (imagens)Suportado
ReaçõesNão suportado
ThreadsNão suportado
EnquetesNão suportado
Comandos nativosNão suportado
StreamingBloqueado (limite de 2000 caracteres)

Alvos de entrega (CLI/cron)

  • Use um chat id como alvo.
  • Exemplo: openclaw message send --channel zalo --target 123456789 --message "oi".

Resolução de problemas

Bot não responde:

  • Verifique se o token é válido: openclaw channels status --probe
  • Verifique se o remetente está aprovado (pareamento ou allowFrom)
  • Verifique os logs do gateway: openclaw logs --follow

Webhook não recebe eventos:

  • Confirme que a URL do webhook usa HTTPS
  • Verifique que o secret token tem 8-256 caracteres
  • Confirme que o endpoint HTTP do gateway está acessível no caminho configurado
  • Verifique que o polling getUpdates não está rodando (são mutuamente exclusivos)

Referência de configuração (Zalo)

Configuração completa: Configuração

Opções do provedor:

  • channels.zalo.enabled: habilitar/desabilitar inicialização do canal.
  • channels.zalo.botToken: token do bot da Zalo Bot Platform.
  • channels.zalo.tokenFile: ler token de um caminho de arquivo regular. Symlinks são rejeitados.
  • channels.zalo.dmPolicy: pairing | allowlist | open | disabled (padrão: pairing).
  • channels.zalo.allowFrom: allowlist de DM (IDs de usuário). open requer "*". O wizard pedirá IDs numéricos.
  • channels.zalo.groupPolicy: open | allowlist | disabled (padrão: allowlist).
  • channels.zalo.groupAllowFrom: allowlist de remetentes de grupo (IDs de usuário). Faz fallback para allowFrom quando não definido.
  • channels.zalo.mediaMaxMb: limite de mídia de entrada/saída (MB, padrão 5).
  • channels.zalo.webhookUrl: habilitar modo webhook (HTTPS obrigatório).
  • channels.zalo.webhookSecret: segredo do webhook (8-256 caracteres).
  • channels.zalo.webhookPath: caminho do webhook no servidor HTTP do gateway.
  • channels.zalo.proxy: URL de proxy para requisições API.

Opções de múltiplas contas:

  • channels.zalo.accounts.<id>.botToken: token por conta.
  • channels.zalo.accounts.<id>.tokenFile: arquivo de token regular por conta. Symlinks são rejeitados.
  • channels.zalo.accounts.<id>.name: nome de exibição.
  • channels.zalo.accounts.<id>.enabled: habilitar/desabilitar conta.
  • channels.zalo.accounts.<id>.dmPolicy: política de DM por conta.
  • channels.zalo.accounts.<id>.allowFrom: allowlist por conta.
  • channels.zalo.accounts.<id>.groupPolicy: política de grupo por conta.
  • channels.zalo.accounts.<id>.groupAllowFrom: allowlist de remetentes de grupo por conta.
  • channels.zalo.accounts.<id>.webhookUrl: URL de webhook por conta.
  • channels.zalo.accounts.<id>.webhookSecret: segredo de webhook por conta.
  • channels.zalo.accounts.<id>.webhookPath: caminho de webhook por conta.
  • channels.zalo.accounts.<id>.proxy: URL de proxy por conta.