Wszystkie artykuły
Zdarzenia wiadomości mobilnych przechodzące przez weryfikację webhooka Meta i bezpieczny tunel do aplikacji na localhost.
WhatsApp Cloud APIMeta webhookslocalhostwebhook security

Testowanie webhooków WhatsApp Cloud API na localhost

Aby przetestować webhook API WhatsApp Cloud na hoście lokalnym, udostępnij lokalny punkt końcowy za pośrednictwem protokołu HTTPS, zaimplementuj wyzwanie weryfikacyjne Meta GET, a następnie zweryfikuj X-Hub-Signature-256 każde żądanie POST w stosunku do nieprzetworzonej treści. Zarejestruj tunel URL w swojej aplikacji Meta, zasubskrybuj konto WhatsApp Business w messages i wyślij wiadomość testową, aby otrzymać prawdziwy ładunek bez wdrażania.

Webhooki WhatsApp korzystają z dwóch różnych procesów weryfikacji

Najważniejszą różnicą jest to, że konfiguracja webhooka i dostarczanie webhooka są uwierzytelniane w różny sposób. Podczas instalacji Meta wysyła żądanie GET zawierające hub.mode, hub.verify_token i hub.challenge. Twój punkt końcowy porównuje token weryfikacji i zwraca wyzwanie jako zwykły tekst. Później zdarzenia są dostarczane jako żądania POST; należy je uwierzytelnić poprzez sprawdzenie podpisu HMAC utworzonego za pomocą klucza tajnego aplikacji Meta.

Token weryfikacyjny to losowy, wybrany przez Ciebie ciąg znaków; nie jest to token dostępu WhatsApp ani sekret aplikacji. Zwrócenie wyzwania potwierdza kontrolę nad punktem końcowym wywołania zwrotnego. Nie uwierzytelnia przyszłych żądań POST. Meta oficjalny przewodnik po webhooku WhatsApp obejmuje konfigurację wywołania zwrotnego, subskrypcje i pola elementu webhook.

Utwórz punkt końcowy routera aplikacji Next.js

Poniższa trasa obsługuje obie fazy. Odczyt danych POST za pomocą request.text() zachowuje dokładnie te bajty potrzebne do weryfikacji podpisu.

// 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 });
}

Nie wywołuj request.json(), a następnie rekonstruuj JSON dla HMAC. Białe znaki, znaki ucieczki lub kolejność kluczy mogą ulec zmianie, tworząc inny skrót. Jeśli używasz Express, przechwyć Buffer przed globalnym analizatorem składni JSON. Ogólny przewodnik po podpisach webhooków wyjaśnia obsługę surowej treści w różnych frameworkach.

Uruchom tunel i skonfiguruj wywołanie zwrotne

  1. Uruchom aplikację Next.js lokalnie, zwykle z npm run dev na porcie 3000.
  2. Uruchom npx portpreview 3000 w oddzielnym terminalu.
  3. Ustaw META_VERIFY_TOKEN losową wartość i META_APP_SECRET klucz aplikacji w ustawieniach aplikacji Meta.
  4. W panelu programisty Meta otwórz konfigurację produktu WhatsApp strona.
  5. Ustaw adres URL wywołania zwrotnego na https://YOUR-TUNNEL.portpreview.dev/api/webhooks/whatsapp i wprowadź ten sam token weryfikacyjny.
  6. Po pomyślnej weryfikacji zasubskrybuj pole messages dla konta WhatsApp Business.

Tunel musi pozostać aktywny zarówno podczas wyzwania GET, jak i kolejnych dostaw POST. Adres URL skopiowany ze starszej sesji może zostać rozwiązany, ale nie będzie już przesyłany do Twojego komputera, więc potwierdź dokładne wywołanie zwrotne za każdym razem, gdy zmieni się lokalny tunel.

Przetestuj niezależnie wyzwanie GET

Przed użyciem panelu odtwórz żądanie lokalnie:

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

Prawidłowa odpowiedź to status 200 z treścią 123456, a nie JSON i nie "123456" w cudzysłowie. Jeśli token jest błędny, odpowiedni jest 403. Nie rejestruj parametrów zapytania, ponieważ pojawia się tam token weryfikacji.

Zrozumienie ładunku wiadomości przed napisaniem logiki biznesowej

WhatsApp zawija dane kilka poziomów głęboko. Typowe powiadomienie składa się z object: "whatsapp_business_account", tablicy entry, tablicy changes i zmiany, której field wynosi messages. Wewnątrz value przychodzące treści użytkownika pojawiają się w messages; aktualizacje dotyczące dostarczenia, przeczytania i niepowodzenia wysłanych wiadomości pojawiają się w 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);
    }
  }
}

Nie zakładaj, że każde powiadomienie zawiera wiadomość tekstową. Obrazy, pliki audio, dokumenty, lokalizacje, odpowiedzi interaktywne, komunikaty systemowe i ładunki zawierające tylko status mają różne kształty. Zachowaj klucz dyspozytora za pomocą message.type, sprawdź poprawność pól opcjonalnych i zachowaj nieznane typy zdarzeń do sprawdzenia, zamiast powodować awarię.

Sprawdź poprawność podpisu POST

Wartość X-Hub-Signature-256 ma postać sha256=<hex digest>. Oblicz wartość HMAC-SHA256 na podstawie surowych bajtów żądania, korzystając z Meta Secret App. Stały lub tymczasowy token dostępu WhatsApp jest używany do wywołań Graph API; to nie jest klucz HMAC. Użyj porównania w czasie stałym i odrzuć brakujący podpis.

