Przejdź do głównej zawartości

Korzystanie z webhooków w Gridaly

Napisane przez Patryk Karawajski

1. Czym są Webhooki?

Webhooki to potężne narzędzie umożliwiające platformie Gridaly wysyłanie powiadomień w czasie rzeczywistym do Twoich zewnętrznych systemów za każdym razem, gdy w organizacji lub wydarzeniach zarządzanych w Gridaly zajdzie określone zdarzenie.

Zamiast ciągłego wysyłania zapytań do API Gridaly z pytaniem, czy pojawiły się nowe dane (tzw. polling), Gridaly automatycznie wyśle żądanie HTTP POST z odpowiednimi danymi pod wskazany przez Ciebie adres URL (tzw. webhook endpoint) natychmiast po wystąpieniu zdarzenia.

Typowe zastosowania:

  • Synchronizacja danych rejestracyjnych uczestników z systemem CRM.

  • Aktualizacja zewnętrznych baz danych w momencie sprzedaży biletu lub zameldowania (check-in) uczestnika.

  • Wyzwalanie niestandardowych scenariuszy (workflows) w narzędziach do automatyzacji marketingu.

  • Budowanie własnych pulpitów nawigacyjnych (dashboards) z danymi o wydarzeniu w czasie rzeczywistym.

  • Integracja z oprogramowaniem księgowym po wygenerowaniu faktury.

2. Tworzenie i konfiguracja Webhooka

Zarządzanie webhookami odbywa się w ustawieniach Organizacji w panelu administracyjnym Gridaly (Gridaly Admin).

Podczas tworzenia lub edycji webhooka należy skonfigurować następujące pola:

  • Name (Nazwa): Opisowa nazwa webhooka (np. „Synchronizacja CRM – Uczestnicy”).

  • Description (Opis - opcjonalnie): Dodatkowe informacje o przeznaczeniu webhooka.

  • URL: Adres URL punktu końcowego (HTTPS) Twojej zewnętrznej aplikacji, która będzie odbierać powiadomienia z Gridaly. Punkt końcowy musi być publicznie dostępny.

  • Active (Aktywny): Przełącznik włączający lub wyłączający webhook. Nieaktywne webhooki nie będą odbierać żadnych powiadomień.

  • Event Types (Typy zdarzeń): Wybór konkretnych zdarzeń w Gridaly, które mają wyzwalać ten webhook (np. attendee.created, attendee.updated, attendee.deleted). Możesz zaznaczyć wiele typów zdarzeń. Pełna lista dostępna jest w sekcji 7.

  • Events (Wydarzenia - opcjonalnie): Domyślnie webhook dotyczy wszystkich wydarzeń w ramach organizacji. Możesz ograniczyć jego działanie tylko do wyznaczonych wydarzeń.

  • Authentication Type (Typ uwierzytelniania): Metoda autoryzacji stosowana przez Gridaly przy wysyłaniu żądań:

    • None: Brak uwierzytelniania (zalecane tylko wtedy, gdy punkt końcowy jest zabezpieczony w inny sposób).

    • Header: Gridaly dołączy niestandardowy nagłówek HTTP.

    • Basic Auth: Gridaly użyje uwierzytelniania HTTP Basic Authentication.

    • Bearer Token: Gridaly dołączy nagłówek Authorization: Bearer TWÓJ_TOKEN.

    • Query String: Gridaly dołączy parametry uwierzytelniające bezpośrednio do adresu URL.

  • Authentication Token (Token uwierzytelniający): Sekret, token lub poświadczenia odpowiadające wybranemu typowi uwierzytelniania. Wymagany format zależy od wybranej metody:

    • Header: Wprowadź nazwę nagłówka i jego wartość rozdzielone dwukropkiem (:), np. X-API-Key: twojaTajnaWartosc123.

    • Basic Auth: Wprowadź nazwę użytkownika i hasło rozdzielone dwukropkiem (:), np. uzytkownik:haslo.

    • Bearer Token: Wprowadź samą wartość tokena, np. twojaWartoscTokenaBearer.

    • Query String: Wprowadź klucz i wartość parametru zapytania, np. apiKey=twojTajnyKlucz (nie dołączaj znaków ? ani & – Gridaly doda je automatycznie).

  • Secret Key (Klucz prywatny): Klucz generowany automatycznie przez Gridaly podczas tworzenia webhooka. Jest kluczowy do weryfikacji autentyczności przychodzących żądań. Należy go skopiować i bezpiecznie przechowywać w aplikacji odbierającej. Nie należy go nikomu udostępniać.

  • Retry Count (Liczba ponowień): Maksymalna liczba prób ponownego wysłania powiadomienia w przypadku niepowodzenia pierwotnej dostawy (np. z powodu tymczasowych problemów z siecią lub błędu serwera). Ponowne próby wykorzystują strategię wycofania wykładniczego (exponential backoff – wydłużanie odstępów czasowych między kolejnymi próbami).

