Интеграция SMS-рассылок в 1С: от провайдера до своего кода
Содержание
Отправить СМС из 1С можно двумя путями. Первый — включить встроенный механизм рассылки в разделе Администрирование → Органайзер, выбрать провайдера из списка и вписать логин с паролем: пять минут и без строчки кода. Второй — написать свой код, который шлёт HTTP-запрос на API шлюза, разбирает ответ и ставит сообщения в фоновую очередь.
Какой путь ваш, зависит от задачи. Нужна рассылка паролей, статусов заказа или напоминаний из типовой конфигурации — хватит настроек. Нужен нестандартный сценарий, свой текст из произвольной обработки или провайдер, которого нет в списке, — придётся обратиться к HTTP-запросу напрямую. Ниже разберём оба варианта: настройку шлюза в интерфейсе, отправку сообщения кодом, обработку кодов ошибок и защиту логина с паролем.
Встроенный механизм или собственный HTTP-запрос
В типовых конфигурациях на платформе 8.3 (Бухгалтерия 3.0, ЗУП 3.1, УТ 11, ERP) механизм отправки SMS поставляется вместе с Библиотекой стандартных подсистем (БСП). Он умеет работать с готовым перечнем провайдеров, хранить настройки, подставлять имя отправителя и повторять неудачные попытки.
Выбор между двумя подходами сводится к одному вопросу — хватает ли вам готового механизма.
Администрирование → Органайзер. Код писать не нужно — достаточно логина и пароля шлюза.ОтправкаSMS. Настройки провайдера берутся из той же формы.HTTPСоединение. Так вы сами управляете параметрами, разбором ответа и повторами.Даже если выбрали свой код, не отключайте встроенный механизм. Он пригодится как резервный канал и как хранилище настроек подключения.
Подключение SMS-провайдера в настройках программы
Путь к настройке в типовых конфигурациях одинаковый: Администрирование → Органайзер. В группе, отвечающей за почту и SMS, поставьте флажок отправки SMS и перейдите по ссылке настроек.
Дальше порядок такой:
- Выберите провайдера из выпадающего списка. В БСП поддерживаются популярные российские шлюзы — например, СМСЦентр (smsc.ru), SMS.RU, SMS4B, Devino Telecom, iQSMS, MFMSolutions. Набор в списке зависит от релиза.
- Впишите логин и пароль от личного кабинета у провайдера. Это не пароль пользователя 1С, а учётные данные вашего аккаунта у оператора рассылки.
- Укажите имя отправителя (альфа-имя), если провайдер его зарегистрировал. Без зарегистрированного имени сообщения уйдут с общего номера или не уйдут вовсе.
- Нажмите проверку соединения. Шлюз вернёт либо успех, либо текст ошибки — обычно это неверный логин или нулевой баланс.
Отправитель (альфа-имя) регистрируется на стороне провайдера и у сотового оператора, а не в 1С. Пока имя не прошло модерацию, сообщения с ним блокируются оператором. Это частая причина, когда в 1С всё настроено, а SMS не приходят.
После настройки типовые механизмы (рассылка расчётных листков в ЗУП, оповещения в CRM, пароли на вход) начнут отправлять сообщения через выбранный шлюз автоматически.
Отправка SMS своим кодом через HTTP-запрос
Если механизм включён, самый короткий путь из кода — вызвать функцию общего модуля БСП. Она сама возьмёт провайдера и учётные данные из настроек:
// НомераТелефонов — массив строк, Текст — строка
Результат = ОтправкаSMS.ОтправитьSMS(НомераТелефонов, "Ваш заказ собран", "MyShop");
Если Результат.ОтправленоУспешно Тогда
Сообщить("SMS отправлено");
Иначе
Сообщить("Ошибка: " + Результат.ОписаниеОшибки);
КонецЕсли;
Точный состав возвращаемого значения зависит от релиза БСП — проверьте его в синтакс-помощнике по имени модуля ОтправкаSMS.
Когда провайдера нет в списке или нужен полный контроль, запрос к API шлюза собирают вручную. Большинство SMS-шлюзов принимают обычный HTTPS-запрос. Пример для СМСЦентра (smsc.ru), который отвечает в формате JSON при параметре fmt=3:
Процедура ОтправитьЧерезHTTP(Номер, Текст) Экспорт
Логин = ПолучитьЛогинSMS(); // из безопасного хранилища, не хардкод
Пароль = ПолучитьПарольSMS();
Адрес = "/sys/send.php"
+ "?login=" + Логин
+ "&psw=" + Пароль
+ "&phones=" + Номер
+ "&mes=" + КодироватьСтроку(Текст, СпособКодированияСтроки.КодировкаURL)
+ "&fmt=3";
Соединение = Новый HTTPСоединение(
"smsc.ru", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL);
Запрос = Новый HTTPЗапрос(Адрес);
Ответ = Соединение.Получить(Запрос);
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку("UTF-8");
РазобратьОтвет(Ответ.КодСостояния, ТелоОтвета);
КонецПроцедуры
Три детали, на которых чаще всего спотыкаются:
- Текст сообщения обязательно кодируйте методом
КодироватьСтрокус кодировкой URL. Иначе пробелы и кириллица разорвут строку запроса, и шлюз вернёт ошибку формата. - Для HTTPS четвёртым с конца параметром конструктора
HTTPСоединениепередавайте порт443, а последним — объектЗащищенноеСоединениеOpenSSL. Без него соединение по 443-му порту не установится. - Метод
Получить— это GET. Если шлюз требует POST (длинные тексты, пакетная рассылка), тело формируют отдельно и вызываютОтправитьДляОбработки.
Передавать логин и пароль прямо в строке GET-запроса небезопасно: они попадают в логи прокси и сервера шлюза. Для боевой нагрузки используйте POST и HTTPS, а учётные данные держите в безопасном хранилище (о нём ниже).
Как разобрать ответ шлюза и поймать ошибку
Ответ проверяют на двух уровнях. Сначала — код состояния HTTP: 200 означает, что запрос дошёл и шлюз его принял. Любой другой код (401, 403, 500) — это проблема транспорта или доступа, само сообщение даже не рассматривалось.
Но код 200 ещё не значит, что SMS ушло. Шлюз возвращает собственный статус в теле ответа. При fmt=3 СМСЦентр присылает JSON: при успехе — идентификатор и число сообщений, при неудаче — поле с кодом ошибки.
Процедура РазобратьОтвет(КодHTTP, ТелоJSON)
Если КодHTTP <> 200 Тогда
ЗаписьЖурналаРегистрации("SMS", УровеньЖурналаРегистрации.Ошибка,
, , "HTTP " + КодHTTP);
Возврат;
КонецЕсли;
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТелоJSON);
Данные = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
Если Данные.Свойство("error_code") Тогда
ЗаписьЖурналаРегистрации("SMS", УровеньЖурналаРегистрации.Ошибка,
, , "Шлюз: код " + Данные.error_code + ", " + Данные.error);
Иначе
// Данные.id — идентификатор, Данные.cnt — число частей
ЗаписьЖурналаРегистрации("SMS", УровеньЖурналаРегистрации.Информация,
, , "Отправлено, id " + Данные.id);
КонецЕсли;
КонецПроцедуры
Коды ошибок у каждого провайдера свои, но смысл совпадает. Вот как читать типичные ответы СМСЦентра:
КодироватьСтроку, а номер непустой.7XXXXXXXXXX без плюса, пробелов и скобок.Главный вывод: ошибку всегда пишите в журнал регистрации. Без этого рассылка «молча не работает », и причину приходится искать вслепую.
Массовая рассылка в фоне без зависания интерфейса
Если отправить сотню сообщений в цикле прямо из формы, 1С будет ждать ответа шлюза на каждое — интерфейс замрёт на минуты. Отправку выносят в фоновое задание.
Самый простой способ — запустить метод общего модуля в фоне:
Параметры = Новый Массив;
Параметры.Добавить(МассивПолучателей);
Параметры.Добавить("Текст рассылки");
ФоновыеЗадания.Выполнить(
"РассылкаSMS.ОтправитьПакет",
Параметры,
,
"Рассылка SMS клиентам");
Метод РассылкаSMS.ОтправитьПакет переберёт получателей на сервере и будет слать сообщения, пока пользователь продолжает работать. Для контроля прогресса из формы применяют механизм длительных операций БСП (ДлительныеОперации), который показывает индикатор и умеет прерывать задание.
Для регулярной рассылки лучше подходит очередь и регламентное задание:
- Складывайте сообщения на отправку в отдельный регистр сведений — номер, текст, статус «в очереди».
- Регламентное задание раз в несколько минут выбирает из очереди неотправленные записи и шлёт их пачками.
- После ответа шлюза запись помечается как «отправлено» или «ошибка» с кодом.
Такая схема переживает перезапуск сервера: неотправленные записи останутся в очереди и уйдут при следующем проходе.
Повторные попытки настройте с головой. Если шлюз вернул неверный логин или нулевой баланс, повторять бессмысленно — запись сразу помечайте ошибкой и не трогайте. А вот временные сбои (таймаут соединения, код 500) стоит повторить через нарастающую паузу: минуту, пять, пятнадцать. Ограничьте число попыток тремя-четырьмя, иначе «мёртвое» сообщение будет вечно крутиться в очереди и тормозить остальные.
Соблюдайте лимит скорости. Многие шлюзы ограничивают число сообщений в секунду и блокируют при всплеске (это и есть ошибка о частой отправке). Между пачками делайте паузу или отправляйте не по одному, а пакетом в одном запросе — почти все API это умеют.
Хранение паролей и проверка номеров
Логин и пароль шлюза — это доступ к вашим деньгам на балансе провайдера. Их нельзя хранить в тексте модуля, в комментариях или в открытой константе, которую видит любой пользователь.
В типовых конфигурациях на БСП для этого есть безопасное хранилище — отдельный механизм, куда настройки пишутся в защищённом виде и читаются только серверным кодом. Храните учётные данные там, а в коде получайте их функцией-обёрткой, как в примерах выше (ПолучитьПарольSMS()). Если встроенного хранилища в вашей конфигурации нет, заведите константу с ограничением прав на чтение и записью значения только администратором.
Отдельная проверка — номер телефона. Шлюз ждёт его в строгом формате, а пользователи вводят как придётся: со скобками, пробелами, через +7 или 8. Приведите номер к единому виду перед отправкой:
Функция НормализоватьНомер(Исходный) Экспорт
ТолькоЦифры = "";
Для Сч = 1 По СтрДлина(Исходный) Цикл
Символ = Сред(Исходный, Сч, 1);
Если Символ >= "0" И Символ <= "9" Тогда
ТолькоЦифры = ТолькоЦифры + Символ;
КонецЕсли;
КонецЦикла;
// 8XXXXXXXXXX -> 7XXXXXXXXXX
Если СтрДлина(ТолькоЦифры) = 11 И Лев(ТолькоЦифры, 1) = "8" Тогда
ТолькоЦифры = "7" + Сред(ТолькоЦифры, 2);
КонецЕсли;
// Проверка длины российского номера
Если СтрДлина(ТолькоЦифры) <> 11 Тогда
Возврат ""; // некорректный номер — на отправку не берём
КонецЕсли;
Возврат ТолькоЦифры;
КонецФункции
Функция убирает всё, кроме цифр, меняет ведущую 8 на 7 и отбраковывает номера неверной длины. Пустую строку на выходе трактуйте как «номер некорректен» и такого получателя в рассылку не включайте.
Перед запуском интеграции в работу пройдитесь по короткому списку — он закрывает причины, по которым рассылка «настроена, но не идёт».
Частые вопросы
Можно ли отправлять SMS без интернета, через GSM-модем?
Почему кириллица в сообщении превращается в «кракозябры»?
КодироватьСтроку с кодировкой URL, а тело ответа читайте как UTF-8. Учтите: кириллическое сообщение вмещает меньше символов в одну SMS, чем латиница, — длинный текст разобьётся на несколько частей и спишется дороже.Сколько стоит одно сообщение?
Можно ли поставить вместо номера имя компании?
Как узнать, дошло ли сообщение до абонента?
200 с идентификатором) — это ещё не доставка. Статус доставки запрашивают отдельным методом API по идентификатору сообщения либо получают через callback от провайдера. Храните возвращённый id — по нему и проверяют доставку.