Webhooks da Emitra no n8n
Atualizado em
Nesta página
O n8n roda na nuvem ou no seu servidor e permite validar a assinatura do webhook com código, o que o torna a opção mais completa entre as ferramentas sem código.
Pré-requisitos#
- Uma instância do n8n acessível pela internet em https, na porta 443. A Emitra recusa URLs com IP privado, outras portas ou redirect. Veja Requisitos da URL.
- Usuário owner ou admin na Emitra.
- Uma chave de API, se o fluxo for chamar a Emitra de volta.
1. Configure o nó Webhook#
- Crie um workflow e adicione o nó Webhook.
- Método HTTP:
POST. - Peça ao nó para entregar o corpo bruto (opção de raw body), porque a assinatura é calculada sobre os bytes originais.
- Em Respond, responda imediatamente (
200), sem esperar o fim do workflow. A Emitra espera no máximo 10 segundos. - Copie a URL de produção do nó (não a de teste, que só funciona com o editor aberto).
2. Cadastre a URL na Emitra#
No painel, vá em Notas › Automação › Integrações › Webhooks, crie o webhook com a URL do n8n, escolha os eventos e guarde o segredo. Use Testar para disparar um evento de exemplo.
3. Valide a assinatura#
Adicione um nó Code depois do Webhook. Guarde o segredo em uma credencial ou variável de ambiente do n8n, nunca no próprio workflow exportado.
const crypto = require("crypto");
const item = $input.first();
const headers = item.json.headers;
const secret = $env.EMITRA_WEBHOOK_SECRET;
const timestamp = headers["x-portalnfse-timestamp"];
const signature = headers["x-portalnfse-signature"] || "";
// O corpo bruto chega como binário quando a opção de raw body está ligada
const rawBody = Buffer.from(item.binary.data.data, "base64").toString("utf8");
const expected =
"sha256=" + crypto.createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(timestamp)) <= 300;
const same =
expected.length === signature.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
if (!fresh || !same) {
throw new Error("Assinatura do webhook inválida");
}
return [{ json: { ...JSON.parse(rawBody), delivery_id: headers["x-portalnfse-delivery"] } }];4. Roteie e processe#
- Use um nó Switch ou IF sobre
typepara tratar cada evento. - Descarte eventos repetidos pelo
id(por exemplo, consultando uma tabela antes de agir). Veja idempotência no receptor.
5. Chame a API com HTTP Request#
Crie uma credencial de autenticação por header no n8n com Authorization: Bearer <sua chave> e use no nó HTTP Request:
| Campo | Valor |
|---|---|
| Método | GET |
| URL | https://emitra.com.br/api/v1/integracao/nfse/{{ $json.data.nfse_id }} |
| Autenticação | a credencial com a chave emt_test_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
Para emitir pela API a partir de outro sistema, faça POST /integracao/nfse com o header Idempotency-Key estável. Veja a referência de NFS-e.