Pular para o conteúdo principal
O WaClient recebe um objeto WaClientOptions e um logger opcional:
Apenas store e sessionId são obrigatórios; todo o resto tem um valor padrão sensato.

Opções obrigatórias

store
WaStore
obrigatório
A instância da store construída por createStore. Mantém cada domínio por sessão (auth, signal, app-state, …).
sessionId
string
obrigatório
Identificador lógico da sessão — ele indexa cada domínio dentro da store. Use uma string estável por dispositivo/conta. Trocá-lo entre execuções deixa as credenciais anteriores órfãs e força um novo pareamento.

Sessões e multi-tenancy

Como cada domínio da store é indexado por sessionId, uma única store pode conter muitas contas independentes. Para rodar várias contas em um processo, crie um WaClient por sessionId sobre a mesma store:
Cada client pareia e reconecta de forma independente. Para o panorama completo — o que é por sessão vs compartilhado, a regra de single-writer entre processos, orçamento de memória, sharding e shutdown — veja Deploys multi-sessão.

Fingerprint do dispositivo

Estes controlam como o dispositivo aparece em Dispositivos conectados no celular:
deviceBrowser
string
padrão:"'chrome'"
Id do navegador anunciado durante o pareamento ('chrome', 'firefox', 'safari', …; veja WA_BROWSERS). Define o rótulo em Dispositivos conectados.
devicePlatform
string
Sobrescrita do id numérico de plataforma companion (WA_COMPANION_PLATFORM_IDS). Inferido de deviceBrowser quando omitido; defina explicitamente para plataformas não-navegador.

Sincronização de histórico

history
WaHistorySyncOptions
Controla o processamento dos chunks de historySyncNotification — tanto o bootstrap inicial que o WhatsApp envia após o pareamento quanto o backfill sob demanda disparado por message.requestHistorySync.
  • enabled?: boolean — processa os chunks de histórico recebidos. Padrão true. Defina como false para descartá-los silenciosamente (útil quando você não persiste mailbox/threads/contacts e o download da conversa só gastaria banda). A lib ainda envia ack do chunk para o servidor parar de re-enviar, igual ao wa-web.
  • requireFullSync?: boolean — solicita o arquivo completo em vez de apenas os chats recentes.
O histórico chega como eventos history_sync_chunk.

Timeouts

Todos em milissegundos; os padrões são ajustados para produção.

Versão do WhatsApp

O zapo embarca uma versão de produção testada por transporte. Ocasionalmente o WhatsApp rejeita clients antigos durante o handshake noise com HTTP 405 / failure_client_too_old. Você tem três opções para se recuperar.
version
string | () => string | Promise<string>
Sobrescreve a string de versão anunciada pelo client. Aceita um literal ou um resolver chamado uma vez por connect() — útil para buscar a versão atual sob demanda sem recriar o client. O formato aceito depende do transporte resolvido para o connect:
  • Web aceita uma versão de 3 a 5 partes (2.3000.x[.y.z]); as 4ª e 5ª partes, quando fornecidas, são anunciadas no payload noise.
  • Mobile aceita exatamente uma app version Android de 4 partes (2.26.x.y); ela sobrescreve mobileTransport.deviceInfo.appVersion no payload de login.
Uma quantidade de partes inválida para o transporte resolvido lança no connect().
recoverFromClientTooOld
boolean
padrão:"false"
Quando true, ao receber failure_client_too_old o client emite um warning, busca a versão atual para o transporte ativo (fetchLatestWaWebVersion() para Web, fetchLatestWaMobileVersion() para Mobile), aplica como override de uso único e reconecta automaticamente. Em Mobile, o override é aplicado atualizando deviceInfo.appVersion para o próximo connect. Trate como paliativo até atualizar o zapo — o default embarcado continua sendo o caminho recomendado.

fetchLatestWaWebVersion()

Faz scraping do client_revision atual em web.whatsapp.com/sw.js e retorna uma string de versão no formato 2.3000.x aceito por version em uma sessão Web.
Opções: timeoutMs (padrão 10s), proxy (apenas dispatcher do undici — o fetch global não honra http.Agent), signal, userAgent, headers e uma override de fetch para testes. Erros de rede e parsing são lançados — envolva em try/catch se quiser cair no default embarcado.

fetchLatestWaMobileVersion()

Faz scraping da versão atual do WhatsApp para Android em uma página pública de app-listing e retorna uma string 2.26.x.y de 4 partes adequada para version em uma sessão Mobile (ou como override para mobileTransport.deviceInfo.appVersion).
Opções: tudo que o fetcher Web aceita (timeoutMs, proxy, signal, userAgent, headers, fetch) mais:
  • url?: string — sobrescreve a página a ser lida. A fonte padrão é um mirror público de app-listing porque a própria página do WhatsApp em whatsapp.com/android só mostra a versão mínima obsoleta; re-aponte se o layout mudar ou for inalcançável da sua rede.
  • versionPattern?: RegExp — sobrescreve o regex de extração. Precisa expor a versão no capture group 1. O padrão combina com um 2.x.x.x de 4 partes e retorna o primeiro hit na página.
