Как отправлять SMS через SMPP из Telegram-бота

Как отправлять SMS через SMPP из Telegram-бота

Telegram-бот может принимать заявку, сообщать статус заказа и запускать отправку SMS через SMPP-шлюз. Для этого между ботом и шлюзом нужен небольшой сервис-посредник: он получает событие из Telegram, формирует текст, передаёт сообщение по SMPP и обрабатывает ответ. В статье разберём архитектуру, параметры подключения, формат номера, delivery receipt, повторные попытки и порядок тестирования. После настройки такой связки бизнес сможет отправлять технические уведомления из одного сценария без ручной работы менеджера.

Зачем связывать Telegram-бота и SMPP-шлюз?

Telegram подходит для диалога с клиентом: бот принимает команду, показывает варианты и уточняет данные. SMS нужен в момент, когда уведомление должно дойти вне зависимости от того, открыт ли мессенджер. Например, бот может сообщить сотруднику о новой заявке, клиенту — о готовности услуги, а администратору — о сбое в расписании.

У Telegram-бота нет прямого встроенного подключения к SMPP. Между ними размещают приложение, которое принимает события от Telegram Bot API и открывает соединение с SMS-шлюзом. Приложение хранит очередь сообщений, следит за ответами шлюза и записывает технический результат отправки.

Для малого бизнеса схема выглядит так:

  • клиент или сотрудник отправляет команду Telegram-боту;
  • бот передаёт событие в backend-приложение;
  • backend проверяет данные и создаёт SMS-задачу;
  • SMPP-клиент отправляет сообщение через submit_sm;
  • шлюз возвращает идентификатор сообщения и, если включён delivery receipt, итог доставки;
  • бот показывает статус или передаёт его оператору.

Если SMS должны уходить большими сериями, подключение через SMPP удобнее строить как отдельный сервис, а не добавлять сетевую логику прямо в обработчик Telegram-команд. Тогда временный сбой шлюза не блокирует ответы бота.

Какие параметры нужны для SMPP-подключения?

До написания кода запросите у провайдера параметры подключения. Обычно приложение получает адрес шлюза, порт, логин, пароль, тип bind и ограничения по скорости. Для отправки сообщений используется bind_transmitter либо bind_transceiver. Второй вариант нужен, если приложение должно принимать delivery receipt по тому же соединению.

ПараметрЧто проверитьГде использовать
Адрес и портДоступен ли порт с сервера, где работает backendПри создании TCP-соединения
Логин и парольСовпадают ли значения с настройками шлюзаВ команде bind
Тип bindНужен ли только исходящий трафик или также приём статусовПри выборе transmitter или transceiver
Source addressКакое имя отправителя разрешено использоватьВ submit_sm
TON и NPIКакие значения принимает конкретный шлюзДля адреса отправителя и номера получателя
КодировкаКакие символы поддерживает шлюз и как передавать кириллицуВ data_coding и тексте сообщения
Delivery receiptКак включить отчёт и в каком поле приходит message IDДля обновления статуса SMS

Кириллица требует отдельной проверки. Если текст содержит русские буквы, приложение должно выбрать корректную кодировку и рассчитать длину сообщения по правилам шлюза. Нельзя просто передать UTF-8-строку в data без согласования параметров: SMS может прийти с повреждёнными символами или разбиться иначе, чем ожидает разработчик.

Для диагностики полезно заранее проверить скорость и стабильность SMPP-шлюза: в тесте фиксируйте время подключения, bind, submit_sm и получение ответа. Практический разбор такой проверки есть в материале как проверить скорость и стабильность SMPP-шлюза. Для офиса с нестабильным интернетом отдельно продумайте повторное подключение и параметры SMPP-bind, описанные в статье как настроить SMPP-bind при нестабильном интернете.

Как построить обработчик Telegram-события?

Telegram-обработчик не должен ждать, пока SMS-шлюз ответит окончательно. После проверки команды он создаёт запись в очереди и быстро возвращает пользователю подтверждение: например, «заявка принята». Отправка идёт отдельным worker-процессом, который подключается к SMPP и обрабатывает задачи последовательно или с согласованным ограничением скорости.

Минимальная запись в очереди содержит номер получателя, текст, внутренний тип уведомления, время создания и число попыток. Для контроля результата добавьте поля message ID, статус SMPP и время последнего ответа. В Telegram храните только те данные, которые нужны конкретному сценарию бота, а технический журнал делайте понятным разработчику: по одной записи должно быть видно, когда задача создана и какой ответ дал шлюз.

