Pular para o conteúdo

n8n, Make e Zapier

Ferramentas de automação rodam no servidor delas — então a chave fica protegida lá, nas credenciais da ferramenta. Você usa dois blocos:

  • Chamar a API (enviar mensagem, criar contato, mover card): um nó/módulo HTTP.
  • Receber eventos (mensagem recebida, etapa alterada): um gatilho de webhook.

Os dados são sempre os mesmos:

Campo Valor
Método POST (enviar), GET (consultar), PATCH (atualizar)
URL https://platform.toptalking.com.br/v1/messages (ou outro endpoint da referência)
Cabeçalho Authorization: Bearer tt_live_...
Cabeçalho Content-Type: application/json
Cabeçalho (envios) Idempotency-Key: <id único da operação>
Corpo JSON

Exemplo de corpo para enviar mensagem:

{
"to": "5511999998888",
"contact_name": "Maria Souza",
"text": "Olá, Maria! Recebemos seu pedido #1234. Obrigado pela compra!"
}
  1. Adicione um nó HTTP Request.

  2. Method: POST. URL: https://platform.toptalking.com.br/v1/messages.

  3. Authentication: Generic Credential Type → Header Auth. Crie a credencial com Name Authorization e Value Bearer tt_live_SUA_CHAVE. (Assim a chave fica guardada nas credenciais, e não visível no fluxo.)

  4. Send Headers: ligado, com Idempotency-Key = uma expressão única por operação, por exemplo:

    {{ 'pedido-' + $json.pedido_id + '-confirmado' }}
  5. Send Body: ligado, Body Content Type JSON, Specify Body Using JSON (com o campo em modo Expression para os {{ }} funcionarem):

    {
    "to": "{{ $json.telefone }}",
    "contact_name": "{{ $json.nome }}",
    "text": "Olá, {{ $json.nome }}! Recebemos seu pedido #{{ $json.pedido_id }}."
    }
  6. Em Settings do nó, ative Retry On Fail se quiser retentativas — a Idempotency-Key garante que não haverá mensagens duplicadas.

Para listas grandes, use a opção Pagination do nó com o parâmetro cursor recebendo {{ $response.body.next_cursor }} e pare quando has_more for false.

  1. Crie o gatilho de webhook na ferramenta e copie a URL de produção dele:
    • n8n: nó Webhook, método POST.
    • Make: módulo Webhooks → Custom webhook.
    • Zapier: gatilho Webhooks by Zapier → Catch Raw Hook (mantém o corpo cru e os cabeçalhos).
  2. No painel da TopTalking, em Configurações → Desenvolvedor → Webhooks → Novo webhook, cole a URL e escolha os eventos.
  3. Clique em Enviar teste: a ferramenta deve receber um evento ping. Use-o para mapear os campos (type, data.message.text, data.contact.phone…).
  4. No fluxo, filtre pelo campo type (ex.: só message.received) e ignore o ping.

A URL do gatilho é pública: qualquer um que a descubra pode mandar eventos falsos. Escolha uma das proteções:

Opção 1 — validar a assinatura (recomendado quando a ferramenta tem o corpo cru e um passo de código). A regra é a de Verificar a assinatura: v1 = HMAC-SHA256 em hex de <t>.<corpo cru> com o segredo whsec_....

No n8n, ative a opção Raw Body do nó Webhook e adicione um nó Code (JavaScript) logo depois:

n8n — nó Code (Run Once for All Items)
const crypto = require('crypto');
const SECRET = 'whsec_SEU_SEGREDO'; // segredo de assinatura do webhook na TopTalking
const item = $input.first();
const cabecalho = item.json.headers['x-toptalking-signature'] || '';
// Corpo cru (opção "Raw Body" do nó Webhook).
const corpo = (await this.helpers.getBinaryDataBuffer(0, 'data')).toString('utf8');
const partes = Object.fromEntries(
cabecalho.split(',').map((p) => {
const i = p.indexOf('=');
return [p.slice(0, i).trim(), p.slice(i + 1).trim()];
}),
);
const t = partes.t;
const v1 = partes.v1 || '';
const esperado = Buffer.from(
crypto.createHmac('sha256', SECRET).update(`${t}.${corpo}`).digest('hex'),
);
const recebido = Buffer.from(v1);
const recente = Math.abs(Date.now() / 1000 - Number(t)) <= 300;
const valido =
recente && recebido.length === esperado.length && crypto.timingSafeEqual(recebido, esperado);
if (!valido) throw new Error('Assinatura inválida: evento ignorado.');
return [{ json: JSON.parse(corpo) }];

Se o seu n8n bloquear o require('crypto'), libere o módulo com a variável de ambiente NODE_FUNCTION_ALLOW_BUILTIN=crypto (n8n auto-hospedado).

No Zapier, o Catch Raw Hook entrega o corpo cru e os cabeçalhos; dá para validar num passo Code by Zapier (JavaScript) com a mesma lógica acima.

Opção 2 — tratar o webhook só como aviso e confirmar na API. Quando não der para validar a assinatura (comum no Make), não confie no conteúdo do evento: use apenas o ID e busque o dado real na API com a sua chave. Um evento falso não terá um ID válido na sua conta.

Evento Confirme com
message.received, message.sent, message.status_updated GET /v1/messages/{data.message.id}
contact.created, contact.updated, contact.stage_changed GET /v1/contacts/{data.contact.id}
scheduled_message.sent, scheduled_message.failed GET /v1/scheduled-messages/{data.scheduled_message.id}
channel.status_updated GET /v1/channels/{data.channel.id}
campaign.status_updated GET /v1/campaigns/{data.campaign.id}

Em qualquer opção: responda rápido (a ferramenta normalmente já responde 200 sozinha), e deduplique pelo id do evento — a mesma entrega pode chegar mais de uma vez. Veja Entregas e novas tentativas.