3. Struktura ładunku danych (Payload)

W momencie wystąpienia wybranego zdarzenia Gridaly wysyła żądanie HTTP POST pod skonfigurowany adres URL z nagłówkiem Content-Type: application/json. Ciało żądania w formacie JSON posiada następującą strukturę:

JSON

{

"id": "123e4567-e89b-12d3-a456-426614174000",

// UUID of the primary resource related to the event

"event": "attendee.created",

// The type of event that occurred

"data": {

// Object containing detailed information about the event and resource

"id": "123e4567-e89b-12d3-a456-426614174000",

"firstname": "John",

"surname": "Doe",

// ... other relevant attendee fields

}

}

  • id: Unikalny identyfikator (UUID) głównego zasobu Gridaly powiązanego ze zdarzeniem (np. UUID uczestnika dla zdarzenia attendee.created).

  • event: Ciąg znaków określający typ zdarzenia, które wyzwoliło webhook (zgodny z subskrybowanymi typami).

  • data: Obiekt zawierający szczegółowe dane dotyczące zdarzenia. Jego struktura zależy od typu zdarzenia.

4. Zabezpieczanie punktu końcowego (Weryfikacja podpisu)

Aby upewnić się, że przychodzące żądania rzeczywiście pochodzą z platformy Gridaly i nie zostały zmodyfikowane, należy zweryfikować podpis dołączony do każdego zapytania.

Gridaly dołącza do każdego żądania webhooka następujące nagłówki HTTP:

  • X-Gridaly-Signature: Podpis HMAC-SHA256 wygenerowany przy użyciu klucza Secret Key oraz surowej zawartości ładunku JSON (raw payload).

  • X-Gridaly-Timestamp: Znacznik czasu Unixa (Unix timestamp) określający moment wysłania żądania.

  • X-Gridaly-Event: Nazwa typu zdarzenia (np. attendee.created).

  • X-Gridaly-Delivery: Unikalny identyfikator (UUID) konkretnej próby doręczenia.

  • User-Agent: Zawsze ustawiony na Gridaly-Webhooks/1.0.

Proces weryfikacji:

  1. Pobranie nagłówków: Odczytaj wartości X-Gridaly-Signature oraz X-Gridaly-Timestamp z nagłówków przychodzącego żądania.

  2. Sprawdzenie znacznika czasu (opcjonalne, ale zalecane): Porównaj X-Gridaly-Timestamp z aktualnym czasem serwera. Odrzuć żądania zbyt stare (np. starsze niż 5 minut), aby zapobiec atakom typu replay attack.

  3. Pobranie surowego ładunku: Uzyskaj dostęp do surowej, niesparsowanej treści JSON żądania POST (raw payload).

  4. Wygenerowanie podpisu: Oblicz skrót HMAC-SHA256 z surowego ładunku JSON, używając klucza Secret Key przypisanego do danego webhooka w panelu Gridaly.

  5. Porównanie podpisów: Porównaj podpis obliczony w kroku 4 z podpisem odebranym w nagłówku X-Gridaly-Signature. Jeśli to możliwe, użyj funkcji porównywania odpornej na ataki czasowe (timing-safe comparison).

  6. Akceptacja lub odrzucenie: Jeżeli podpisy są zgodne (a znacznik czasu mieści się w dopuszczalnym przedziale), żądanie jest autentyczne i można je przetworzyć. W przeciwnym razie odrzuć żądanie (zwracając kod błędu HTTP 400 lub 401) i zarejestruj zdarzenie w logach.

Przykład kodu (pseudokod):

JavaScript

// Your webhook endpoint handler function

