Ir para o conteúdo

WF1 — Envio de Fotos de Pedidos Faturados

ID: YvGAoK7CrZOBVSj2 · Status: ✅ ATIVO · Trigger: Webhook POST

Objetivo

Ao receber o XML de uma NF-e de venda, busca automaticamente as fotos dos produtos faturados, gera um link seguro com token temporário e envia para o cliente via e-mail (RD Station) e WhatsApp (Evolution API).

Endpoint do Webhook

POST https://n8n.turmadabia.com.br/webhook/1ac13120-af86-485f-bd22-e3cc3c46bcf0

O corpo da requisição deve conter o XML da NF-e como anexo binário (attachments).


Fluxo Resumido

  1. Recebe XML da NF-e via webhook
  2. Extrai o XML do anexo e converte para JSON
  3. Filtra somente notas de venda com CNPJ de destinatário preenchido
  4. Extrai dados do cliente (nome, e-mail, telefone 1, CNPJ formatado) e referências dos produtos (primeiros 10 chars do cProd)
  5. Busca fotos na tabela materiais_telegram por referência
  6. Gera token alfanumérico de 24 caracteres e monta URLs de acesso
  7. Grava token no Cloudflare KV (TTL 45 dias)
  8. Salva registro na tabela pedidos_midias (UPSERT por numero_nf)
  9. Autentica no RD Station e dispara e-mail ao cliente
  10. Aguarda 5 minutos
  11. Verifica se o telefone 1 (NF-e) existe no WhatsApp via Evolution API
  12. Se válido: envia WhatsApp para o telefone 1
  13. Se inválido: consulta telefone 2 na API Sisplan (por CNPJ), trata e verifica no WhatsApp
  14. Se telefone 2 válido: envia WhatsApp para o telefone 2

Lógica de Validação de Telefone (Fallback WhatsApp)

O fluxo implementa uma estratégia de fallback em duas etapas para garantir que o WhatsApp seja enviado para um número válido.

  • Telefone 1: extraído diretamente da NF-e (campo fone do destinatário). Formatado como 55 + dígitos.
  • Telefone 2: consultado via API Sisplan (api.turmadabia.com.br/clientes?cnpj=XX.XXX.XXX/XXXX-XX). Campo telefone2 do retorno. Formatado como 55 + dígitos.

A verificação usa o nó Evolution API (chat-api / checkWhatsapp). O campo avaliado é data[0].exists = true.

Etapa Ação Resultado
1 Verificar Telefone 1 no WhatsApp exists = true → envia WA para fone 1 ✅
2 (fallback) Consultar fone 2 na API Sisplan Busca por CNPJ formatado (XX.XXX.XXX/XXXX-XX)
3 (fallback) Verificar Telefone 2 no WhatsApp exists = true → envia WA para fone 2 ✅
Fim Se fone 2 também inválido Fluxo encerra sem envio de WhatsApp

Descrição dos Nós

# Nome do Nó Tipo Função
1 [IN] Receber XML Nota Webhook POST Ponto de entrada. Recebe o XML da NF-e como anexo binário
2 Gera xml_puro Code (JS) Extrai o arquivo XML do payload do webhook
3 [CONVERT] XML para JSON XML Node Converte o XML bruto em objeto JSON
4 [FILTER] Validar E-mail Destino IF Filtra por CNPJ preenchido e natureza de operação válida
5 [JS] Extrair Dados e Itens Code (JS) Extrai número da NF, itens únicos, nome/e-mail/telefone 1/CNPJ formatado
6 [DB] Buscar Imagens por Referência PostgreSQL Busca imagens na tabela materiais_telegram por referência
7 [JS] Gerar Token e Links Code (JS) Gera token de 24 chars, monta view_url e zip_url, define expiração
8 [API] Gravar no Cloudflare KV HTTP PUT Grava o token no Cloudflare KV
9 [DB] Salvar no Postgres PostgreSQL UPSERT na tabela pedidos_midias
10 [API] Autenticar no RD Station HTTP POST Autentica no RD Station via refresh_token
11 [EMAIL] Disparar E-mail pelo RD HTTP POST Envia evento de conversão ao RD Station (veggi_connect_hub)
12 Espera de 5 Minutos Wait Aguarda antes de verificar WhatsApp
13 Verificar Telefone 1 no whatsapp Evolution API Verifica se o telefone da NF-e existe no WhatsApp
14 Se Nº 1 Whatsapp Válido IF data[0].exists = true → envia WA / false → fallback
15 [Whatsapp] Envia Whatsapp para o cliente Evolution API Envia link das fotos via WhatsApp para o telefone 1
16 Consulta Telefone 2 - Sisplan HTTP Request GET api.turmadabia.com.br/clientes?cnpj={cnpj_formatado}
17 Tratamento para Nº2 Code (JS) Extrai telefone2 do retorno da API e formata como 55+dígitos. Mantém todos os dados anteriores via spread.
18 Verificar Telefone 2 no whatsapp Evolution API Verifica se o telefone 2 (Sisplan) existe no WhatsApp
19 Se Nº 2 Whatsapp Válido IF data[0].exists = true → envia WA / false → fim
20 [Whatsapp] Envia Whatsapp para o cliente nº2 Evolution API Envia link das fotos via WhatsApp para o telefone 2

