Использование объекта "HTTPСоединение" для отправки и получения SMS сообщений через модем Huawei с прошивкой HiLink (Возможности на 8.3.11.3034)


В данной статье я бы хотел поделиться опытом работы с GSM модемом. Точнее, опытом отправки SMS сообщений, используя обращения к модему Huawei с прошивкой HiLink, через встроенные механизмы платформы 1С:Предприятие 8.3.

Я понимаю, что для массовой рассылки СМС лучше использовать какой нибудь сервис с готовым API. Однако, в моем случае в офисе для обеспечения резервного интернет-канала используется usb LTE-модем, подключенный напрямую  к маршрутизатору Mikrotik. Почему бы и не использовать оплаченный пакет смс для рассылки сообщений сотрудникам. 

После небольших поисков в сети выяснилось, что прошивка LTE-модема HiLink имеет встроенный API и, для отправки/чтения сообщений, достаточно применять  HTTP-запрос с передачей xml строки методом POST.

Для обращения к модему используем HTTPСоединение:

Соединение = Новый HTTPСоединение(АдресIP, 80);

АдресIP по умолчанию 192.168.8.1

Кроме этого, для каждого действия необходимо получать токен . Это действие проще вывести в отдельную функцию:

Функция ПолучитьТокенИСессию(Соединение)
Запрос = Новый HTTPЗапрос("/api/webserver/SesTokInfo");

Результат = Соединение.Получить(Запрос);
Если Результат.КодСостояния<>200 Тогда
Возврат Неопределено;
КонецЕсли;

ЧтениеXML=Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Результат.ПолучитьТелоКакСтроку());
РезXDTO=ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
Токен=РезXDTO.TokInfo;
СессияID=РезXDTO.SesInfo;


Заголовки=Новый Соответствие;
Заголовки.Вставить("Cookie" , СессияID);
Запрос = Новый HTTPЗапрос("/html/smsinbox.html",Заголовки);

Результат = Соединение.Получить(Запрос);
Если Результат.КодСостояния<>200 Тогда
Возврат Неопределено;
КонецЕсли;

ЧтениеHTML=Новый ЧтениеHTML;
ЧтениеHTML.УстановитьСтроку(Результат.ПолучитьТелоКакСтроку());
ПостроительDOM = Новый ПостроительDOM;
ДокументHTML = ПостроительDOM.Прочитать(ЧтениеHTML);

Токен=ДокументHTML.ПолучитьЭлементыПоИмени("*","meta")[1].Содержание;

Возврат Новый Структура("СессияID,Токен",СессияID,Токен);

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

Хочу обратить внимание на предпоследнюю строку. Почему-то для вызова какого-нибудь метода API признается токен, который указан в HTML заголовке формы smsinbox.

Отправка сообщения: 

//функция возвращает Истина при успешной отправки, ЛОЖЬ при возникновении ошибок
Функция ОтправитьSMSHuaweiHiLink(АдресIP,Телефон,Сообщение)

/// Формируем запрос
ЗаписьXML=Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("request");

ЗаписьXML.ЗаписатьНачалоЭлемента("Index");
ЗаписьXML.ЗаписатьТекст("-1");
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Phones");
ЗаписьXML.ЗаписатьНачалоЭлемента("Phone");
ЗаписьXML.ЗаписатьТекст(Телефон);
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Sca");
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Content");
ЗаписьXML.ЗаписатьТекст(Сообщение);
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Length");
ЗаписьXML.ЗаписатьТекст(Формат(СтрДлина(Сообщение),"ЧРГ=0"));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Reserved");
ЗаписьXML.ЗаписатьТекст("1");
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Date");
ЗаписьXML.ЗаписатьТекст(Формат(ТекущаяДата(),"ДФ='yyyy-MM-dd HH:mm:ss'"));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьКонецЭлемента();
СтрокаЗапроса=ЗаписьXML.Закрыть();


Соединение = Новый HTTPСоединение(
АдресIP, // сервер (хост)
80);



ТокенИСессия=ПолучитьТокенИСессию(Соединение);
Если ТокенИСессия=Неопределено Тогда
Возврат Ложь;
КонецЕсли;


//Создаём запрос на отправку
Заголовки=Новый Соответствие;
Заголовки.Вставить("Origin" , "http://"+АдресIP);
Заголовки.Вставить("Referer" , "http://"+АдресIP+"/html/smsinbox.html");
Заголовки.Вставить("Content-Type" , "text/xml");
Заголовки.Вставить("X-Requested-With" , "XMLHttpRequest");
Заголовки.Вставить("__RequestVerificationToken" , ТокенИСессия.Токен);
Заголовки.Вставить("Cookie" , ТокенИСессия.СессияID);

Запрос = Новый HTTPЗапрос("/api/sms/send-sms",Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаЗапроса);

Результат = Соединение.ОтправитьДляОбработки(Запрос);
Если Результат.КодСостояния<>200 Тогда
Возврат Ложь;
КонецЕсли;

Возврат Найти(Результат.ПолучитьТелоКакСтроку(),"<response>OK</response>")>0;

Чтение полученных сообщений

//возвращает структуру
//count - количество сообщений
//data массив сообщений
Функция ПрочитатьSMSHuaweiHiLink(АдресIP, boxType = 1, page = 1, count = 20, unreadPreferred = false)

