Kody statusu DLR: stany wiadomości SMPP i co naprawdę stwierdzają
Potwierdzenia doręczenia to najbliższe przybliżenie prawdy, jakie daje stos SMS, a mimo to nadal nie są prawdą. Ten artykuł mapuje wartości message_state SMPP v3.4 na to, co każde z nich stwierdza i czego nie stwierdza, które stany mogą się jeszcze zmienić, jak wpasowują się teksty potwierdzeń i rodziny błędów sieciowych oraz jak obsługiwać je w webhookach bez nadmiernego zaufania do pojedynczego pola statusu.
Wartości message_state SMPP v3.4: co każde stwierdza
SMPP v3.4 definiuje mały zestaw wartości message_state używanych w potwierdzeniach doręczenia deliver_sm oraz w odpowiedziach query_sm. Traktuj je jako klasyfikacje zgłoszone przez sieć, a nie jako dowód kryminalistyczny zachowania telefonu. Ta sama etykieta może nadejść z różnych hopów z różnym poziomem pewności. Zawsze łącz stan z tekstem potwierdzenia, ewentualnym kodem błędu sieciowego oraz własnymi znacznikami czasu submit/done.
ENROUTE stwierdza, że wiadomość została przyjęta na ścieżkę doręczenia i nie jest jeszcze w terminalnym wyniku znanym węzłowi raportującemu. Nie stwierdza, że telefon jest osiągalny, że zapytanie HLR się powiodło ani że wiadomość ostatecznie dotrze. DELIVRD lub DELIVERED stwierdza, że węzeł downstream zgłosił pomyślne doręczenie do telefonu lub do zaakceptowanego endpointu store-and-forward, który sieć traktuje jako doręczony. Nie stwierdza odczytu przez użytkownika, instalacji aplikacji ani poprawnego wyrenderowania treści. EXPIRED stwierdza, że upłynął okres ważności bez pomyślnego raportu doręczenia, który sieć uznaje za finalny. Nie stwierdza, że telefon był wyłączony przez cały czas - tylko że czas się skończył według reguł ścieżki.
DELETED stwierdza, że wiadomość została usunięta z centrum wiadomości lub kolejki przed finalnym doręczeniem, zwykle przez akcję administracyjną lub czyszczenie sieciowe. Nie mówi, kto zainicjował usunięcie ani czy telefon kiedykolwiek zobaczył SMS. UNDELIVERABLE stwierdza, że sieć uznała, iż doręczenie nie może się dokończyć w obecnych warunkach. Nie oznacza trwałego oznaczenia MSISDN jako nieprawidłowego przy każdej przyszłej próbie; warunki się zmieniają. ACCEPTED stwierdza, że wiadomość została przyjęta przez encję downstream, która niekoniecznie zwróci klasyczne doręczenie do telefonu - typowe dla niektórych endpointów aplikacyjnych lub pośrednich semantyki akceptacji. Nie jest synonimem DELIVERED.
UNKNOWN stwierdza, że węzeł raportujący nie może zmapować wyniku na bardziej konkretny stan. Nie oznacza, że wiadomość zniknęła bez logów po Twojej stronie; oznacza, że otrzymane potwierdzenie jest nieinformacyjne. REJECTED stwierdza, że wiadomość została odrzucona przez politykę sieci lub platformy przed lub zamiast normalnego zakończenia próby doręczenia. Nie zawsze oznacza, że numer jest nieprawidłowy - treść, originator, przepustowość lub reguły blokad mogą dawać ten sam stan w zależności od ścieżki.
Konta SMSRoute obejmują panel, API oraz historię nadawania.armowe kredyty testowe, które potwierdzają doręczenie przed płatnością, a narzędzia do testowania doręczeń są dostępne w panelu SMSRoute.
| message_state | Stwierdza | Nie stwierdza |
|---|---|---|
| ENROUTE | W drodze na ścieżce raportującej | Dotarcie do telefonu lub ostateczny sukces |
| DELIVERED | Otrzymano raport sukcesu z downstream | Potwierdzenie odczytu, sukces UX lub niezmienna prawda |
| EXPIRED | Okno ważności zakończone bez sukcesu | Trwała awaria telefonu lub numeru |
| DELETED | Usunięto z MC/kolejki przed finalnym doręczeniem | Tożsamość aktora lub widoczność telefonu |
| UNDELIVERABLE | Ścieżka uznała, że doręczenie nie może się teraz dokończyć | Dożywotnia trwała nieprawidłowość |
| ACCEPTED | Przyjęte przez endpoint z nieklasyczną semantyką DLR | Doręczenie do telefonu równoważne DELIVERED |
| UNKNOWN | Brak lepszej dostępnej klasyfikacji | Brak jakichkolwiek logów systemowych |
| REJECTED | Odrzucone z powodu polityki lub reguł routingu | Zawsze błędny MSISDN |
Stany końcowe a pośrednie
Stany pośrednie mogą się jeszcze zmienić. ENROUTE to wyraźny stan pośredni: później może nadejść DELIVERED, EXPIRED, UNDELIVERABLE, REJECTED, DELETED, a nawet ACCEPTED. UNKNOWN operacyjnie traktuj jako niekońcowy, chyba że kontrakt upstream stanowi inaczej; wiele integracji widzi zastąpienie UNKNOWN jaśniejszym potwierdzeniem, a niektóre w ogóle nie dostają aktualizacji.
Stany końcowe to te, dla których handler zwykle przestaje ponawiać logikę submit: DELIVERED, EXPIRED, DELETED, UNDELIVERABLE, REJECTED oraz typowo ACCEPTED, gdy ścieżka używa ACCEPTED jako terminalnej akceptacji aplikacyjnej. Końcowy oznacza końcowy dla tej tożsamości wiadomości na tej ścieżce — nie dla wyniku biznesowego. DLR DELIVERED nadal może być błędny; po EXPIRED użytkownik może zobaczyć spóźniony SMS tylko w zepsutych lub wielościeżkowych setupach, co należy traktować jako sygnał defektu, a nie oczekiwane zachowanie SMPP.
Projektuj maszyny stanów wokół korelacji message id, nie wokół nadziei. Po ENROUTE trzymaj wiersz otwarty. Po stanie końcowym zamknij ponowienia wychodzące dla tego id, zapisz state i err, a otwieraj ponownie tylko przy jawnej polityce konfliktu duplicate-id, którą kontrolujesz. Nie cofaj DELIVERED do ENROUTE, bo drugi raport wygląda przyjaźniej — zamiast tego zaloguj anomalię.
Konwencja tekstu potwierdzeń i rodziny kodów błędów sieciowych
Wiele raportów deliver_sm SMSC osadza krótki tekst treści według wieloletniej konwencji w stylu ESM. Pola zwykle występują jako etykietowane tokeny: id (identyfikator wiadomości znany MC), sub (liczba submit), dlvrd (liczba dostarczonych), submit date, done date, stat (stan tekstowy, np. DELIVRD, EXPIRED, UNDELIV, ACCEPTD, REJECTD) oraz err (kod błędu sieci lub MC). Parsowanie musi być defensywne: odstępy, zero-padding dat i pisownia stat różnią się ścieżkami. Preferuj strukturalny TLV message_state, gdy jest obecny, a stat traktuj jako potwierdzenie, nie jedyny sygnał.
Pole err to nie uniwersalny słownik. Operatorzy i huby kompresują różne awarie do nakładających się kodów. Pracuj rodzinami jakościowymi zamiast wymyślać tabele per-carrier. Rodzina absent-subscriber: sieć nie mogła zlokalizować abonenta — wyłączony, poza zasięgiem lub tymczasowo odłączony, zależnie od hopu. Rodzina handset-memory: urządzenie lub ścieżka pamięci SIM odmówiła lub odroczyła przyjęcie. Rodzina barring: blokada nadawcy, docelowego, klasy treści lub abonenta uniemożliwiła domknięcie. Rodzina routing-failure: brak dostępnej trasy, sieć docelowa nieosiągalna z danego interconnectu albo format adresu odrzucony przed głębokim doręczeniem. Te rodziny sterują ponawianiem i komunikatami do użytkownika; nie uzasadniają hardcodowanych mitów, że jeden kod numeryczny zawsze oznacza jedną przyczynę źródłową.
Mapuj rodziny na zachowanie produktu z umiarem. Wyniki absent-subscriber i handset-memory często uzasadniają ograniczone ponawianie z uwzględnieniem ważności lub wolniejszą ponowną próbę. Blokad i wielu błędów routingu zwykle nie należy przełamywać szybkimi ponowieniami tej samej treści. Gdy err brakuje lub jest zero, a stat wskazuje awarię, wierz klasie awarii i zachowaj surowy raport na eskalację do supportu.
Narzędzie lookup kodów błędów SMSRoute's pokrywa te same stany interaktywnie.
EXPIRED a REJECTED w praktyce
EXPIRED i REJECTED są zwykle końcowe, ale odpowiadają na inne pytania. EXPIRED oznacza, że wiadomość mogła próbować w oknie validity i to okno skończyło się bez sukcesu akceptowanego przez węzeł raportujący. Przyczyny skupiają się wokół niedostępności handsetu, odroczonego doręczenia, które nigdy nie weszło, lub opóźnienia ścieżki poza TTL ustawione przez Ciebie lub MC. REJECTED oznacza odmowę — polityka, screening, obsługa nieprawidłowego lub nieroutowalnego adresu na odrzucającym hopie, blokada komercyjna lub podobna odmowa z góry albo niemal z góry — a nie czyste wyczerpanie czasu.
W handlerach EXPIRED skłania do sprawdzenia konfiguracji validity period, czasu submit względem done time oraz tego, czy ENROUTE trwał do timeoutu. REJECTED skłania do sprawdzenia formatu destination (E.164 do 15 cyfr), uprawnień originatora, reguł treści i tego, czy odrzucenie nastąpiło natychmiast po wysłaniu. Natychmiastowy REJECTED z niemal zerową latencją to inna historia operacyjna niż długi ENROUTE, który staje się EXPIRED na krawędzi validity. Żaden stan nie jest grzecznym synonimem drugiego; zwijanie ich w jedną wartość logiczną failed gubi sygnał ponawiania i zgodności.
Czerwone flagi fałszywych DLR
Ponieważ DLR mają wartość reputacyjną, traktuj nieprawdopodobne raporty jako incydenty pierwszej klasy. Czerwone flagi to m.in. jednolite DELIVERED na dużych mieszanych zbiorach numerów docelowych bez wariancji rodzin wyników, które znasz z realnego ruchu, oraz nieprawdopodobna latencja — done date na poziomie szumu pomiarowego wysyłki przy perfekcyjnym sukcesie albo stałe latencje, które nie zmieniają się wraz z regionem docelowym ani porą dnia. Kolejna flaga to tekst stat, który nigdy nie rozjeżdża się z zawsze-zerowym err na trasach podatnych na awarie, albo identyfikatory wiadomości nieskorelowane z odpowiedziami na submit.
Gdy pojawią się czerwone flagi, zamroź automatyczne założenia utożsamiające DELIVERED z osiągalnością użytkownika, zachowaj surowe PDU lub payloady webhooków i weryfikuj kontrolowanymi senderami, które operujesz. Konta SMSRoute obejmują panel, API oraz historię nadawania.armowe test credits, które potwierdzają delivery zanim zapłacisz, a narzędzia delivery-testing są dostępne w dashboardzie SMSRoute. Użyj ich, by ustalić baseline realistycznego mixu stanów i timingów, zanim zaufasz nowej trasie w logice produkcyjnej.
Przewodnik DLR SMSRoute wyjaśnia mechanikę webhooków, którą te stany przychodzą.
Jak używać tego w handlerach webhooków
Strukturyzuj webhook jako korelator, nie jako przełącznik jednego pola. Kluczuj po provider message id zwróconym przy submit; sam przechowuj timestampy submit; ingestuj message_state lub stat, err i done date; potem przełącz wewnętrzny rekord jawną maszyną stanów. Akceptuj HTTP 200 dopiero po trwałym utrwaleniu receiptu, by uniknąć podwojenia efektów ubocznych przez retry providera; odpowiadaj HTTP 429 lub HTTP 500 tylko gdy naprawdę potrzebujesz retry, i trzymaj te ścieżki idempotentne.
Normalizuj stany przychodzące do własnego enuma zachowującego rozróżnienia SMPP — co najmniej osobno delivered, expired, rejected, undeliverable, accepted, deleted, enroute i unknown. Dołączaj tagi rodzin błędów jakościowo, bez roszczenia oficjalnych słowników carrierskich, których nie utrzymujesz. Dla ENROUTE i nierozwiązanego UNKNOWN planuj obserwację, nie sukces widoczny użytkownikowi. Dla DELIVERED oznacz sukces transportu i nadal bramkuj krytyczne akcje biznesowe własnymi potwierdzeniami aplikacyjnymi, gdy domena tego wymaga.
Na koniec loguj p50 i p95 latencji submit-to-done per klasa trasy, by fałszywe lub zdegradowane wzorce DLR wychodziły jako przesunięcia rozkładu, a nie anegdoty. Pamiętaj o dyscyplinie rozmiaru payloadu przy wysyłce — reguły segmentacji 160/153 GSM-7 i 70/67 UCS-2 nadal kształtują, jak splity i częściowe awarie wyglądają downstream — ale nie wymyślaj procentów delivery. Niepewność jest częścią powierzchni protokołu; precyzyjne handlery zapisują, co stwierdzono, czego nie, i co zrobisz dalej.
Częste pytania
- Jakie są wartości message_state SMPP v3.4 i które są końcowe?
- Zestaw v3.4 obejmuje ENROUTE, DELIVERED, EXPIRED, DELETED, UNDELIVERABLE, ACCEPTED, UNKNOWN i REJECTED. ENROUTE jest pośredni i może się jeszcze zmienić; UNKNOWN operacyjnie jest niekońcowy, chyba że kontrakt upstream stanowi inaczej. DELIVERED, EXPIRED, DELETED, UNDELIVERABLE, REJECTED oraz typowo ACCEPTED traktuje się jako końcowe dla danego message id na danej ścieżce.
- Czym EXPIRED różni się od REJECTED na SMS DLR?
- EXPIRED oznacza, że validity period wyczerpał się bez sukcesu akceptowanego przez węzeł raportujący, po tym jak wiadomość mogła próbować delivery. REJECTED oznacza, że wiadomość została odmówiona z powodu polityki, routingu lub reguł screeningu, a nie timeoutu. Natychmiastowe rejecty i długie ścieżki enroute-then-expired nie powinny wpadać do jednego bucketa failed, jeśli zależy Ci na retry i poprawkach konfiguracji.
- Jakie pola występują w klasycznym body tekstowym delivery receipt SMPP?
- Typowe etykietowane tokeny to id, sub, dlvrd, submit date, done date, stat i err. Używaj strukturalnego message_state, gdy dostępny, a stat/err traktuj jako potwierdzenie; kody err grupuj w rodziny jakościowe, np. absent subscriber, handset memory, barring i routing failures, zamiast ufać im jako uniwersalnej tabeli per-carrier.