Salta el contingut

Webhooks a n8n

Que és un webhook?

Un webhook és un mecanisme que permet a una aplicació enviar dades a una altra aplicació en temps real quan passa un event concret, sense necessitat de que la segona aplicació pregunti periòdicament.

flowchart LR
    A[Servei extern\nex: Stripe] -->|"POST /webhook (event: payment)"| B[n8n\nWebhook node]
    B --> C[Processar\nl'event]

    style A fill:#e3f2fd
    style B fill:#e8f5e9

Diferències amb el polling:

Polling Webhook
n8n pregunta cada X temps: "Hi ha novetats?" El servei avisa n8n quan passa alguna cosa
Pot perdre events si el periode és molt llarg Temps real
Consuma recursos innecessariament Eficient
Simple d'implementar Requereix una URL pública

Webhook Trigger a n8n

Configuració bàsica

  1. Afegeix el node Webhook al workflow
  2. Configura:
  3. HTTP Method: GET, POST, PUT, DELETE (la majoria de serveis usen POST)
  4. Path: un path personalitzat (ex: nova-comanda) o deixa el UUID per defecte
  5. Authentication: cap, bàsic auth, o header auth per seguretat

La URL generada serà:

# Mode test (workflow en mode "Listen for test event")
http://localhost:5678/webhook-test/[path]

# Mode produccio (workflow actiu)
http://localhost:5678/webhook/[path]

Accés a les dades del webhook

Un cop el webhook rep una petició, les dades queden disponibles al workflow:

// Headers de la peticio
$json.headers['content-type']
$json.headers['x-signature']

// Parametres de la URL (?param=valor)
$json.query.param

// Cos de la peticio (JSON)
$json.body.event
$json.body.data.id

// Meta-informacio
$json.webhookId
$json.executionId

Respondre al webhook

Per defecte, n8n respon automàticament al webhook amb un 200 OK tan aviat com el rep. Per personalitzar la resposta:

  1. A la configuració del node Webhook, estableix Respond a Using Respond to Webhook Node
  2. Afegeix el node Respond to Webhook al final (o quan vulguis respondre)

Exemple de resposta personalitzada

flowchart LR
    A[Webhook\nPOST /orders] --> B{IF\ndades valides?}
    B -->|Si| C[Processar\ncomanda]
    B -->|No| E[Respond to Webhook\n400 Bad Request]
    C --> D[Respond to Webhook\n200 OK + JSON]

Configuració del node Respond to Webhook:

Respond With: JSON
Status Code: 200
Response Body: {
  "status": "ok",
  "id": "{{ $json.orderId }}",
  "message": "Comanda processada correctament"
}

Seguretat dels webhooks

Els webhooks son URLs publiques. Qualsevol que conegui la URL pot enviar dades. Per securitzar-los:

1. Autenticació per header

Configura el node Webhook amb:

Authentication: Header Auth
Header name: X-Webhook-Secret
Header value: el-teu-secret-compartit

El servei emissor ha d'incloure el header X-Webhook-Secret: el-teu-secret-compartit a cada petició.

2. Verificar la signatura

Molts serveis (GitHub, Stripe, Shopify) signen les peticions amb HMAC-SHA256. Pots verificar la signatura amb un Code node:

const crypto = require('crypto');

const payload = JSON.stringify($json.body);
const secret = $env.WEBHOOK_SECRET;
const signature = $json.headers['x-hub-signature-256'];

const expectedSignature = 'sha256=' + 
  crypto.createHmac('sha256', secret)
        .update(payload)
        .digest('hex');

if (signature !== expectedSignature) {
  throw new Error('Signatura invalida - peticio no autoritzada');
}

return $input.item;

3. Restringir IP (avançat)

Si el servei emissor te una llista d'IPs fixes, pots afegir un node IF al principi per verificar l'IP de la petició.

Casos d'ús comuns

Stripe: Pagament completat

flowchart LR
    A[Stripe\npayment.succeeded] --> B[n8n Webhook]
    B --> C[Code\nExtreure dades]
    C --> D[Google Sheets\nAfegir registre]
    D --> E[Gmail\nFactura al client]

GitHub: Push al repositori

flowchart LR
    A[GitHub\npush event] --> B[n8n Webhook]
    B --> C{IF\nbranch=main?}
    C -->|Si| D[HTTP Request\nDeploy API]
    C -->|No| E[Google Chat\nNotificar al team]

Formulari web extern

flowchart LR
    A[Web/App\nFormulari contacte] --> B[n8n Webhook\nPOST /contact]
    B --> C[IF\nvalidar dades]
    C -->|Valid| D[CRM API\nCrear lead]
    D --> E[Gmail\nCorreu de seguiment]
    C -->|Invalid| F[Respond\n422 Unprocessable]

Depuració de webhooks

Provar localment amb curl

# GET request
curl http://localhost:5678/webhook-test/el-teu-path

# POST amb JSON
curl -X POST \
  http://localhost:5678/webhook-test/el-teu-path \
  -H "Content-Type: application/json" \
  -d '{"event": "test", "data": {"id": 123, "nom": "prova"}}'

# POST amb header d'autenticacio
curl -X POST \
  http://localhost:5678/webhook-test/el-teu-path \
  -H "Content-Type: application/json" \
  -H "X-Webhook-Secret: el-meu-secret" \
  -d '{"missatge": "hola"}'

Usar Postman o Insomnia

Per a proves més complexes, eines com Postman o Insomnia permeten: - Guardar les peticions per reusar-les - Configurar entorns (test, producció) - Inspeccionar la resposta de manera clara

Miniactivitat ACN8N15

Crea un webhook que actuï com una API mínima per registrar incidències:

  1. Endpoint: POST /webhook/incidències
  2. Dades esperades: { "títol": "...", "severitat": "baixa|mitjana|alta", "reporter": "..." }
  3. Vàlida que tots els camps estan presents
  4. Si la severitat es "alta", enviï un missatge urgent a Google Chat (o mostra'l com a output)
  5. Guarda l'incidència a un Google Sheet (o mostra-la com a output)
  6. Respon 201 Created amb les dades de la incidència creada i un ID generat