Ir para o conteúdo principal

Guia de integração com o n8n

Resposta rápida: use o nó de gatilho Webhook do n8n para receber os eventos report.completed da Surmado. Aponte o webhook_url da Surmado para a URL do webhook do n8n, filtre por event e report.product e envie o payload para Google Sheets, Slack, Postgres ou qualquer outra integração. O n8n auto-hospedado é gratuito; o n8n Cloud custa $20/mês.

Tempo de leitura: 16 minutos


Pré-requisitos

  1. Instância do n8n (auto-hospedada via Docker ou n8n Cloud)
  2. Chave de API da Surmado (sur_live_...) – crie em app.surmado.com → Settings → API Keys
  3. Uma URL pública para o seu webhook do n8n (o n8n Cloud cuida disso; a versão auto-hospedada precisa de um domínio ou túnel)

Por que o n8n

  • Auto-hospedável: seu fluxo de trabalho roda na sua própria infraestrutura (Docker, Kubernetes, servidor físico)
  • Código aberto: inspecione cada nó e estenda com código próprio
  • Sem cobrança por tarefa: execuções ilimitadas na versão auto-hospedada (só o custo do servidor)
  • Mais de 400 nós nativos: Notion, Google Sheets, Slack, Airtable, PostgreSQL, HTTP Request, Code etc.
  • Cofre de credenciais: guarde sua chave de API da Surmado uma vez e use em vários fluxos de trabalho

Início rápido: auto-hospedado via Docker

docker volume create n8n_data

docker run -d --name n8n \
  -p 5678:5678 \
  -v n8n_data:/home/node/.n8n \
  -e N8N_HOST="n8n.yourdomain.com" \
  -e WEBHOOK_URL="https://n8n.yourdomain.com/" \
  n8nio/n8n

Depois, configure um proxy reverso de n8n.yourdomain.com para http://localhost:5678 com Caddy / Nginx / Traefik, para que a Surmado alcance o seu endpoint de webhook por HTTPS.


Guarde sua chave de API da Surmado

No n8n, vá em Credentials → New → Header Auth (ou use a credencial nativa do nó genérico HTTP Request):

  • Name: Surmado API
  • Header name: Authorization
  • Header value: Bearer sur_live_YOUR_API_KEY

Use essa credencial em qualquer nó HTTP Request que chame api.surmado.com.


O padrão de integração

  1. Nó de gatilho Webhook. O n8n fornece uma URL como https://n8n.yourdomain.com/webhook/abc123.
  2. Configure a Surmado para enviar por POST os relatórios concluídos a essa URL, usando webhook_url ao criar um relatório.
  3. Nó IF para filtrar por event e report.product.
  4. (Opcional) Nó HTTP Request para chamar GET /v1/reports/{{ $json.report.id }} e obter dados mais detalhados.
  5. Nós de destino: Google Sheets, Slack, Notion, Postgres etc.

Exemplo de payload do nó Webhook

{
  "event": "report.completed",
  "timestamp": "2026-04-15T12:00:00+00:00",
  "report": {
    "id": "rpt_abc123xyz",
    "token": "SIG-2026-04-A1B2C",
    "product": "signal",
    "status": "completed",
    "tier": "basic",
    "data_url": "https://api.surmado.com/v1/reports/rpt_abc123xyz",
    "pdf_url": "https://api.surmado.com/v1/reports/view/VIEW_TOKEN",
    "summary": {
      "business_name": "Acme Coffee Roasters",
      "presence_score": 34.2,
      "authority_score": 42.7,
      "competitive_rank": 4,
      "top_competitor": "Blue Bottle"
    }
  }
}

Relatórios de Strategy ("product": "solutions") chegam sem o objeto summary: apenas report.token e report.pdf_url.


Fluxo 1: AI Visibility no Google Sheets

Nó 1: gatilho Webhook

  • HTTP method: POST
  • Path: surmado-signal (o n8n vai gerar https://n8n.yourdomain.com/webhook/surmado-signal)
  • Response mode: Immediately (retorna 200 OK assim que o n8n recebe)

Passe essa URL para a Surmado:

curl -X POST https://api.surmado.com/v1/reports/signal \
  -H "Authorization: Bearer sur_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "brand_slug": "acme_corp",
    "url": "https://acme.com",
    "email": "founder@acme.com",
    "industry": "B2B SaaS",
    "location": "United States",
    "persona": "Small business owners",
    "pain_points": "Losing track of customer conversations",
    "brand_details": "Simple CRM with email integration",
    "direct_competitors": "HubSpot, Pipedrive",
    "webhook_url": "https://n8n.yourdomain.com/webhook/surmado-signal"
  }'

Clique em Listen for test event no nó Webhook e depois dispare um relatório para que o n8n capture a estrutura do payload.

Nó 2: IF

Condição 1: {{ $json.event }} equals report.completed Condição 2: {{ $json.report.product }} equals signal

Combinar: AND

Nó 3: Google Sheets: Append row

Operation: Append Spreadsheet / Sheet: sua planilha de acompanhamento

Mapeamento de colunas:

  • Date: {{ $json.timestamp }}
  • Token: {{ $json.report.token }}
  • Business: {{ $json.report.summary.business_name }}
  • Presence Score: {{ $json.report.summary.presence_score }}
  • Authority Score: {{ $json.report.summary.authority_score }}
  • Competitive Rank: {{ $json.report.summary.competitive_rank }}
  • Top Competitor: {{ $json.report.summary.top_competitor }}

Ative o fluxo de trabalho. Todo relatório de AI Visibility concluído passa a ser registrado.


Fluxo 2: Site Audit com alerta condicional no Slack

