Интеграция SMS-рассылок в 1С: от провайдера до своего кода

· 9 мин

Содержание

Отправить СМС из 1С можно двумя путями. Первый — включить встроенный механизм рассылки в разделе Администрирование → Органайзер, выбрать провайдера из списка и вписать логин с паролем: пять минут и без строчки кода. Второй — написать свой код, который шлёт HTTP-запрос на API шлюза, разбирает ответ и ставит сообщения в фоновую очередь.

Какой путь ваш, зависит от задачи. Нужна рассылка паролей, статусов заказа или напоминаний из типовой конфигурации — хватит настроек. Нужен нестандартный сценарий, свой текст из произвольной обработки или провайдер, которого нет в списке, — придётся обратиться к HTTP-запросу напрямую. Ниже разберём оба варианта: настройку шлюза в интерфейсе, отправку сообщения кодом, обработку кодов ошибок и защиту логина с паролем.

Встроенный механизм или собственный HTTP-запрос

В типовых конфигурациях на платформе 8.3 (Бухгалтерия 3.0, ЗУП 3.1, УТ 11, ERP) механизм отправки SMS поставляется вместе с Библиотекой стандартных подсистем (БСП). Он умеет работать с готовым перечнем провайдеров, хранить настройки, подставлять имя отправителя и повторять неудачные попытки.

Выбор между двумя подходами сводится к одному вопросу — хватает ли вам готового механизма.

Встроенный механизм или свой код?

Даже если выбрали свой код, не отключайте встроенный механизм. Он пригодится как резервный канал и как хранилище настроек подключения.

Подключение SMS-провайдера в настройках программы

Путь к настройке в типовых конфигурациях одинаковый: Администрирование → Органайзер. В группе, отвечающей за почту и SMS, поставьте флажок отправки SMS и перейдите по ссылке настроек.

Дальше порядок такой:

  1. Выберите провайдера из выпадающего списка. В БСП поддерживаются популярные российские шлюзы — например, СМСЦентр (smsc.ru), SMS.RU, SMS4B, Devino Telecom, iQSMS, MFMSolutions. Набор в списке зависит от релиза.
  2. Впишите логин и пароль от личного кабинета у провайдера. Это не пароль пользователя 1С, а учётные данные вашего аккаунта у оператора рассылки.
  3. Укажите имя отправителя (альфа-имя), если провайдер его зарегистрировал. Без зарегистрированного имени сообщения уйдут с общего номера или не уйдут вовсе.
  4. Нажмите проверку соединения. Шлюз вернёт либо успех, либо текст ошибки — обычно это неверный логин или нулевой баланс.

Отправитель (альфа-имя) регистрируется на стороне провайдера и у сотового оператора, а не в 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);
    КонецЕсли;

КонецПроцедуры

Коды ошибок у каждого провайдера свои, но смысл совпадает. Вот как читать типичные ответы СМСЦентра:

Диагностика: выберите симптом

Главный вывод: ошибку всегда пишите в журнал регистрации. Без этого рассылка «молча не работает », и причину приходится искать вслепую.

Массовая рассылка в фоне без зависания интерфейса

Если отправить сотню сообщений в цикле прямо из формы, 1С будет ждать ответа шлюза на каждое — интерфейс замрёт на минуты. Отправку выносят в фоновое задание.

Самый простой способ — запустить метод общего модуля в фоне:

Параметры = Новый Массив;
Параметры.Добавить(МассивПолучателей);
Параметры.Добавить("Текст рассылки");

ФоновыеЗадания.Выполнить(
    "РассылкаSMS.ОтправитьПакет",
    Параметры,
    ,
    "Рассылка SMS клиентам");

Метод РассылкаSMS.ОтправитьПакет переберёт получателей на сервере и будет слать сообщения, пока пользователь продолжает работать. Для контроля прогресса из формы применяют механизм длительных операций БСП (ДлительныеОперации), который показывает индикатор и умеет прерывать задание.

Для регулярной рассылки лучше подходит очередь и регламентное задание:

  1. Складывайте сообщения на отправку в отдельный регистр сведений — номер, текст, статус «в очереди».
  2. Регламентное задание раз в несколько минут выбирает из очереди неотправленные записи и шлёт их пачками.
  3. После ответа шлюза запись помечается как «отправлено» или «ошибка» с кодом.

Такая схема переживает перезапуск сервера: неотправленные записи останутся в очереди и уйдут при следующем проходе.

