Срок жизни SMS: как не отправлять клиенту устаревшее уведомление
Как связать актуальность бизнес-события, очередь отправки и срок доставки SMS: абсолютный дедлайн, отмена, повторные попытки и метрики.

Содержание
Клиент уже получил заказ, а SMS «Курьер выехал» только приходит. Код подтверждения истёк, но очередь продолжает отправлять его после восстановления связи. Технически доставка может завершиться успешно, а для бизнеса сообщение уже бесполезно. Поэтому каждому уведомлению нужен срок актуальности, который сохраняется на всём пути от события до провайдера.
Начните с бизнес-события
Срок жизни определяет владелец процесса. Для кода входа он связан с периодом действия кода, для напоминания — со временем встречи, для статуса заказа — с переходом в следующее состояние. Единый TTL для всех сообщений скрывает эти различия.
Храните момент создания события и абсолютный дедлайн expiresAt. Если событие произошло в 10:00 и актуально десять минут, задержка в CRM до 10:04 не должна сдвигать окончание срока на 10:14. В примере дедлайн остаётся 10:10; конкретные интервалы задаёт бизнес.
Разделите три разных ограничения
Уведомление проходит несколько систем, и каждое ограничение действует на своём участке:
| Ограничение | Что оно определяет |
|---|---|
| Бизнес-дедлайн | До какого момента сообщение полезно получателю |
| Хранение в очереди | Как долго инфраструктура сохраняет задание |
| Срок доставки у провайдера | Как долго принятая отправка может ожидать доставки |
Срок хранения в очереди не заменяет проверку актуальности. А параметр срока доставки провайдера не отменяет уже отправленное сообщение. Поддержку, точность и минимальные значения такого параметра нужно проверить по документации и условиям конкретного маршрута.
Проверяйте дедлайн перед каждой попыткой
Сохраните дедлайн вместе с заданием, например по паттерну transactional outbox. При извлечении из очереди обработчик сравнивает его с текущим временем, проверяет состояние события и только затем выбирает маршрут.
Перед обращением к провайдеру рассчитайте оставшийся срок. Если его недостаточно с учётом задержек и ограничений API, завершите задание как устаревшее. Если провайдер поддерживает срок доставки, передавайте оставшееся время в его формате, сохраняя исходный бизнес-дедлайн.
Повторная попытка не начинает срок заново. После тайм-аута сначала выясните, принят ли первый запрос: новый submit может дать дубль. Этот случай подробнее разобран в материале о каскаде SMS-маршрутов.
Отменяйте по смыслу, а не только по времени
Сообщение может устареть раньше дедлайна: заказ отменён, встреча перенесена, пользователь запросил новый код. Свяжите задание с ID бизнес-объекта и версией события. Новая версия позволяет отменить старое задание, пока оно находится под вашим контролем.
Проверка и отправка не являются одной атомарной операцией с внешним оператором. Если событие изменилось после submit, гарантировать отзыв SMS нельзя. Для таких случаев полезнее нейтральный текст со ссылкой на текущий статус, чем обещание безусловной отмены.
Сделайте истечение срока наблюдаемым
Разделяйте expired_before_submit, отказ провайдера и доставку после бизнес-дедлайна. Это разные причины и разные ответственные. Поздний DLR сохраняйте в журнале, но не запускайте из-за него новую отправку.
Для каждого типа уведомлений измеряйте возраст задания перед submit, долю отменённых и устаревших сообщений, а также доставку в полезное окно. Большая доля просрочки может означать перегруженную очередь, задержку источника событий или слишком короткий срок.
Проверьте отключение провайдера, длительную очередь, перенос встречи и повторное получение callback. Система должна отбрасывать утратившие смысл задания и объяснять причину. При подключении QuickTel согласуйте поддерживаемые параметры маршрута; бизнес-правила актуальности остаются частью вашей интеграции.