/// Формируем запрос
ЗаписьXML=Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("request");

ЗаписьXML.ЗаписатьНачалоЭлемента("PageIndex");
ЗаписьXML.ЗаписатьТекст(строка(page));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("ReadCount");
ЗаписьXML.ЗаписатьТекст(строка(count));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("BoxType");
ЗаписьXML.ЗаписатьТекст(строка(boxType));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("SortType");
ЗаписьXML.ЗаписатьТекст("0");
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("Ascending");
ЗаписьXML.ЗаписатьТекст("0");
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьНачалоЭлемента("UnreadPreferred");
ЗаписьXML.ЗаписатьТекст(?(unreadPreferred,"1","0"));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьКонецЭлемента();
СтрокаЗапроса=ЗаписьXML.Закрыть();


Соединение = Новый HTTPСоединение(
АдресIP, // сервер (хост)
80);


ТокенИСессия=ПолучитьТокенИСессию(Соединение);
Если ТокенИСессия=Неопределено Тогда
Возврат Новый Структура("Count",-1);
КонецЕсли;


//Создаём запрос на отправку
Заголовки=Новый Соответствие;
Заголовки.Вставить("Origin" , "http://"+АдресIP);
Заголовки.Вставить("Referer" , "http://"+АдресIP+"/html/smsinbox.html");
Заголовки.Вставить("Content-Type" , "text/xml");
Заголовки.Вставить("X-Requested-With" , "XMLHttpRequest");
Заголовки.Вставить("__RequestVerificationToken" , ТокенИСессия.Токен);
Заголовки.Вставить("Cookie" , ТокенИСессия.СессияID);


Запрос = Новый HTTPЗапрос("/api/sms/sms-list",Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаЗапроса);

Результат = Соединение.ОтправитьДляОбработки(Запрос);
Если Результат.КодСостояния<>200 Тогда
Возврат Новый Структура("Count",-1);
КонецЕсли;

ЧтениеXML=Новый ЧтениеXML;
ЧтениеXML.УстановитьСтроку(Результат.ПолучитьТелоКакСтроку());
РезXDTO=ФабрикаXDTO.ПрочитатьXML(ЧтениеXML);
Рез=Новый Структура("Count,Data",Число(РезXDTO.Count),Новый Массив);

Если РезXDTO.Count<>"0" Тогда
Мас=РезXDTO.Messages.Message;
Если ТипЗнч(РезXDTO.Messages.Message)=Тип("ОбъектXDTO") Тогда
Мас=Новый Массив;
Мас.Добавить(РезXDTO.Messages.Message);
КонецЕсли;



Для каждого Стр из Мас Цикл
Рез.Data.Добавить(Новый Структура("Content,Date,Index,Phone",
Стр.Content,
Дата(СтрЗаменить(СтрЗаменить(СтрЗаменить(Стр.Date,"-","")," ",""),":","")),
Стр.Index,
Стр.Phone
)
)
КонецЦикла;
КонецЕсли;



Возврат Рез;

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

Удаление сообщений

индекс сообщения берем из предыдущей процедуры

Функция УдалитьSMSHuaweiHiLink(АдресIP,Индес)



/// Формируем запрос
ЗаписьXML=Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку("UTF-8");
ЗаписьXML.ЗаписатьОбъявлениеXML();
ЗаписьXML.ЗаписатьНачалоЭлемента("request");

ЗаписьXML.ЗаписатьНачалоЭлемента("Index");
ЗаписьXML.ЗаписатьТекст(строка(Индес));
ЗаписьXML.ЗаписатьКонецЭлемента();

ЗаписьXML.ЗаписатьКонецЭлемента();
СтрокаЗапроса=ЗаписьXML.Закрыть();


Соединение = Новый HTTPСоединение(
АдресIP, // сервер (хост)
80 );





ТокенИСессия=ПолучитьТокенИСессию(Соединение);
Если ТокенИСессия=Неопределено Тогда
Возврат Ложь;
КонецЕсли;



//Создаём запрос на отправку
Заголовки=Новый Соответствие;
Заголовки.Вставить("Origin" , "http://"+АдресIP);
Заголовки.Вставить("Referer" , "http://"+АдресIP+"/html/smsinbox.html");
Заголовки.Вставить("Content-Type" , "text/xml");
Заголовки.Вставить("X-Requested-With" , "XMLHttpRequest");
Заголовки.Вставить("__RequestVerificationToken" , ТокенИСессия.Токен);
Заголовки.Вставить("Cookie" , ТокенИСессия.СессияID);


Запрос = Новый HTTPЗапрос("/api/sms/delete-sms",Заголовки);
Запрос.УстановитьТелоИзСтроки(СтрокаЗапроса);

Результат = Соединение.ОтправитьДляОбработки(Запрос);
Если Результат.КодСостояния<>200 Тогда
Возврат Ложь;
КонецЕсли;

Возврат Истина;


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

Собственно все. 

P.S. При разработке использовалась информация с ресурсов:

https://stackoverrun.com/ru/q/10478644

https://github.com/if0xx/Huawei-Hilink-API/blob/master/src/if0xx/HuaweiHilinkApi/Router.php

1 Comment

  1. Barbos

    интерсно, возьму на заметку

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *