Alle Artikel
Mobile Messaging-Ereignisse, die über eine Meta-Webhook-Verifizierung und einen sicheren Tunnel zu einer localhost-Anwendung gelangen.
WhatsApp Cloud APIMeta webhookslocalhostwebhook security

WhatsApp Cloud API-Webhooks auf localhost testen

Um einen WhatsApp Cloud API-Webhook auf localhost zu testen, machen Sie Ihren lokalen Endpunkt über HTTPS verfügbar, implementieren Sie die GET-Verifizierungsherausforderung von Meta und überprüfen Sie dann jede POST-Anfrage X-Hub-Signature-256 anhand des Rohtexts.Registrieren Sie die Tunnel-URL in Ihrer Meta-App, abonnieren Sie das WhatsApp Business-Konto messages und senden Sie eine Testnachricht, um eine echte Nutzlast ohne Bereitstellung zu empfangen.

WhatsApp-Webhooks verwenden zwei verschiedene Verifizierungsabläufe

Der wichtigste Unterschied besteht darin, dass Webhook-Einrichtung und Webhook-Zustellung unterschiedlich authentifiziert werden. Während der Einrichtung sendet Meta eine GET-Anfrage mit hub.mode, hub.verify_token und hub.challenge. Ihr Endpunkt vergleicht das Verifizierungstoken und gibt die Herausforderung als Klartext zurück. Spätere Ereignislieferungen sind POST-Anfragen; Diese sollten durch Validierung der mit Ihrem Meta-App-Geheimnis erstellten HMAC-Signatur authentifiziert werden.

Ein Verifizierungstoken ist eine zufällige Zeichenfolge, die Sie auswählen. Es handelt sich nicht um das WhatsApp-Zugriffstoken und nicht um das App-Geheimnis. Die Rückgabe der Herausforderung beweist die Kontrolle über den Callback-Endpunkt. Zukünftige POST-Anfragen werden nicht authentifiziert. Meta's offizieller WhatsApp-Webhook-Leitfaden deckt Rückrufkonfiguration, Abonnements und Webhook-Felder ab.

Erstellen Sie einen Next.js App Router-Endpunkt

Die folgende Route behandelt beide Phasen. Beim Lesen von POST-Daten mit request.text() bleiben genau die Bytes erhalten, die für die Signaturüberprüfung erforderlich sind.

// app/api/webhooks/whatsapp/route.ts
import crypto from 'node:crypto';
import { NextRequest } from 'next/server';

export const runtime = 'nodejs';

export async function GET(request: NextRequest) {
  const mode = request.nextUrl.searchParams.get('hub.mode');
  const token = request.nextUrl.searchParams.get('hub.verify_token');
  const challenge = request.nextUrl.searchParams.get('hub.challenge');

  if (mode === 'subscribe' && token === process.env.META_VERIFY_TOKEN) {
    return new Response(challenge ?? '', { status: 200 });
  }
  return new Response('Forbidden', { status: 403 });
}

export async function POST(request: Request) {
  const rawBody = await request.text();
  const supplied = request.headers.get('x-hub-signature-256') ?? '';
  const expected = 'sha256=' + crypto
    .createHmac('sha256', process.env.META_APP_SECRET!)
    .update(rawBody)
    .digest('hex');

  const a = Buffer.from(supplied);
  const b = Buffer.from(expected);
  if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
    return new Response('Invalid signature', { status: 401 });
  }

  const payload = JSON.parse(rawBody);
  await enqueueWhatsAppPayload(payload);
  return new Response('EVENT_RECEIVED', { status: 200 });
}

Rufen Sie nicht request.json() auf und rekonstruieren Sie dann den JSON für HMAC. Leerzeichen, Escapezeichen oder Schlüsselreihenfolge können sich ändern und zu einem anderen Digest führen. Wenn Sie Express verwenden, erfassen Sie ein Buffer vor einem globalen JSON-Parser. Der allgemeine Webhook-Signatur-Leitfaden erklärt die Raw-Body-Verarbeitung über Frameworks hinweg.

Starten Sie einen Tunnel und konfigurieren Sie den Rückruf

  1. Führen Sie die Next.js-App lokal aus, normalerweise mit npm run dev auf Port 3000.
  2. Führen Sie npx portpreview 3000 in einem separaten Terminal aus.
  3. Setzen Sie META_VERIFY_TOKEN auf einen zufälligen Wert und META_APP_SECRET auf das App-Geheimnis aus Metas App-Einstellungen.
  4. Öffnen Sie im Meta-Entwickler-Dashboard die Konfiguration des WhatsApp-Produkts Seite.
  5. Setzen Sie die Rückruf-URL auf https://YOUR-TUNNEL.portpreview.dev/api/webhooks/whatsapp und geben Sie das gleiche Verifizierungstoken ein.
  6. Nach erfolgreicher Verifizierung abonnieren Sie das Feld messages für das WhatsApp Business-Konto.