function handleGridalyWebhook(request) {

const receivedSignature = request.headers['X-Gridaly-Signature'];

const receivedTimestamp = request.headers['X-Gridaly-Timestamp'];

const rawPayload = request.rawBody; // Access the raw request body

// 1. Get your stored Secret Key for this webhook

const secretKey = getSecretKeyFromYourConfig();

// 2. (Optional) Check timestamp tolerance

const tolerance = 5 * 60; // 5 minutes in seconds

const currentTimestamp = Math.floor(Date.now() / 1000);

if (Math.abs(currentTimestamp - receivedTimestamp) > tolerance) {

console.error("Timestamp validation failed");

return response.status(400).send("Timestamp validation failed");

}

// 3. Compute the expected signature

const expectedSignature = computeHmacSha256(rawPayload, secretKey);

// 4. Compare signatures securely

if (secureCompare(receivedSignature, expectedSignature)) {

// Signatures match - process the payload

const payload = JSON.parse(rawPayload);

processEvent(payload);

return response.status(200).send("OK");

} else {

// Signatures do NOT match - reject the request

console.error("Signature validation failed");

return response.status(401).send("Signature validation failed");

}

}

// Helper function for HMAC-SHA256

// (implementation depends on your language/framework)

function computeHmacSha256(data, secret) {

// ... use crypto library to compute HMAC-SHA256 hash ...

return computedHash;

}

// Helper function for timing-safe comparison

// (implementation depends on your language/framework)

function secureCompare(a, b) {

// ... implement timing-safe string comparison ...

return areEqual;

}

5. Monitorowanie doręczeń

Gridaly prowadzi dziennik wszystkich prób doręczenia powiadomień. Logi te są dostępne w sekcji konfiguracji Webhooków.

Tabela dziennika doręczeń (Delivery Logs) zawiera:

  • Event Type (Typ zdarzenia): Zdarzenie, które wyzwoliło próbę doręczenia.

  • Status: Wynik próby doręczenia:

    • Pending (Oczekujące): Doręczenie zaplanowane, próba jeszcze się nie odbyła.

    • Success (Sukces): Punkt końcowy odebrał żądanie i zwrócił kod statusu HTTP z zakresu 2xx.

    • Failed (Niepowodzenie): Próba zakończona błędem (np. błąd sieci, przekroczenie czasu oczekiwania lub kod statusu inny niż 2xx).

  • Response Code (Kod odpowiedzi): Kod statusu HTTP zwrócony przez Twój punkt końcowy (jeśli odpowiedź nadeszła).

  • Attempt (Próba): Numer próby dla danego powiadomienia (1 dla pierwszej próby, 2 dla pierwszego ponowienia itd.).

  • Processed At (Czas przetworzenia): Data i godzina zakończenia próby doręczenia.

Regularna analiza dzienników jest kluczowa do diagnozowania problemów. W przypadku powtarzających się błędów należy zweryfikować dostępność punktu końcowego, przejrzeć logi serwera oraz upewnić się, że prawidłowo zwraca on kody z zakresu 2xx po pomyślnym przetworzeniu żądania.

6. Rozwiązywanie problemów (Troubleshooting)

  • Notoryczne błędy doręczeń:

    • Sprawdź kody odpowiedzi i komunikaty błędów w dzienniku doręczeń (Delivery Logs).

    • Upewnij się, że podany adres URL jest poprawny i publicznie dostępny.

    • Sprawdź, czy serwer/aplikacja działa prawidłowo i nie zgłasza błędów w logach wewnętrznych.

    • Zweryfikuj ustawienia reguł zapory sieciowej (firewall) lub grup bezpieczeństwa, które mogą blokować ruch z serwerów Gridaly.

    • Upewnij się, że punkt końcowy odpowiada kodem z zakresu 2xx w odpowiednim czasie (domyślny limit czasu oczekiwania w Gridaly wynosi około 10 sekund).

  • Błąd weryfikacji podpisu:

    • Upewnij się, że używasz właściwego klucza Secret Key skopiowanego z panelu Gridaly.

    • Upewnij się, że skrót HMAC-SHA256 jest obliczany na surowej treści żądania (raw request body), a nie na obiekcie już przetworzonym/sparsowanym.

  • Brak przychodzących zdarzeń:

    • Upewnij się, że webhook ma status Active.

    • Sprawdź, czy zasubskrybowano właściwe Event Types.

    • Jeśli stosujesz filtrowanie wydarzeń, upewnij się, że zdarzenie występuje w ramach wybranego wydarzenia.

7. Dostępne zdarzenia Webhooków

7.1. Zdarzenia dotyczące Uczestników (Attendee Events)

Typ zdarzenia

Wyzwalacz

Opis

attendee.created

Utworzenie nowego uczestnika

Wysyłane w momencie zarejestrowania nowego uczestnika na wydarzenie

