Отправка SMS из 1С через свою SIM-карту
Задача обычно звучит так: при событии в 1С — заказ оплачен, товар приехал, запись к врачу подтверждена — клиенту должна уйти SMS. Дальше начинается поиск «сервиса для отправки SMS из 1С», и он упирается в закрытый список провайдеров внутри самой 1С.
Почему нужного провайдера нет в списке
В типовых конфигурациях на базе библиотеки стандартных подсистем есть готовая подсистема «Отправка SMS». Список провайдеров в ней закрытый: он зашит в саму библиотеку, и добавить туда стороннего оператора, не меняя конфигурацию, нельзя. Если нужного провайдера в списке нет — через этот механизм подключиться не получится.
Поэтому интеграция делается иначе: 1С сама отправляет HTTP-запрос туда, куда нужно. Это работает в любой конфигурации, не требует изменения типовой (если положить код во внешнюю обработку) и не зависит от версии библиотеки.
Что понадобится
- Платформа 1С:Предприятие 8.3, любая конфигурация.
- Телефон на Android с вашей SIM-картой и установленным приложением — он и отправляет сообщения.
- Долгоживущий API-ключ из личного кабинета: раздел «Песочница» → API-ключи. Ключ, который выдаётся при обычном входе, сессионный и для интеграции не годится.
Белый IP, открытые порты и проброс наружу не нужны: 1С обращается к сервису сама, а телефон подключается к облаку сам.
Готовый код: отправка сообщения
Функцию можно положить в общий модуль конфигурации или во внешнюю
обработку — тогда типовую менять не придётся вовсе. Код должен
выполняться на сервере: в веб-клиенте
HTTPСоединение на стороне браузера недоступно.
Функция ОтправитьSMS(Номер, Текст) Экспорт
Токен = "ВАШ_API_КЛЮЧ";
// Тело запроса
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
Запись.ЗаписатьНачалоОбъекта();
Запись.ЗаписатьИмяСвойства("phoneNumber");
Запись.ЗаписатьЗначение(Номер);
Запись.ЗаписатьИмяСвойства("text");
Запись.ЗаписатьЗначение(Текст);
// requestId — свой идентификатор запроса. Если 1С повторит отправку
// (обрыв связи, перезапуск задания), второе SMS с тем же requestId
// создано не будет.
Запись.ЗаписатьИмяСвойства("requestId");
Запись.ЗаписатьЗначение(Строка(Новый УникальныйИдентификатор));
Запись.ЗаписатьКонецОбъекта();
ТелоЗапроса = Запись.Закрыть();
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Заголовки.Вставить("Content-Type", "application/json");
Соединение = Новый HTTPСоединение(
"api.textbee.ru", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL);
HTTPЗапрос = Новый HTTPЗапрос("/v1/sms/send", Заголовки);
HTTPЗапрос.УстановитьТелоИзСтроки(ТелоЗапроса, КодировкаТекста.UTF8);
Ответ = Соединение.ОтправитьДляОбработки(HTTPЗапрос);
Результат = Новый Структура("Успех, Статус, Идентификатор, Ошибка",
Ложь, "", "", "");
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(ТелоОтвета);
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Если Ответ.КодСостояния = 200 Или Ответ.КодСостояния = 201 Тогда
Результат.Успех = Истина;
Результат.Статус = Данные.Получить("status");
Результат.Идентификатор = Данные.Получить("messageId");
Иначе
Результат.Ошибка = "" + Ответ.КодСостояния + ": "
+ Строка(Данные.Получить("message"));
КонецЕсли;
Возврат Результат;
КонецФункции
Вызов:
Итог = ОтправитьSMS("+79161234567", "Заказ №1245 оплачен. Спасибо!");
Если Итог.Успех Тогда
Сообщить("Отправлено, статус: " + Итог.Статус);
Иначе
Сообщить("Не отправлено. " + Итог.Ошибка);
КонецЕсли;
Что приходит в ответ
Поле status отвечает на главный вопрос — что произошло с
сообщением прямо сейчас:
sent— телефон отправил сообщение;queued— принято, но телефон сейчас не на связи; уйдёт, когда вернётся;failed— отправить не удалось, причина в ответе.
Коды ответа, которые стоит обработать отдельно: 402 — исчерпан лимит тарифа или нужен платный; 429 — слишком часто; 503 — ни одного телефона на связи.
Статус доставки позже
Доставка подтверждается не мгновенно. Если она важна, идентификатор из
messageId нужно сохранить у себя и запросить статус позже —
например, регламентным заданием раз в несколько минут:
Функция СтатусSMS(Идентификатор) Экспорт
Токен = "ВАШ_API_КЛЮЧ";
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Соединение = Новый HTTPСоединение(
"api.textbee.ru", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL);
HTTPЗапрос = Новый HTTPЗапрос("/v1/messages/" + Идентификатор, Заголовки);
Ответ = Соединение.Получить(HTTPЗапрос);
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(Ответ.ПолучитьТелоКакСтроку());
Данные = ПрочитатьJSON(Чтение, Истина);
Чтение.Закрыть();
Возврат Данные.Получить("status");
КонецФункции
Грабли, на которые наступают
Код выполняется на клиенте. В веб-клиенте
HTTPСоединение недоступно. Отправку надо выполнять в
серверной процедуре — директивой &НаСервере или из
регламентного задания.
Прокси в организации. Если сервер 1С ходит в интернет через прокси, его нужно передать в соединение — иначе запрос просто не уйдёт:
Прокси = Новый ИнтернетПрокси;
Прокси.Установить("https", "proxy.company.local", 3128);
Соединение = Новый HTTPСоединение(
"api.textbee.ru", 443, , , Прокси, 30, Новый ЗащищенноеСоединениеOpenSSL);
Отправка в цикле по документу. Не отправляйте SMS прямо в проведении документа: запрос в интернет внутри транзакции затягивает проведение и падает вместе с ним. Правильнее записать задание в регистр и отправлять регламентным заданием.
Повторы и дубли. Если задание перезапустится, клиент
получит второе такое же SMS. От этого спасает requestId:
сохраните его вместе с заданием и передавайте тот же самый при повторе —
второе сообщение создано не будет.
Кодировка. Тело запроса передаётся строго в UTF-8
(УстановитьТелоИзСтроки(..., КодировкаТекста.UTF8)).
Без этого русский текст уедет вопросительными знаками.
Честно про готовую обработку
Готовой внешней обработки .epf или расширения конфигурации
у нас пока нет — есть код выше, и он рабочий. Если вам нужна именно
обработка «поставил и работает», напишите:
support (собака) textbee.ru.
Мы собираем такие запросы, и по ним решаем, что делать следующим.
Своя SIM-карта вместо оператора рассылок
Сообщения уходят с вашего номера по вашему тарифу. Комиссию за SMS мы не берём — на бесплатном тарифе 50 отправок в месяц.
Частые вопросы
Есть ли готовая обработка или расширение для 1С?
Готовой внешней обработки пока нет, и мы говорим об этом прямо. Отправка делается вызовом REST API из встроенного языка — код целиком приведён выше, он работает в любой конфигурации на платформе 8.3 и не требует изменения самой конфигурации, если положить его во внешнюю обработку.
Почему TextBee нет в списке провайдеров SMS в 1С?
Список провайдеров в подсистеме «Отправка SMS» библиотеки стандартных подсистем закрытый: он задан в самой библиотеке, и добавить туда стороннего провайдера без изменения конфигурации нельзя. Поэтому интеграция идёт не через этот список, а прямым HTTP-запросом.
Сколько стоит SMS, отправленная из 1С?
Сообщение уходит с вашей SIM-карты по вашему тарифу у оператора — мы комиссию за сообщение не берём. Оплачивается только тариф сервиса, на бесплатном доступно 50 отправок в месяц.
Нужен ли для этого белый IP или открытый порт?
Нет. 1С сама обращается наружу к api.textbee.ru по HTTPS, входящих подключений к серверу 1С не требуется. Телефон со шлюзом тоже подключается наружу сам.
Что будет, если телефон в этот момент выключен?
Сообщение встанет в очередь и уйдёт, когда телефон вернётся на связь. В ответе при этом придёт статус queued, а не sent — по нему видно, что сообщение принято, но ещё не отправлено.