Webhook → IF (report.product = scan) → Google Sheets (sempre) → IF (report.summary.performance_score < 70) → Slack.

Mensagem do Slack:

:warning: Performance regression on {{ $json.report.summary.business_name }}

Performance: {{ $json.report.summary.performance_score }} (below 70 threshold)
SEO: {{ $json.report.summary.seo_score }}
Accessibility: {{ $json.report.summary.accessibility_score }}
Critical issues: {{ $json.report.summary.critical_issues_count }}

View report: {{ $json.report.pdf_url }}

Fluxo 3: resumo em PDF do Strategy

O Strategy não inclui resumo. Padrão:

  1. Webhook → IF (report.product = solutions) → Send Email (Gmail, SMTP, SendGrid).

Corpo do e-mail:

<p>Strategy report <code>{{ $json.report.token }}</code> is ready.</p>
<p><a href="{{ $json.report.pdf_url }}">View the full report (PDF)</a></p>

Buscar dados mais detalhados pela API REST

O resumo do webhook atende à maioria das necessidades. Para variação por plataforma, problemas por página ou detalhes das lacunas de conteúdo, adicione um nó HTTP Request depois do filtro:

Nó: HTTP Request

  • Method: GET
  • URL: https://api.surmado.com/v1/reports/{{ $json.report.id }}
  • Authentication: credencial predefinida → Surmado API (o Header Auth que você criou acima)
  • Response format: JSON

Os nós seguintes podem então usar {{ $json.public_intelligence.data.platform_variance.chatgpt.presence_score }}, {{ $json.public_intelligence.data.audit_data.enrichment.content_gaps.executive_summary }} etc.


Verificação de assinatura do webhook

Em produção, verifique o cabeçalho X-Surmado-Signature antes de confiar no payload. A Surmado assina os webhooks com HMAC-SHA256 sobre uma representação JSON canonizada.

Nó Function: verificar assinatura

const crypto = require('crypto');

const secret = $env.SURMADO_WEBHOOK_SECRET;
const signature = $('Webhook').first().json.headers['x-surmado-signature'];
const body = $('Webhook').first().json.body;

function canonicalize(value) {
  if (value === null || typeof value !== 'object') return JSON.stringify(value);
  if (Array.isArray(value)) return '[' + value.map(canonicalize).join(',') + ']';
  const keys = Object.keys(value).sort();
  return '{' + keys.map(k => JSON.stringify(k) + ':' + canonicalize(value[k])).join(',') + '}';
}

function asciiEscape(str) {
  return str.replace(/[\u0080-\uffff]/g, c =>
    '\\u' + ('0000' + c.charCodeAt(0).toString(16)).slice(-4)
  );
}

const canonical = asciiEscape(canonicalize(body));
const expected = crypto.createHmac('sha256', secret).update(canonical).digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex'))) {
  throw new Error('Invalid webhook signature');
}

return [{ json: body }];

Encadeamento: Webhook → Function (verificar) → IF (filtro) → nós de destino.


Formatos de token

  • AI Visibility: SIG-YYYY-MM-XXXXX (regex: SIG-\d{4}-\d{2}-[A-Z0-9]{5})
  • Site Audit: SCN-YYYY-MM-XXXXX (regex: SCN-\d{4}-\d{2}-[A-Z0-9]{5})
  • Strategy: SOL-YYYY-MM-XXXXX (regex: SOL-\d{4}-\d{2}-[A-Z0-9]{5})

Os tokens não expiram. As URLs de download assinadas da API REST valem por cerca de 15 minutos; os links mágicos pdf_url dos webhooks valem por cerca de 30 dias.


Padrões avançados

Direcione por produto com Switch

Use um nó Switch em $json.report.product com casos para signal, scan e solutions. Cada caso leva a um fluxo de trabalho específico do produto. Uma única URL de webhook atende todos os tipos de relatório.

Grave no Postgres para análise de séries temporais

Adicione um nó Postgres depois do filtro IF que faça INSERT de (timestamp, token, report_id, product, business_name, presence_score, authority_score, ...) em uma tabela de relatórios. Consulte depois com Grafana ou Metabase para montar painéis de tendência.

Roteamento multicliente para agências

Use um Data store (ou um banco de dados externo) que associe business_name / brand_slug à configuração do cliente (qual canal do Slack, qual aba da planilha etc.). Consulte a cada relatório e direcione de forma dinâmica.


Solução de problemas

O webhook não dispara – ative o fluxo de trabalho (o n8n só processa webhooks quando o fluxo está ativo, não durante os testes). Confirme que o webhook_url foi definido ao criar o relatório. Use o webhook.site como URL de teste para verificar se a Surmado envia o payload esperado.

O nó HTTP Request retorna 401 – a credencial não está associada, ou a chave está sem o prefixo Bearer . O valor completo do cabeçalho deve ser Bearer sur_live_....

Os campos chegam vazios nos nós seguintes – confirme o tipo de produto. Os webhooks de Strategy não incluem report.summary; só report.token e report.pdf_url vêm preenchidos.

O webhook auto-hospedado está inacessível – a Surmado exige HTTPS. Se você roda o n8n em localhost, use um túnel (ngrok, Cloudflare Tunnel) ou publique atrás de um proxy reverso com certificado TLS válido.

A verificação de assinatura falha com caracteres não ASCII – a função canonicalize acima resolve isso; se você escreveu a sua, escape com ASCII os caracteres não ASCII para corresponder à saída de json.dumps(..., ensure_ascii=True) do Python, usada pela Surmado.


Relacionados: Guia de integração da API | Dados estruturados e Intelligence Tokens | Integração com o Zapier | Integração com o Make | Integração com o Notion