- Рефакторинг процедур http запросов

- Изменил структуру логирования
- Добавил метод sendDocument()
- Структурировал код для большей читабельности
This commit is contained in:
2025-05-18 18:31:19 +03:00
parent cfcc6b55bd
commit a7e569e141
19 changed files with 685 additions and 130 deletions

View File

@@ -2,82 +2,115 @@
Функция ВыполнитьGetЗапрос(АдресРесурса, Параметры = Неопределено, ДвоичныеДанные = Ложь) Экспорт
Соединение = Новый HTTPСоединение("api.telegram.org",443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
РезультатЗапроса = Новый Структура();
РезультатЗапроса.Вставить("Успех", Ложь);
РезультатЗапроса.Вставить("Тело", Неопределено);
РезультатЗапроса.Вставить("Описание", "");
РезультатЗапроса.Вставить("ДвоичныеДанные", ДвоичныеДанные);
Если Параметры <> Неопределено Тогда
АдресРесурса = АдресРесурсаСПараметрами(АдресРесурса, Параметры);
КонецЕсли;
Запрос = Новый HTTPЗапрос(АдресРесурса);
Запрос.Заголовки.Вставить("Content-Type","application/json");
Ответ = Соединение.Получить(Запрос);
Если Константы.ЛогироватьHttpЗапросы.Получить() Тогда
Лог = Документы.ЛогHttpЗапроса.СоздатьДокумент();
Лог.Дата = ТекущаяДатаСеанса();
Лог.HTTPЗапрос = Запрос.АдресРесурса;
Лог.HTTPОтвет = ?(ДвоичныеДанные,"Двоичные данные",
HttpОбщегоНазначения.ФорматированныйJson(Ответ.ПолучитьТелоКакСтроку()));
Лог.Записать();
КонецЕсли;
КодСостояния = Ответ.КодСостояния;
Если КодСостояния = 200 Тогда
ТелоОтвета = ?(ДвоичныеДанные, Ответ.ПолучитьТелоКакДвоичныеДанные(), Ответ.ПолучитьТелоКакСтроку());
Иначе
ТелоОтвета = HttpОбщегоНазначения.СтрокаJsonВОбъект(Ответ.ПолучитьТелоКакСтроку());
Описание = ?(ТелоОтвета.Получить("description") <> Неопределено, ТелоОтвета["description"], "");
Попытка
Соединение = Новый HTTPСоединение("api.telegram.org",443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
ЗаписьЖурналаРегистрации("HTTPСервисы.Ошибка", УровеньЖурналаРегистрации.Ошибка,,,
СтрШаблон("Не удалось выполнить запрос. Код состояния = %1. %2", КодСостояния, Описание));
ТелоОтвета = Неопределено;
КонецЕсли;
Если Параметры <> Неопределено Тогда
АдресРесурса = АдресРесурсаСПараметрами(АдресРесурса, Параметры);
КонецЕсли;
Запрос = Новый HTTPЗапрос(АдресРесурса);
Запрос.Заголовки.Вставить("Content-Type","application/json");
Ответ = Соединение.Получить(Запрос);
ТелоОтветаКакСтрока = Ответ.ПолучитьТелоКакСтроку();
РезультатЗапроса.Тело = ?(ДвоичныеДанные, Ответ.ПолучитьТелоКакДвоичныеДанные(),
HttpОбщегоНазначения.СтрокаJsonВОбъект(ТелоОтветаКакСтрока));
Если НЕ ДвоичныеДанные И РезультатЗапроса.Тело.Получить("description") <> Неопределено Тогда
РезультатЗапроса.Описание = РезультатЗапроса.Тело["description"];
КонецЕсли;
КодСостояния = Ответ.КодСостояния;
Если КодСостояния = 200 Тогда
РезультатЗапроса.Успех = Истина;
Иначе
ЗаписьЖурналаРегистрации("HTTPСервисы.Ошибка", УровеньЖурналаРегистрации.Ошибка,,,
СтрШаблон("Ошибка выполнения HTTP-запроса. Код состояния = %1. Описание:%2", КодСостояния,
РезультатЗапроса.Описание));
КонецЕсли;
Если Константы.ЛогироватьHttpЗапросы.Получить() Тогда
ЗалогироватьЗапрос(АдресРесурса, Перечисления.МетодHTTPЗапроса.GET, ТелоОтветаКакСтрока, КодСостояния);
КонецЕсли;
Исключение
РезультатЗапроса.Успех = Ложь;
РезультатЗапроса.Описание = "Исключение при выполнении HTTP-запроса: " + ОписаниеОшибки();
ЗаписьЖурналаРегистрации("HTTPСервисы.Ошибка", УровеньЖурналаРегистрации.Ошибка,,, РезультатЗапроса.Описание);
КонецПопытки;
Возврат ТелоОтвета;
Возврат РезультатЗапроса;
КонецФункции
Функция ВыполнитьPostЗапрос(АдресРесурса, Параметры = Неопределено, Тело = Неопределено) Экспорт
Функция ВыполнитьPostЗапрос(АдресРесурса, Параметры = Неопределено, Данные = Неопределено) Экспорт
Соединение = Новый HTTPСоединение("api.telegram.org",443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
РезультатЗапроса = Новый Структура();
РезультатЗапроса.Вставить("Успех", Ложь);
РезультатЗапроса.Вставить("Тело", Неопределено);
РезультатЗапроса.Вставить("Описание", "");
Если Параметры <> Неопределено Тогда
АдресРесурса = АдресРесурсаСПараметрами(АдресРесурса, Параметры);
КонецЕсли;
Запрос = Новый HTTPЗапрос(АдресРесурса);
Запрос.Заголовки.Вставить("Content-Type","application/json");
Если Тело <> Неопределено Тогда
Запрос.УстановитьТелоИзСтроки(ОбъектВСтрокуJson(Тело));
КонецЕсли;
Попытка
Соединение = Новый HTTPСоединение("api.telegram.org",443,,,,, Новый ЗащищенноеСоединениеOpenSSL);
Если Параметры <> Неопределено Тогда
АдресРесурса = АдресРесурсаСПараметрами(АдресРесурса, Параметры);
КонецЕсли;
Запрос = Новый HTTPЗапрос(АдресРесурса);
Если Данные <> Неопределено Тогда
Если Данные.Свойство("Разделитель") Тогда
Запрос.УстановитьТелоИзДвоичныхДанных(Данные.ДвоичныеДанные);
Запрос.Заголовки.Вставить("Content-Length", Формат(Данные.ДвоичныеДанные.Размер(), "ЧН=0; ЧГ="));
Запрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Данные.Разделитель);
КонецЕсли;
Иначе
Запрос.Заголовки.Вставить("Content-Type","application/json");
КонецЕсли;
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
ТелоОтветаКакСтрока = Ответ.ПолучитьТелоКакСтроку();
ТелоДляОтвета = HttpОбщегоНазначения.СтрокаJsonВОбъект(ТелоОтветаКакСтрока);
Если ТелоДляОтвета <> Неопределено Тогда
РезультатЗапроса.Тело = ТелоДляОтвета;
РезультатЗапроса.Описание = ?(ТелоДляОтвета.Получить("description") <> Неопределено, ТелоДляОтвета["description"], "");
КонецЕсли;
КодСостояния = Ответ.КодСостояния;
Если КодСостояния = 200 Тогда
РезультатЗапроса.Успех = Истина;
Иначе
ЗаписьЖурналаРегистрации("HTTPСервисы.Ошибка", УровеньЖурналаРегистрации.Ошибка,,,
СтрШаблон("Ошибка выполнения HTTP-запроса. Код состояния = %1. Описание:%2", КодСостояния,
РезультатЗапроса.Описание));
КонецЕсли;
Если Константы.ЛогироватьHttpЗапросы.Получить() Тогда
ЗалогироватьЗапрос(АдресРесурса, Перечисления.МетодHTTPЗапроса.POST, ТелоОтветаКакСтрока, КодСостояния);
КонецЕсли;
Исключение
РезультатЗапроса.Успех = Ложь;
РезультатЗапроса.Описание = "Исключение при выполнении HTTP-запроса: " + ОписаниеОшибки();
ЗаписьЖурналаРегистрации("HTTPСервисы.Ошибка", УровеньЖурналаРегистрации.Ошибка,,, РезультатЗапроса.Описание);
КонецПопытки;
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Константы.ЛогироватьHttpЗапросы.Получить() Тогда
Лог = Документы.ЛогHttpЗапроса.СоздатьДокумент();
Лог.Дата = ТекущаяДатаСеанса();
Лог.HTTPЗапрос = Запрос.АдресРесурса;
Лог.HTTPОтвет = HttpОбщегоНазначения.ФорматированныйJson(Ответ.ПолучитьТелоКакСтроку());
Лог.Записать();
КонецЕсли;
КодСостояния = Ответ.КодСостояния;
Если КодСостояния = 200 Тогда
ТелоОтвета = Ответ.ПолучитьТелоКакСтроку();
Иначе
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не удалось выполнить запрос. Код состояния = " + КодСостояния;
Сообщение.Сообщить();
ТелоОтвета = Неопределено;
КонецЕсли;
Возврат ТелоОтвета;
Возврат РезультатЗапроса;
КонецФункции
Функция СтрокаJsonВОбъект(СтрокаJson) Экспорт
Если НЕ ЗначениеЗаполнено(СтрокаJson) Тогда
Возврат Неопределено;
КонецЕсли;
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(СтрокаJson);
Попытка
@@ -95,6 +128,11 @@
Функция ОбъектВСтрокуJson(Объект) Экспорт
Если Объект = Неопределено Тогда
Возврат "";
КонецЕсли;
ЗаписьJSON = Новый ЗаписьJSON;
ПараметрыЗаписи = Новый ПараметрыЗаписиJSON(, Символы.Таб);
ЗаписьJSON.УстановитьСтроку(ПараметрыЗаписи);
@@ -150,7 +188,6 @@
КонецФункции
Функция АдресРесурсаСПараметрами(АдресРесурса, Параметры)
Если Параметры.Количество() = 0 Тогда
@@ -169,4 +206,18 @@
КонецФункции
Процедура ЗалогироватьЗапрос(АдресРесурса, Метод, ТелоОтветаКакСтрока, КодСостояния)
АдресРесурса = СтрЗаменить(АдресРесурса, Константы.ТелеграмТокен.Получить(), "#token#");
Лог = Документы.ЛогHttpЗапроса.СоздатьДокумент();
Лог.Дата = ТекущаяДатаСеанса();
Лог.HTTPЗапрос = АдресРесурса;
Лог.Метод = Метод;
Лог.КодСостояния = КодСостояния;
Лог.HTTPОтвет = HttpОбщегоНазначения.ФорматированныйJson(ТелоОтветаКакСтрока);
Лог.Записать();
КонецПроцедуры
#КонецОбласти

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.19">
<CommonModule uuid="bc2f6893-5ccb-40f8-8de8-ef7624ff4a5d">
<Properties>
<Name>РаботаСФайламиКлиентСервер</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Работа с файлами клиент сервер</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Global>false</Global>
<ClientManagedApplication>true</ClientManagedApplication>
<Server>true</Server>
<ExternalConnection>true</ExternalConnection>
<ClientOrdinaryApplication>false</ClientOrdinaryApplication>
<ServerCall>true</ServerCall>
<Privileged>false</Privileged>
<ReturnValuesReuse>DontUse</ReturnValuesReuse>
</Properties>
</CommonModule>
</MetaDataObject>

View File

@@ -0,0 +1,10 @@
Функция ПолучитьРасширениеИмениФайла(Знач ИмяФайла) Экспорт
РасширениеФайла = "";
МассивСтрок = СтрРазделить(ИмяФайла, ".", Ложь);
Если МассивСтрок.Количество() > 1 Тогда
РасширениеФайла = МассивСтрок[МассивСтрок.Количество() - 1];
КонецЕсли;
Возврат РасширениеФайла;
КонецФункции

View File

@@ -4,7 +4,7 @@
ТелоЗапроса = Новый Структура("chat_id, text", ИдЧата, СообщениеДляОтправки);
АдресРесурса = АдресРесурсаПоИмениМетода("sendMessage");
Возврат HttpОбщегоНазначения.ВыполнитьPostЗапрос(АдресРесурса,,ТелоЗапроса);
Возврат HttpОбщегоНазначения.ВыполнитьPostЗапрос(АдресРесурса,, ТелоЗапроса);
КонецФункции
@@ -48,13 +48,101 @@
КонецФункции
Функция GetMe() Экспорт
АдресРесурса = АдресРесурсаПоИмениМетода("getMe");
Возврат HttpОбщегоНазначения.ВыполнитьGetЗапрос(АдресРесурса);
КонецФункции
Функция SendDocument(ИдЧата, ДокументДляОтправки, Надпись = Неопределено, БезУведомления = Ложь) Экспорт
АдресРесурса = АдресРесурсаПоИмениМетода("sendDocument");
Разделитель = СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
ДвоичныеДанныеДокумента = ДвоичныеДанныеДокумента(ИдЧата, ДокументДляОтправки, Надпись, БезУведомления, Разделитель);
ДанныеДокумента = Новый Структура("Разделитель, ДвоичныеДанные", Разделитель, ДвоичныеДанныеДокумента);
Возврат HttpОбщегоНазначения.ВыполнитьPostЗапрос(АдресРесурса,, ДанныеДокумента);
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция АдресРесурсаПоИмениМетода(ИмяМетода)
Возврат СтрШаблон("/bot%1/%2", ТелеграмПовторноеИспользование.ТелеграмТокен(), ИмяМетода);
Токен = ТелеграмПовторноеИспользование.ТелеграмТокен();
Если ПустаяСтрока(Токен) Тогда
ВызватьИсключение "Не задан токен Telegram бота";
КонецЕсли;
Возврат СтрШаблон("/bot%1/%2", Токен, ИмяМетода);
КонецФункции
Функция ДвоичныеДанныеДокумента(ИдЧата, Документ, Надпись = Неопределено, БезУведомления = Ложь, Разделитель)
Если Документ = Неопределено ИЛИ Не (Документ.Свойство("ДанныеФайла") И ТипЗнч(Документ.ДанныеФайла) = Тип("ДвоичныеДанные")) Тогда
ВызватьИсключение "Неверный параметр Документ: ожидается непустой объект, содержащий двоичные данные";
КонецЕсли;
ИмяФайла = Документ.ИмяФайла;
ТипСодержимого = СтрШаблон("application/%1", РаботаСФайламиКлиентСервер.ПолучитьРасширениеИмениФайла(ИмяФайла));
ТелоЗапроса = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(ТелоЗапроса, , , Символы.ВК + Символы.ПС, "");
ЗаписатьЭлементаЗапроса(ЗаписьДанных, Разделитель, "document", Документ.ДанныеФайла, ИмяФайла, ТипСодержимого);
ЗаписатьЭлементаЗапроса(ЗаписьДанных, Разделитель, "chat_id", Формат(ИдЧата, "ЧН=0; ЧГ="));
ЗаписатьЭлементаЗапроса(ЗаписьДанных, Разделитель, "caption", Надпись);
ЗаписатьЭлементаЗапроса(ЗаписьДанных, Разделитель, "disable_notification", БулевоСтрокой(БезУведомления));
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель + "--");
ЗаписьДанных.Закрыть();
Возврат ТелоЗапроса.ЗакрытьИПолучитьДвоичныеДанные();
КонецФункции
Процедура ЗаписатьЭлементаЗапроса(ЗаписьДанных, Разделитель, ИмяПоля, Значение, ИмяФайла = Неопределено, ТипСодержимого = Неопределено)
Если Значение = Неопределено Тогда
Возврат;
КонецЕсли;
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
Если ИмяФайла <> Неопределено Тогда
ЗаписьДанных.ЗаписатьСтроку(СтрШаблон("Content-Disposition: form-data; name=%1; filename=%2", ИмяПоля, ИмяФайла));
Иначе
ЗаписьДанных.ЗаписатьСтроку(СтрШаблон("Content-Disposition: form-data; name=%1", ИмяПоля));
КонецЕсли;
Если ТипСодержимого <> Неопределено Тогда
ЗаписьДанных.ЗаписатьСтроку(СтрШаблон("Content-Type: %1", ТипСодержимого));
КонецЕсли;
ЗаписьДанных.ЗаписатьСтроку("");
Если ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
ЗаписьДанных.Записать(Значение);
Иначе
ЗаписьДанных.ЗаписатьСтроку(Значение);
КонецЕсли;
ЗаписьДанных.ЗаписатьСтроку("");
КонецПроцедуры
Функция БулевоСтрокой(БулевоЗначение)
Если ТипЗнч(БулевоЗначение) = Тип("Булево") Тогда
Если БулевоЗначение Тогда
Возврат "true";
КонецЕсли;
КонецЕсли;
Возврат "false";
КонецФункции

View File

@@ -109,25 +109,8 @@
Ответ = ТелеграмМетодыВызовСервера.GetFile(ИдДокумента);
Если Ответ = Неопределено Тогда
Возврат Ответ;
КонецЕсли;
ДанныеФайла = HttpОбщегоНазначения.СтрокаJsonВОбъект(Ответ);
//Если ДанныеФайла.Получить("ok") <> Неопределено Тогда
// Если ДанныеФайла["ok"] И ДанныеФайла.Получить["result"] <> Неопределено Тогда
// ПутьКФайлуНаСервереТелеграм = ДанныеФайла["result"]["file_path"];
// Возврат ПолучитьФайлССервераТелеграм(ПутьКФайлуНаСервереТелеграм);
// Иначе
// ЗаписьЖурналаРегистрации("Телеграм.Ошибка", УровеньЖурналаРегистрации.Ошибка,,,
// СтрШаблон("Не удалось получить файл по id. Код ошибки %1, описание: %2", , ДанныеФайла["error_code"],
// ДанныеФайла["description"]));
// КонецЕсли;
//КонецЕсли;
Если ДанныеФайла.Получить("result") <> Неопределено Тогда
Возврат ПолучитьФайлССервераТелеграм(ДанныеФайла["result"]["file_path"]);
Если Ответ.Успех И Ответ.Тело.Получить("result") <> Неопределено Тогда
Возврат ПолучитьФайлССервераТелеграм(Ответ.Тело["result"]["file_path"]);
Иначе
Возврат Неопределено;
КонецЕсли;