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

Публикация № 940236 10.11.18

Интеграция - SMS рассылки

В данной статье я бы хотел поделиться опытом работы с 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

Скачать файлы

Наименование Файл Версия Размер
Пример использования (проверялась на 8.3.11.3034)

.epf 7,62Kb
15
.epf 7,62Kb 15 Скачать

Специальные предложения

Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. Barbos 12.11.18 09:16 Сейчас в теме
интерсно, возьму на заметку
2. user1201748 29.03.21 19:50 Сейчас в теме
3. heroinepta 08.04.22 09:25 Сейчас в теме
Огромное спасибо! На 1С 8.2 УТ10.3 работает без проблем!
4. heroinepta 12.04.22 10:53 Сейчас в теме
(3) Разбираюсь с получением и удалением ... )
5. Hawk_sib 29 05.09.22 13:16 Сейчас в теме
Здравствуйте, при отправке запроса "/html/smsinbox.html" всё время приходи код состояния 307 с заголовком LOCATION "/html/index.html", при отправке запроса на указанный ресурс ответ приходит со статусом 200, но не получается выполнить запрос "/api/sms/sms-list", ответ приходит вот такой: <?xml version="1.0" encoding="UTF-8"?>
<error>
100003

<message/>
</error>

ссылка https://stackoverrun.com/ru/q/10478644 у меня почему-то не открывается, а в поиске не смог найти ответ почему не работает получение токена у меня правильно и само api, может быть подскажите что нужно поправить?
6. Hawk_sib 29 06.09.22 09:08 Сейчас в теме
(5) продолжаю изучать вопрос, никак не могу получить правильный токен. возникла такая мысль: если меня перенаправляет на начальную страницу (html/index.html), может быть пароль нужно указывать при создании http соединения. Но как его указать, если он отличается от стандартного (менять мне его нельзя)?
указывал

HTTPСоединение("192.168.8.1", 80, , Пароль) - ни имя пользователя, ни пароль не передаются при получении объекта
HTTPСоединение("192.168.8.1", 80, Пароль, Пароль),
HTTPСоединение("192.168.8.1", 80, "admin", Пароль)

результат не поменялся
Оставьте свое сообщение