Zdarzenia SMS
Każda wiadomość przechodzi przez cykl życia, a Bird emituje zdarzenie na każdym etapie. Ta strona to pełny słownik zdarzeń; sposób dostarczania zdarzeń do Twojego endpointu (sygnatury, ponowne próby, odtwarzanie) opisuje Przewodnik po webhookach.
Cykl życia dostarczania jako ścieżka przez typy zdarzeń:
- sms.accepted: Bird przyjął wiadomość i przygotowuje ją do przekazania operatorowi.
- sms.sent: Bird przekazał wiadomość operatorowi i oczekuje na potwierdzenie dostarczenia.
- Jedno zdarzenie końcowe:
- sms.delivered: Operator potwierdził dostarczenie na urządzenie.
- sms.undelivered: Operator zgłosił tymczasowe niedostarczenie, np. niedostępne urządzenie.
- sms.failed: Trwały błąd uniemożliwił dostarczenie.
- sms.expired: Operator zaprzestał prób dostarczenia i zgłosił wiadomość jako wygasłą.
Zdarzenia końcowe ujawniają potwierdzenie dostarczenia od operatora, które platformy SMS nazywają raportem dostarczenia (DLR).
Wyjątkiem jest sms.rejected: wiadomość została odrzucona (przez kontrolę polityki, nieukończone naliczenie opłaty lub operatora, który ją odrzucił), a nie próbowano jej dostarczyć i utracono. Wiadomość odrzucona podczas przetwarzania ma sms.rejected jako jedyne zdarzenie.
Bird odbiera też odpowiedzi. Gdy subskrybent wyśle SMS na jeden z Twoich numerów, Bird zapisuje wiadomość i emituje sms.received, dzięki czemu możesz reagować bez odpytywania. Payload zawiera treść, podział na segmenty, oba numery oraz operatora, jeśli operator go zgłasza.
Bird porównuje odpowiedź z regułami słów kluczowych dla danego numeru. Obsługiwane słowo kluczowe stop, takie jak STOP, rejestruje blokadę nadawca-subskrybent i nadal emituje sms.received.
Zdarzenie type jest otwartym enumem: Bird może z czasem dodawać nowe typy zdarzeń, więc traktuj nierozpoznany type jako przyszłe zdarzenie, a nie błąd. Obsługuj typy, które Cię interesują, a resztę ignoruj.
Koperta zdarzenia
Zdarzenia docierają do Twojego endpointu webhook w zagnieżdżonej kopercie Standard Webhooks opisanej w Przewodniku po webhookach: trzy pola, type, timestamp i obiekt data specyficzny dla typu. Tożsamość zdarzenia nie jest w ciele żądania: znajduje się w nagłówku webhook-id HTTP, który jest stały między ponownymi próbami tego samego dostarczenia i służy jako klucz deduplikacji.
| Pole | Opis |
|---|---|
| type | Jeden z typów zdarzeń na tej stronie, np. sms.delivered |
| timestamp | Moment wystąpienia zdarzenia (RFC 3339); sortuj po tym polu, nigdy po kolejności odbioru, bo dostarczenia nie są uporządkowane |
| data | Payload specyficzny dla zdarzenia |
data każdego zdarzenia SMS zawiera sms_id, workspace_id oraz adresy to i from. Powtarza też tags i metadata wysyłki, dzięki czemu możesz kierować i korelować zdarzenia bez dodatkowego zapytania. Każde z nich ma wartość null, jeśli wysyłka ich nie zawierała.
Ten sam obiekt zawiera cost, opłatę za wiadomość na moment danego zdarzenia, podzieloną na transaction_amount i passthrough_amount z ich sumą w amount. Ma wartość null dla zdarzenia, które niczego nie wyceniło. Ponieważ dostarczenia nie są uporządkowane, scalaj cost komponent po komponencie zamiast zastępować cały obiekt: dla każdego komponentu zachowaj wartość ze zdarzenia z najnowszym timestamp. amount sumuje tylko komponenty obecne w swoim payloadzie, więc traktuj go jako dotychczasową opłatę, a nie ostateczną kwotę. Koszty i rozliczenia opisują znaczenie każdego komponentu.
Przykład kodu
{
"type": "sms.delivered",
"timestamp": "2026-06-10T14:30:00Z",
"data": {
"sms_id": "sms_01krdgeqcxet5s7t44vh8rt9mg",
"workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
"to": "+15551234567",
"from": "+12025550188",
"carrier": "Example Wireless",
"mcc_mnc": "310260",
"cost": {
"amount": "0.00990",
"currency_code": "USD",
"transaction_amount": "0.00790",
"passthrough_amount": "0.00200"
},
"tags": [{ "name": "campaign", "value": "spring-2026" }],
"metadata": { "order_id": "ord_123" }
}
}Zdarzenia cyklu życia
sms.accepted
Emitowane, gdy Bird przyjmie wysyłkę i rozpocznie przygotowanie do przekazania operatorowi. Payload dodaje segments, podział Bird obliczony w momencie akceptacji; jego count jest podstawą naliczenia opłaty za wysyłkę.
sms.sent
Emitowane, gdy Bird przekazał wiadomość operatorowi i oczekuje na potwierdzenie dostarczenia. Payload dodaje carrier i mcc_mnc (obsługującą sieć i jej kod kraju/sieci mobilnej). Każde z nich jest nieobecne, a nie null, gdy operator go nie zgłasza. Aby zmierzyć opóźnienie przetwarzania, porównaj timestamp tego zdarzenia z sms.accepted.
sms.delivered
Operator potwierdził, że wiadomość dotarła na urządzenie. Payload dodaje carrier i mcc_mnc, każde nieobecne, gdy potwierdzenie ich nie identyfikowało.
Zdarzenia błędów
Payload każdego zdarzenia błędu dodaje obiekt error: stabilny w Bird code (np. unreachable lub blocked_by_carrier), czytelny dla człowieka description, surowy carrier_error_code, jeśli został podany, oraz occurred_at.
sms.undelivered
Niedostarczenie nietrwałe: urządzenie było wyłączone lub nieosiągalne.
sms.failed
Trwały błąd dostarczenia zatrzymał wiadomość.
sms.rejected
Wiadomość została odrzucona przez kontrole Bird podczas przetwarzania, nieukończone naliczenie opłaty lub operatora, który ją odrzucił. Odrzucenie zatrzymuje wiadomość, zanim próba dostarczenia się powiedzie. Wyczerpany portfel kończy się tutaj z kodem błędu insufficient_balance, a wiadomość, której opłata nie mogła zostać naliczona, nie jest rozliczana.
sms.expired
Operator zaprzestał prób dostarczenia i zgłosił wiadomość jako wygasłą. Wygaśnięcie pochodzi z potwierdzenia dostarczenia operatora: Bird nie ustawia własnego okna ważności i nie uruchamia żadnego licznika kończącego wiadomość. error opisuje, dlaczego wiadomość pozostała niedostarczona, gdy operator się poddał, zazwyczaj unreachable: urządzenie pozostawało wyłączone lub poza zasięgiem przez cały czas.
Zdarzenia blokad
Poza cyklem życia poszczególnych wiadomości jedno zdarzenie zgłasza zmianę na liście blokad obszaru roboczego: sms_suppression.created jest emitowane, gdy blokada zostaje otwarta, niezależnie od tego, czy subskrybent wysłał słowo kluczowe stop, operator zgłosił opt-out, czy ktoś dodał ją ręcznie. Payload zawiera suppression_id, numer subskrybenta jako destination, originator, do którego blokada jest przypisana (blokada SMS to dokładna para nadawca-subskrybent), reason oraz workspace_id, dzięki czemu Twój system może odzwierciedlać listę bez odpytywania:
Przykład kodu
{
"type": "sms_suppression.created",
"timestamp": "2026-08-25T14:52:03.192524705Z",
"data": {
"suppression_id": "ssu_01krdgeqcxet5s7t44vh8rt9mg",
"destination": "+15550001234",
"originator": "+15557654321",
"reason": "keyword_stop",
"workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf"
}
}Opt-out obejmujący cały obszar roboczy, zapisany na karcie Preferences, jest wyrażoną preferencją, a nie blokadą, i nie wyzwala tego zdarzenia.
Odczytywanie osi czasu wiadomości
Webhooki dostarczają zdarzenia do Twoich systemów. Do jednorazowego przeglądu log SMS renderuje ten sam strumień jako oś czasu ze znacznikami czasu, szczegółami operatora i błędami. Aby pobrać oś czasu programowo, wywołaj GET /v1/sms/messages/{message_id}/events. Aby odczytać tylko najnowszy stan, wywołaj GET /v1/sms/messages/{message_id}.
Kolejne kroki
- Webhooki i zdarzenia: skonfiguruj endpoint, weryfikuj sygnatury i obsługuj ponowne próby oraz odtwarzanie.
- Log SMS: sprawdź oś czasu poszczególnych wiadomości, którą napędzają te zdarzenia.
- Wysyłanie SMS: ustaw tags i metadata powtarzane w każdym zdarzeniu.
Powiązane zasoby
Kontynuuj z dokumentacją, przewodnikami i przykładami dotyczącymi tego tematu. Zasoby są w języku angielskim.
Zrozum koncepcjęOne-way and two-way SMSPoznaj możliwościTwo-way SMSPodążaj ścieżką naukiBuild your first integration
Uzyskaj brief wdrożeniowy