Pozostaw włączoną weryfikację lokalną. Każdy, kto pozna adres URL tunelu, może wysłać do niego dowolny kod JSON. Bez weryfikacji sfałszowane zdarzenie może wywołać automatyczne odpowiedzi, zmutować rekordy CRM lub ujawnić stan klienta. Obróć klucz tajny aplikacji, jeśli został przypadkowo zatwierdzony, wydrukowany lub udostępniony.

Szybko potwierdzaj i usuwaj duplikaty wiadomości

Zwróć 200 po uwierzytelnieniu i trwałym umieszczeniu zdarzenia w kolejce. Nie czekaj z pobieraniem multimediów, dzwonieniem do LLM lub aktualizacją kilku usług. Dostawcy ponawiają próby dostarczenia, gdy potwierdzenia nie powiodą się, a niejednoznaczność sieci oznacza, że ​​duplikaty są normalne.

Użyj wiadomości WhatsApp id jako klucza idempotencji dla wiadomości przychodzących i obiektów stanu. Nałóż unikalne ograniczenie na przetwarzane identyfikatory. Przejścia stanu mogą zgodnie z prawem przebiegać od wysłanego do dostarczonego do odczytu, dlatego deduplikuj każde istotne przejście bez odrzucania późniejszego stanu.

Rozwiązywanie problemów z konfiguracją webhooka WhatsApp

Nie można sprawdzić adresu URL wywołania zwrotnego

Przetestuj trasę GET przez publiczny adres URL. Upewnij się, że akceptuje GET, porównuje dokładny token weryfikacyjny i odpowiada tylko wyzwaniem. Przekierowania, oprogramowanie pośredniczące uwierzytelniania, ponowne zapisywanie ustawień regionalnych lub opakowanie JSON mogą złamać weryfikację. Upewnij się, że zmienna środowiskowa została załadowana przez działający proces deweloperski.

Weryfikacja przebiegła pomyślnie, ale nie nadeszły żadne wiadomości

Sama weryfikacja wywołania zwrotnego nie powoduje subskrybowania pól na koncie WhatsApp Business. Potwierdź subskrypcję messages w panelu kontrolnym i upewnij się, że numer telefonu należy do oczekiwanej aplikacji i konta. Wyślij wiadomość od dozwolonego odbiorcy, jeśli aplikacja jest nadal w trybie programowania.

Każdy POST nie sprawdza poprawności podpisu

Zwykłe przyczyny to użycie tokena dostępu zamiast tajnego klucza aplikacji, mieszanie przeanalizowanego kodu JSON, pomijanie przedrostka sha256= lub porównywanie różnych kodowań. Rejestruj długość treści i informację, czy nagłówek istnieje, ale nigdy nie drukuj tajnego ani pełnego ładunku klienta.

Wiadomości tekstowe działają, ale obsługa multimediów nie działa

Powiadomienia o multimediach zawierają identyfikator, niekoniecznie bajty pliku. Pobierz multimedia za pomocą interfejsu Graph API z prawidłowym tokenem dostępu, a następnie pobierz je. Zachowaj wolniejszy przepływ pracy poza ścieżką potwierdzenia webhooka.

Lokalny punkt końcowy widzi zduplikowane zdarzenia

Sprawdź stan odpowiedzi i opóźnienie, dodaj trwałą idempotencję i odtwarzaj jedno przechwycone zdarzenie po każdej naprawie. przewodnik powtórek webhooka pokazuje, jak uniknąć wysyłania nowej prawdziwej wiadomości w przypadku każdej zmiany kodu.

Chroń dane klientów podczas testów lokalnych

  • W miarę możliwości używaj testowych numerów telefonów i syntetycznych rozmów.
  • Uredaguj numery telefonów, treść wiadomości, adresy URL multimediów, kontakty i nazwy profili z dzienników.
  • Przechowuj tajne dane aplikacji, tokeny dostępu i weryfikuj token tylko w ignorowanych plikach środowiska lub w menedżerze tajnych danych.
  • Ograniczaj, kto może przeglądać przechwycone tunele i usuwaj je po sesji debugowania.
  • Weryfikuj identyfikatory obiektów, pól i kont przed wykonaniem działań biznesowych.

Tunel przyspiesza iterację, ale jednocześnie dostarcza dane osobowe w formie produkcyjnej do maszyny programisty. Zastosuj kontrole z listy kontrolnej bezpieczeństwa tunelu przed testowaniem z prawdziwymi użytkownikami.

Najczęściej zadawane pytania

Jak przetestować webhook interfejsu API WhatsApp Cloud na serwerze lokalnym?
Uruchom lokalnie moduł obsługi webhooka i udostępnij go za pomocą tunelu HTTPS zarejestruj publiczny adres URL wywołania zwrotnego i zweryfikuj token w Meta, subskrybuj wiadomości, a następnie wyślij wiadomość testową.
Co powinien zwrócić punkt końcowy weryfikacji webhooka WhatsApp?
W przypadku prawidłowego żądania GET, w którym hub.mode jest subskrybowany, a hub.verify_token pasuje, zwróć wartość hub.challenge jako zwykły tekst za pomocą protokołu HTTP 200.
Jak to zrobić zweryfikować żądania POST webhooka WhatsApp?
Oblicz kod HMAC-SHA256 na podstawie dokładnej nieprzetworzonej treści żądania za pomocą klucza Meta App Secret, poprzedź skrót szesnastkowy sha256= i bezpiecznie porównaj go z X-Hub-Signature-256.
Dlaczego mój zweryfikowany webhook WhatsApp nie odbiera żadnych zdarzeń?
Weryfikacja wywołania zwrotnego nie automatycznie subskrybuj każde pole. Potwierdź, że konto WhatsApp Business subskrybuje wiadomości oraz że Twój testowy nadawca i numer telefonu są dostępne dla aplikacji.