Guia do desenvolvedorIntegrações
Enviar e-mail no n8n
Enviar e-mail pelo Couryo no n8n com o nó HTTP Request (API com idempotência) ou o nó Send Email (SMTP), e receber os eventos de entrega num fluxo com o nó Webhook.
Dois jeitos de enviar e um de receber. Antes: verifique o domínio no Couryo e crie uma chave de API com escopo send.
Enviar pelo nó HTTP Request (recomendado)#
Pela API, cada envio volta com o ID da mensagem e você pode usar uma chave de idempotência: se o fluxo rodar de novo para o mesmo item, o e-mail não sai duplicado.
- Crie uma credencial Header Auth (em Credentials > Add credential): nome
Authorization, valorBearer ck_live_.... - Adicione um nó HTTP Request:
| Campo | Valor |
|---|---|
| Method | POST |
| URL | https://api.couryo.com/v1/emails |
| Authentication | Generic Credential Type > Header Auth (a credencial acima) |
| Send Headers | ligado: Idempotency-Key = {{ 'pedido-' + $json.pedido_id }} |
| Send Body | ligado, Body Content Type JSON, Specify Body Using JSON |
- No corpo, use expressões com os dados do nó anterior:
{
"from": "Loja Exemplo <pedidos@exemplo.com.br>",
"to": "{{ $json.email }}",
"subject": "Pedido {{ $json.pedido_id }} confirmado",
"html": "<p>Oi, {{ $json.nome }}! Recebemos o seu pedido.</p>",
"text": "Oi, {{ $json.nome }}! Recebemos o seu pedido.",
"tags": { "origem": "n8n" }
}A resposta (202) traz { "id": "msg_...", "status": "queued" }. Em erro, o corpo traz error.code e error.message em português: ligue On Error > Continue (using error output) no nó para tratar no fluxo.
Com um template salvo, troque subject, html e text por "template": "pedido-confirmado" e "variables": { "nome": "{{ $json.nome }}" }.
Enviar pelo nó Send Email (SMTP)#
Crie uma credencial SMTP:
| Campo | Valor |
|---|---|
| User | couryo |
| Password | a chave de API (ck_live_...) |
| Host | smtp.couryo.com |
| Port | 587 (STARTTLS) ou 465 |
| SSL/TLS | desligado na 587; ligado na 465 |
No nó Send Email, o From Email precisa estar no domínio verificado.
Receber os eventos de entrega#
- Adicione um nó Webhook com método
POSTe copie a Production URL. - No painel do Couryo, em Webhooks, crie um webhook com essa URL e os eventos que interessam (por exemplo,
bouncedecomplained). Guarde o segredowhsec_. - Ative o fluxo. Cada evento chega com
typeedata(email_id,recipient,smtp_code,explanation...).
Conferir a assinatura#
Para garantir que o evento veio do Couryo, ligue a opção Raw Body no nó Webhook e acrescente um nó Code logo depois:
const crypto = require("crypto");
const secret = $env.COURYO_WEBHOOK_SECRET; // whsec_...
const headers = $input.first().json.headers;
const corpo = (await this.helpers.getBinaryDataBuffer(0, "data")).toString("utf8");
const chave = Buffer.from(secret.replace(/^whsec_/, ""), "base64");
const esperado = crypto
.createHmac("sha256", chave)
.update(`${headers["webhook-id"]}.${headers["webhook-timestamp"]}.${corpo}`)
.digest("base64");
const recebidas = String(headers["webhook-signature"] || "").split(" ").map((s) => s.split(",")[1]);
const recente = Math.abs(Date.now() / 1000 - Number(headers["webhook-timestamp"])) <= 300;
if (!recente || !recebidas.includes(esperado)) throw new Error("assinatura inválida");
return [{ json: JSON.parse(corpo) }];No n8n auto-hospedado, o módulo crypto precisa estar liberado (NODE_FUNCTION_ALLOW_BUILTIN=crypto), e a variável COURYO_WEBHOOK_SECRET precisa existir no ambiente. O formato completo está em Webhooks.
Ideias de fluxo#
- Pedido pago no seu sistema → HTTP Request para o Couryo com
Idempotency-Keyigual ao ID do pedido. - Evento
bounced→ marcar o contato no CRM e avisar o time no canal de vendas. - Evento de cadastro →
POST https://api.couryo.com/v1/eventscom{ "contact": { "email": ... }, "name": "user.signed_up" }para iniciar uma sequência.