Der Tunnel muss sowohl während der GET-Challenge als auch bei nachfolgenden POST-Zustellungen aktiv bleiben. Eine aus einer älteren Sitzung kopierte URL wird möglicherweise aufgelöst, aber nicht mehr an Ihren Computer weitergeleitet. Bestätigen Sie daher den genauen Rückruf, wenn sich der lokale Tunnel ändert.

Testen Sie die GET-Herausforderung unabhängig

Bevor Sie das Dashboard verwenden, reproduzieren Sie die Anfrage lokal:

curl -i \
  "http://localhost:3000/api/webhooks/whatsapp?hub.mode=subscribe&hub.verify_token=${META_VERIFY_TOKEN}&hub.challenge=123456"

Eine korrekte Antwort ist Status 200 mit Text 123456, nicht JSON und nicht "123456" mit Anführungszeichen. Wenn das Token falsch ist, ist 403 angemessen. Protokollieren Sie keine Abfrageparameter, da dort das Verifizierungstoken angezeigt wird.

Verstehen Sie die Nutzlast einer Nachricht, bevor Sie Geschäftslogik schreiben

WhatsApp verpackt Daten mehrere Ebenen tief. Eine typische Benachrichtigung besteht aus object: "whatsapp_business_account", einem entry-Array, einem changes-Array und einer Änderung, deren field messages ist. Innerhalb von value werden eingehende Benutzerinhalte in messages angezeigt; Zustellungs-, Lese- und Fehleraktualisierungen für von Ihnen gesendete Nachrichten werden in statuses.

for (const entry of payload.entry ?? []) {
  for (const change of entry.changes ?? []) {
    if (change.field !== 'messages') continue;
    for (const message of change.value.messages ?? []) {
      await handleInboundMessage({
        id: message.id,
        from: message.from,
        type: message.type,
        text: message.text?.body,
      });
    }
    for (const status of change.value.statuses ?? []) {
      await updateDeliveryStatus(status.id, status.status);
    }
  }
}

Gehen Sie nicht davon aus, dass jede Benachrichtigung eine Textnachricht enthält. Bilder, Audio, Dokumente, Standorte, interaktive Antworten, Systemmeldungen und Nur-Status-Nutzlasten haben unterschiedliche Formen. Halten Sie einen Dispatcher mit message.type verschlüsselt, validieren Sie optionale Felder und behalten Sie unbekannte Ereignistypen zur Überprüfung bei, anstatt abzustürzen.

Überprüfen Sie die POST-Signatur korrekt

Der X-Hub-Signature-256-Wert verwendet die Form sha256=<hex digest>. Berechnen Sie HMAC-SHA256 über die Rohanforderungsbytes mithilfe des Meta App Secret. Für Graph-API-Aufrufe wird das permanente oder temporäre WhatsApp-Zugriffstoken verwendet; Es ist nicht der HMAC-Schlüssel. Verwenden Sie einen Vergleich mit konstanter Zeit und lehnen Sie eine fehlende Signatur ab.

Lassen Sie die lokale Überprüfung aktiviert. Jeder, der eine Tunnel-URL lernt, kann beliebiges JSON darin posten. Ohne Überprüfung könnte ein gefälschtes Ereignis automatische Antworten auslösen, CRM-Datensätze verändern oder den Kundenstatus offenlegen. Rotieren Sie das App-Geheimnis, wenn es versehentlich festgeschrieben, gedruckt oder geteilt wird.

Nachrichten schnell bestätigen und deduplizieren

Gibt 200 zurück, nachdem das Ereignis authentifiziert und dauerhaft in die Warteschlange gestellt wurde. Warten Sie nicht, während Sie Medien herunterladen, einen LLM anrufen oder mehrere Dienste aktualisieren. Anbieter versuchen die Zustellung erneut, wenn Bestätigungen fehlschlagen und Netzwerkmehrdeutigkeiten bedeuten, dass Duplikate normal sind.

Verwenden Sie die WhatsApp-Nachricht id als Idempotenzschlüssel für eingehende Nachrichten und Statusobjekte. Legen Sie eine eindeutige Einschränkung für verarbeitete IDs fest. Statusübergänge können legitim von „Gesendet“ über „Zugestellt“ bis „Lesen“ fortschreiten. Deduplizieren Sie daher jeden relevanten Übergang, ohne einen späteren Status zu verwerfen.

Fehlerbehebung bei der WhatsApp-Webhook-Einrichtung

Die Rückruf-URL konnte nicht validiert werden

Testen Sie die GET-Route über die öffentliche URL. Stellen Sie sicher, dass es GET akzeptiert, das genaue Verifizierungstoken vergleicht und nur mit der Herausforderung antwortet. Weiterleitungen, Authentifizierungs-Middleware, Gebietsschemaumschreibungen oder ein JSON-Wrapper können die Überprüfung unterbrechen. Bestätigen Sie, dass die Umgebungsvariable vom laufenden Entwicklungsprozess geladen wird.

Die Überprüfung ist erfolgreich, aber es kommen keine Nachrichten an.

Die Rückrufüberprüfung allein führt nicht dazu, dass das WhatsApp Business-Konto Felder abonniert. Bestätigen Sie das messages Abonnement im Dashboard und stellen Sie sicher, dass die Telefonnummer zur erwarteten App und zum erwarteten Konto gehört. Senden Sie eine Nachricht von einem zulässigen Empfänger, wenn sich die App noch im Entwicklungsmodus befindet.

Jeder POST schlägt bei der Signaturvalidierung fehl

Die üblichen Ursachen sind die Verwendung des Zugriffstokens anstelle von App Secret, das Hashing von geparstem JSON, das Weglassen des Präfixes sha256= oder der Vergleich verschiedener Codierungen. Protokollieren Sie die Länge des Hauptteils und ob der Header vorhanden ist, aber geben Sie niemals das Geheimnis oder die vollständige Kundennutzlast aus.

Textnachrichten funktionieren, aber die Medienverarbeitung schlägt fehl

Medienbenachrichtigungen enthalten eine ID, nicht unbedingt die Dateibytes. Rufen Sie Medien über die Graph-API mit einem gültigen Zugriffstoken ab und laden Sie sie dann herunter. Halten Sie diesen langsameren Workflow außerhalb des Webhook-Bestätigungspfads.

Der lokale Endpunkt erkennt doppelte Ereignisse.

Überprüfen Sie den Antwortstatus und die Latenz, fügen Sie dauerhafte Idempotenz hinzu und spielen Sie nach jedem Fix ein erfasstes Ereignis ab. Der Webhook-Wiedergabeleitfaden zeigt, wie Sie vermeiden, bei jeder Codeänderung eine neue echte Nachricht zu senden.

Kundendaten bei lokalen Tests schützen

  • Verwenden Sie nach Möglichkeit Testtelefonnummern und synthetische Konversationen.
  • Redigieren Sie Telefonnummern, Nachrichtentexte, Medien-URLs, Kontakte usw Profilnamen aus Protokollen.
  • App Secret speichern, auf Token zugreifen und Token nur in ignorierten Umgebungsdateien oder einem Secret Manager überprüfen.
  • Beschränken Sie, wer Tunnelerfassungen anzeigen und nach der Debugging-Sitzung löschen kann.
  • Validieren Sie Objekt-, Feld- und Konto-IDs, bevor Sie Geschäftsaktionen ausführen.

Ein Tunnel führt eine Iteration durch schnell, aber es überträgt auch produktionsbezogene personenbezogene Daten auf einen Entwicklercomputer. Wenden Sie die Kontrollen in der Tunnelsicherheits-Checkliste an, bevor Sie mit echten Benutzern testen.

Häufig gestellte Fragen

Wie teste ich einen WhatsApp Cloud API-Webhook auf Localhost?
Führen Sie Ihren Webhook-Handler lokal aus und machen Sie ihn mit einem HTTPS verfügbar tunneln, die öffentliche Rückruf-URL registrieren und das Token in Meta überprüfen, Nachrichten abonnieren und dann eine Testnachricht senden.
Was sollte ein WhatsApp-Webhook-Verifizierungsendpunkt zurückgeben?
Für eine gültige GET-Anfrage, bei der hub.mode „subscribe“ ist und hub.verify_token übereinstimmt, geben Sie den hub.challenge-Wert als Klartext mit HTTP 200 zurück.
Wie überprüfe ich WhatsApp-Webhook-POST-Anfragen?
Berechnen Sie HMAC-SHA256 über den genauen Rohanfragetext mit dem Meta-App-Geheimnis, stellen Sie dem Hex-Digest sha256= voran und vergleichen Sie ihn zeitsicher mit X-Hub-Signature-256.
Warum empfängt mein verifizierter WhatsApp-Webhook keine Ereignisse?
Die Rückrufüberprüfung abonniert nicht automatisch jedes Feld. Bestätigen Sie, dass das WhatsApp Business-Konto Nachrichten abonniert hat und dass Ihr Testabsender und Ihre Telefonnummer für die App verfügbar sind.