Омниканальные транзакционные уведомления: архитектура без дублей
Как построить омниканальные транзакционные уведомления: единая модель событий, приоритеты SMS/push/email, TTL, каскады, дедупликация и статусы.

Содержание
Омниканальная система уведомлений должна выбирать канал по срочности, согласию, доступности контакта и фактическому статусу предыдущей попытки. Одновременная отправка SMS, push и email без координации — не омниканальность, а дублирование, лишние расходы и раздражение пользователя.
Практичная архитектура отделяет бизнес-событие от провайдеров: приложение один раз публикует намерение уведомить, а оркестратор применяет политику каналов, шаблонов, дедупликации и эскалации.
Транзакционное событие — источник истины
Не передавайте готовый текст во все каналы прямо из CRM или интернет-магазина. Создайте нормализованное событие:
{
"eventId": "evt_01...",
"type": "order.ready",
"recipientId": "customer_123",
"occurredAt": "2026-07-13T10:15:00Z",
"expiresAt": "2026-07-14T10:15:00Z",
"data": { "orderNumber": "A-1042" }
}
eventId нужен для дедупликации, type — для политики и шаблона, expiresAt — чтобы устаревшее сообщение не ушло после восстановления очереди. Персональные данные лучше получать внутри защищённого контура по recipientId, а не размножать в каждом событии.
Архитектуру контрактов, очередей и адаптеров подробнее разбирает руководство по интеграционной API-архитектуре.
Роли каналов
| Канал | Сильная сторона | Ограничение | Подходящий сценарий |
|---|---|---|---|
| SMS | Не требует приложения и интернета на телефоне | Цена, длина, нет гарантии мгновенной доставки | OTP, критичный статус, резервный канал |
| Push | Быстро и дёшево для активного приложения | Токен может устареть, уведомления отключаются | Статус заказа, действие в приложении |
| Подробный формат и архив | Может быть прочитан поздно | Чек, документ, некритичное подтверждение | |
| Внутренний канал | Контекст внутри продукта | Пользователь должен открыть продукт | Центр уведомлений, история |
SMS остаётся важным универсальным каналом. Чтобы выбрать платформу по маршрутам, статусам и SLA, используйте чек-лист выбора SMS-платформы, а для отправки — QuickTel, SMS-платформу компании «Лоджик Телеком».
Политика выбора канала
Политика должна быть данными, а не набором if в каждом приложении. Для типа события задайте:
- обязательный и допустимые каналы;
- порядок или параллельность;
- время ожидания статуса;
- TTL всего сценария;
- максимальное число попыток;
- тихие часы;
- требования к согласию;
- условия остановки каскада.
Пример: push отправляется первым; если за две минуты нет подтверждения доставки и сообщение ещё актуально, система отправляет SMS. Email с чеком может идти параллельно, потому что решает другую задачу.
Не используйте открытие сообщения как универсальный сигнал доставки. Каналы дают разные подтверждения, а privacy-настройки и клиентское ПО могут искажать события чтения.
Единая модель статусов
Адаптеры возвращают разные коды. Нормализуйте их во внутреннюю модель:
queued— поставлено в локальную очередь;submitted— принято провайдером;delivered— получен конечный положительный статус;temporary_failure— возможен повтор;permanent_failure— повтор без изменения данных бессмыслен;expired— TTL истёк;suppressed— отправка запрещена политикой;unknown— конечный статус не получен.
Храните сырой код провайдера рядом с нормализованным статусом для диагностики. Для SMS ответ API или SMPP подтверждает принятие, но не доставку; эту границу подробно объясняет сравнение SMPP и HTTP API.
Как избежать дублей
Дедупликация нужна минимум на двух уровнях:
- Бизнес-событие: повторная публикация того же
eventIdне создаёт новый сценарий. - Попытка канала: retry с тем же ключом не создаёт второе сообщение.
Ключ может включать eventId + policyVersion + channel + recipient. Храните его дольше максимального TTL и периода возможного повтора. При изменении содержания создавайте новую версию события осознанно.
Используйте transactional outbox: бизнес-транзакция записывает событие в ту же базу, а отдельный publisher переносит его в брокер. Это уменьшает риск, когда заказ сохранён, а уведомление потеряно между двумя независимыми операциями.
Повторы и каскады
Повторяйте только временные ошибки: сетевой сбой, ограничение скорости, временная недоступность провайдера. Некорректный адрес, запрещённый канал или истёкший TTL требуют остановки или другой ветки.
Каскад должен учитывать статус, а не только таймер. Если провайдер поздно подтвердил доставку первого канала, оркестратор должен попытаться отменить ожидающую альтернативу. Полностью исключить гонки удаётся не всегда, поэтому политика должна определять допустимое поведение.
Для push стандартизованный Web Push описывает RFC 8030, включая TTL и подтверждение приёма на уровне push-сервиса. Это также не равно факту прочтения пользователем.
Шаблоны и данные
Храните шаблоны по типу события, каналу, языку и версии. Изменение текста должно проходить review и не ломать обязательные переменные.
Контрольный список:
- длина SMS проверяется с учётом кодировки и сегментации;
- ссылка использует доверенный домен и не раскрывает секрет;
- OTP не попадает в email или push без решения модели угроз;
- параметры экранируются;
- fallback-шаблон существует для отсутствующего перевода;
- архив позволяет установить, какая версия была отправлена.
Согласия и предпочтения
Разделяйте обязательные сервисные сообщения и маркетинговые коммуникации в политиках, шаблонах и аудитах согласия. Пользовательские предпочтения не должны отключать сообщение, которое необходимо для безопасности операции, но такое исключение должно иметь подтверждённое основание.
Храните источник, время и область согласия. Отписку применяйте до постановки маркетинговой попытки в очередь. Юридическую квалификацию конкретного сообщения следует согласовывать с профильным специалистом.
Что измерять
- end-to-end доставка до TTL;
- p50/p95/p99 по каждому каналу;
- доля каскадов и причина переключения;
- постоянные ошибки контактов;
- доля дублей;
- возраст очереди;
- расходы на одно успешно завершённое событие;
- конверсия только для сценариев, где она корректно определена.
Метрики провайдера сверяйте с событиями самого продукта. Общий подход к корреляции описан в статье о наблюдаемости инфраструктуры.
Чек-лист запуска
- Приложения публикуют событие один раз.
- У каждого события есть ID, тип и TTL.
- Политики каналов версионируются.
- Согласия и предпочтения проверяются централизованно.
- Статусы провайдеров нормализованы.
- Retry не создаёт дубль.
- Каскад прекращается после успешного результата.
- Персональные данные маскируются в логах.
- Есть тесты задержки, отказа провайдера и накопления очереди.
- Для критичных сценариев определён ручной режим.
Как можем помочь
Команда «Лоджик Телеком» может помочь спроектировать оркестратор и интеграционные адаптеры, а QuickTel — реализовать SMS-часть омниканального маршрута. Практичный первый шаг — одно событие, явно описанная политика и проверяемый результат; затем каналы можно добавлять без изменений в бизнес-приложении.