A string parseada precisa ter exatamente quatro partes numéricas; qualquer outra coisa lança (invalid wa-mobile version parsed from page). Erros de rede e parsing são lançados — envolva em try/catch se quiser cair em uma versão hardcoded conhecida.

Presença ao conectar

markOnlineOnConnect
boolean
padrão:"false"
  • false (padrão) — anuncia como indisponível. Igual ao WhatsApp Web quando a aba não está em foco e mantém bots headless invisíveis por padrão. Com isso desligado, você continua recebendo notificações de mensagens enquanto está “offline”.
  • true — anuncia o client como online (igual ao WhatsApp Web com a aba em foco no momento do login).

Linking com passkey

signPasskeyAssertion
WaShortcakeAssertionSigner
Signer WebAuthn externo para o handshake Shortcake de passkey forçado pelo servidor. Chamado com o PublicKeyCredentialRequestOptions bruto (Uint8Array) que o servidor emitiu; deve retornar { credentialId, webauthnAssertion }. A source da credencial (authenticator real / virtual, relay) fica fora da lib.Sem isso, uma conta que receber um passkey prologue forçado pelo servidor emite auth_passkey_required com hasSigner: false e o link fica parado — veja o deep dive de reverse engineering pro detalhe no nível do fio.

Addons (reações, votos em enquetes)

addons
{ autoDecrypt?: boolean, persistAllSecrets?: boolean }
padrão:"{ autoDecrypt: true, persistAllSecrets: false }"
Addons criptografados (votos em enquetes, reações, edições de mensagem, …) são descriptografados automaticamente e emitidos como eventos tipados message_addon. Defina autoDecrypt: false para recebê-los criptografados e descriptografar você mesmo via client.message.tryDecryptAddon(event). O secret da mensagem-pai é procurado no cache messageSecret primeiro, depois no store messages.persistAllSecrets: true persiste o secret de 32 bytes de toda mensagem enviada e recebida, não só as de poll / event / bot-prompt que a lib sabe que terão follow-up. Addons criptografados cujo pai pode ser qualquer tipo de mensagem — reações, comentários, edições via secretEncryptedMessage — precisam do secret do pai para decifrar; sem essa flag, esses pais só continuam decifráveis depois de um restart quando o arquivo messages completo é persistente. Use para manter a decifragem possível guardando apenas o secret (messages: 'none').Sem efeito quando o cache messageSecret é 'none' — toda escrita de secret cai no noop store e é silenciosamente descartada. Com o provider 'memory' default funciona pelo tempo de vida do processo, mas perde no restart e fica limitado ao LRU e ao TTL messageSecretMs do cache; aponte messageSecret para um backend persistente para manter os secrets entre restarts.

Mídia

media
WaMediaOptions
Processamento de mídia. Passe um processor (de @zapo-js/media-utils) para gerar thumbnails/previews, medir dimensões e durações e construir waveforms de notas de voz antes do upload — e ligue/desligue cada etapa. Sem um processor a mídia ainda é enviada, só sem esse processamento. Veja o guia de mídia para a configuração completa.
  • processor?: WaMediaProcessor — a instância do processor
  • generateThumbnail?: boolean — thumbnails de preview de imagem/vídeo
  • generateProbe?: boolean — mede largura/altura/duração
  • generateWaveform?: boolean — waveform de nota de voz (PTT)
  • generateStickerThumbnail?: boolean
  • normalizeVoiceNote?: boolean — recodifica o áudio PTT para o formato que o WhatsApp espera
Configuração global do fetcher embutido de preview de link, usado ao enviar texto que contém uma URL. Sobrescreva por mensagem com a opção de envio linkPreview.
  • enabled?: boolean — liga ou desliga globalmente a busca automática de preview de link
  • fetchTimeoutMs?: number — quanto esperar pela página de destino
  • uploadHqThumbnail?: boolean — envia uma thumbnail de preview em alta resolução
  • allowPrivateHosts?: boolean — permite buscar endereços privados/loopback (desligado por padrão, como proteção contra SSRF)
  • maxHtmlBytes?: number / maxThumbnailBytes?: number — limites de tamanho para o HTML e a imagem buscados
  • userAgent?: string — User-Agent enviado na busca
  • proxy?: WaProxyTransport — aplica proxy só a este fetcher (igual a proxy.linkPreview)
  • fetcher?: WaLinkPreviewFetcher — substitui o fetcher padrão por completo (ex.: seu próprio pipeline de scraping)

Eventos de chat

chatEvents
{ emitSnapshotMutations?: boolean }
Defina emitSnapshotMutations: true para reemitir eventos mutation para cada mudança vista durante uma sincronização de snapshot de app-state. Desligado por padrão, já que mutações de snapshot representam estado histórico, não mudanças ao vivo.

Persistência write-behind

writeBehind
WaWriteBehindOptions
Agrupa as mensagens recebidas em lotes antes de descarregá-las nas stores messages / threads / contacts.
  • maxPendingKeys?: number
  • maxWriteConcurrency?: number
  • flushTimeoutMs?: number

Proxy