attendee.updated

Modyfikacja danych uczestnika

Wysyłane po aktualizacji danych (profil, status, ustawienia itp.)

attendee.deleted

Usunięcie uczestnika

Wysyłane po usunięciu uczestnika z systemu

attendee.checkin

Zameldowanie uczestnika (check-in)

Wysyłane w momencie zameldowania uczestnika na wydarzeniu (używa odrębnego, skróconego ładunku danych)

Struktura ładunku dla danych Uczestnika:

Obiekt data dla zdarzeń attendee.created, attendee.updated oraz attendee.deleted:

JSON

{

"id": "123e4567-e89b-12d3-a456-426614174000",

"additionalEmail": "john.alternate@example.com",

"activity": "active",

"status": "confirmed",

"active": true,

"public": true,

"virtualPerson": false,

"phone": "+1234567890",

"order": 1,

"lang": "en",

"country": "US",

"externalId": "EXT-12345",

"externalTicket": "TKT-98765",

"firstname": "John",

"surname": "Doe",

"headline": "Software Engineer",

"website": "https://johndoe.com",

"pphone": "+1234567890",

"biography": "Experienced software engineer...",

"location": "New York, USA",

"company": "Tech Corp",

"position": "Senior Developer",

"timezone": "America/New_York",

"activedAt": "2024-01-15T10:30:00Z",

"checkinAt": "2024-01-20T09:00:00Z",

"firstAt": "2024-01-15T10:35:00Z",

"activityWebAt": "2024-01-15T10:30:00Z",

"activityMobileAt": "2024-01-16T08:00:00Z",

"activityWebApp": "active",

"activityMobileApp": "active",

"disableTransmissionReactions": false,

"gamificationShowInRanking": true,

"gamificationNotifyEndedTask": true,

"meetingsNotificationsViaEmail": true,

"groupsNotificationsViaEmail": true,

"doNotDisturb": false,

"receiveMeetingProposals": true,

"autoAcceptMeetingInvitations": false,

"autoCreateExhibitorScanForLead": true,

"pushNotifications": true,

"canBeVoted": true,

"headlinePattern": "default",

"showOnNetworkingList": true,

"marketingConsent": true,

"ticket": {

"id": "ticket-uuid",

"name": "VIP Pass"

},

"addonables": [],

"exhibitors": [],

"roles": [

{

"id": "role-uuid",

"name": "Speaker"

}

],

"tags": [

{

"id": "tag-uuid",

"name": "Technology"

}

],

"twitter": "@johndoe"

}

Struktura ładunku dla zameldowania Uczestnika (Check-in):

Zdarzenie attendee.checkin przesyła dedykowany, skrócony obiekt data:

JSON

{

"id": "123e4567-e89b-12d3-a456-426614174000",

"firstname": "John",

"surname": "Doe",

"ticket": {

"id": "ticket-uuid",

"name": "VIP Pass"

},

"checkinAt": "2024-01-20T09:00:00Z",

"checkinBy": "Anna Kowalska",

"createdAt": "2024-01-15T10:30:00Z"

}

7.2. Zdarzenia dotyczące Zamówień (Order Events)

Typ zdarzenia

Wyzwalacz

Opis

order.created

Złożenie nowego zamówienia

Wysyłane po utworzeniu nowego zamówienia w systemie

order.updated

Modyfikacja zamówienia

Wysyłane po aktualizacji danych zamówienia (status, dane kupującego, dane do faktury itp.)

order.deleted

Usunięcie zamówienia

Wysyłane po usunięciu zamówienia z systemu

Struktura ładunku dla Zamówień:

Obiekt data dla zdarzeń dotyczących zamówień:

JSON

{

"id": "123e4567-e89b-12d3-a456-426614174000",

"eid": "ORD-2024-001234",

"externalId": "EXT-ORD-5678",

"status": "completed",

"firstname": "Jane",

"surname": "Smith",

"customFields": {

"dietary_preferences": "vegetarian",

"company_size": "50-100"

},

"invoiceType": "company",

"invoiceFirstname": "Jane",

"invoiceSurname": "Smith",

"invoiceCompany": "Smith & Co",

"invoiceTaxId": "1234567890",

"invoiceStreet": "Main Street",

"invoiceHouse": "123",

"invoiceApartment": "4B",

"invoicePostalCode": "10001",

"invoiceCity": "New York",

"invoiceCountry": "US",

"language": "en",

"timezone": "America/New_York",

"eventId": "event-uuid",

"events": [

"event-uuid-1",

"event-uuid-2"

],

"createdAt": "2024-01-15T10:30:00Z",

"updatedAt": "2024-01-15T11:00:00Z"

}