Логика worker-процесса может выглядеть так:

  1. получить из очереди задачу со статусом «новая»;
  2. проверить формат номера и наличие текста;
  3. установить SMPP-соединение или использовать уже активный bind;
  4. передать submit_sm с нужными параметрами;
  5. сохранить message ID и ответ шлюза;
  6. дождаться delivery receipt, если он предусмотрен подключением;
  7. назначить финальный статус либо запланировать повторную попытку по правилам проекта.

Повторная отправка требует осторожности. Если приложение потеряло ответ после submit_sm, оно не знает, принял ли шлюз сообщение. Автоматический повтор может привести к двум SMS. Поэтому для критичных уведомлений задайте отдельный статус «результат неизвестен», сохраните исходный запрос и решите, когда повтор допустим. Простое правило «повторять всегда» для SMPP-сценария не подходит.

Как настроить статусы и отчёты о доставке?

Ответ submit_sm подтверждает приём запроса шлюзом, но сам по себе не доказывает, что SMS дошло до телефона. Для этого используют delivery receipt. Шлюз передаёт в отчёте идентификатор сообщения и статус, который backend сопоставляет с записью в очереди.

В коде разделите как минимум четыре состояния:

  • «создано» — задача появилась после события Telegram;
  • «принято шлюзом» — приложение получило положительный ответ submit_sm;
  • «доставлено» — пришёл соответствующий delivery receipt;
  • «ошибка» или «не доставлено» — шлюз вернул отказ или финальный отрицательный статус.

Такое разделение помогает правильно отвечать пользователю. Бот не должен писать клиенту «SMS доставлено», если приложение получило только подтверждение приёма запроса. В интерфейсе лучше показывать короткий статус, а полный текст ошибки оставлять в журнале для администратора.

Проверьте, как шлюз передаёт message ID: в разных интеграциях встречаются различия в формате, длине и регистре символов. Сохраняйте значение без изменения, иначе входящий отчёт не сопоставится с исходной задачей.

Как протестировать связку до запуска?

Тестирование начинайте с одного тестового номера и короткого сообщения. Сначала проверьте bind, затем одну отправку, после этого delivery receipt. Каждый этап должен иметь отдельную запись в журнале. Такой порядок быстро показывает, где проблема: в Telegram, очереди, кодировке, SMPP-параметрах или обработке статуса.

Проверьте несколько сценариев:

  • бот принимает корректную команду и создаёт ровно одну SMS-задачу;
  • пустой номер и пустой текст отклоняются до обращения к шлюзу;
  • кириллица приходит без повреждения символов;
  • длинное сообщение обрабатывается согласно правилам шлюза;
  • разрыв соединения не останавливает worker навсегда;
  • повторная доставка одного delivery receipt не меняет статус ошибочно;
  • ошибка шлюза отображается оператору в понятном виде;
  • после перезапуска приложения очередь продолжает обработку.

Для технических уведомлений можно использовать отдельные шаблоны: «Заявка принята», «Заказ готов», «Код доступа: 4821». Содержимое шаблона храните отдельно от кода. Тогда сотрудник сможет изменить текст без переписывания обработчика, а разработчик сохранит единый формат параметров и логирования.

Какие ошибки чаще всего ломают отправку?

  • Отправка SMS прямо из Telegram-webhook. Долгий сетевой запрос задерживает ответ бота. Используйте очередь и отдельный worker.
  • Неверная кодировка. Русский текст превращается в нечитаемые символы, если data_coding и фактическое содержимое не согласованы.
  • Отсутствие контроля message ID. Без этого приложение не свяжет delivery receipt с конкретной задачей.
  • Повтор после любого тайм-аута. Тайм-аут не всегда означает, что шлюз не принял сообщение. Сначала сохраняйте состояние «результат неизвестен».
  • Один бесконечный bind без проверки. Соединение может разорваться, поэтому worker должен выявлять потерю связи и выполнять повторный bind с ограничением попыток.
  • Смешение бизнес- и технических статусов. Статус «бот ответил» не равен статусу «SMS доставлено». Разделяйте эти события в базе.

3 шага для запуска связки на этой неделе:

  1. описать события Telegram, после которых действительно нужно отправлять SMS, и подготовить таблицу статусов;
  2. получить параметры SMPP, проверить bind, кодировку и delivery receipt на одном тестовом сообщении;
  3. вынести отправку в очередь, добавить журнал message ID и проверить восстановление после разрыва соединения.

Если Telegram-бот уже работает, подключение SMPP обычно оформляют отдельным модулем: бот отвечает за сценарий, очередь — за задачи, SMPP-клиент — за транспорт. При таком разделении проще менять тексты и бизнес-логику, не затрагивая сетевое подключение. Для SMS-кодов восстановления доступа полезно сравнить архитектуру с материалом как настроить восстановление доступа по SMS.