Повторные попытки настройте с головой. Если шлюз вернул неверный логин или нулевой баланс, повторять бессмысленно — запись сразу помечайте ошибкой и не трогайте. А вот временные сбои (таймаут соединения, код 500) стоит повторить через нарастающую паузу: минуту, пять, пятнадцать. Ограничьте число попыток тремя-четырьмя, иначе «мёртвое» сообщение будет вечно крутиться в очереди и тормозить остальные.

Соблюдайте лимит скорости. Многие шлюзы ограничивают число сообщений в секунду и блокируют при всплеске (это и есть ошибка о частой отправке). Между пачками делайте паузу или отправляйте не по одному, а пакетом в одном запросе — почти все API это умеют.

Хранение паролей и проверка номеров

Логин и пароль шлюза — это доступ к вашим деньгам на балансе провайдера. Их нельзя хранить в тексте модуля, в комментариях или в открытой константе, которую видит любой пользователь.

В типовых конфигурациях на БСП для этого есть безопасное хранилище — отдельный механизм, куда настройки пишутся в защищённом виде и читаются только серверным кодом. Храните учётные данные там, а в коде получайте их функцией-обёрткой, как в примерах выше (ПолучитьПарольSMS()). Если встроенного хранилища в вашей конфигурации нет, заведите константу с ограничением прав на чтение и записью значения только администратором.

Отдельная проверка — номер телефона. Шлюз ждёт его в строгом формате, а пользователи вводят как придётся: со скобками, пробелами, через +7 или 8. Приведите номер к единому виду перед отправкой:

Функция НормализоватьНомер(Исходный) Экспорт

    ТолькоЦифры = "";
    Для Сч = 1 По СтрДлина(Исходный) Цикл
        Символ = Сред(Исходный, Сч, 1);
        Если Символ >= "0" И Символ <= "9" Тогда
            ТолькоЦифры = ТолькоЦифры + Символ;
        КонецЕсли;
    КонецЦикла;

    // 8XXXXXXXXXX -> 7XXXXXXXXXX
    Если СтрДлина(ТолькоЦифры) = 11 И Лев(ТолькоЦифры, 1) = "8" Тогда
        ТолькоЦифры = "7" + Сред(ТолькоЦифры, 2);
    КонецЕсли;

    // Проверка длины российского номера
    Если СтрДлина(ТолькоЦифры) <> 11 Тогда
        Возврат ""; // некорректный номер — на отправку не берём
    КонецЕсли;

    Возврат ТолькоЦифры;

КонецФункции

Функция убирает всё, кроме цифр, меняет ведущую 8 на 7 и отбраковывает номера неверной длины. Пустую строку на выходе трактуйте как «номер некорректен» и такого получателя в рассылку не включайте.

Перед запуском интеграции в работу пройдитесь по короткому списку — он закрывает причины, по которым рассылка «настроена, но не идёт».

Проверка перед запуском рассылки
Выполнено: 0 / 7

Частые вопросы

Можно ли отправлять SMS без интернета, через GSM-модем?
Да, если провайдер или ваше решение поддерживают работу через подключённый к серверу GSM-модем. Но встроенный механизм БСП и примеры выше рассчитаны на HTTP-шлюз, которому нужен доступ в интернет с сервера 1С.
Почему кириллица в сообщении превращается в «кракозябры»?
Текст ушёл без URL-кодирования либо в неверной кодировке. Прогоняйте его через КодироватьСтроку с кодировкой URL, а тело ответа читайте как UTF-8. Учтите: кириллическое сообщение вмещает меньше символов в одну SMS, чем латиница, — длинный текст разобьётся на несколько частей и спишется дороже.
Сколько стоит одно сообщение?
Ориентировочно от 2 до 5 рублей за сегмент по России — точная цена зависит от провайдера, оператора получателя и объёма. Длинное сообщение делится на сегменты, и каждый тарифицируется отдельно, поэтому следите за длиной текста.
Можно ли поставить вместо номера имя компании?
Да, это альфа-имя отправителя. Его регистрируют у провайдера и согласуют с сотовыми операторами, а в 1С только указывают в настройках. Пока имя не прошло модерацию, сообщения с ним не доставляются.
Как узнать, дошло ли сообщение до абонента?
Факт приёма шлюзом (ответ 200 с идентификатором) — это ещё не доставка. Статус доставки запрашивают отдельным методом API по идентификатору сообщения либо получают через callback от провайдера. Храните возвращённый id — по нему и проверяют доставку.