proxy
WaClientProxyOptions
Roteie cada perna através de um proxy de forma independente:
  • ws — a conexão WebSocket.
  • mediaUpload / mediaDownload — transferências de mídia.
  • linkPreview — o fetcher padrão de preview de link.
Cada perna aceita um WaProxyTransport, que é:
  • um dispatcher do undici (WaProxyDispatcher, por exemplo um ProxyAgent do undici) — usado para as pernas baseadas em fetch (mídia, preview de link), ou
  • um Agent http/https do Node (WaProxyAgent) — usado para a perna WebSocket (ws).
O zapo escolhe a forma certa por perna automaticamente.
A perna ws requer o pacote ws, porque o WebSocket nativo do runtime não consegue aceitar um Agent HTTP. Sem um proxy, nenhum pacote extra é necessário.

Proxy HTTP / HTTPS

Use um ProxyAgent do undici (um dispatcher) para as pernas de mídia/preview de link, e um https-proxy-agent (um http.Agent) para a perna ws:

Proxy SOCKS

Use socks-proxy-agent (funciona como um http.Agent para todas as pernas, incluindo ws):

Hosts IPv4 e IPv6

O host do proxy pode ser um domínio ou um literal de IP. Endereços IPv6 devem ser envolvidos em colchetes:
Aponte para o proxy apenas as pernas que você precisar — por exemplo, defina só ws para tunelar a conexão deixando a mídia transferir diretamente, ou vice-versa.

Limpeza da store no logout

logoutStoreClear
WaLogoutStoreClearOptions
Controle por domínio do que o logout() apaga.Por padrão, o arquivo da mailbox (messages, threads, contacts) é preservado para que o usuário mantenha seu histórico ao reparear. Todos os outros domínios (credenciais, estado Signal, app-state, caches, privacy tokens) são limpos para começar o próximo pareamento do zero. true / false explícitos sempre vencem o padrão.

Logging

O WaClient aceita um Logger como segundo argumento do construtor. Se você omitir, um ConsoleLogger('info') padrão é usado. Níveis, do mais baixo ao mais alto: trace, debug, info, warn, error. Duas implementações vêm com o pacote.

ConsoleLogger

Sem dependências. Escreve registros estruturados em console.log / console.warn / console.error. Bom para desenvolvimento, testes e funções serverless onde você não consegue adicionar um transport de logger.

createPinoLogger

Factory async que carrega dinamicamente o pino (e o pino-pretty quando pretty: true), configura e envolve no adapter PinoLogger. Lança optional dependency "pino" is not installed quando o pino não está presente — instale com npm i pino pino-pretty.

PinoLogger (traga o seu Pino)

Se você já configura Pino centralmente — child loggers, transports customizados, destinos em arquivo — construa PinoLogger diretamente para envolver sua instância existente. A factory é uma conveniência; a classe é o adapter de fato, e usá-la evita o import dinâmico do pino.
A assinatura é new PinoLogger(logger, level = 'info'). O nível é encaminhado pra logger.level e usado como o level reportado pelo adapter.

Logger customizado

Precisa de um sink que as implementações nativas não cobrem — Datadog, OpenTelemetry, syslog, um pipeline de observabilidade interno? Implemente a interface Logger e passe a instância pro WaClient. A interface é pequena:
LogLevel é 'trace' | 'debug' | 'info' | 'warn' | 'error'. A biblioteca chama os cinco métodos de level diretamente — não há uma camada de level-gating à frente, então sua implementação é responsável por filtrar contra this.level se quiser pular chamadas baratas. Um exemplo mínimo que encaminha para um sink externo e rastreia bindings por child():
child() é usado internamente para anexar bindings por componente (ex.: { component: 'noise' }, { component: 'signal', sessionId }). Retornar uma nova instância com bindings mesclados — em vez de mutar — mantém esses tags com escopo no subsistema que os produziu.

Plugins

plugins
readonly WaClientPluginDefinition[]
Plugins opcionais de WaClient — hooks de comportamento e/ou coordinators expostos em client[exposeAs]. Autorados com defineWaClientPlugin. O plugin de chamadas de voz (@zapo-js/voip) é a implementação de referência; veja a página do sistema de plugins para saber como conectar e autorar plugins.

Opções avançadas

Raramente necessárias — listadas para completude.
  • chatSocketUrls?: readonly string[] — sobrescreve a lista de endpoints WebSocket de chat do WhatsApp (ex.: rotear por um servidor falso em testes, ou fixar um edge específico).
  • privacyToken?: WaPrivacyTokenOptions — ajusta a emissão de trusted-contact-token (TC token): durações e número de buckets.
  • testHooks?: WaClientTestHooks — fixtures só para testes (ex.: um root CA Noise customizado). Eles não burlam nenhuma verificação de segurança; para realmente pular uma checagem, use as opções dangerous abaixo.

Opções perigosas

As flags dangerous desabilitam, cada uma, uma verificação de segurança que o caminho de produção aplica (verificação de assinatura, checagens de MAC do app-state, …). Elas existem para testes contra um servidor falso. Nunca as habilite em produção.
Última modificação em 12 de julho de 2026