Detalhes dos Nós Principais

[JS] Extrair Dados e Itens

Além dos dados básicos, o nó extrai e formata o CNPJ do destinatário:

  • cliente_telefone: telefone 1 da NF-e, formatado como 55 + dígitos
  • cliente_cnpj: CNPJ formatado com máscara XX.XXX.XXX/XXXX-XX (necessário para a consulta na API Sisplan)

O CNPJ vem como string numérica pura na NF-e (ex: 17216144000182) e é formatado via regex.

const cnpjBruto = (destinatario.CNPJ || "").replace(/\D/g, "");
const cnpjFormatado = cnpjBruto.replace(
  /^(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})$/,
  "$1.$2.$3/$4-$5"
);

Consulta Telefone 2 - Sisplan

Acionado quando o telefone 1 não é encontrado no WhatsApp.

  • URL: https://api.turmadabia.com.br/clientes
  • Método: GET
  • Autenticação: Bearer Token
  • Parâmetro: cnpj = {{ $('[JS] Extrair Dados e Itens').item.json.cliente_cnpj }}

Retorno esperado:

[
  {
    "quantidade": 1,
    "dados": [
      {
        "telefone2": "XXXXXXXXXXX",
        ...
      }
    ]
  }
]

Tratamento para Nº2

const dados = $input.first().json.dados[0];
const fone2Bruto = dados.telefone2 || "";
const fone2Tratado = fone2Bruto
  ? "55" + fone2Bruto.replace(/\D/g, "")
  : "";

return [{
  json: {
    ...$('[JS] Extrair Dados e Itens').item.json,
    cliente_telefone2: fone2Tratado,
  }
}];

Info

O spread ...item.json preserva todos os campos anteriores (cliente_nome, numero_nf, view_url, etc.) necessários para o envio da mensagem.

Warning

O nó está em modo Run Once for All Items. Isso é intencional — a consulta ao Sisplan é feita uma única vez por CNPJ, independente do número de itens da nota.


Filtro de Natureza de Operação (natOp)

O nó [FILTER] Validar E-mail Destino só processa notas com as seguintes naturezas:

  • VENDA DE MERCADORIA
  • VENDA DE MERCADORIA DO ESTABELECIMENTO
  • VENDA DE MERCADORIA ADQUIRIDA OU RECEBIDAS DE TERCEIROS
  • VENDA DE PRODUÇÃO DO ESTABELECIMENTO ORIGINADA DE ENCOMENDA
  • VENDA ADQUIRIDA DE TERCEIROS ORIGINADA DE ENCOMENDA PARA ENTREGA FUTURA
  • VENDA DE PRODUTO DO ESTABELECIMENTO DESTINADA A NÃO CONTRIBUINTE
  • VENDA DE MERCADORIA ADQUIRIDA OU RECEBIDA DE TERCEIROS, DESTINADA A NÃO CONTRIBUINTE
  • VENDA DE PRODUÇÃO DO ESTABELECIMENTO DESTINADA A ZONA FRANCA
  • VENDA DE MERCADORIA ADQUIRIDA DE TERCEIRO DESTINADA A ZONA FRANCA DE MANAUS

Notas sem CNPJ de destinatário ou com outras naturezas são descartadas silenciosamente.


Lógica de Token e URLs

  • Token: string alfanumérica de 24 caracteres (minúsculas + números)
  • Expira em 45 dias (TTL no KV: 3.888.000 segundos; campo expires_at no PostgreSQL)
  • view_url: https://hub.grupoveggi.com.br/?token={token}
  • zip_url: https://drive.grupoveggi.com.br/{token}

Warning

O refresh_token do RD Station está hardcoded no body do nó 10. Se o e-mail parar de funcionar, esse token pode ter expirado — atualizar diretamente no nó.