Um Mailgun webhooks auf localhost zu testen, setzen Sie Ihren lokalen Handler mit npx portpreview PORTKonfigurieren Sie den resultierenden HTTPS-Endpunkt für die erforderlichen Mailgun Ereignistypen und überprüfen Sie die Zeitstempel, das Token und die HMAC-SHA256 Signatur der Nutzlast, bevor Sie das Ereignis akzeptieren.
Was Mailgun webhooks Bericht
Mailgun sendet einen HTTP- oder HTTPS-POST mit einer JSON-Nutzlast, wenn ein konfiguriertes Ereignis auftritt. Aktuelle Ereignisarten umfassen accepted, delivered, temporary_fail, permanent_fail, opened, clickedSpam-Beschwerden und Abmeldungen. Trackingabhängige Ereignisse erscheinen nur, wenn das entsprechende Tracking aktiviert ist.
Ein aktueller Mailgun Send Webhook-Körper hat eine signature Objekt neben event-dataDie Ereignisdaten enthalten Felder wie event, id, timestamp, Nachrichten-Header, Empfängerinformationen, Tags und Lieferdetails, abhängig vom Ereignistyp. Code gegen dokumentierte Felder und tolerieren fehlende optionale Eigenschaften. Mailgun Offiziell Nutzlastbeispiele sind die besten Geräte für Vertragstests.
Verwechseln Sie einen Mailgun Send Webhook nicht mit Mailgun Warnungen. Warnungen verwenden einen anderen Signaturschlüssel und unterschreiben den gesamten POST-Körper in eine X-Sign Header. Dieses Handbuch behandelt Senden Webhooks: die Signaturfelder in der Nutzlast und das Konto Webhook Signing Key.
1. Erstellen Sie einen lokalen Mailgun Endpunkt
Im Gegensatz zu Schemata, die den rohen JSON-Körper signieren, verwendet die dokumentierte Berechnung des Mailgun Send den Zeitstempel und das Token des Signaturobjekts. Standard-JSON-Parsing ist daher angemessen. Der folgende Express Handler überprüft HMAC, führt eine Überprüfung des Wiederspielalters durch und akzeptiert das Ereignis dauerhaft.
import crypto from 'node:crypto';
import express from 'express';
const app = express();
app.use(express.json({ limit: '1mb' }));
function verifyMailgunSignature({ timestamp, token, signature }) {
if (!timestamp || !token || !signature) return false;
const expected = crypto
.createHmac('sha256', process.env.MAILGUN_WEBHOOK_SIGNING_KEY)
.update(String(timestamp) + String(token))
.digest('hex');
const expectedBytes = Buffer.from(expected, 'hex');
const actualBytes = Buffer.from(String(signature), 'hex');
return expectedBytes.length === actualBytes.length &&
crypto.timingSafeEqual(expectedBytes, actualBytes);
}
app.post('/webhooks/mailgun', async (req, res) => {
const signing = req.body?.signature;
const event = req.body?.['event-data'];
if (!signing || !event || !verifyMailgunSignature(signing)) {
return res.status(406).send('invalid webhook');
}
const ageSeconds = Math.abs(Date.now() / 1000 - Number(signing.timestamp));
if (!Number.isFinite(ageSeconds) || ageSeconds > 15 * 60) {
return res.status(406).send('stale webhook');
}
await acceptOnce({
eventId: event.id,
replayToken: signing.token,
payload: event,
});
return res.sendStatus(200);
});
app.listen(3000);
Das 15-Minuten-Fenster ist eine Anwendungsrichtlinie, kein Mailgun-mandatierter Wert. Mailgun empfiehlt, zu überprüfen, ob der Zeitstempel nicht zu weit von der aktuellen Zeit entfernt ist, warnt jedoch davor, übermäßig aggressiv zu sein, da sich die Lieferung verzögern kann. Wählen Sie ein Fenster, das Ihren Warteschlangen- und Incident-Recovery-Anforderungen entspricht, überwachen Sie legitime Ablehnungen und passen Sie es absichtlich an.
Speichern Sie die Webhook Signing Key in einer geheimen Manager- oder Umgebungsvariablen, niemals in der Quellsteuerung. Mailgun Sicherungssteghakenführung definiert die genaue Berechnung: verketteter Zeitstempel und Token ohne Separator, berechnen Sie HMAC-SHA256 mit Webhook Signing Key und vergleichen Sie den hexadezimalen Digest mit signature.
2. Exposition localhost über HTTPS
Mit der Anwendung hören auf Port 3000, laufen:
npx portpreview 3000
Fügen Sie die lokale Route an den öffentlichen HTTPS-Ursprung an. Zum Beispiel:
https://example.portpreview.dev/webhooks/mailgun
Lassen Sie sowohl die Anwendung als auch den Tunnel während des Tests laufen. Mailgun benötigt eine öffentlich erreichbare URL; localhost, eine private LAN-Adresse und ein selbstsigniertes Entwicklungszertifikat sind keine geeigneten Remote-Ziele. PortPreview beendet öffentliche HTTPS und leitet die Anfrage an Ihren lokalen Port weiter.
3. Konfigurieren von Mailgun Ereignis-URLs
Mailgun unterstützt die Webhook-Konfiguration auf Konto- und Domänenebene. Endpunkte auf Kontoebene können Ereignisse über Domains und geerbte Unterkonten hinweg empfangen; Endpunkte auf Domainebene gelten nur für diese Domain. Jeder Ereignistyp ist individuell konfiguriert und kann bis zu drei URLs haben. Wählen Sie den engsten Bereich, der Ihrer Anwendung entspricht.
- Öffnen Sie den Webhooks-Bereich für das beabsichtigte Konto oder die sendende Domain.
- Wählen Sie einen Ereignistyp, wie z.B.
deliveredoderpermanent_fail. - Fügen Sie den vollständigen PortPreview HTTPS-Endpunkt hinzu.
- Wiederholen Sie für jeden Ereignistyp, den Ihr Handler unterstützt.
- Senden Sie eine Test- oder echte Nachricht und prüfen Sie die lokalen Anfrage- und Anwendungsprotokolle.
Mailgun dedupliziert die gleiche URL für dasselbe Ereignis, wenn sie sowohl auf Konto- als auch auf Domainebene konfiguriert ist, aber verschiedene URLs können jeweils eine Kopie erhalten. Die Vererbung von Elternkonten kann auch zu Lieferungen an mehrere verschiedene Endpunkte führen. Überprüfen Sie den Beamten Konfigurationsregeln Vor der Zuweisung jeder zusätzlichen Lieferung an Retries.
Wie Mailgun Signatur Verifizierung funktioniert
Die signature Das Objekt enthält:
timestampUnix Zeit in Sekunden.token: eine zufällig generierte 50-stellige Zeichenfolge.signature: hexadezimaler HMAC-Verdau.parent-signature: optional für ein Ereignis aus einem Unterkonto vorhanden, so dass die Validierung mit der von Mailgun beschriebenen primären Kontobeziehung möglich ist.
Für die normale Kontosignatur berechnen HMAC-SHA256(signingKey, timestamp + token)Es gibt keinen Separator und der event-data JSON ist nicht Teil dieser dokumentierten Mailgun Send Berechnung. Vergleichen Sie decodierte Bytes mit einer Timing-sicheren Funktion nach Prüfung gleicher Längen. Eine Ebene === Der Vergleich ist einfacher, aber ein Timing-sicherer Vergleich ist der sicherere Produktionsstandard.
Ein authentisches HMAC beweist, dass eine Partei, die den Signaturschlüssel hält, die Signatur erstellt hat. Es beweist nicht, dass diese Lieferung nicht wiederholt wurde. Mailgun empfiehlt ausdrücklich, das Token zwischenzuspeichern und eine nachfolgende Anfrage mit demselben Token abzulehnen. Eine Zeitstempel-Altersprüfung begrenzt, wie lange eine erfasste gültige Anforderung nützlich bleibt. Verwenden Sie beide Steuerelemente: eine eindeutige Token-Einschränkung für die Wiederholung und ein angemessenes Zeitfenster für Frische.
Deduplizieren Sie sowohl Lieferungen als auch Effekte
Behalten Sie zwei dauerhafte Eindeutigkeitsbeschränkungen: eine für das Signatur-Token und eine für die Mailgun event-data.idDas Token fängt eine identische signierte Lieferwiederholung. Die Ereignis-ID schützt die Geschäftslogik, wenn dasselbe Ereignis in einem anderen gültigen Lieferkontext erscheint. Namespace sowohl nach Anbieter und Konto oder Umgebung.
async function acceptOnce({ eventId, replayToken, payload }) {
await db.transaction(async (tx) => {
const tokenWasNew = await tx.webhookTokens.insertIfAbsent({
provider: 'mailgun',
token: replayToken,
});
if (!tokenWasNew) return;
const eventWasNew = await tx.webhookEvents.insertIfAbsent({
provider: 'mailgun',
eventId,
receivedAt: new Date(),
});
if (!eventWasNew) return;
await tx.jobs.enqueue({
type: 'process-mailgun-event',
payload,
});
});
}
Back the insert-if-absent operations with database unique indexes; ein read gefolgt von einem insert ist bei gleichzeitigen lieferungen rennenanfällig. Begehen Sie die Dedup-Aufzeichnungen und Warteschlange Job atomar. Dann bestätigen Sie schnell und lassen Sie einen Mitarbeiter den Nachrichtenstatus aktualisieren, Alarme auslösen oder ein CRM synchronisieren. Siehe: Retry und Idempotency Guide Alternativen, wenn die Warteschlange und die Geschäftsdatenbank eine Transaktion nicht gemeinsam nutzen können.
Mailgun Antwortcodes und Wiederholungsverhalten
Mailgun aktuelle Send Webhook Dokumentation gibt drei wichtige Ergebnisse:
- 200 Erfolge: Mailgun behandelt den Webhook POST als erfolgreich und wiederholt ihn nicht.
- 406 Nicht akzeptabel: Mailgun behandelt die POST als abgelehnt und wiederholt sie nicht.
- sonstiger Code: bei Webhooks, die keine Lieferbenachrichtigungen sind, Mailgun wiederholt acht Stunden nach 5 Minuten, 10 Minuten, 15 Minuten, 1 Stunde, 2 Stunden und 4 Stunden.
Die Ausnahme der Liefermitteilung ist wichtig: Versprechen Sie nicht, dass jeder Ereignistyp dem allgemeinen Wiederholungsplan folgt. Überprüfen Sie die neuesten Dokumentation der automatischen Retries wenn Liefergarantien Ihr Design beeinflussen.
Verwenden Sie 406 nur für eine Anfrage, die Sie absichtlich dauerhaft ablehnen, z. B. eine ungültige Signatur oder eine Wiederholungsrichtlinie außerhalb. Verwenden Sie 500 oder 503 für transiente Datenbank- und Warteschlangenfehler, damit berechtigte Webhook-Typen wiederholt werden können. Geben Sie 200 erst nach dauerhafter Annahme zurück. Wenn Sie 200 zurückgeben, während Sie nicht verfolgte Hintergrundarbeiten starten, kann das Ereignis verloren gehen, wenn der Prozess beendet wird.
Fehlerbehebung Mailgun webhooks lokal
Der berechnete HMAC passt nie
Bestätigen Sie, dass Sie die Webhook Signing Key, kein API-Schlüssel, SMTP-Passwort oder Signaturschlüssel für Warnungen. Konkatenieren Sie den Zeitstempel und das Token des Signaturobjekts ohne Abgrenzung. Produzieren Sie einen kleinen hexadezimalen SHA-256 Digest. Überprüfen Sie auch, ob Ihr Framework den Bindestrich nicht umbenannt hat event-data Eigentum; Bracket Notation vermeidet diesen Fehler.
Der Handler erhält Formularfelder anstelle des aktuellen JSON
Überprüfen Sie, welche Mailgun-Funktion und Endpunktversion die Anforderung generiert hat. Wenden Sie kein Legacy-Nutzlast-Tutorial blind auf einen aktuellen Webhook senden an. Protokollinhaltstyp, top-level-feldnamen und körperlänge in der entwicklung, ohne nachrichteninhalte oder geheimnisse zu protokollieren, dann implementieren sie den dokumentierten vertrag für ihr konto und integration.
Mailgun wiederholt
Überprüfen Sie den tatsächlichen Status, der über den Draht gesendet wird. Eine Ausnahme nach dem Datenbank-Commit kann die Antwort in 500 verwandeln, was einen weiteren Versuch verursacht. Deshalb müssen die Ereignis-ID und die Token-Einsätze einzigartig und langlebig sein. Wenn eine Anforderung dauerhaft ungültig ist, geben Sie 406 zurück; wenn der Fehler vorübergehend ist, beheben Sie den Dienst und lassen Sie das Wiederholverhalten funktionieren.
Kein Event erreicht localhost
Bestätigen Sie, dass die URL an das richtige Konto oder die richtige Domain und den genauen Ereignistyp angehängt ist. A delivered URL wird nicht erhalten opened Ereignisse. Überprüfen Sie, ob der lokale Prozess und der Tunnel noch aktiv sind und ob der konfigurierte Pfad /webhooks/mailgunFolgen Sie dem Local Webhook Debugging Guide Anbieterkonfiguration von Routing- und Anwendungsfehlern zu trennen.
Sicherheitscheckliste
- Überprüfen Sie HMAC vor dem Vertrauen oder Protokollieren
event-data. - Bewahren Sie den Signaturschlüssel in einem geheimen Speicher auf und drehen Sie ihn durch eine kontrollierte Bereitstellung; setzen Sie ihn niemals im clientseitigen Code aus.
- Verwenden Sie einen Timing-sicheren Digest-Vergleich, eine Zeitstempelrichtlinie und eine dauerhafte einzigartige Einschränkung des Tokens.
- Validieren Sie den Ereignistyp und die erforderlichen Felder vor dem Enqueueing. Behandeln Sie Empfängeradressen, Themen, Speicher-URLs und Benutzervariablen als sensible Daten.
- Akzeptieren Sie nur POST, die Körpergröße der Kappe, verwenden Sie HTTPS und Ratenbegrenzungsfehler, ohne legitime Mailgun-Wiederholungen zu blockieren.
- Entlarven Sie keine nicht verwandten lokalen Admins oder Debug-Endpunkte durch den temporären öffentlichen Ursprung.
- Wenn das Testen endet, entfernen Sie die temporäre URL und konfigurieren Sie den stabilen Produktionsendpunkt.
Mailgun dokumentiert auch ein optionales TLS-Clientzertifikat für Webhook-Anfragen, wenn Ihr empfangender Server über gültiges TLS verfügt. Dies kann eine Validierung auf Transportebene ermöglichen, ersetzt jedoch nicht die Nutzlast-HMAC-Verifizierung, Wiedergabesteuerung und Anwendungsautorisierung. Layer-Kontrollen gemäß Ihrem Bedrohungsmodell.
Produktionsannahmeprüfungen
- Liefern Sie eine gültige signierte Einrichtung und bestätigen Sie ein dauerhaftes Ereignis plus eine 200-Antwort.
- Ändern Sie das Token, ohne die Signatur zu ändern, und bestätigen Sie eine 406 ohne Ereignisschreiben.
- Wiederholen Sie den genau gültigen Körper und bestätigen Sie keinen zweiten Job oder Nebeneffekt.
- Senden Sie eine gültige Signatur mit einem Zeitstempel außerhalb Ihres konfigurierten Fensters und überprüfen Sie die beabsichtigte Ablehnung.
- Erzwingen Sie einen temporären Datenbankfehler, bestätigen Sie eine Nicht-200/Nicht-406-Antwort, stellen Sie dann die Datenbank wieder her und überprüfen Sie eine erfolgreiche Akzeptanz.
- Üben Sie jeden konfigurierten Mailgun Ereignistyp aus, da sich Nutzlastfelder und Wiederholungserwartungen unterscheiden.
Sobald diese Tests bestehen, verwenden Sie den gleichen Verifizierungs- und Deduplizierungspfad in der Produktion. Für eine anbieterunabhängige Erklärung des HMAC-Vergleichs und der geheimen Handhabung lesen Sie die Webhook-Signaturprüfungsleitfaden.
