Как проектировать SMS-уведомления при сбое

Чтобы SMS-уведомления продолжали доходить при сбое, заранее задайте правила повторной отправки, переключения на резервный канал и защиты от дублей. Начните с описания событий: что запускает сообщение, какой статус подтверждает его отправку и когда система прекращает попытки. Такой порядок помогает не отправлять клиенту несколько одинаковых SMS и не терять важное уведомление о заказе или входе. Ниже — схема, которую можно адаптировать к небольшому интернет-магазину, службе доставки или онлайн-сервису.
Что считать сбоем и когда повторять отправку?
Сбой — это не только ошибка при передаче сообщения. Уведомление может принять SMS-платформа, но дальше оно задержится или не получит подтверждение доставки. Поэтому разделите статусы на три группы: запрос не принят, сообщение принято в обработку, результат доставки неизвестен или отрицательный. Для каждой группы задайте отдельное действие.
Если система сразу получила техническую ошибку, повторите отправку через короткую паузу. При следующей неудаче увеличьте интервал, чтобы не создавать очередь из одинаковых запросов. Ограничьте число попыток: после последней отметьте сообщение как требующее проверки или передайте задачу ответственному сотруднику. Точные интервалы зависят от скорости, с которой клиенту нужно получить уведомление.
При задержке ответа не отправляйте SMS повторно автоматически, пока не проверите статус исходного сообщения. Иначе первый запрос может завершиться успешно уже после того, как система отправит второй. Для уведомления о готовности заказа такая гонка обернётся двумя сообщениями, хотя заказ один.
Как переключиться на резервный канал?
Определите заранее, какие уведомления требуют резервирования. Для критичного кода входа задержка важнее стоимости повторной попытки; для обычного статуса заказа допустима очередь, если клиент всё равно получит обновление до нужного действия. Не переводите каждое сообщение на другой канал при единичной задержке: сначала проверьте, что основной канал действительно недоступен.
Задайте понятное условие переключения: например, несколько последовательных ошибок соединения или отсутствие ответа дольше установленного для сценария срока. После срабатывания условия направьте новые сообщения через резервный маршрут. Уже отправленные запросы сначала проверьте по статусу, чтобы резервный канал не продублировал доставленное SMS.
Для SMS-канала резервирование зависит от того, как приложение подключено к провайдеру и как получает статусы. При работе через SMPP полезно отдельно описать резервное подключение и проверку его доступности. Подробный разбор этого подхода — в материале о резервном SMPP-канале. Если сбой касается push-уведомлений, отдельная логика перехода на SMS описана в статье о SMS-фолбэке при недоставленном push.
Как защитить клиента от повторных SMS?
Добавьте каждому событию уникальный идентификатор. Например, уведомление о выдаче заказа связывайте с номером заказа и конкретным событием «готов к выдаче». Если приложение повторно обработает тот же запрос, оно проверит идентификатор и не создаст новую отправку. Идентификатор должен сохраняться при повторных попытках.
Разделяйте повтор запроса и новое событие. Если клиенту сначала сообщили о передаче заказа курьеру, а позже — о готовности к выдаче, это два разных уведомления с разными идентификаторами. Если же сервер повторил запрос о передаче курьеру из-за тайм-аута, это та же отправка, а не новое сообщение.
Перед отправкой проверяйте, не изменился ли статус. Если заказ уже отменён, сообщение «можно забрать» отправлять нельзя, даже если оно стояло в очереди. В такой ситуации отмените устаревшую задачу и зафиксируйте причину в журнале.
Что записывать и как проверить сценарий?
Для каждого сообщения сохраняйте идентификатор события, время создания, выбранный канал, число попыток, последний статус и причину ошибки. Так сотрудник сможет понять, почему SMS задержалось, не просматривая всю историю заказа. В журнале фиксируйте именно этапы отправки: запрос создан, принят платформой, получен статус доставки или сработало резервирование.
Проверьте сценарий на тестовом номере: отключите основной канал в тестовой среде, вызовите событие и проследите, что происходит после ошибки. Затем повторите один и тот же запрос. Система должна сохранить одну логическую отправку, а не создать две. Отдельно проверьте случай, когда статус приходит с задержкой, и ситуацию, когда событие теряет актуальность до отправки.
Типичные ошибки
- Повторять отправку сразу после любого тайм-аута, не проверив статус первого запроса.
- Не ограничивать количество попыток и оставлять сообщения в бесконечной очереди.
- Создавать новый идентификатор при каждом техническом повторе.
- Переключать канал без условия, которое подтверждает сбой основного маршрута.
- Не отменять уведомления, если связанный заказ уже изменил статус.
Перед запуском выберите один сценарий, например уведомление о готовности заказа, и опишите для него три ветки: успешная отправка, техническая ошибка и неопределённый статус. Затем добавьте уникальный идентификатор события и проверьте повторный запрос. Когда этот сценарий проходит тест без потери сообщения и дубля, используйте ту же схему для остальных уведомлений.


