Skip to Content
WebhooksEsempi

Esempi di webhook

Questa pagina offre esempi completi e pronti per la produzione per ricevere ed elaborare i webhook Ignite in diversi linguaggi di programmazione.

Esempi di server completi

// pages/api/webhook.ts import { createHmac, timingSafeEqual } from "crypto"; import { NextApiRequest, NextApiResponse } from "next"; // Disable body parser to access raw body for signature verification export const config = { api: { bodyParser: false, }, }; interface ThumbnailFormat { url: string; fileSize: number; } interface ThumbnailVariant { name: string; width: number; height: number; formats: { jpeg: ThumbnailFormat; webp: ThumbnailFormat; }; } interface VideoWebhookData { id: string; status: "COMPLETE" | "PROCESSING" | "NO_FILE" | "FAILED"; title: string; src?: { thumbnails?: ThumbnailVariant[]; thumbnailUrl?: string; // deprecated — use src.thumbnails instead mp4?: Array<{ name: string; url: string; width: number; height: number }>; }; // ... other video properties } async function getRawBody(req: NextApiRequest): Promise<string> { const chunks: Buffer[] = []; for await (const chunk of req) { chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk); } return Buffer.concat(chunks).toString("utf-8"); } function isValidSignature( rawBody: string, signatureHeader: string | string[] | undefined, secret: string ): boolean { try { if (typeof signatureHeader !== "string") { return false; } const time = signatureHeader.match(/t=(\d+)/)?.[1]; const token = signatureHeader.match(/v1=(\w+)/)?.[1]; if (!time || !token) { return false; } const signedPayload = `${time}.${rawBody}`; const hmac = createHmac("sha256", secret); const calculatedSignature = hmac.update(signedPayload).digest("hex"); return timingSafeEqual( Buffer.from(token), Buffer.from(calculatedSignature) ); } catch { return false; } } export default async function handler( req: NextApiRequest, res: NextApiResponse ) { if (req.method !== "POST") { return res.status(405).end(); } const rawBody = await getRawBody(req); if ( !isValidSignature( rawBody, req.headers["x-webhook-signature"], process.env.WEBHOOK_SIGNING_SECRET! ) ) { console.error("Invalid webhook signature"); return res.status(403).end(); } const eventType = req.headers["x-webhook-event"]; const deliveryId = req.headers["x-webhook-delivery-id"]; const video = JSON.parse(rawBody) as VideoWebhookData; // Process based on event type switch (eventType) { case "video.created": console.log("New video created:", video.id, video.title); // await handleVideoCreated(video); break; case "video.updated": console.log("Video updated:", video.id, video.title); if (video.status === "COMPLETE") { // Video processing finished - update your database // await db.updateVideo(video.id, { // thumbnails: video.src?.thumbnails, // thumbnail: video.src?.thumbnails?.[0]?.formats.jpeg.url, // sizes: video.src?.mp4, // }); } break; case "video.deleted": console.log("Video deleted:", video.id); // await handleVideoDeleted(video); break; } return res.status(204).end(); }

Consegne webhook

Ogni tentativo di consegna webhook viene registrato. Se una consegna fallisce, il sistema riprova automaticamente.

Stato della consegna

StatoDescrizione
successEvento consegnato con successo (risposta HTTP 2xx)
failedConsegna fallita (timeout, HTTP 4xx/5xx, errore di rete)

Informazioni sulla consegna

Ogni record di consegna contiene:

CampoDescrizione
responseCodeCodice di stato HTTP restituito dal tuo endpoint
responseBodyCorpo della risposta del tuo endpoint (troncato per risposte grandi)
errorMessageMessaggio di errore se la consegna è fallita
deliveredAtTimestamp del tentativo di consegna
attemptNumberNumero del tentativo (si incrementa con i retry)
nextRetryAtQuando verrà tentato il prossimo retry (se applicabile)

Comportamento dei retry

  • Le consegne fallite vengono riprovate automaticamente
  • Se nextRetryAt è impostato, è pianificato un retry
  • Se nextRetryAt non è impostato, non verranno effettuati altri retry

Buone pratiche

Seguire queste buone pratiche garantisce un’elaborazione affidabile dei webhook e aiuta a risolvere i problemi.

Tempo di risposta

Il tuo endpoint deve rispondere entro 30 secondi. Per operazioni lunghe, conferma subito la ricezione del webhook ed elabora in modo asincrono:

app.post('/webhook', async (req, res) => { // Immediately acknowledge receipt res.status(200).json({ received: true }); // Process asynchronously (don't await) processWebhookAsync(req.body).catch(console.error); }); async function processWebhookAsync(video) { // Long-running operations here }

Sicurezza

  • Proteggi i segreti — Non esporre mai il signing secret nel codice lato client o nel controllo versione
  • Usa HTTPS — In produzione usa sempre endpoint HTTPS
  • Valida tutto — Verifica sempre le firme prima di elaborare
  • Rate limiting — Valuta di applicare il rate limiting sul tuo endpoint

Affidabilità

  • Idempotenza — Memorizza e controlla X-Webhook-Delivery-Id per gestire consegne duplicate
  • Logging — Registra tutte le richieste webhook per il debug
  • Monitoraggio — Imposta avvisi per elaborazioni webhook fallite
  • Gestione errori — Restituisci codici di stato HTTP appropriati così i retry funzionano correttamente

Codici di stato HTTP

CodiceSignificato
200-299Successo — evento elaborato
4xxErrore client — verrà riprovato
5xxErrore server — verrà riprovato

Risoluzione dei problemi

Nessun evento ricevuto

  1. Controlla che la sottoscrizione webhook sia impostata su Active
  2. Verifica che siano selezionati i tipi di evento corretti
  3. Assicurati che gli eventi avvengano nel workspace corretto
  4. Controlla i log del server per le richieste in arrivo

La verifica della firma fallisce

  1. Verifica di usare il signing secret corretto (non un token API)
  2. Assicurati che il corpo della richiesta non venga modificato prima della verifica
  3. Controlla che la serializzazione JSON coincida (compatta, senza spazi extra)
  4. Verifica che il formato dell’intestazione firma sia analizzato correttamente: t=timestamp,v1=signature

Errori di timeout

  1. Rispondi entro 30 secondi
  2. Sposta le operazioni lunghe in elaborazione in background
  3. Restituisci subito 200, elabora in modo asincrono

Eventi duplicati

  1. Implementa l’idempotenza usando X-Webhook-Delivery-Id
  2. Controlla attemptNumber per i retry
  3. Memorizza gli ID di consegna elaborati in un database