npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

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

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-zapcore e 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

  1. zapCore Trigger → Events: Message.
  2. IF → {{ $json.event.Info.IsFromMe }} é false.
  3. 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:check falha 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ó carregado

O 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.