Webhook-Beispiele
Diese Seite enthält vollständige, produktionsreife Beispiele zum Empfangen und Verarbeiten von Ignite-Webhooks in verschiedenen Programmiersprachen.
Vollständige Serverbeispiele
Next.js API Routes
// 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();
}Webhook-Zustellungen
Jeder Webhook-Zustellversuch wird protokolliert. Schlägt eine Zustellung fehl, versucht das System automatisch erneut.
Zustellstatus
| Status | Beschreibung |
|---|---|
success | Ereignis wurde erfolgreich zugestellt (HTTP-2xx-Antwort) |
failed | Zustellung fehlgeschlagen (Timeout, HTTP 4xx/5xx, Netzwerkfehler) |
Zustellinformationen
Jeder Zustellungsdatensatz enthält:
| Feld | Beschreibung |
|---|---|
responseCode | Von deinem Endpoint zurückgegebener HTTP-Statuscode |
responseBody | Antwortbody deines Endpoints (bei großen Antworten gekürzt) |
errorMessage | Fehlermeldung, falls die Zustellung fehlschlug |
deliveredAt | Zeitstempel des Zustellversuchs |
attemptNumber | Welcher Versuch dies war (steigt bei Wiederholungen) |
nextRetryAt | Wann der nächste Wiederholungsversuch stattfindet (falls zutreffend) |
Wiederholungsverhalten
- Fehlgeschlagene Zustellungen werden automatisch wiederholt
- Ist
nextRetryAtgesetzt, ist eine Wiederholung geplant - Ist
nextRetryAtnicht gesetzt, gibt es keine weiteren Wiederholungen
Best Practices
Diese Best Practices sorgen für zuverlässige Webhook-Verarbeitung und helfen bei der Fehlersuche.
Antwortzeit
Dein Endpoint muss innerhalb von 30 Sekunden antworten. Bei lang laufenden Vorgängen bestätige den Webhook sofort und verarbeite asynchron weiter:
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
}Sicherheit
- Geheimnisse schützen — Signing Secret niemals in Client-Code oder der Versionskontrolle offenlegen
- HTTPS nutzen — In Produktion immer HTTPS-Endpoints verwenden
- Alles prüfen — Signaturen immer vor der Verarbeitung verifizieren
- Rate Limiting — Erwäge Rate Limiting für deinen Endpoint
Zuverlässigkeit
- Idempotenz —
X-Webhook-Delivery-Idspeichern und prüfen, um doppelte Zustellungen zu behandeln - Logging — Alle Webhook-Anfragen für Debugging protokollieren
- Monitoring — Alerts bei fehlgeschlagener Webhook-Verarbeitung einrichten
- Fehlerbehandlung — Passende HTTP-Statuscodes zurückgeben, damit Wiederholungen korrekt funktionieren
HTTP-Statuscodes
| Code | Bedeutung |
|---|---|
200-299 | Erfolg — Ereignis verarbeitet |
4xx | Clientfehler — wird wiederholt |
5xx | Serverfehler — wird wiederholt |
Fehlerbehebung
Keine Ereignisse empfangen
- Prüfe, ob das Webhook-Abonnement auf Aktiv steht
- Stelle sicher, dass die richtigen Ereignistypen gewählt sind
- Vergewissere dich, dass Ereignisse im richtigen Workspace auftreten
- Sieh in deinen Server-Logs nach eingehenden Anfragen
Signaturverifizierung schlägt fehl
- Verwende das richtige Signing Secret (keinen API-Token)
- Stelle sicher, dass der Request-Body vor der Verifizierung nicht verändert wird
- Prüfe, ob die JSON-Serialisierung übereinstimmt (kompakt, ohne zusätzliche Leerzeichen)
- Prüfe, ob das Signaturheader-Format korrekt geparst wird:
t=timestamp,v1=signature
Timeout-Fehler
- Antworte innerhalb von 30 Sekunden
- Verlange lang laufende Arbeiten in den Hintergrund
- Sofort
200zurückgeben, Verarbeitung asynchron ausführen
Doppelte Ereignisse
- Idempotenz mit
X-Webhook-Delivery-Idumsetzen attemptNumberbei Wiederholungen prüfen- Verarbeitete Delivery-IDs in einer Datenbank speichern