n8n-nodes-zapcore
v0.1.4
Published
Nó comunitário n8n para a API REST v2 do zapCore (WhatsApp) — ações geradas da OpenAPI e gatilho de webhook com verificação HMAC
Maintainers
Readme
n8n-nodes-zapcore
Nó comunitário do n8n para a API REST v2 do zapCore (WhatsApp). Dois nós e uma credencial:
- zapCore faz: enviar texto, mídia (imagem, vídeo, áudio, documento, figurinha, PTV, álbum, GIF), botões, lista, carrossel, enquete e voto em enquete, link com prévia, localização, contato, evento, reação, editar e apagar; fila de envio assíncrona (listar, consultar, cancelar); grupos, comunidades, etiquetas, chat (presença, lido/não lido, histórico, busca de conversas, fixar, arquivar), sessão (status, QR, código de pareamento, conectar, desconectar), usuário (checar número, info, contatos), canais, status, perfil, formulários, campanhas em lote e webhook. 217 operações: a API v2 inteira, exceto as rotas de administração da instalação.
- zapCore Trigger: recebe os webhooks, verifica a assinatura HMAC e filtra por tipo de evento.
- Credencial zapCore API: URL base + token da instância (+ chave HMAC opcional).
Desenho: docs/specs/2026-10-05-paridade-ryzeapi-fase3-n8n.md.
Instalação
Ainda não publicado no npm. Não instale por nome (Settings → Community Nodes ou
npm install n8n-nodes-zapcore): o nome ainda não é nosso no registro, e um pacote de terceiros com esse nome receberia a credencial com o token da instância. Até a publicação, instale do código desta pasta (veja Desenvolvimento abaixo) ou use o nó HTTP do n8n. Quando for publicado, a instalação será Settings → Community Nodes → Install →n8n-nodes-zapcoree este aviso sai.
Em Docker, monte ~/.n8n como volume para o nó sobreviver à troca de imagem.
Credenciais
| Campo | O que é |
|---|---|
| Base URL | Endereço do motor, sem /api/v2 (ex.: https://api.seudominio.com) |
| Instance Token | Token da instância (número). Vai no header token |
| Webhook HMAC Secret | Opcional. A mesma chave gravada em POST /session/hmac/config |
O botão Test chama GET /api/v2/session/status. Ele segue a mesma regra do nó: Base URL http:// para host que não é localhost exige ligar Allow Insecure HTTP (BREAKING: antes o Test mandava o token em claro para http remoto). Sem o opt-in o teste falha em base-url-precisa-ser-https.invalid, sem enviar o token.
Idempotency-Key automática. Quando o campo fica vazio, o nó gera a chave a partir de execução + nó + rodada (runIndex) + item + conteúdo. Isso cobre só o Retry On Fail; um nó em laço, em rodadas diferentes, gera chaves diferentes (envio intencional não é deduplicado). Se o motor responder 409 idempotency_in_progress (o mesmo envio ainda em voo), o nó espera o Retry-After e repete com a mesma chave (até 3 tentativas, espera máxima 30 s); quando o motor reaproveita a resposta guardada, cada item sai com idempotentReplay: true. Retry manual pela lista de execuções cria execução nova e envia de novo: para deduplicar entre execuções, preencha o campo por expressão (ex.: {{$json.id}}).
Exemplos
Responder toda mensagem recebida
- zapCore Trigger → Events:
Message. - IF →
{{ $json.event.Info.IsFromMe }}éfalse. - zapCore → Message → Send Text → Phone:
{{ $json.event.Info.Chat }}, Body:Recebemos sua mensagem!.
Enviar um PDF gerado no workflow
HTTP Request (baixa o arquivo, saída binária data) → zapCore → Message →
Send Document → Phone, File Name, e Input Binary Field = data. O nó
converte o binário em data URL sozinho (e, para áudio com codecs=opus, põe o mime
completo no campo próprio: o motor recusa parâmetro dentro do data URL).
Checar números antes de uma campanha
zapCore → User → Check → Phone: 5527999999999, 5527988888888 (vírgula ou array
JSON). A resposta traz Users[] com IsInWhatsapp e o JID de cada número. Use um
Split Out em Users para seguir item a item.
Votar em enquete, GIF e link com prévia
zapCore → Message → Send Pollvote (campos Poll Msg ID, do histórico local, e Options exatas da enquete), Send Gif (Phone e Gif: mp4 até 16 MB por URL ou data URL) e Send Link (Phone, URL e, opcionalmente, Title, Description e Body).
Fila de envio assíncrona
Em qualquer envio (por exemplo Message → Send Text), Additional Fields → Async =
true enfileira e responde 202 na hora; Track Source e Track ID etiquetam o envio.
Depois, em Message: Get Send Async (lista a fila), Get Send Async By ID (estado de um
envio), Delete Send Async By ID (cancela um pendente; 409 se já saiu) e
Send Async Cancel (cancela em massa por Track Source e/ou Track ID).
Buscar conversas
zapCore → Chat → Get Search: filtros por tipo, trecho do JID, etiqueta, período e
estado (arquivada, fixada, silenciada, não lida). Os contadores (counts) só vêm na primeira
página: sem Cursor e com Offset ausente ou 0.
Botões / lista / carrossel
Os campos estruturados (Buttons, Sections, Cards) recebem JSON. O formato de cada
um está no portal do desenvolvedor do seu zapCore (/dev), na rota correspondente.
Paginação: em listagens, ative Options → Full Response para receber meta.next_cursor
e repasse-o no campo Cursor da chamada seguinte.
Campo novo na API antes de atualizar o nó: Options → Extra Body (JSON) mescla campos extras no corpo.
Gatilho e assinatura
Com a credencial preenchida, o gatilho cadastra a própria URL na instância ao ativar
(POST /webhook, com os eventos escolhidos) e restaura a URL anterior ao desativar.
Se a instância já entrega para outra URL, a ativação falha em vez de roubar as
entregas de outra integração. Ligue Options → Replace Existing Webhook para trocar.
Desligue Register Webhook Automatically para cadastrar à mão.
A URL anterior fica guardada no static data do nó, que o n8n persiste logo após
registrar os webhooks (conferido no n8n 2.35). Ressalva: se esse static data se
perder entre ativar e desativar (workflow importado/duplicado, banco restaurado, versão
do n8n que não o persista), a desativação remove o webhook em vez de restaurar o
anterior. Recadastre a URL antiga à mão (POST /webhook).
Com Webhook HMAC Secret preenchido:
- exige
x-hmac-signature-v2= HMAC-SHA256(x-webhook-timestamp+.+ corpo cru) e carimbo com no máximo 300 s (ajustável). Fecha a janela de replay; - compara em tempo constante, sobre os bytes crus (formulário ou JSON);
- inválida → 401 e o workflow não roda. A verificação acontece antes do filtro de eventos;
- assinatura só v1 (sem carimbo) é recusada, a menos que Accept V1 Signature esteja ligado.
Sem segredo, o workflow não ativa. Uma URL de gatilho sem assinatura dispara para qualquer um que a descubra. Para aceitar mesmo assim (rede fechada, teste), ligue Options → Allow Unsigned Webhooks, padrão desligado; sem ele, toda entrega sem segredo configurado também recebe 401.
Se vier qualquer peça da v2 (x-hmac-signature-v2 ou x-webhook-timestamp), a v2
precisa fechar inteira: o gatilho nunca cai para a v1 nesse caso. Se o n8n não expuser
os bytes crus, o corpo é reconstruído como o Go serializa; o que não puder ser
reconstruído é recusado com 401.
A saída é o evento já achatado (o jsonData do formato formulário vira objeto, igual ao
WEBHOOK_FORMAT=json), mais _zapcore com webhookId, attempt, redelivery e qual
assinatura foi verificada. Use webhookId para deduplicar reentregas.
Por que este nó
- Gerado da OpenAPI do motor: as operações saem do mesmo snapshot que o motor testa
a cada build (
npm run gerar:checkfalha se divergirem). Rota nova não fica de fora porque alguém esqueceu de escrever à mão. - Assinatura verificada de verdade, com proteção contra replay. Não só repassada como header para o workflow conferir.
- Registro do webhook que não atropela outra integração e se desfaz sozinho.
- Binário → mídia sem nó de conversão no meio.
- Erros com código estável do envelope v2 (
session_not_connected,rate_limited...), bons para ramificar o workflow. - Pode ser usado como ferramenta de agente de IA (
usableAsTool).
Desenvolvimento
npm install # .npmrc liga ignore-scripts: nada de postinstall de dependência
npm run gerar # regenera nodes/ZapCore/operacoes.generated.ts do snapshot
npm run build
npm run lint # n8n-node lint (modo strict)
npm test # HMAC, gatilho, gerador, montagem de requisição
npm run dev # sobe um n8n local com o nó carregadoO snapshot lido é painel/src/dados/openapi.json (o mesmo de TestOpenAPISnapshot).
Depois de mexer em rota no motor: regenere o snapshot no Go, depois npm run gerar.
Publicação (npm publish) é feita pelo dono do pacote, com 2FA.
Licença
MIT.
