SMS-напоминания о записи можно связать с системой бронирования через SMPP и отправлять автоматически: после создания визита ставить задачу на таймер, при отмене удалять её, а после отправки проверять DLR-статус. В статье разберём рабочую схему для малого бизнеса в Беларуси: какие данные передавать в очередь, как выбрать время отправки, чем отличаются повторная попытка и новое напоминание, а также как не допустить дублирования сообщений.
Как устроена отправка напоминания через SMPP?
Система записи хранит визит клиента: номер телефона, дату и время, идентификатор записи и её статус. Когда администратор или клиент создаёт запись, приложение рассчитывает время SMS и добавляет задачу в очередь. В назначенный момент воркер подключается к SMS-шлюзу по SMPP и передаёт сообщение командой submit_sm.
Для каждой записи лучше создавать отдельную задачу с уникальным ключом. Например, ключ можно собрать из идентификатора записи и типа события: booking-1842-reminder-24h. Такой ключ помогает проверить, не поставила ли система одно и то же напоминание дважды после повторного нажатия кнопки или сбоя связи.
Схема выглядит так:
- Клиент записывается на услугу.
- Приложение проверяет, что номер заполнен и запись имеет активный статус.
- Планировщик рассчитывает время отправки.
- Задача попадает в очередь с датой выполнения.
- SMPP-клиент устанавливает bind и передаёт SMS.
- Система сохраняет message_id и ждёт DLR.
- При отмене визита задача получает статус cancelled и больше не отправляется.
В рабочей базе полезно разделять состояние записи и состояние SMS. Запись может быть подтверждена, отменена или перенесена. SMS при этом имеет собственный статус: queued, submitted, delivered, failed или expired. Такое разделение позволяет понять, почему клиент не получил уведомление, даже если сама запись в календаре сохранилась.
Как выбрать время и поставить SMS в очередь?
Время напоминания зависит от услуги. Для визита на следующий день подходит отправка за 24 часа. Если запись создана поздно вечером, задача всё равно должна учитывать часовой пояс бизнеса и клиента. В приложении лучше хранить время в UTC, а перед расчётом переводить его в локальное время, заданное настройками проекта.
Не отправляйте SMS сразу после создания визита, если его смысл связан именно с предстоящим временем. Для мгновенного подтверждения создайте отдельное событие, например booking_created, а напоминание обозначьте как booking_reminder. Эти события имеют разные шаблоны и разные правила повторной отправки.
Пример таблицы задач для базы данных:
| Поле | Зачем нужно |
|---|---|
| task_id | Уникальный идентификатор задания |
| booking_id | Связь с записью клиента |
| phone | Номер получателя в международном формате |
| send_at | Планируемое время отправки |
| status | queued, submitted, delivered, failed или cancelled |
| message_id | Идентификатор SMS от шлюза |
| attempts | Количество попыток передачи |
Планировщик запускается с небольшим интервалом и выбирает задачи, у которых наступил send_at. Чтобы два процесса не взяли одну задачу, используйте блокировку строки или атомарную смену статуса с queued на processing. После этого воркер отправляет сообщение и записывает результат SMPP-операции.
Если сайт работает на WordPress, отдельный cron-процесс часто надёжнее запуска WP-Cron по посещениям. Настройку сервера и проверку стабильности соединения полезно сверить с материалом как выбрать VPS под WordPress. Для проекта с постоянным потоком задач планировщик лучше запускать независимо от посещаемости сайта.
Как обрабатывать DLR и отличать доставку от отправки?
Ответ шлюза на submit_sm подтверждает приём запроса, но не означает, что абонент уже получил SMS. Для контроля нужен DLR, то есть отчёт о состоянии сообщения. SMPP-клиент должен сохранить message_id из ответа и сопоставить его с исходной задачей.
DLR приходит отдельным сообщением или через предусмотренный интеграцией механизм. В нём могут передаваться идентификатор сообщения, статус и дополнительный код. Формат зависит от шлюза, поэтому обработчик нужно проверять на тестовых отправках, а не строить логику на одном фиксированном расположении полей.
| Состояние | Действие системы |
|---|---|
| submitted | Сохранить идентификатор и ждать DLR |
| delivered | Закрыть задачу как доставленную |
| failed | Записать код ошибки и решить, нужна ли новая попытка |
| expired | Зафиксировать истечение срока доставки |
| unknown | Оставить задачу на контроле и проверить журнал |
Отдельно храните исходный ответ шлюза и нормализованный статус. Так разработчик видит техническую причину сбоя, а администратор получает понятную отметку в интерфейсе. Для систем, где SMS сопровождают заказ или другой процесс, похожий подход описан в материале автоматизация SMS-статусов доставки интернет-магазина.
Для DLR нужен повторяемый обработчик. Если отчёт пришёл повторно, он не должен создавать новую SMS или менять delivered на failed без проверки времени и правил перехода. Практичная защита — уникальный ключ из message_id и статуса либо журнал уже обработанных событий.
Когда нужна повторная отправка и как отменить SMS?
Повторная попытка нужна после технической ошибки, отказа соединения или временной недоступности шлюза. Она не подходит для каждого failed-статуса. Если номер некорректен или оператор отклонил сообщение из-за параметров текста, повтор с теми же данными только создаст лишний трафик.
Задайте ограничение попыток и задержку между ними. Например, после первой ошибки задача возвращается в очередь через несколько минут, после второй задержка увеличивается. Конкретные интервалы зависят от нагрузки и ответа шлюза. При этом зафиксируйте максимальное число попыток в конфигурации, чтобы сбой не превратился в бесконечную отправку.
Отмена работает через проверку актуального статуса записи непосредственно перед передачей SMS. Даже если планировщик выбрал задачу час назад, воркер должен ещё раз запросить запись. Если визит отменён или перенесён, старую задачу нужно пометить cancelled, а для нового времени создать новую с другим ключом.
При переносе записи не изменяйте старую задачу «на месте», если она уже получила message_id. Оставьте историю первой попытки и создайте новое задание. Это упрощает разбор ситуации, когда клиент получил напоминание о старом времени.
Какие параметры SMPP проверить до запуска?
Для теста подготовьте отдельную конфигурацию подключения: host, port, system_id, password, bind-режим, скорость отправки и параметры DLR. Логин и пароль храните в переменных окружения или закрытом хранилище, а не в файле плагина или открытом репозитории.
Проверьте, как система кодирует кириллицу. Для кириллического SMS в SMPP обычно используют UTF-16BE и data_coding 0x08; длина одного сообщения при такой кодировке составляет 70 символов (Stream Telecom, «Протокол SMPP v.3.4 для рассылки СМС»). Если текст длиннее, приложение должно заранее учитывать сегментацию и корректно обрабатывать составное сообщение.
Перед запуском отправьте тесты для нескольких сценариев:
- обычная доставка короткого сообщения;
- кириллический текст и длинное сообщение;
- отмена записи до наступления send_at;
- перенос визита на другую дату;
- ошибка соединения во время submit_sm;
- повторный DLR с тем же message_id.
Измеряйте не только время ответа на submit_sm, но и задержку до получения DLR. Для этого подходят отдельные тестовые задачи и журнал с временными метками. Проверить скорость и стабильность SMPP-шлюза можно по методике, описанной в материале как проверить скорость и стабильность SMPP-шлюза.
Типичные ошибки при автоматизации напоминаний
- Система считает успешным сам факт ответа submit_sm и не ждёт DLR.
- При переносе визита старая задача остаётся в очереди и отправляет устаревшее время.
- Два экземпляра планировщика выбирают одну задачу без блокировки.
- Приложение повторяет отправку после любой ошибки, включая некорректный номер.
- Кириллический текст передаётся с неверным data_coding и отображается неправильно.
- В журнале не сохраняются message_id и исходный ответ SMPP, поэтому сбой нельзя сопоставить с конкретной записью.
Для небольшого проекта достаточно начать с одной очереди напоминаний, таблицы статусов и отдельного обработчика DLR. Затем добавьте отмену, перенос и повторные попытки, не смешивая их в одном условии. Если понадобится готовая логика SMS-напоминаний о визите, полезно сравнить её со схемой автоматических SMS-напоминаний о визите, а техническую передачу подключить через SMPP с учётом лимитов и формата отчётов.
3 шага, которые можно сделать на этой неделе:
- Описать события booking_created, booking_rescheduled и booking_cancelled и связать каждое с отдельным типом задачи.
- Добавить таблицу очереди с send_at, статусом, attempts и message_id.
- Провести тесты доставки, отмены и повторного DLR, после чего включить отправку для реальных записей.