7.3. Zdarzenia dotyczące Płatności (Payment Events)

Typ zdarzenia

Wyzwalacz

Opis

payment.created

Inicjalizacja płatności

Wysyłane po utworzeniu nowego rekordu płatności

payment.updated

Zmiana statusu/danych płatności

Wysyłane po aktualizacji płatności (zmiana statusu, zatwierdzenie, odrzucenie itp.)

payment.deleted

Usunięcie płatności

Wysyłane po usunięciu płatności z systemu

Struktura ładunku dla Płatności:

Obiekt data dla zdarzeń dotyczących płatności:

JSON

{

"id": "123e4567-e89b-12d3-a456-426614174000",

"eid": "PAY-2024-001234",

"number": "INV/2024/001234",

"kind": "invoice",

"externalId": "STRIPE-ch_1234567890",

"amount": 15000,

"currency": "USD",

"paymentStatus": "paid",

"paymentMethod": "card",

"paymentProvider": "stripe",

"paymentDays": 14,

"paymentItems": [

{

"name": "VIP Pass",

"type": "ticket",

"quantity": 2,

"netTotal": 12195.12,

"vatTotal": 2804.88,

"grossTotal": 15000

}

],

"ticketsQuantity": 2,

"addonsQuantity": 0,

"invoiceType": "company",

"invoiceFirstname": "Jane",

"invoiceSurname": "Smith",

"invoiceCompany": "Smith & Co",

"invoiceTaxId": "1234567890",

"invoiceStreet": "Main Street",

"invoiceHouse": "123",

"invoiceApartment": "4B",

"invoicePostalCode": "10001",

"invoiceCity": "New York",

"invoiceCountry": "US",

"invoiceAlert": null,

"vatFree": false,

"commentBuyer": "Please send invoice to accounting department",

"commentOrganiser": "VIP client - priority processing",

"serviceRealized": true,

"voucherId": "voucher-uuid",

"orderId": "order-uuid",

"eventId": "event-uuid",

"events": [

"event-uuid-1",

"event-uuid-2"

],

"createdAt": "2024-01-15T10:30:00Z",

"updatedAt": "2024-01-15T11:00:00Z",

"expiredAt": "2024-01-29T23:59:59Z",

"approvedAt": "2024-01-15T11:00:00Z",

"rejectedAt": null

}

7.4. Zdarzenia dotyczące Dokumentów Księgowych (Accounting Document Events)

Gridaly przesyła również webhooki dla dokumentów księgowych wystawianych w systemie: zaliczek, korekt, faktur, proform oraz paragonów. Wszystkie typy dokumentów dzielą wspólną bazową strukturę ładunku, rozszerzoną o pola specyficzne dla danego typu.

Typ zdarzenia

Wyzwalacz

Opis

advance.created

Utworzenie faktury zaliczkowej

Wysyłane po wystawieniu faktury zaliczkowej

advance.updated

Modyfikacja faktury zaliczkowej

Wysyłane po zmianie danych zaliczki (status, numeracja, płatność itp.)

correction.created

Utworzenie korekty

Wysyłane po utworzeniu korekty faktury, zaliczki lub paragonu

correction.updated

Modyfikacja korekty

Wysyłane po zmianie danych dokumentu korekty

invoice.created

Utworzenie faktury

Wysyłane po wystawieniu nowej faktury

invoice.updated

Modyfikacja faktury

Wysyłane po zmianie danych faktury (status, numeracja, płatność itp.)

proforma.created

Utworzenie proformy

Wysyłane po wystawieniu proformy

proforma.updated

Modyfikacja proformy

Wysyłane po zmianie danych proformy

receipt.created

Utworzenie paragonu

Wysyłane po wystawieniu paragonu

receipt.updated

Modyfikacja paragonu

Wysyłane po zmianie danych paragonu

Bazowa struktura ładunku dla Dokumentów Księgowych:

Obiekt data dla wszystkich zdarzeń związanych z dokumentami księgowymi zawiera następujące pola podstawowe:

JSON

