Pular para o conteúdo principal

Documentation Index

Fetch the complete documentation index at: https://zapo.to/llms.txt

Use this file to discover all available pages before exploring further.

O WhatsApp endereça usuários de duas formas, e o zapo expõe ambas. Entender a distinção importa assim que você mexe com grupos, porque o WhatsApp está migrando as identidades de grupo para LID por privacidade.

PN vs LID

JID de número de telefone (PN)LID
Forma5511999999999@s.whatsapp.net<opaque-id>@lid
Sufixo do servidor@s.whatsapp.net@lid
Revela o número de telefoneSimNão
Detecte com!isLidJid(jid)isLidJid(jid)
Um LID (“linked identity”) é um identificador estável e opaco que representa um usuário sem expor seu número de telefone. O WhatsApp usa LIDs cada vez mais em grupos e comunidades para que os membros possam interagir sem compartilhar seu número.
import { isLidJid } from 'zapo-js'

isLidJid('5511999999999@s.whatsapp.net') // false  (PN)
isLidJid('199998888777@lid')             // true   (LID)

Addressing mode

Ao enviar para um grupo, a mensagem é endereçada aos participantes por PN ou por LID — o addressingMode: 'pn' | 'lid'. O zapo resolve isso automaticamente: ele varre os participantes do grupo e usa lid se qualquer participante for um LID, caso contrário pn. O servidor pode confirmar ou sobrepor a escolha, o que é refletido de volta no resultado do publish:
const result = await client.message.send(groupJid, 'hi')
console.log(result.ack.addressingMode) // 'pn' | 'lid'
Normalmente você não define isso por conta própria — é derivado da composição do grupo.

O que você recebe em uma mensagem de entrada

Um WaIncomingMessageEvent carrega ambos os identificadores quando o servidor os fornece:
CampoSignificado
senderJidO JID primário do remetente para esta mensagem (PN ou LID, conforme o addressing mode).
senderAltA forma alternativa — se senderJid for um PN, este é o LID, e vice-versa (quando disponível).
recipientJidSeu JID de recebimento.
recipientAltA forma alternativa do destinatário (quando disponível).
client.on('message', (event) => {
  console.log('primary:', event.senderJid)   // ex.: 1999...@lid em um grupo LID
  console.log('alt:    ', event.senderAlt)    // ex.: 5511...@s.whatsapp.net
})
Então, em um grupo endereçado por LID, você normalmente verá senderJid como um @lid e senderAlt como o JID de telefone (se o servidor o compartilhar).

Respondendo — qual JID usar

O client.message.send aceita tanto um JID PN quanto um LID e normaliza o destino para você, então você raramente precisa converter:
// Todos válidos:
await client.message.send('5511999999999', 'hi')                  // dígitos → JID PN
await client.message.send('5511999999999@s.whatsapp.net', 'hi')   // JID PN
await client.message.send('199998888777@lid', 'hi')               // JID LID
Sempre prefira enviar por LID quando você tiver um. O LID é a identidade que preserva privacidade e é compatível com o futuro, para a qual o WhatsApp está migrando — endereçar um peer por LID é a escolha à prova de futuro e evita vazar/depender de números de telefone. Recorra ao PN apenas quando nenhum LID estiver disponível.Obtenha o LID a partir do senderAlt do evento de entrada (quando senderJid for um PN) ou resolva-o com getLidsByPhoneNumbers.
Em um grupo, sempre responda para event.chatJid (o JID do grupo), não para o JID de um participante. Para chats 1:1, prefira o LID do peer; event.chatJid / event.senderJid também funcionam, sejam eles um PN ou um LID.

Mapeando um número de telefone para o seu LID

Para resolver LIDs de um conjunto de números de telefone, use o profile coordinator:
const results = await client.profile.getLidsByPhoneNumbers([
  '5511999999999',
  '5511888888888'
])

for (const r of results) {
  // SignalLidSyncResult: { phoneJid, lidJid, exists }
  console.log(r.phoneJid, '→', r.lidJid, '(exists:', r.exists, ')')
}
lidJid é null quando o servidor não tem mapeamento de LID para aquele número.

Mudanças de LID

O LID de um usuário pode mudar (no lado do servidor, por privacidade). Quando isso acontece, você recebe um mex_notification do tipo lid_change:
client.on('mex_notification', (event) => {
  if (event.kind === 'lid_change') {
    console.log('LID changed:', event.oldLidJid, '→', event.newLidJid)
    // WaMexLidChangeEvent
  }
})
O zapo cuida da contabilidade subjacente da sessão Signal; este evento é para seus próprios caches/contabilidade.

Onde a ligação PN ↔ LID é armazenada

Vários schemas de app-state rastreiam o relacionamento e o sincronizam entre seus dispositivos (veja mutações de chat):
SchemaPapel
LidContactPerfil de contato (nome/nome de usuário) indexado por um LID.
PnForLidChatLembra o JID de telefone de um chat que é primariamente endereçado por LID.
ShareOwnPnSe o seu próprio número de telefone é compartilhado em um determinado contexto.

Sessões Signal

As sessões Signal são indexadas pelo JID canônico (PN ou LID) mais o id do dispositivo. O zapo canonicaliza as variantes de servidor hospedado (hosted.lidlid, hosted → s.whatsapp.net) antes das buscas, e mantém sessões para ambas as formas de endereçamento. Se você algum dia precisar forçar uma nova sincronização de sessão para um peer, use:
await client.message.syncSignalSession(jid)
Last modified on May 27, 2026