{

"id": "123e4567-e89b-12d3-a456-426614174000",

"eid": "INV-2024-001234",

"number": "FV/01/2024/0001",

"status": 2,

"netTotal": 12195.12,

"vatTotal": 2804.88,

"grossTotal": 15000,

"currency": "USD",

"languages": [

"en",

"pl"

],

"alert": null,

"vatFree": false,

"vatExemption": null,

"NBPExchangeRate": null,

"items": [

{

"name": "VIP Pass",

"type": "ticket",

"quantity": 2,

"netTotal": 12195.12,

"vatTotal": 2804.88,

"grossTotal": 15000

}

],

"ticketsQuantity": 2,

"addonsQuantity": 0,

"buyerType": "company",

"buyerFirstname": "Jane",

"buyerSurname": "Smith",

"buyerCompany": "Smith & Co",

"buyerTaxId": "1234567890",

"buyerStreet": "Main Street",

"buyerHouse": "123",

"buyerApartment": "4B",

"buyerPostalCode": "10001",

"buyerCity": "New York",

"buyerCountry": "US",

"sellerCompany": "Event Organizer Ltd",

"sellerTaxId": "0987654321",

"system": "gridaly",

"integration": null,

"orderId": "order-uuid",

"paymentId": "payment-uuid",

"eventId": "event-uuid",

"events": [

"event-uuid-1",

"event-uuid-2"

],

"invoiceAt": "2024-01-15T10:30:00Z",

"exchangeAt": null,

"createdAt": "2024-01-15T10:30:00Z",

"updatedAt": "2024-01-15T11:00:00Z"

}

Struktura obiektu integration zależy od zewnętrznego systemu księgowego, w którym dokument został wystawiony:

  • Dla Fakturowni oraz inFaktu: { "id": "external-document-id" }

  • Dla KSeF: { "number": "ksef-number", "referenceNumber": "ksef-reference-number" }

  • Dla Gridaly: null (dokument wystawiony bezpośrednio w Gridaly)

Pola specyficzne dla poszczególnych typów dokumentów:

Oprócz pól bazowych, poszczególne typy dokumentów zawierają dodatkowo:

  • Faktura (invoice.*): paymentStatus, paymentDays, advances (identyfikatory UUID zaliczek rozliczonych fakturą), soldAt, paidAt.

  • Zaliczka (advance.*): paymentStatus, paymentDays, corrections (identyfikatory UUID korekt danej zaliczki), issuePlannedAt, soldAt, paidAt.

  • Paragon (receipt.*): paymentStatus, paymentDays, advances (identyfikatory UUID zaliczek rozliczonych paragonem), soldAt, paidAt.

  • Proforma (proforma.*): paymentStatus, paymentDays.

  • Korekta (correction.*): kind (valueCorrection lub quantitiveCorrection), correctableId oraz correctableType (UUID oraz typ korygowanego dokumentu: invoice, advance lub receipt), correctionId (UUID nowszej korekty zastępującej obecną, jeśli występuje), refundId (UUID powiązanego zwrotu środków, jeśli występuje), soldAt, dueAt.

8. Dobre praktyki (Best Practices)

  • Stosuj protokół HTTPS: Adresy URL punktów końcowych powinny zawsze używać protokołu https://, aby zapewnić szyfrowanie danych w transmisji.

  • Weryfikuj podpisy: Zawsze weryfikuj nagłówek X-Gridaly-Signature w celu potwierdzenia autentyczności i spójności danych.

  • Odpowiadaj niezwłocznie: Potwierdzaj odebranie webhooka, zwracając kod statusu HTTP z zakresu 2xx tak szybko, jak to możliwe (optymalnie w ciągu 2–3 sekund). Złożone operacje logiczne wykonuj asynchronicznie (np. przy użyciu kolejek zadań w tle), aby uniknąć przekroczenia limitu czasu odpowiedzi (timeout).

  • Obsługuj powtórzenia (Idempotentność): Z powodu mechanizmu ponowień punkt końcowy może odebrać to samo powiadomienie wielokrotnie. Zaprojektuj logikę przetwarzania w sposób idempotentny (tak, aby wielokrotne przetworzenie tego samego powiadomienia nie powodowało niepożądanych skutków ubocznych). Do identyfikacji dubli wykorzystaj nagłówek X-Gridaly-Delivery (unikalny dla każdej próby) lub pole id z ładunku danych.

  • Monitoruj punkt końcowy: Prowadź stały monitoring logów i wydajności aplikacji, aby upewnić się, że jest ona w stanie obsłużyć bieżący wolumen ruchu wygenerowanego przez webhooki.

Czy to odpowiedziało na twoje pytanie?