1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2024-12-25 02:42:28 +02:00

Унификация кода 1С и OneScript, тесты

This commit is contained in:
Anton Titovets 2024-03-01 16:27:30 +03:00
parent ae8df587d8
commit 78fcc4833b
18 changed files with 8942 additions and 312 deletions

View File

@ -0,0 +1,559 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
#Область РаботаСМетаданнымиКалендарей
// Создать календарь.
//
// Параметры:
// Токен - Строка - Токен
// Наименование - Строка - Наименование создаваемого календаря
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - ответ сервера Google
Функция СоздатьКалендарь(Знач Токен, Знач Наименование) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars";
Параметры = Новый Структура;
Параметры.Вставить("summary" , Наименование);
Параметры.Вставить("timeZone", "Europe/Moscow");
Ответ = OPI_Инструменты.Post(URL, Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить календарь.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - ответ сервера Google
Функция ПолучитьМетаданныеКалендаря(Знач Токен, Знач Календарь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/" + Календарь;
Ответ = OPI_Инструменты.Get(URL, , Заголовки);
Возврат Ответ;
КонецФункции
// Изменить календарь.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
// Наименование - Строка - Новое наименование
// Описание - Строка - Новое описание календаря
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - ответ сервера Google
Функция ИзменитьМетаданныеКалендаря(Знач Токен
, Знач Календарь
, Знач Наименование = ""
, Знач Описание = "") Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/" + Календарь;
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Наименование) Тогда
Параметры.Вставить("summary", Наименование);
КонецЕсли;
Если ЗначениеЗаполнено(Описание) Тогда
Параметры.Вставить("description", Описание);
КонецЕсли;
Ответ = OPI_Инструменты.Patch(URL, Параметры, Заголовки, Истина);
Возврат Ответ;
КонецФункции
// Очистить основной календарь.
//
// Параметры:
// Токен - Строка - Токен
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция ОчиститьОсновнойКалендарь(Знач Токен) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/primary/clear";
Ответ = OPI_Инструменты.Post(URL, , Заголовки, Ложь);
Возврат Ответ;
КонецФункции
// Удалить календарь.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - ответ сервера Google
Функция УдалитьКалендарь(Знач Токен, Знач Календарь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/" + Календарь;
Ответ = OPI_Инструменты.Delete(URL, , Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область РаботаСоСпискомКалендарей
// Получить список календарей.
//
// Параметры:
// Токен - Строка - Токен
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Массив соответствий данных календарей
Функция ПолучитьСписокКалендарей(Знач Токен) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
МассивКалендарей = Новый Массив;
ПолучитьСписокКалендарейРекурсивно(Заголовки, МассивКалендарей);
Возврат МассивКалендарей;
КонецФункции
// Добавить календарь в список.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - ответ сервера Google
Функция ДобавитьКалендарьВСписок(Знач Токен, Знач Календарь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/users/me/calendarList";
Параметры = Новый Структура;
Параметры.Вставить("id", Календарь);
Ответ = OPI_Инструменты.Post(URL, Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить календарь списка.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция ПолучитьКалендарьСписка(Знач Токен, Знач Календарь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/users/me/calendarList/" + Календарь;
Ответ = OPI_Инструменты.Get(URL, , Заголовки);
Возврат Ответ;
КонецФункции
// Удалить календарь из списка.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция УдалитьКалендарьИзСписка(Знач Токен, Знач Календарь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/users/me/calendarList/" + Календарь;
Ответ = OPI_Инструменты.Delete(URL, , Заголовки);
Возврат Ответ;
КонецФункции
// Изменить календарь списка.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
// ОсновнойЦвет - Строка - HEX основного цвета (#ffffff)
// ДополнительныйЦвет - Строка - HEX дополнительного цвета (#ffffff)
// Скрытый - Булево - Скрытый календарь
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция ИзменитьКалендарьСписка(Знач Токен
, Знач Календарь
, Знач ОсновнойЦвет
, Знач ДополнительныйЦвет
, Знач Скрытый = Ложь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/users/me/calendarList/" + Календарь + "?colorRgbFormat=true";
Параметры = Новый Соответствие;
Параметры.Вставить("hidden" , Скрытый);
Параметры.Вставить("foregroundColor", ОсновнойЦвет);
Параметры.Вставить("backgroundColor", ДополнительныйЦвет);
Ответ = OPI_Инструменты.Put(URL, Параметры, Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область РаботаССобытиями
// Получить описание события.
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Пустой макет события
Функция ПолучитьОписаниеСобытия() Экспорт
ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДата();
Час = 3600;
Событие = Новый Соответствие;
Событие.Вставить("Описание" , ""); // Описание события
Событие.Вставить("Заголовок" , "Новое событие"); // Заголовок события
Событие.Вставить("МестоПроведения" , ""); // Строка описание места проведения
Событие.Вставить("ДатаНачала" , ТекущаяДата); // Дата начала события
Событие.Вставить("ДатаОкончания" , ТекущаяДата + Час); // Дата окончания события
Событие.Вставить("МассивURLФайловВложений", Новый Соответствие); // Ключ - название, Значение - URL к файлу
Событие.Вставить("ОтправлятьУведомления" , Истина); // Признак отправки уведомлений участникам
Возврат Событие;
КонецФункции
// Получить список событий.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
//
// Возвращаемое значение:
// Соответствие Из КлючИЗначение - Массив соответствий событий
Функция ПолучитьСписокСобытий(Знач Токен, Знач Календарь) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
МассивСобытий = Новый Массив;
ПолучитьСписокСобытийРекурсивно(Заголовки, Календарь, МассивСобытий);
Возврат МассивСобытий;
КонецФункции
// Получить событие.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
// Событие - Строка - ID события
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция ПолучитьСобытие(Знач Токен, Знач Календарь, Знач Событие) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/"
+ Календарь
+ "/events/"
+ Событие;
Ответ = OPI_Инструменты.Get(URL, , Заголовки);
Возврат Ответ;
КонецФункции
// Создать событие.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
// ОписаниеСобытия - Соответствие Из КлючИЗначение - Описание события. См. ПолучитьОписаниеСобытия
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция СоздатьСобытие(Знач Токен, Знач Календарь, Знач ОписаниеСобытия) Экспорт
Возврат УправлениеСобытием(Токен, Календарь, ОписаниеСобытия);
КонецФункции
// Переместить событие.
//
// Параметры:
// Токен - Строка - Токен
// КалендарьИсточник - Строка - ID календаря источника
// КалендарьПриемник - Строка - ID календаря приемника
// Событие - Строка - ID события календаря источника
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция ПереместитьСобытие(Знач Токен, Знач КалендарьИсточник, Знач КалендарьПриемник, Знач Событие) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/"
+ КалендарьИсточник
+ "/events/"
+ Событие
+ "/move?destination="
+ КалендарьПриемник;
Ответ = OPI_Инструменты.Post(URL, , Заголовки);
Возврат Ответ;
КонецФункции
// Изменить событие.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
// ОписаниеСобытия - Строка - Новое описание события
// Событие - Строка - ID события
//
// Возвращаемое значение:
// HTTPОтвет - Изменить событие
Функция ИзменитьСобытие(Знач Токен, Знач Календарь, Знач ОписаниеСобытия, Знач Событие) Экспорт
Возврат УправлениеСобытием(Токен, Календарь, ОписаниеСобытия, Событие);
КонецФункции
// Удалить событие.
//
// Параметры:
// Токен - Строка - Токен
// Календарь - Строка - ID календаря
// Событие - Строка - ID события
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - ответ сервера Google
Функция УдалитьСобытие(Знач Токен, Знач Календарь, Знач Событие) Экспорт
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
URL = "https://www.googleapis.com/calendar/v3/calendars/"
+ Календарь
+ "/events/"
+ Событие;
Ответ = OPI_Инструменты.Delete(URL, , Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ПолучитьЗаголовокАвторизации(Знач Токен)
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "Bearer " + Токен);
Возврат Заголовки;
КонецФункции
Функция ПреобразоватьДату(Знач Дата)
СтруктураДаты = Новый Структура;
Если Не ТипЗнч(Дата) = Тип("Дата") Тогда
Возврат Неопределено;
КонецЕсли;
Если Дата = НачалоДня(Дата) Тогда
ФорматДаты = "ДФ=yyyy-MM-dd";
Поле = "date";
Иначе
ФорматДаты = "ДФ=yyyy-MM-ddTHH:mm:ssZ";
Поле = "dateTime";
КонецЕсли;
Дата = Формат(Дата, ФорматДаты);
СтруктураДаты.Вставить(Поле , Дата);
СтруктураДаты.Вставить("timeZone", "Europe/Moscow");
Возврат СтруктураДаты;
КонецФункции
Функция ПреобразоватьВложения(Знач Вложения)
МассивВложений = Новый Массив;
Если ТипЗнч(Вложения) = Тип("Соответствие") Тогда
Для Каждого Вложение Из Вложения Цикл
ТекущеВложение = Новый Структура;
ТекущеВложение.Вставить("title" , Вложение.Ключ);
ТекущеВложение.Вставить("fileUrl", Вложение.Значение);
МассивВложений.Добавить(ТекущеВложение);
КонецЦикла;
КонецЕсли;
Если МассивВложений.Количество() > 0 Тогда
Возврат МассивВложений;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция УправлениеСобытием(Знач Токен, Знач Календарь, Знач ОписаниеСобытия, Знач Событие = "")
Заголовки = ПолучитьЗаголовокАвторизации(Токен);
Существующее = ЗначениеЗаполнено(Событие);
URL = "https://www.googleapis.com/calendar/v3/calendars/"
+ Календарь
+ "/events"
+ ?(Существующее, "/" + Событие, "");
Дата0 = ОписаниеСобытия["ДатаНачала"];
Дата1 = ОписаниеСобытия["ДатаОкончания"];
Вложения = ОписаниеСобытия["МассивURLФайловВложений"];
Вложения = ПреобразоватьВложения(Вложения);
Уведомления = ?(ОписаниеСобытия["ОтправлятьУведомления"] = Неопределено
, Ложь
, ОписаниеСобытия["ОтправлятьУведомления"]);
Параметры = Новый Структура;
Параметры.Вставить("summary" , ОписаниеСобытия["Заголовок"]);
Параметры.Вставить("description", ОписаниеСобытия["Описание"]);
Параметры.Вставить("location" , ОписаниеСобытия["МестоПроведения"]);
Параметры.Вставить("start" , ПреобразоватьДату(Дата0));
Параметры.Вставить("end" , ПреобразоватьДату(Дата1));
Параметры.Вставить("attachments", Вложения);
ПараметрыURL = Новый Структура;
ПараметрыURL.Вставить("sendUpdates" , ?(Уведомления, "all", "none"));
ПараметрыURL.Вставить("supportsAttachments" , ?(ЗначениеЗаполнено(Вложения), "true", "false"));
URL = URL + OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
OPI_Инструменты.УдалитьПустыеПоляКоллекции(Параметры);
Если Существующее Тогда
Ответ = OPI_Инструменты.Patch(URL, Параметры, Заголовки, Истина);
Иначе
Ответ = OPI_Инструменты.Post(URL, Параметры, Заголовки, Истина);
КонецЕсли;
Возврат Ответ;
КонецФункции
Процедура ПолучитьСписокКалендарейРекурсивно(Знач Заголовки, МассивКалендарей, Страница = "")
Items = "items";
NPT = "nextPageToken";
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Страница) Тогда
Параметры.Вставить("pageToken", Страница);
КонецЕсли;
Результат = OPI_Инструменты.Get("https://www.googleapis.com/calendar/v3/users/me/calendarList"
,
, Заголовки);
Календари = Результат[Items];
Страница = Результат[NPT];
Для Каждого Календарь Из Календари Цикл
МассивКалендарей.Добавить(Календарь);
КонецЦикла;
Если Календари.Количество() > 0 И ЗначениеЗаполнено(Страница) Тогда
ПолучитьСписокКалендарейРекурсивно(Заголовки, МассивКалендарей, Страница);
КонецЕсли;
КонецПроцедуры
Процедура ПолучитьСписокСобытийРекурсивно(Знач Заголовки, Знач Календарь, МассивСобытий, Страница = "")
Items = "items";
NPT = "nextPageToken";
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Страница) Тогда
Параметры.Вставить("pageToken", Страница);
КонецЕсли;
Результат = OPI_Инструменты.Get("https://www.googleapis.com/calendar/v3/calendars/" + Календарь + "/events"
,
, Заголовки);
События = Результат[Items];
Страница = Результат[NPT];
Для Каждого Событие Из События Цикл
МассивСобытий.Добавить(Событие);
КонецЦикла;
Если События.Количество() > 0 И ЗначениеЗаполнено(Страница) Тогда
ПолучитьСписокСобытийРекурсивно(Заголовки, МассивСобытий, Страница);
КонецЕсли;
КонецПроцедуры
#КонецОбласти

View File

@ -0,0 +1,118 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
// Сформировать ссылку получения кода.
//
// Параметры:
// ClientID - Строка - Client ID
//
// Возвращаемое значение:
// Строка - Сформировать ссылку получения кода
Функция СформироватьСсылкуПолученияКода(Знач ClientID) Экспорт
URL = "https://accounts.google.com/o/oauth2/auth";
ПараметрыURL = Новый Структура;
ПараметрыURL.Вставить("response_type", "code");
ПараметрыURL.Вставить("client_id" , ClientID);
ПараметрыURL.Вставить("redirect_uri" , "http://localhost");
ПараметрыURL.Вставить("access_type" , "offline");
ПараметрыURL.Вставить("scope" , ПолучитьСписокРазрешений());
URL = URL + OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
Возврат URL;
КонецФункции
// Получить токен по коду.
//
// Параметры:
// ClientID - Строка - Client ID
// ClientSecret - Строка - Client secret
// Code - Строка - Code из браузера
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - Получить токен по коду
Функция ПолучитьТокенПоКоду(Знач ClientID, Знач ClientSecret, Знач Code) Экспорт
URL = "https://accounts.google.com/o/oauth2/token";
ПараметрыURL = Новый Структура;
ПараметрыURL.Вставить("grant_type" , "authorization_code");
ПараметрыURL.Вставить("client_id" , ClientID);
ПараметрыURL.Вставить("client_secret", ClientSecret);
ПараметрыURL.Вставить("redirect_uri" , "http://localhost");
ПараметрыURL.Вставить("code" , Code);
Ответ = OPI_Инструменты.Post(URL, ПараметрыURL, , Ложь);
Возврат Ответ;
КонецФункции
// Обновить токен.
//
// Параметры:
// ClientID - Строка - Client ID
// ClientSecret - Строка - Client secret
// RefreshToken - Строка - Refresh token
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - Обновить токен
Функция ОбновитьТокен(Знач ClientID, Знач ClientSecret, Знач RefreshToken) Экспорт
URL = "https://accounts.google.com/o/oauth2/token";
ПараметрыURL = Новый Структура;
ПараметрыURL.Вставить("grant_type" , "refresh_token");
ПараметрыURL.Вставить("client_id" , ClientID);
ПараметрыURL.Вставить("client_secret", ClientSecret);
ПараметрыURL.Вставить("refresh_token", RefreshToken);
Ответ = OPI_Инструменты.Post(URL, ПараметрыURL, , Ложь);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область СлужебныеПроцедурыИфункции
Функция ПолучитьСписокРазрешений()
МассивРазрешений = Новый Массив;
МассивРазрешений.Добавить("https://www.googleapis.com/auth/calendar");
Возврат СтрСоединить(МассивРазрешений, " ");
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,799 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
#Область РаботаСоСтраницами
// Создать дочернюю страницу над другой страницей-родителем
//
// Параметры:
// Токен - Строка - Токен
// Родитель - Строка - ID Родителя
// Заголовок - Строка - Заголовок страницы
//
// Возвращаемое значение:
// Строка, Произвольный, HTTPОтвет, ДвоичныеДанные, Неопределено - Ответ сервера Notion
Функция СоздатьСтраницу(Знач Токен, Знач Родитель, Знач Заголовок) Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Свойства = Новый Структура;
Параметры = Новый Структура;
ДобавитьЗаголовокСтраницы(Заголовок, Свойства);
ДобавитьРодителяСтраницы(Родитель, Ложь, Параметры);
Параметры.Вставить("properties", Свойства);
Ответ = OPI_Инструменты.Post("https://api.notion.com/v1/pages", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Создать страницу в базу.
//
// Параметры:
// Токен - Строка - Токен
// Родитель - Строка - ID родительской базы
// Данные - Соответствие Из КлючИЗначение - Соответствие свойств. Должен соответствовать шаблону свойств базы
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - Создать страницу в базу
Функция СоздатьСтраницуВБазу(Знач Токен, Знач Родитель, Знач Данные) Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Параметры = Новый Структура;
ДобавитьРодителяСтраницы(Родитель, Истина, Параметры);
Свойства = ЗаполнитьДанныеПоСхеме(Родитель, Данные, Токен);
Параметры.Вставить("properties", Свойства);
Ответ = OPI_Инструменты.Post("https://api.notion.com/v1/pages", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить страницу.
//
// Параметры:
// Токен - Строка - Токен
// Страница - Строка - ID Родителя
//
// Возвращаемое значение:
// ДвоичныеДанные, Неопределено, Строка, Произвольный - Ответ сервера Notion
Функция ПолучитьСтраницу(Знач Токен, Знач Страница) Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
ПреобразоватьИД(Страница);
Ответ = OPI_Инструменты.Get("https://api.notion.com/v1/pages/" + Страница, , Заголовки);
Возврат Ответ;
КонецФункции
// Изменить свойства страницы.
//
// Параметры:
// Токен - Строка - Токен
// Страница - Строка - ID изменяемой страницы
// Данные - Соответствие Из КлючИЗначение - Соответствие изменяемых параметров
// Иконка - Строка - URL картинки - иконки страницы
// Обложка - Строка - URL картинки - обложки страницы
// Архивирована - Булево - Истина - Архивировать страницу
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, HTTPОтвет, ДвоичныеДанные - Изменить свойства страницы
// @skip-check method-too-many-params
// BSLLS:NumberOfOptionalParams-off
Функция ИзменитьСвойстваСтраницы(Знач Токен
, Знач Страница
, Знач Данные = ""
, Знач Иконка = ""
, Знач Обложка = ""
, Знач Архивирована = Ложь) Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Параметры = Новый Структура;
Files = "files";
Если ЗначениеЗаполнено(Данные) И ТипЗнч(Данные) = Тип("Соответствие") Тогда
Свойства = ЗаполнитьДанныеПоСхеме(Страница, Данные, Токен, Ложь);
Иначе
Свойства = Новый Соответствие;
КонецЕсли;
Если ЗначениеЗаполнено(Иконка) Тогда
СоответствиеИконки = Новый Соответствие;
СоответствиеИконки.Вставить("Icon", Иконка);
ОбъектИконка = ПреобразоватьЗначениеПоТипу(Files, СоответствиеИконки);
ОбъектИконка = ОбъектИконка[Files][0];
ОбъектИконка.Удалить("name");
Параметры.Вставить("icon", ОбъектИконка);
КонецЕсли;
Если ЗначениеЗаполнено(Обложка) Тогда
СоответствиеОбложки = Новый Соответствие;
СоответствиеОбложки.Вставить("Cover", Обложка);
ОбъектОбложка = ПреобразоватьЗначениеПоТипу(Files, СоответствиеОбложки);
ОбъектОбложка = ОбъектОбложка[Files][0];
ОбъектОбложка.Удалить("name");
Параметры.Вставить("cover", ОбъектОбложка);
КонецЕсли;
Параметры.Вставить("properties", Свойства);
Параметры.Вставить("archived" , Архивирована);
ПреобразоватьИД(Страница);
Ответ = OPI_Инструменты.Patch("https://api.notion.com/v1/pages/" + Страница, Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// BSLLS:NumberOfOptionalParams-on
#КонецОбласти
#Область РаботаСБазамиДанных
// Создать базу данных страниц
//
// Параметры:
// Токен - Строка - Токен
// Родитель - Строка - ID страницы родителя
// Заголовок - Строка - Заголовок базы данных
// Свойства - Структура Из Строка - Свойства базы данных
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - Ответ сервера Notion
Функция СоздатьБазуДанных(Знач Токен, Знач Родитель, Знач Заголовок, Знач Свойства = "") Экспорт
// Пример структуры/соответствия свойств
// Имя : title
// Описание : rich_text
// В работе : checkbox
// Количество : number
// Дата : date
// Статус : Соответствие
// Активный : green
// Неактивный : red
// Архив : yellow
// Все страницы, которые будут созданы как дочерние, должны иметь свойства базы-родителя
Если Не ТипЗнч(Свойства) = Тип("Структура") И Не ТипЗнч(Свойства) = Тип("Соответствие") Тогда
Свойства = Новый Структура("Наименование", "title");
КонецЕсли;
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Параметры = Новый Структура;
ДобавитьРодителяБазы(Родитель, Ложь, Параметры);
ДобавитьЗаголовокБазы(Заголовок, Параметры);
ДобавитьСвойстваБазы(Свойства, Параметры);
Ответ = OPI_Инструменты.Post("https://api.notion.com/v1/databases", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить данные о базе данных
//
// Параметры:
// Токен - Строка - Токен
// База - Строка - ID базы данных
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено - Ответ сервера Notion
Функция ПолучитьБазуДанных(Знач Токен, Знач База) Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
ПреобразоватьИД(База);
Ответ = OPI_Инструменты.Get("https://api.notion.com/v1/databases/" + База, , Заголовки);
Возврат Ответ;
КонецФункции
// Изменить свойства базы.
//
// Параметры:
// Токен - Строка - Токен
// База - Строка - ID целевой базы
// Свойства - Соответствие из КлючИЗначение - Соответствие, как при создании новой базы. Если значение - пусто,
// то свойство будет удалено
// Заголовок - Строка - Заголовок базы
// Описание - Строка - Описание базы
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, HTTPОтвет, ДвоичныеДанные - Ответ сервера Notion
Функция ИзменитьСвойстваБазы(Знач Токен, Знач База, Знач Свойства = "", Знач Заголовок = "", Знач Описание = "") Экспорт
Параметры = Новый Структура;
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
ПреобразоватьИД(База);
Если ЗначениеЗаполнено(Заголовок) Тогда
ДобавитьЗаголовокБазы(Заголовок, Параметры);
КонецЕсли;
Если ЗначениеЗаполнено(Описание) Тогда
ДобавитьОписаниеБазы(Описание, Параметры);
КонецЕсли;
Если ТипЗнч(Свойства) = Тип("Структура") Или ТипЗнч(Свойства) = Тип("Соответствие") Тогда
ДобавитьСвойстваБазы(Свойства, Параметры);
КонецЕсли;
Ответ = OPI_Инструменты.Patch("https://api.notion.com/v1/databases/" + База, Параметры, Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область РаботаСБлоками
// Создать блок.
//
// Параметры:
// Токен - Строка - Токен
// Родитель - Строка - ID родительского блока или страницы
// Блок - Строка,Соответствие Из КлючИЗначение - ID блока, копию которого необходимо добавить или сам блок
// ВставитьПосле - Строка - ID блока, после которого необходимо встаивть новый, если родитель уже имеет дочерние блоки
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Ответ сервера Notion
Функция СоздатьБлок(Знач Токен, Знач Родитель, Знач Блок, Знач ВставитьПосле = "") Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
ПреобразоватьИД(Родитель);
Если ТипЗнч(Блок) = Тип("Строка") Тогда
ПреобразоватьИД(Блок);
Блок = ВернутьБлок(Токен, Блок);
КонецЕсли;
МассивБлоков = Новый Массив;
МассивБлоков.Добавить(Блок);
Параметры = Новый Соответствие;
Параметры.Вставить("children", МассивБлоков);
Если ЗначениеЗаполнено(ВставитьПосле) Тогда
Параметры.Вставить("after", ВставитьПосле);
КонецЕсли;
Ответ = OPI_Инструменты.Patch("https://api.notion.com/v1/blocks/" + Родитель + "/children"
, Параметры
, Заголовки);
Возврат Ответ;
КонецФункции
// Вернуть блок.
//
// Параметры:
// Токен - Строка - Токен
// ИДБлока - Строка - ID блока
// ТолькоОснова - Булево - Истина - служебные поля удаляются, остается только сам блок
//
// Возвращаемое значение:
// Неопределено, ДвоичныеДанные, Строка, Произвольный - Ответ сервера Notion
Функция ВернутьБлок(Знач Токен, Знач ИДБлока, Знач ТолькоОснова = Истина) Экспорт
ПреобразоватьИД(ИДБлока);
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Ответ = OPI_Инструменты.Get("https://api.notion.com/v1/blocks/" + ИДБлока, , Заголовки);
Если ТолькоОснова Тогда
УдалитьЛишниеПоляБлока(Ответ);
КонецЕсли;
Возврат Ответ;
КонецФункции
// Вернуть дочерние блоки.
//
// Параметры:
// Токен - Строка - Токен
// ИДБлока - Строка - ID блока-родителя
//
// Возвращаемое значение:
// Неопределено, ДвоичныеДанные, Строка, Произвольный - Ответ сервера Notion
Функция ВернутьДочерниеБлоки(Знач Токен, Знач ИДБлока) Экспорт
ПреобразоватьИД(ИДБлока);
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Ответ = OPI_Инструменты.Get("https://api.notion.com/v1/blocks/" + ИДБлока + "/children", , Заголовки);
Возврат Ответ;
КонецФункции
// Удалить блок.
//
// Параметры:
// Токен - Строка - Токен
// ИДБлока - Строка - ID блока
//
// Возвращаемое значение:
// Неопределено, ДвоичныеДанные, Строка, Произвольный - Ответ сервера Notion
Функция УдалитьБлок(Знач Токен, Знач ИДБлока) Экспорт
ПреобразоватьИД(ИДБлока);
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Ответ = OPI_Инструменты.Delete("https://api.notion.com/v1/blocks/" + ИДБлока, , Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область Пользователи
// Список пользователей.
//
// Параметры:
// Токен - Строка - Токен
//
// Возвращаемое значение:
// Неопределено, ДвоичныеДанные, Строка, Произвольный - Ответ сервера Notion
Функция СписокПользователей(Знач Токен) Экспорт
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Ответ = OPI_Инструменты.Get("https://api.notion.com/v1/users", , Заголовки);
Возврат Ответ;
КонецФункции
// Получить данные пользователя.
//
// Параметры:
// Токен - Строка - Токен
// ИДПользователя - Строка - ID целевого пользователя
//
// Возвращаемое значение:
// Неопределено, ДвоичныеДанные, Строка, Произвольный - Получить данные пользователя
Функция ПолучитьДанныеПользователя(Знач Токен, Знач ИДПользователя) Экспорт
ПреобразоватьИД(ИДПользователя);
Заголовки = СоздатьЗаголовкиЗапроса(Токен);
Ответ = OPI_Инструменты.Get("https://api.notion.com/v1/users/" + ИДПользователя, , Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция СоздатьЗаголовкиЗапроса(Знач Токен)
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization" , "Bearer " + Токен);
Заголовки.Вставить("Notion-Version", "2022-06-28");
Возврат Заголовки;
КонецФункции
Процедура ПреобразоватьИД(Идентификатор)
Идентификатор = СтрЗаменить(Идентификатор, "-", "");
КонецПроцедуры
Процедура ДобавитьРодителяСтраницы(Знач Родитель, Знач РодительБаза, ОсновнаяСтруктура)
ПреобразоватьИД(Родитель);
ПолеИдентификатора = ?(РодительБаза, "database_id", "page_id");
СтруктураРодителя = Новый Структура(ПолеИдентификатора, Родитель);
ОсновнаяСтруктура.Вставить("parent", СтруктураРодителя);
КонецПроцедуры
Процедура ДобавитьРодителяБазы(Знач Родитель, Знач РодительБаза, ОсновнаяСтруктура)
ПреобразоватьИД(Родитель);
ПолеИдентификатора = ?(РодительБаза, "database_id", "page_id");
СтруктураРодителя = Новый Структура();
СтруктураРодителя.Вставить("type" , ПолеИдентификатора);
СтруктураРодителя.Вставить(ПолеИдентификатора, Родитель);
ОсновнаяСтруктура.Вставить("parent", СтруктураРодителя);
КонецПроцедуры
Процедура ДобавитьЗаголовокСтраницы(Знач Заголовок, ОсновнаяСтруктура)
ПодчиненнаяСтруктура = Новый Структура;
СтруктураДанных = Новый Структура;
СтруктураТекста = Новый Структура;
МассивДанных = Новый Массив;
Title = "title";
СтруктураТекста.Вставить("content", Заголовок);
СтруктураТекста.Вставить("link" , Неопределено);
СтруктураДанных.Вставить("text", СтруктураТекста);
СтруктураДанных.Вставить("type", "text");
МассивДанных.Добавить(СтруктураДанных);
ПодчиненнаяСтруктура.Вставить("id" , Title);
ПодчиненнаяСтруктура.Вставить("type" , Title);
ПодчиненнаяСтруктура.Вставить(Title , МассивДанных);
ОсновнаяСтруктура.Вставить(Title, ПодчиненнаяСтруктура);
КонецПроцедуры
Процедура ДобавитьЗаголовокБазы(Знач Заголовок, ОсновнаяСтруктура)
Заголовок = ПреобразоватьЗаголовок(Заголовок);
ОсновнаяСтруктура.Вставить("title", Заголовок["title"]);
КонецПроцедуры
Процедура ДобавитьОписаниеБазы(Знач Описание, ОсновнаяСтруктура)
Заголовок = ПреобразоватьЗаголовок(Описание);
ОсновнаяСтруктура.Вставить("description", Заголовок["title"]);
КонецПроцедуры
Процедура ДобавитьСвойстваБазы(Знач Свойства, ОсновнаяСтруктура)
Если Свойства.Количество() = 0 Тогда
ОсновнаяСтруктура.Вставить("properties", Новый Структура);
Возврат;
КонецЕсли;
СоответствиеПараметров = Новый Соответствие;
Для Каждого Свойство Из Свойства Цикл
Если ТипЗнч(Свойство.Значение) = Тип("Строка") Тогда
СоответствиеПараметров.Вставить(Свойство.Ключ, Новый Структура(Свойство.Значение, Новый Структура));
ИначеЕсли ТипЗнч(Свойство.Значение) = Тип("Структура")
Или ТипЗнч(Свойство.Значение) = Тип("Соответствие") Тогда
ВыборЗначения = СформироватьЗначенияВыбора(Свойство.Значение);
СоответствиеПараметров.Вставить(Свойство.Ключ, Новый Структура("select", ВыборЗначения));
Иначе
СоответствиеПараметров.Вставить(Свойство.Ключ, Свойство.Значение);
КонецЕсли;
КонецЦикла;
ОсновнаяСтруктура.Вставить("properties", СоответствиеПараметров);
КонецПроцедуры
Функция СформироватьЗначенияВыбора(Знач СтруктураВариантов)
МассивВариантов = Новый Массив;
Для Каждого Вариант Из СтруктураВариантов Цикл
СоответствиеВарианта = Новый Соответствие;
СоответствиеВарианта.Вставить("name" , Вариант.Ключ);
СоответствиеВарианта.Вставить("color", Вариант.Значение);
МассивВариантов.Добавить(СоответствиеВарианта);
КонецЦикла;
Возврат Новый Структура("options", МассивВариантов);
КонецФункции
Функция ЗаполнитьДанныеПоСхеме(Знач Схема, Знач Данные, Знач Токен, Знач ЭтоБаза = Истина)
Если ЭтоБаза Тогда
ДанныеСхемы = ПолучитьБазуДанных(Токен, Схема);
Иначе
ДанныеСхемы = ПолучитьСтраницу(Токен, Схема);
КонецЕсли;
ПоляБазы = ДанныеСхемы["properties"];
Свойства = Новый Соответствие;
Если ЗначениеЗаполнено(ПоляБазы) Тогда
Для Каждого Поле Из ПоляБазы Цикл
ДанныеПоля = Поле.Значение;
ТипПоля = ДанныеПоля["type"];
ЗаполняемыеДанные = Данные.Получить(Поле.Ключ);
Если ЗаполняемыеДанные = Неопределено Тогда
Продолжить;
КонецЕсли;
ПреобразованныеДанные = ПреобразоватьЗначениеПоТипу(ТипПоля, ЗаполняемыеДанные);
Если ПреобразованныеДанные = Неопределено Тогда
Продолжить;
КонецЕсли;
Свойства.Вставить(ДанныеПоля["id"], ПреобразованныеДанные);
КонецЦикла;
КонецЕсли;
Возврат Свойства;
КонецФункции
Процедура УдалитьЛишниеПоляБлока(Знач Блок)
МассивЛишних = Новый Массив;
МассивЛишних.Добавить("request_id");
МассивЛишних.Добавить("archived");
МассивЛишних.Добавить("created_by");
МассивЛишних.Добавить("last_edited_time");
МассивЛишних.Добавить("created_time");
МассивЛишних.Добавить("has_children");
МассивЛишних.Добавить("parrent");
МассивЛишних.Добавить("last_edited_by");
МассивЛишних.Добавить("id");
Для Каждого Поле Из МассивЛишних Цикл
Если Не Блок.Получить(Поле) = Неопределено Тогда
Блок.Удалить(Поле);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#Область ПреобразованиеТипов
Функция ПреобразоватьЗначениеПоТипу(Знач Тип, Знач Значение)
Если Тип = "title" Тогда
Возврат ПреобразоватьЗаголовок(Значение);
ИначеЕсли Тип = "rich_text" Тогда
Возврат ПреобразоватьТекст(Значение);
ИначеЕсли Тип = "number" Тогда
Возврат ПреобразоватьЧисло(Значение);
ИначеЕсли Тип = "select" Тогда
Возврат ПреобразоватьВариантВыбора(Значение);
ИначеЕсли Тип = "multi_select" Тогда
Возврат ПреобразоватьМножественныйВыбор(Значение);
ИначеЕсли Тип = "status" Тогда
Возврат ПреобразоватьСтатус(Значение);
ИначеЕсли Тип = "date" Тогда
Возврат ПреобразоватьДату(Значение);
ИначеЕсли Тип = "relation" Тогда
Возврат ПреобразоватьСвязь(Значение);
ИначеЕсли Тип = "people" Тогда
Возврат ПреобразоватьПользователей(Значение);
ИначеЕсли Тип = "files" Тогда
Возврат ПреобразоватьФайлы(Значение);
ИначеЕсли Тип = "checkbox" Тогда
Возврат ПреобразоватьБулево(Значение);
ИначеЕсли Тип = "url" Тогда
Возврат ПреобразоватьСсылку(Значение);
ИначеЕсли Тип = "email" Тогда
Возврат ПреобразоватьПочту(Значение);
ИначеЕсли Тип = "phone_number" Тогда
Возврат ПреобразоватьТелефон(Значение);
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция ПреобразоватьЗаголовок(Знач Заголовок)
СтруктураДанных = Новый Структура;
СтруктураТекста = Новый Структура;
МассивДанных = Новый Массив;
СтруктураТекста.Вставить("content", Заголовок);
СтруктураТекста.Вставить("link" , Неопределено);
СтруктураДанных.Вставить("type", "text");
СтруктураДанных.Вставить("text", СтруктураТекста);
МассивДанных.Добавить(СтруктураДанных);
Возврат Новый Структура("title", МассивДанных);
КонецФункции
Функция ПреобразоватьТекст(Знач Текст)
МассивТекста = Новый Массив;
СтруктураТекста = Новый Структура;
СтруктураТекста.Вставить("type", "text");
СтруктураТекста.Вставить("text", Новый Структура("content", Текст));
МассивТекста.Добавить(СтруктураТекста);
Возврат Новый Структура("rich_text", МассивТекста);
КонецФункции
Функция ПреобразоватьЧисло(Знач Число)
Возврат Новый Структура("number", Число);
КонецФункции
Функция ПреобразоватьВариантВыбора(Знач Вариант)
СтруктураВыбора = Новый Структура;
СтруктураВыбора.Вставить("select", Новый Структура("name", Вариант));
Возврат СтруктураВыбора;
КонецФункции
Функция ПреобразоватьСтатус(Знач Статус)
СтруктураСтатуса = Новый Структура;
СтруктураСтатуса.Вставить("status", Новый Структура("name", Статус));
Возврат СтруктураСтатуса;
КонецФункции
Функция ПреобразоватьМножественныйВыбор(Знач МассивВариантов)
МассивВариантовВыбора = Новый Массив;
Для Каждого Вариант Из МассивВариантов Цикл
МассивВариантовВыбора.Добавить(Новый Структура("name", Вариант));
КонецЦикла;
Возврат Новый Структура("multi_select", МассивВариантовВыбора);
КонецФункции
Функция ПреобразоватьДату(Знач Дата)
СтруктураДаты = Новый Структура;
Если Дата = НачалоДня(Дата) Тогда
ФорматДаты = "ДФ=yyyy-MM-dd";
Иначе
ФорматДаты = "ДФ=yyyy-MM-ddThh:mm:ssZ";
КонецЕсли;
Дата = Формат(Дата, ФорматДаты);
СтруктураДаты.Вставить("start", Дата);
Возврат Новый Структура("date", СтруктураДаты);
КонецФункции
Функция ПреобразоватьСвязь(Знач Идентификатор)
МассивСвязи = Новый Массив;
МассивСвязи.Добавить(Новый Структура("id", Идентификатор));
Возврат Новый Структура("relation", МассивСвязи);
КонецФункции
Функция ПреобразоватьПользователей(Знач МассивИД)
Если Не ТипЗнч(МассивИД) = Тип("Массив") Тогда
МассивИД_ = Новый Массив;
МассивИД_.Добавить(МассивИД);
МассивИД = МассивИД_;
КонецЕсли;
МассивПользователей = Новый Массив;
Для Каждого Идентификатор Из МассивИД Цикл
СтруктураПользователя = Новый Структура;
СтруктураПользователя.Вставить("object", "user");
СтруктураПользователя.Вставить("id" , Идентификатор);
МассивПользователей.Добавить(СтруктураПользователя);
КонецЦикла;
Возврат Новый Структура("people", МассивПользователей);
КонецФункции
Функция ПреобразоватьФайлы(Знач СоответствиеФайлов)
МассивФайлов = Новый Массив;
Для Каждого Файл Из СоответствиеФайлов Цикл
СтруктураФайла = Новый Структура;
СтруктураФайла.Вставить("type" , "external");
СтруктураФайла.Вставить("name" , Файл.Ключ);
СтруктураФайла.Вставить("external", Новый Структура("url", Файл.Значение));
МассивФайлов.Добавить(СтруктураФайла);
КонецЦикла;
Возврат Новый Структура("files", МассивФайлов);
КонецФункции
Функция ПреобразоватьБулево(Знач Булево)
Возврат Новый Структура("checkbox", Булево);
КонецФункции
Функция ПреобразоватьСсылку(Знач URL)
Возврат Новый Структура("url", URL);
КонецФункции
Функция ПреобразоватьПочту(Знач Почта)
Возврат Новый Структура("email", Почта);
КонецФункции
Функция ПреобразоватьТелефон(Знач Телефон)
Возврат Новый Структура("phone_number", Телефон);
КонецФункции
#КонецОбласти
#КонецОбласти

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,610 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// Если в не знаете с чего начать, то стоит найти метод ПолучитьСтандартныеПараметры()
// и почитать комментарии
// BSLLS:Typo-off
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
#Область ДанныеИНастройка
// Получить ссылку для авторизации через браузер.
//
// Параметры:
// Параметры - Соответствие Из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка - URL для перехода в браузере
Функция ПолучитьСсылкуАвторизации(Параметры = "") Экспорт
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
ПараметрыURL = Новый Структура;
ПараметрыURL.Вставить("response_type" , "code");
ПараметрыURL.Вставить("client_id" , Параметры_["client_id"]);
ПараметрыURL.Вставить("redirect_uri" , Параметры_["redirect_uri"]);
ПараметрыURL.Вставить("scope" , Параметры_["scope"]);
ПараметрыURL.Вставить("state" , "state");
ПараметрыURL.Вставить("code_challenge" , "challenge");
ПараметрыURL.Вставить("code_challenge_method", "plain");
Линк = "https://twitter.com/i/oauth2/authorize"
+ OPI_Инструменты.ПараметрыЗапросаВСтроку(ПараметрыURL);
Возврат Линк;
КонецФункции
// Получить токен.
//
// Параметры:
// Код - Строка - Код, полученный из авторизации См.ПолучитьСсылкуАвторизации
// Параметры - Соответствие Из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// HTTPОтвет, Произвольный, ДвоичныеДанные - Результат чтения JSON ответа сервера
Функция ПолучитьТокен(Знач Код, Знач Параметры = "") Экспорт
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить("code" , Код);
ПараметрыЗапроса.Вставить("grant_type" , "authorization_code");
ПараметрыЗапроса.Вставить("client_id" , Параметры_["client_id"]);
ПараметрыЗапроса.Вставить("redirect_uri" , Параметры_["redirect_uri"]);
ПараметрыЗапроса.Вставить("code_verifier", "challenge");
Ответ = OPI_Инструменты.Post("https://api.twitter.com/2/oauth2/token"
, ПараметрыЗапроса, , Ложь);
Возврат Ответ;
КонецФункции
// Обновить токен v2 токен при помощи refresh_token
//
// Параметры:
// Параметры - Соответствие Из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// HTTPОтвет, Произвольный, ДвоичныеДанные - Результат чтения JSON ответа сервера
Функция ОбновитьТокен(Знач Параметры = "") Экспорт
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
Refresh = "refresh_token";
ПараметрыЗапроса = Новый Структура;
ПараметрыЗапроса.Вставить(Refresh , Параметры_[Refresh]);
ПараметрыЗапроса.Вставить("grant_type" , Refresh);
ПараметрыЗапроса.Вставить("client_id" , Параметры_["client_id"]);
Ответ = OPI_Инструменты.Post("https://api.twitter.com/2/oauth2/token"
, ПараметрыЗапроса, , Ложь);
Возврат Ответ;
КонецФункции
// Метод для вставки в http-сервис, адрес которого указывается в redirect_uri
// Вызывает метод получения токена, так как для получения токена из кода, приходящего
// на redirect_uri после авторизации через браузер есть всего 30 секунд
//
// Параметры:
// Запрос - HTTPСервисЗапрос - Запрос, приходящий на http-сервис
//
// Возвращаемое значение:
// HTTPОтвет, Произвольный, ДвоичныеДанные - Результат чтения JSON ответа сервера
Функция ОбработкаВходящегоЗапросаПослеАвторизации(Запрос) Экспорт
Код = Запрос.ПараметрыЗапроса["code"];
ОтветТокен = ПолучитьТокен(Код);
// BSLLS:CommentedCode-off
// Предпочтительное хранение токенов
// Константы.TwitterRefresh.Установить(ОтветТокен["refresh_token"]);
// Константы.TwitterToken.Установить(ОтветТокен["access_token"]);
// BSLLS:CommentedCode-on
Возврат ОтветТокен;
КонецФункции
#КонецОбласти
#Область Твиты
// Создать произвольный твит.
//
// Параметры:
// Текст - Строка - Текст твита
// МассивМедиа - Массив из Строка,ДвоичныеДанные - Массив двоичных данных или путей к файлам
// МассивВариантовОпроса - Массив из Строка - Массив вариантов опроса, если необходимо
// ДлительностьОпроса - Строка,Число - Длительность опроса, если необходимо (опрос без длительности не создается)
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Создать произвольный твит
//@skip-check method-too-many-params
// BSLLS:NumberOfOptionalParams-off
Функция СоздатьПроизвольныйТвит(Знач Текст = ""
, Знач МассивМедиа = ""
, Знач МассивВариантовОпроса = ""
, Знач ДлительностьОпроса = ""
, Знач Параметры = "") Экспорт
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
URL = "https://api.twitter.com/2/tweets";
Массив = "Массив";
Если Не ТипЗнч(МассивМедиа) = Тип(Массив) Тогда
МассивМедиа_ = Новый Массив;
Если ЗначениеЗаполнено(МассивМедиа) Тогда
МассивМедиа_.Добавить(МассивМедиа);
КонецЕсли;
МассивМедиа = МассивМедиа_;
КонецЕсли;
Поля = Новый Соответствие;
Если ЗначениеЗаполнено(Текст) Тогда
Поля.Вставить("text", Текст);
КонецЕсли;
Если ТипЗнч(МассивВариантовОпроса) = Тип(Массив) И ЗначениеЗаполнено(ДлительностьОпроса) Тогда
ДлительностьОпроса = Число(ДлительностьОпроса);
Если МассивВариантовОпроса.Количество() > 0 Тогда
Поля.Вставить("poll"
, Новый Структура("options,duration_minutes", МассивВариантовОпроса, ДлительностьОпроса));
КонецЕсли;
КонецЕсли;
Если ТипЗнч(МассивМедиа) = Тип(Массив) Тогда
Если МассивМедиа.Количество() > 0 Тогда
Поля.Вставить("media", Новый Структура("media_ids", МассивМедиа));
КонецЕсли;
КонецЕсли;
Авторизация = СоздатьЗаголовокАвторизацииV2(Параметры_);
Ответ = OPI_Инструменты.Post(URL, Поля, Авторизация);
Возврат Ответ;
КонецФункции
// BSLLS:NumberOfOptionalParams-on
// Создать текстовый твит.
//
// Параметры:
// Текст - Строка - Текст твита
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Создать текстовый твит
Функция СоздатьТекстовыйТвит(Знач Текст, Знач Параметры = "") Экспорт
Возврат СоздатьПроизвольныйТвит(Текст, , , , Параметры);
КонецФункции
// Создать твит картинки.
//
// Параметры:
// Текст - Строка - Текст твита
// МассивКартинок - Массив из Строка,ДвоичныеДанные - Массив двоичных данных или путей к картинкам
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Создать твит картинки
Функция СоздатьТвитКартинки(Знач Текст, Знач МассивКартинок, Знач Параметры = "") Экспорт
МассивМедиа = ЗагрузитьМассивВложений(МассивКартинок, "tweet_image", Параметры);
Возврат СоздатьПроизвольныйТвит(Текст, МассивМедиа, , , Параметры);
КонецФункции
// Создать твит гифки.
//
// Параметры:
// Текст - Строка - Текст твита
// МассивГифок - Массив из Строка,ДвоичныеДанные - Массив двоичных данных или путей к гифкам
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Создать твит гифки
Функция СоздатьТвитГифки(Знач Текст, Знач МассивГифок, Знач Параметры = "") Экспорт
МассивМедиа = ЗагрузитьМассивВложений(МассивГифок, "tweet_gif", Параметры);
Возврат СоздатьПроизвольныйТвит(Текст, МассивМедиа, , , Параметры);
КонецФункции
// Создать твит видео.
//
// Параметры:
// Текст - Строка - Текст твита
// МассивВидео - Массив из Строка,ДвоичныеДанные - Массив двоичных данных или путей к видео
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Создать твит видео
Функция СоздатьТвитВидео(Знач Текст, Знач МассивВидео, Знач Параметры = "") Экспорт
МассивМедиа = ЗагрузитьМассивВложений(МассивВидео, "tweet_video", Параметры);
Возврат СоздатьПроизвольныйТвит(Текст, МассивМедиа, , , Параметры);
КонецФункции
// Создать твит опрос.
//
// Параметры:
// Текст - Строка - Текст твита
// МассивВариантов - Массив из Строка - Массив вариантов опроса
// Длительность - Строка,Число - Длительность опроса
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Создать твит опрос
Функция СоздатьТвитОпрос(Знач Текст, Знач МассивВариантов, Знач Длительность, Знач Параметры = "") Экспорт
Возврат СоздатьПроизвольныйТвит(Текст, , МассивВариантов, Длительность, Параметры);
КонецФункции
// Загрузить массив вложений.
//
// Параметры:
// МассивФайлов - Массив из Строка, ДвоичныеДанные - Массив файлов
// ТипВложений - Строка - Тип вложений
// Параметры - Соответствие из Строка - См.ПолучитьСтандартныеПараметры
//
// Возвращаемое значение:
// Массив Из Строка - Массив ID медиа
Функция ЗагрузитьМассивВложений(Знач МассивФайлов, Знач ТипВложений, Знач Параметры = "") Экспорт
МассивМедиа = Новый Массив;
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
MIS = "media_id_string";
Если ЗначениеЗаполнено(МассивФайлов) Тогда
Если Не ТипЗнч(МассивФайлов) = Тип("Массив") Тогда
МассивФайлов_ = Новый Массив;
МассивФайлов_.Добавить(МассивФайлов);
МассивФайлов = МассивФайлов_;
КонецЕсли;
Для Каждого ФайлОтправки Из МассивФайлов Цикл
Если Не ТипЗнч(ФайлОтправки) = Тип("ДвоичныеДанные") Тогда
ФайлОтправки = Новый ДвоичныеДанные(ФайлОтправки);
КонецЕсли;
IDМедиа = ЗагрузитьМедиафайл(ФайлОтправки, ТипВложений, Параметры_)[MIS];
МассивМедиа.Добавить(IDМедиа);
КонецЦикла;
КонецЕсли;
Возврат МассивМедиа;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ЗагрузитьМедиафайл(Знач Файл, Знач Тип, Знач Параметры)
ProcessingInfo = "processing_info";
MediaKey = "media_key";
MIS = "media_id_string";
Command = "command";
ВидЗапроса = "POST";
Единица = 1024;
Количество = 4;
СоответствиеMIME = Новый Соответствие;
СоответствиеMIME.Вставить("tweet_image", "image/jpeg");
СоответствиеMIME.Вставить("tweet_video", "video/mp4");
СоответствиеMIME.Вставить("tweet_gif" , "image/gif");
Если Не ТипЗнч(Файл) = Тип("ДвоичныеДанные") Тогда
Файл = Новый ДвоичныеДанные(Файл);
КонецЕсли;
Параметры_ = ПолучитьСтандартныеПараметры(Параметры);
URL = "https://upload.twitter.com/1.1/media/upload.json";
Размер = Файл.Размер();
Если Тип = "tweet_image" Тогда
Поля = Новый Структура;
Поля.Вставить("media_data" , Base64Строка(Файл));
Поля.Вставить("media_category", Тип);
Авторизация = СоздатьЗаголовокАвторизацииV1(Параметры_, Поля, ВидЗапроса, URL);
Ответ = OPI_Инструменты.Post(URL, Поля, Авторизация, Ложь);
Иначе
ЧтениеДанных = Новый ЧтениеДанных(Файл);
МассивЧтения = ЧтениеДанных.РазделитьНаЧастиПо(Количество * Единица * Единица);
Поля = Новый Структура;
Поля.Вставить(Command , "INIT");
Поля.Вставить("total_bytes" , OPI_Инструменты.ЧислоВСтроку(Размер));
Поля.Вставить("media_type" , СоответствиеMIME.Получить(Тип));
Поля.Вставить("media_category" , Тип);
Авторизация = СоздатьЗаголовокАвторизацииV1(Параметры_, Поля, ВидЗапроса, URL);
ОтветИнициализации = OPI_Инструменты.Post(URL, Поля, Авторизация, Ложь);
KeyИнициализации = ОтветИнициализации[MediaKey];
IDИнициализации = ОтветИнициализации[MIS];
Счетчик = 0;
Для Каждого Часть Из МассивЧтения Цикл
ДвоичныеЧасти = Часть.ПолучитьДвоичныеДанные();
Поля = Новый Структура;
Поля.Вставить(Command , "APPEND");
Поля.Вставить("media_key" , KeyИнициализации);
Поля.Вставить("segment_index" , OPI_Инструменты.ЧислоВСтроку(Счетчик));
Поля.Вставить("media" , ДвоичныеЧасти);
Авторизация = СоздатьЗаголовокАвторизацииV1(Параметры_, Новый Структура, ВидЗапроса, URL);
OPI_Инструменты.PostMultipart(URL, Поля, , , Авторизация);
Счетчик = Счетчик + 1;
КонецЦикла;
Поля = Новый Структура;
Поля.Вставить(Command , "FINALIZE");
Поля.Вставить("media_id", IDИнициализации);
Авторизация = СоздатьЗаголовокАвторизацииV1(Параметры_, Поля, ВидЗапроса, URL);
Ответ = OPI_Инструменты.Post(URL, Поля, Авторизация, Ложь);
СтатусОбработки = Ответ[ProcessingInfo]["state"];
Поля = Новый Структура;
Поля.Вставить(Command , "STATUS");
Поля.Вставить("media_id", IDИнициализации);
Пока Строка(СтатусОбработки) = "pending" Или Строка(СтатусОбработки) = "in_progress" Цикл
Авторизация = СоздатьЗаголовокАвторизацииV1(Параметры_, Поля, "GET", URL);
Ответ = OPI_Инструменты.Get(URL, Поля, Авторизация);
СтатусОбработки = Ответ[ProcessingInfo]["state"];
КонецЦикла;
Если СтатусОбработки = "failed" Тогда
ВызватьИсключение "Твиттер не смог обработать загруженное вами видео";
КонецЕсли;
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ПолучитьСтандартныеПараметры(Знач Параметры = "")
// Здесь собрано определение данных, необходимых для работы.
// Для Twitter это довольно значительный набор, что обсуловлено наличием сразу 2-х API,
// которые, при этом, созданы не для разныз задач, но просто являются версиями друг друга.
// Актуальной версией API является v2 и она требует получения временных токенов. Несмотря на то,
// что Twitter настаивает на использовании этой актуальной версии, они как-то умудрились не перенести
// механизм загрузки файлов и некоторые другие из старой версии - v1.1. Поэтому что-то нужно делать
// на версии 1.1, а что-то на 2: вплоть до того что они убрали возможность постить твиты из v1.1,
// но только через нее в твит можно добавить картинку. При этом способы авторизации и токены у них разные
// Мировая гигокорпорация Илона Маска, кстати, напоминаю ;)
// P.S Далее часто упоминается "страница настроек Twitter Developer" - это
// https://developer.twitter.com/en/portal/dashboard и выбор конкретного проекта из списка (значек c ключем)
Параметры_ = Новый Соответствие;
Разрешения = "tweet.read tweet.write tweet.moderate.write users.read "
+ "follows.read follows.write offline.access space.read mute.read "
+ "mute.write like.read like.write list.read list.write block.read "
+ "block.write bookmark.read bookmark.write";
// Данные для API v2
// redirect_uri - URL вашего http-сервиса (или другого обработчика запросов) для авторизации
// scope - набор разрешений для получаемого ключа. Может быть любой, но offline.access обязателен
// client_id - Из OAuth 2.0 Client ID and Client Secret страницы настроек Twitter Developer
// client_secret - Из OAuth 2.0 Client ID and Client Secret страницы настроек Twitter Developer
// access_token - ПолучитьСсылкуАвторизации() -> Браузер -> code придет на redirect_uri -> ПолучитьТокен(code)
// refresh_token - Приходит вместе с access_token и используется для его обновления (время жизни access_token - 2 ч)
// Обновление происходит методом ОбновитьТокен с новыми access_token и refresh_token.
// При следующем обновлении нужно использовать уже новый refresh_token, так что захардкодить
// не получится (access_token тоже не получится)
// |--> ОбновитьТокен() ->|access_token --> Используется в т-нии 2-х часов для запросов
// | |refresh_token --|
// |--------[через 2 ч.]-------------------|
// Данные для API v1.1
// oauth_token - из Authentication Tokens -> Access Token and Secret страницы настроек Twitter Developer
// oauth_token_secret - из Authentication Tokens -> Access Token and Secret страницы настроек Twitter Developer
// oauth_consumer_key - из Consumer Keys -> Access Token and Secret страницы настроек Twitter Developer
// oauth_consumer_secret - из Consumer Keys -> Access Token and Secret страницы настроек Twitter Developer
// Эти токены обновлять не надо
Параметры_.Вставить("redirect_uri" , "");
Параметры_.Вставить("scope" , Разрешения);
Параметры_.Вставить("client_id" , "");
Параметры_.Вставить("client_secret" , "");
Параметры_.Вставить("access_token" , ""); // Должно быть нечто вроде Константы.TwitterToken.Получить()
Параметры_.Вставить("refresh_token" , ""); // Должно быть нечто вроде Константы.TwitterRefresh.Получить()
Параметры_.Вставить("oauth_token" , "");
Параметры_.Вставить("oauth_token_secret" , "");
Параметры_.Вставить("oauth_consumer_key" , "");
Параметры_.Вставить("oauth_consumer_secret", "");
Если ТипЗнч(Параметры) = Тип("Структура") Или ТипЗнч(Параметры) = Тип("Соответствие") Тогда
Для Каждого ПереданныйПараметр Из Параметры Цикл
Параметры_.Вставить(ПереданныйПараметр.Ключ, OPI_Инструменты.ЧислоВСтроку(ПереданныйПараметр.Значение));
КонецЦикла;
КонецЕсли;
Возврат Параметры_;
КонецФункции
// BSLLS:LatinAndCyrillicSymbolInWord-off
Функция СоздатьЗаголовокАвторизацииV1(Знач Параметры, Знач Поля, Знач ВидЗапроса, Знач URL)
ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДата();
ЗаголовокАвторизации = "";
МетодХэширования = "HMAC-SHA1";
ВерсияАпи = "1.0";
СтрокаСигнатуры = "";
Подпись = "";
OCK = "oauth_consumer_key";
OTK = "oauth_token";
ТекущаяДатаUNIX = OPI_Инструменты.UNIXTime(ТекущаяДата);
ТекущаяДатаUNIX = OPI_Инструменты.ЧислоВСтроку(ТекущаяДатаUNIX);
ТаблицаПараметров = Новый ТаблицаЗначений;
ТаблицаПараметров.Колонки.Добавить("Ключ");
ТаблицаПараметров.Колонки.Добавить("Значение");
Для Каждого Поле Из Поля Цикл
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = Поле.Ключ;
НоваяСтрока.Значение = Поле.Значение;
КонецЦикла;
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = OCK;
НоваяСтрока.Значение = Параметры[OCK];
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = OTK;
НоваяСтрока.Значение = Параметры[OTK];
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = "oauth_version";
НоваяСтрока.Значение = ВерсияАпи;
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = "oauth_signature_method";
НоваяСтрока.Значение = МетодХэширования;
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = "oauth_timestamp";
НоваяСтрока.Значение = ТекущаяДатаUNIX;
НоваяСтрока = ТаблицаПараметров.Добавить();
НоваяСтрока.Ключ = "oauth_nonce";
НоваяСтрока.Значение = ТекущаяДатаUNIX;
Для Каждого СтрокаТаблицы Из ТаблицаПараметров Цикл
СтрокаТаблицы.Ключ = КодироватьСтроку(СтрокаТаблицы.Ключ, СпособКодированияСтроки.КодировкаURL);
СтрокаТаблицы.Значение = КодироватьСтроку(СтрокаТаблицы.Значение, СпособКодированияСтроки.КодировкаURL);
КонецЦикла;
ТаблицаПараметров.Сортировать("Ключ");
Для Каждого СтрокаТаблицы Из ТаблицаПараметров Цикл
СтрокаСигнатуры = СтрокаСигнатуры
+ СтрокаТаблицы.Ключ
+ "="
+ СтрокаТаблицы.Значение
+ "&";
КонецЦикла;
СтрокаСигнатуры = Лев(СтрокаСигнатуры, СтрДлина(СтрокаСигнатуры) - 1);
СтрокаСигнатуры = вРег(ВидЗапроса)
+ "&"
+ КодироватьСтроку(URL, СпособКодированияСтроки.КодировкаURL)
+ "&"
+ КодироватьСтроку(СтрокаСигнатуры, СпособКодированияСтроки.КодировкаURL);
Подпись = КодироватьСтроку(Параметры["oauth_consumer_secret"], СпособКодированияСтроки.КодировкаURL)
+ "&"
+ КодироватьСтроку(Параметры["oauth_token_secret"], СпособКодированияСтроки.КодировкаURL);
Сигнатура = OPI_Криптография.HMAC(ПолучитьДвоичныеДанныеИзСтроки(Подпись)
, ПолучитьДвоичныеДанныеИзСтроки(СтрокаСигнатуры)
, ХешФункция.SHA1
, 64);
Сигнатура = КодироватьСтроку(Base64Строка(Сигнатура), СпособКодированияСтроки.КодировкаURL);
Разделитель = """,";
ЗаголовокАвторизации = ЗаголовокАвторизации
+ "OAuth "
+ "oauth_consumer_key=""" + Параметры[OCK] + Разделитель
+ "oauth_token=""" + Параметры[OTK] + Разделитель
+ "oauth_signature_method=""" + МетодХэширования + Разделитель
+ "oauth_timestamp=""" + ТекущаяДатаUNIX + Разделитель
+ "oauth_nonce=""" + ТекущаяДатаUNIX + Разделитель
+ "oauth_version=""" + ВерсияАпи + Разделитель
+ "oauth_signature=""" + Сигнатура;
СоответствиеЗаголовка = Новый Соответствие;
СоответствиеЗаголовка.Вставить("authorization", ЗаголовокАвторизации);
Возврат СоответствиеЗаголовка;
КонецФункции
Функция СоздатьЗаголовокАвторизацииV2(Знач Параметры)
СоответствиеВозврата = Новый Соответствие;
СоответствиеВозврата.Вставить("Authorization", "Bearer " + Параметры["access_token"]);
Возврат СоответствиеВозврата;
КонецФункции
// BSLLS:LatinAndCyrillicSymbolInWord-on
#КонецОбласти
// BSLLS:Typo-on

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,409 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
#Область НастройкиИИнформация
// ВАЖНО: Установка Webhook обязательна по правилам Viber. Для этого надо иметь свободный URL,
// который будет возвращать 200 и подлинный SSL сертификат. Если есть сертификат и база опубликована
// на сервере - можно использовать http-сервис. Туда же будет приходить и информация о новых сообщениях
// Viber периодически стучит по адресу Webhook, так что если он будет неактивен, то все перестанет работать
//
// Параметры:
// Токен - Строка - Токен Viber
// URL - Строка - URL для установки Webhook
//
// Возвращаемое значение:
// Произвольный - Ответ сервера Viber
Функция УстановитьWebhook(Знач Токен, Знач URL) Экспорт
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("url" , URL);
СтруктураПараметров.Вставить("auth_token", Токен);
Возврат OPI_Инструменты.Post("https://chatapi.viber.com/pa/set_webhook"
, СтруктураПараметров);
КонецФункции
// Тут можно получить ID пользователей канала. ID для бота необходимо получать из прилетов на Webhook
// ID пользователя из информации о канале не подойдет для отправки сообщений через бота - они разные
//
// Параметры:
// Токен - Строка - Токен
//
// Возвращаемое значение:
// ДвоичныеДанные, Неопределено, Произвольный - Получить информацию о канале
Функция ПолучитьИнформациюОКанале(Знач Токен) Экспорт
Возврат OPI_Инструменты.Get("https://chatapi.viber.com/pa/get_account_info"
,
, ТокенВЗаголовки(Токен));
КонецФункции
// Получить данные пользователя.
//
// Параметры:
// Токен - Строка - Токен
// IDПользователя - Строка, Число - ID пользователя Viber
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ПолучитьДанныеПользователя(Знач Токен, Знач IDПользователя) Экспорт
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("id", IDПользователя);
Ответ = OPI_Инструменты.Post("https://chatapi.viber.com/pa/get_user_details"
, СтруктураПараметров
, ТокенВЗаголовки(Токен));
Попытка
Возврат OPI_Инструменты.JsonВСтруктуру(Ответ.ПолучитьТелоКакДвоичныеДанные());
Исключение
Возврат Ответ;
КонецПопытки;
КонецФункции
// Получить онлайн пользователей.
//
// Параметры:
// Токен - Строка - Токен Viber
// IDПользователей - Строка,Число,Массив из Строка,Число - ID пользователей(-я) Viber
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ПолучитьОнлайнПользователей(Знач Токен, Знач IDПользователей) Экспорт
Если Не ТипЗнч(IDПользователей) = Тип("Массив") Тогда
ОдиночныйID = IDПользователей;
IDПользователей = Новый Массив;
IDПользователей.Добавить(ОдиночныйID);
КонецЕсли;
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("ids", IDПользователей);
Ответ = OPI_Инструменты.Post("https://chatapi.viber.com/pa/get_online"
, СтруктураПараметров
, ТокенВЗаголовки(Токен));
Попытка
Возврат OPI_Инструменты.JsonВСтруктуру(Ответ.ПолучитьТелоКакДвоичныеДанные());
Исключение
Возврат Ответ;
КонецПопытки;
КонецФункции
#КонецОбласти
#Область ОтправкаСообщений
// Отправить текстовое сообщение.
//
// Параметры:
// Токен - Строка - Токен
// Текст - Строка - Текст сообщения
// IDПользователя - Строка,Число - ID пользователя Viber
// ОтправкаВКанал - Булево - Отправка в канал или в чат бота
// Клавиатура - Структура из Строка - См. СформироватьКлавиатуруИзМассиваКнопок
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ОтправитьТекстовоеСообщение(Знач Токен
, Знач Текст
, Знач IDПользователя
, Знач ОтправкаВКанал
, Знач Клавиатура = "") Экспорт
Возврат ОтправитьСообщение(Токен, "text", IDПользователя, ОтправкаВКанал, , Текст, Клавиатура);
КонецФункции
// Отправить картинку.
//
// Параметры:
// Токен - Строка - Токен
// URL - Строка - URL картинки
// IDПользователя - Строка,Число - ID пользователя Viber
// ОтправкаВКанал - булево - Отправка в канал или в чат бота
// Описание - Строка - Аннотация к картинке
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ОтправитьКартинку(Знач Токен, Знач URL, Знач IDПользователя, Знач ОтправкаВКанал, Знач Описание = "") Экспорт
Возврат ОтправитьСообщение(Токен, "picture", IDПользователя, ОтправкаВКанал, URL, Описание);
КонецФункции
// Отправить файл.
//
// Параметры:
// Токен - Строка - Токен
// URL - Строка - URL
// IDПользователя - Строка,Число - ID пользователя Viber
// ОтправкаВКанал - Булево - Отправка в канал или в чат бота
// Расширение - Строка - Расширение файла
// Размер - Число - Размер файла. Если не заполнен - определяется автоматически, но при этом происходит скачивание
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ОтправитьФайл(Знач Токен
, Знач URL
, Знач IDПользователя
, Знач ОтправкаВКанал
, Знач Расширение
, Знач Размер = "") Экспорт
Если Не ЗначениеЗаполнено(Размер) Тогда
Ответ = OPI_Инструменты.Get(URL);
ИВФ = ПолучитьИмяВременногоФайла(Расширение);
Ответ.Записать(ИВФ);
ВремФайл = Новый Файл(ИВФ);
Размер = ВремФайл.Размер();
УдалитьФайлы(ИВФ);
КонецЕсли;
Расширение = СтрЗаменить(Расширение, ".", "");
СтруктураЗначения = Новый Структура;
СтруктураЗначения.Вставить("URL" , URL);
СтруктураЗначения.Вставить("Размер" , Размер);
СтруктураЗначения.Вставить("Расширение" , Расширение);
Возврат ОтправитьСообщение(Токен, "file", IDПользователя, ОтправкаВКанал, СтруктураЗначения);
КонецФункции
// Отправить контакт.
//
// Параметры:
// Токен - Строка - Токен
// ИмяКонтакта - Строка - Имя контакта
// НомерТелефона - Строка - Номер телефона
// IDПользователя - Строка - ID пользователя Viber
// ОтправкаВКанал - Булево - Отправка в канал или в чат бота
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ОтправитьКонтакт(Знач Токен
, Знач ИмяКонтакта
, Знач НомерТелефона
, Знач IDПользователя
, Знач ОтправкаВКанал) Экспорт
СтруктураКонтакта = Новый Структура;
СтруктураКонтакта.Вставить("name", ИмяКонтакта);
СтруктураКонтакта.Вставить("phone_number", Строка(НомерТелефона));
Возврат ОтправитьСообщение(Токен, "contact", IDПользователя, ОтправкаВКанал, СтруктураКонтакта);
КонецФункции
// Отправить локацию.
//
// Параметры:
// Токен - Строка - Токен
// Широта - Строка,Число - Географическая широта
// Долгота - Строка,Число - Географическая долгота
// IDПользователя - Строка,Число - ID пользователя Viber
// ОтправкаВКанал - Булево - Отправка в канал или чат-боту
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Отправить локацию
Функция ОтправитьЛокацию(Знач Токен, Знач Широта, Знач Долгота, Знач IDПользователя, Знач ОтправкаВКанал) Экспорт
СтруктураЛокации = Новый Структура;
СтруктураЛокации.Вставить("lat", OPI_Инструменты.ЧислоВСтроку(Широта));
СтруктураЛокации.Вставить("lon", OPI_Инструменты.ЧислоВСтроку(Долгота));
Возврат ОтправитьСообщение(Токен, "location", IDПользователя, ОтправкаВКанал, СтруктураЛокации);
КонецФункции
// Отправить ссылку.
//
// Параметры:
// Токен - Строка - Токен
// URL - Строка - Отправляемая ссылка
// IDПользователя - Строка,Число - IDПользователя
// ОтправкаВКанал - Булево - Отправка в канал или в чат боту
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Ответ сервера Viber
Функция ОтправитьСсылку(Знач Токен, Знач URL, Знач IDПользователя, Знач ОтправкаВКанал) Экспорт
Возврат ОтправитьСообщение(Токен, "url", IDПользователя, ОтправкаВКанал, URL);
КонецФункции
// Сформировать клавиатуру из массива кнопок.
//
// Параметры:
// МассивКнопок - Массив из Строка - Массив кнопок
// ЦветКнопок - Строка - HEX цвет кнопок с # в начале
//
// Возвращаемое значение:
// Структура - Сформировать клавиатуру из массива кнопок:
// * Buttons - Массив из Структура - Массив сформированных кнопок
// * Type - Строка - Тип клавиатуры
Функция СформироватьКлавиатуруИзМассиваКнопок(Знач МассивКнопок, Знач ЦветКнопок = "") Экспорт
МассивСтруктурКнопок = Новый Массив;
СтруктураКлавиатуры = Новый Структура;
ЦветКнопок = ?(ЗначениеЗаполнено(ЦветКнопок), ЦветКнопок, "#2db9b9");
Для Каждого ТекстКнопки Из МассивКнопок Цикл
СтруктураКнопки = Новый Структура;
СтруктураКнопки.Вставить("ActionType", "reply");
СтруктураКнопки.Вставить("ActionBody", ТекстКнопки);
СтруктураКнопки.Вставить("Text" , ТекстКнопки);
СтруктураКнопки.Вставить("BgColor" , ЦветКнопок);
СтруктураКнопки.Вставить("Coloumns" , 3);
МассивСтруктурКнопок.Добавить(СтруктураКнопки);
КонецЦикла;
СтруктураКлавиатуры.Вставить("Buttons", МассивСтруктурКнопок);
СтруктураКлавиатуры.Вставить("Type" , "keyboard");
Возврат СтруктураКлавиатуры;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// Отправить сообщение.
//
// Параметры:
// Токен - Строка - Токен
// Тип - Строка - Тип отправляемого сообщения
// IDПользователя - Строка,Число - ID пользователя Viber
// ЭтоКанал - Булево - Отправка в канал или чат с ботом
// Значение - Строка, Структура - Значение:
// * URL - Строка - При отправке URL
// * Размер - Число, Строка - Размер файла в случае отправке
// * Расширение - Строка - Расширение файла в случае отправки
// Текст - Строка - Текст сообщения
// Клавиатура - Структура из Строка - Клавиатура, если нужна, см. СформироватьКлавиатуруИзМассиваКнопок
//
// Возвращаемое значение:
// Произвольный, HTTPОтвет - Отправить сообщение
Функция ОтправитьСообщение(Знач Токен
, Знач Тип
, Знач IDПользователя
, Знач ЭтоКанал
, Знач Значение = ""
, Знач Текст = ""
, Знач Клавиатура = "")
СтруктураПараметров = ВернутьСтандартныеПараметры();
СтруктураПараметров.Вставить("type", Тип);
Если (Тип = "text" Или Тип = "picture") И ЗначениеЗаполнено(Текст) Тогда
СтруктураПараметров.Вставить("text", Текст);
КонецЕсли;
Если ТипЗнч(Клавиатура) = Тип("Структура") Тогда
СтруктураПараметров.Вставить("keyboard", Клавиатура);
КонецЕсли;
Если ЗначениеЗаполнено(Значение) Тогда
Если Тип = "file" Тогда
СтруктураПараметров.Вставить("media" , Значение["URL"]);
СтруктураПараметров.Вставить("size" , Значение["Размер"]);
СтруктураПараметров.Вставить("file_name", "Файл." + Значение["Расширение"]);
ИначеЕсли Тип = "contact" Тогда
СтруктураПараметров.Вставить("contact" , Значение);
ИначеЕсли Тип = "location" Тогда
СтруктураПараметров.Вставить("location" , Значение);
Иначе
СтруктураПараметров.Вставить("media" , Значение);
КонецЕсли;
КонецЕсли;
Если ЭтоКанал Тогда
СтруктураПараметров.Вставить("from", IDПользователя);
URL = "https://chatapi.viber.com/pa/post";
Иначе
СтруктураПараметров.Вставить("receiver", IDПользователя);
URL = "https://chatapi.viber.com/pa/send_message";
КонецЕсли;
Ответ = OPI_Инструменты.Post(URL
, СтруктураПараметров
, ТокенВЗаголовки(Токен));
Попытка
Возврат OPI_Инструменты.JsonВСтруктуру(Ответ.ПолучитьТелоКакДвоичныеДанные());
Исключение
Возврат Ответ;
КонецПопытки;
КонецФункции
Функция ВернутьСтандартныеПараметры()
СтруктураОтправителя = Новый Структура;
СтруктураОтправителя.Вставить("name" , "Bot");
СтруктураОтправителя.Вставить("avatar", "");
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("sender", СтруктураОтправителя);
СтруктураПараметров.Вставить("min_api_version", 1);
Возврат СтруктураПараметров;
КонецФункции
Функция ТокенВЗаголовки(Знач Токен)
СтруктураЗаголовков = Новый Соответствие;
СтруктураЗаголовков.Вставить("X-Viber-Auth-Token", Токен);
Возврат СтруктураЗаголовков;
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,500 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
#Область РаботаСФайламиИПапками
// Получить информацию о диске.
//
// Параметры:
// Токен - Строка - Токен
//
// Возвращаемое значение:
// ДвоичныеДанные, Неопределено, Строка, Произвольный - Ответ сервера Yandex
Функция ПолучитьИнформациюОДиске(Знач Токен) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk", , Заголовки);
Возврат Ответ;
КонецФункции
// Создать папку.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь к созаваемой папке
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция СоздатьПапку(Знач Токен, Знач Путь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
URL = "https://cloud-api.yandex.net/v1/disk/resources";
Href = "href";
Параметры = Новый Структура;
Параметры.Вставить("path", Путь);
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
Ответ = OPI_Инструменты.Put(URL + Параметры, , Заголовки, Ложь);
URLОтвета = Ответ[Href];
Ответ = OPI_Инструменты.Get(URLОтвета, , Заголовки);
Возврат Ответ;
КонецФункции
// Получить объект.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь к папке или файлу, о котором необходимо получить информацию
//
// Возвращаемое значение:
// ДвоичныеДанные, Неопределено, Строка, Произвольный - Ответ сервера Yandex
Функция ПолучитьОбъект(Знач Токен, Знач Путь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Параметры.Вставить("path", Путь);
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Удалить объект.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь к удаляемой папке или файлу
// ВКорзину - Булево - В корзину
//
// Возвращаемое значение:
// ДвоичныеДанные, Неопределено, Строка, Произвольный - Ответ сервера Yandex
Функция УдалитьОбъект(Знач Токен, Знач Путь, Знач ВКорзину = Истина) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Параметры.Вставить("path" , Путь);
Параметры.Вставить("permanently", Не ВКорзину);
Ответ = OPI_Инструменты.Delete("https://cloud-api.yandex.net/v1/disk/resources", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Создать копию объекта.
//
// Параметры:
// Токен - Строка - Токен
// Оригинал - Строка - Путь к оригинальному файлу или каталогу
// Путь - Строка - Путь-назначение для копии
// Перезаписывать - Булево - Перезаписывать если файл с таким именем уже существует
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция СоздатьКопиюОбъекта(Знач Токен, Знач Оригинал, Знач Путь, Знач Перезаписывать = Ложь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
URL = "https://cloud-api.yandex.net/v1/disk/resources/copy";
Href = "href";
Параметры = Новый Структура;
Параметры.Вставить("from" , Оригинал);
Параметры.Вставить("path" , Путь);
Параметры.Вставить("overwrite" , Перезаписывать);
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
Ответ = OPI_Инструменты.Post(URL + Параметры, , Заголовки, Ложь);
URLОтвета = Ответ[Href];
Ответ = OPI_Инструменты.Get(URLОтвета, , Заголовки);
Возврат Ответ;
КонецФункции
// Получить ссылку для скачивания.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь к файлу для скачивания
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция ПолучитьСсылкуДляСкачивания(Знач Токен, Знач Путь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Параметры.Вставить("path", Путь);
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources/download", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить список файлов.
//
// Параметры:
// Токен - Строка - Токен
// Количество - Число,Строка - Количество возвращаемых объектов
// СмещениеОтНачала - Число - Смещение для получение объектов не из начала списка
// ОтборПоТипу - Строка - Отбор по типу файла
// Список доступных вариантов: audio, backup, book, compressed, data, development,
// diskimage, document, encoded, executable, flash, font,
// image, settings, spreadsheet, text, unknown, video, web
// СортироватьПоДате - Булево - Истина - сортировать по дате, Ложь - по алфавиту
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
//@skip-check method-too-many-params
// BSLLS:NumberOfOptionalParams-off
Функция ПолучитьСписокФайлов(Знач Токен
, Знач Количество = 0
, Знач СмещениеОтНачала = 0
, Знач ОтборПоТипу = ""
, Знач СортироватьПоДате = Ложь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Количество) Тогда
Параметры.Вставить("limit", OPI_Инструменты.ЧислоВСтроку(Количество));
КонецЕсли;
Если ЗначениеЗаполнено(СмещениеОтНачала) Тогда
Параметры.Вставить("offset", OPI_Инструменты.ЧислоВСтроку(СмещениеОтНачала));
КонецЕсли;
Если ЗначениеЗаполнено(ОтборПоТипу) Тогда
Параметры.Вставить("media_type", ОтборПоТипу);
КонецЕсли;
Если СортироватьПоДате Тогда
Назначение = "last-uploaded";
Иначе
Назначение = "files";
КонецЕсли;
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources/" + Назначение, Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// BSLLS:NumberOfOptionalParams-on
// Переместить объект.
//
// Параметры:
// Токен - Строка - Токен
// Оригинал - Строка - Путь к оригинальному файлу или папке
// Путь - Строка - Путь-назначение для перемещения
// Перезаписывать - Булево - Перезаписывать если файл с таким именем уже существует
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция ПереместитьОбъект(Знач Токен, Знач Оригинал, Знач Путь, Знач Перезаписывать = Ложь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
URL = "https://cloud-api.yandex.net/v1/disk/resources/move";
Href = "href";
Параметры = Новый Структура;
Параметры.Вставить("from" , Оригинал);
Параметры.Вставить("path" , Путь);
Параметры.Вставить("overwrite" , Перезаписывать);
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
Ответ = OPI_Инструменты.Post(URL + Параметры, , Заголовки, Ложь);
URLОтвета = Ответ[Href];
Ответ = OPI_Инструменты.Get(URLОтвета, , Заголовки);
Возврат Ответ;
КонецФункции
// Получить ссылку загрузки файла.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь для сохранение файла на Диске
// Файл - Строка,ДвоичныеДанные - Файл для загрузки
// Перезаписывать - Булево - Перезаписывать, если файл с таким именем уже существует
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция ЗагрузитьФайл(Знач Токен, Знач Путь, Знач Файл, Знач Перезаписывать = Ложь) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Href = "href";
Если Не ТипЗнч(Файл) = Тип("ДвоичныеДанные") Тогда
Файл = Новый ДвоичныеДанные(Файл);
КонецЕсли;
Файл = Новый Структура("file", Файл);
Параметры = Новый Структура;
Параметры.Вставить("path" , Путь);
Параметры.Вставить("overwrite" , Перезаписывать);
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources/upload", Параметры, Заголовки);
URL = Ответ[Href];
Ответ = OPI_Инструменты.PutMultipart(URL, Новый Структура(), Файл, "multipart", Заголовки);
Возврат Ответ;
КонецФункции
// Загрузить файл по URL.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь помещения загруженного файла
// Адрес - Строка - URL файла
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - Ответ сервера Yandex
Функция ЗагрузитьФайлПоURL(Знач Токен, Знач Путь, Знач Адрес) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
URL = "https://cloud-api.yandex.net/v1/disk/resources/upload";
Параметры = Новый Структура;
Параметры.Вставить("url" , КодироватьСтроку(Адрес, СпособКодированияСтроки.URLВКодировкеURL));
Параметры.Вставить("path" , Путь);
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
Ответ = OPI_Инструменты.Post(URL + Параметры, , Заголовки, Ложь);
Возврат Ответ;
КонецФункции
#КонецОбласти
#Область УправлениеПубличнымДоступом
// Опубликовать объект.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь к публикуемому объекту
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция ОпубликоватьОбъект(Знач Токен, Знач Путь) Экспорт
Возврат ПереключениеОбщегоДоступа(Токен, Путь, Истина);
КонецФункции
// Отменить публикацию объекта.
//
// Параметры:
// Токен - Строка - Токен
// Путь - Строка - Путь к опубликованному ранее объекту
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция ОтменитьПубликациюОбъекта(Знач Токен, Знач Путь) Экспорт
Возврат ПереключениеОбщегоДоступа(Токен, Путь, Ложь);
КонецФункции
// Получить список опубликованных объектов.
//
// Параметры:
// Токен - Строка - Токен
// Количество - Число - Количество возвращаемых объектов
// СмещениеОтНачала - Число - Смещение для получение объектов не из начала списка
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, HTTPОтвет, Неопределено - Ответ сервера Yandex
Функция ПолучитьСписокОпубликованныхОбъектов(Знач Токен, Знач Количество = 0, Знач СмещениеОтНачала = 0) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Количество) Тогда
Параметры.Вставить("limit", OPI_Инструменты.ЧислоВСтроку(Количество));
КонецЕсли;
Если ЗначениеЗаполнено(СмещениеОтНачала) Тогда
Параметры.Вставить("offset", OPI_Инструменты.ЧислоВСтроку(СмещениеОтНачала));
КонецЕсли;
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources/public", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить публичный объект.
//
// Параметры:
// Токен - Строка - Токен
// URL - Строка - Адрес объекта
// Количество - Число - Количество возвращаемых вложенных объектов (для каталога)
// СмещениеОтНачала - Число - Смещение для получение вложенных объектов не из начала списка
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено - Ответ сервера Yandex
Функция ПолучитьПубличныйОбъект(Знач Токен, Знач URL, Знач Количество = 0, Знач СмещениеОтНачала = 0) Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Количество) Тогда
Параметры.Вставить("limit", OPI_Инструменты.ЧислоВСтроку(Количество));
КонецЕсли;
Если ЗначениеЗаполнено(СмещениеОтНачала) Тогда
Параметры.Вставить("offset", OPI_Инструменты.ЧислоВСтроку(СмещениеОтНачала));
КонецЕсли;
Параметры.Вставить("public_key", URL);
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/public/resources", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Получить ссылку скачивания публичного объекта.
//
// Параметры:
// Токен - Строка - Токен
// URL - Строка - Адрес объекта
// Путь - Строка - Путь
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено - Ответ сервера Yandex
Функция ПолучитьСсылкуСкачиванияПубличногоОбъекта(Знач Токен, Знач URL, Знач Путь = "") Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Параметры = Новый Структура;
Если ЗначениеЗаполнено(Путь) Тогда
Параметры.Вставить("path", Путь);
КонецЕсли;
Параметры.Вставить("public_key", URL);
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/public/resources/download", Параметры, Заголовки);
Возврат Ответ;
КонецФункции
// Сохранить публичный объект на диск.
//
// Параметры:
// Токен - Строка - Токен
// URL - Строка - Адрес объекта
// Откуда - Строка - Путь внутри публичного каталога (только для папок)
// Куда - Строка - Путь сохранения файла
//
// Возвращаемое значение:
// Строка, Произвольный, ДвоичныеДанные, Неопределено, HTTPОтвет - Ответ сервера Yandex
Функция СохранитьПубличныйОбъектНаДиск(Знач Токен, Знач URL, Откуда = "", Куда = "") Экспорт
Заголовки = ЗаголовокАвторизации(Токен);
Адрес = "https://cloud-api.yandex.net/v1/disk/public/resources/save-to-disk";
Href = "href";
Параметры = Новый Структура;
Параметры.Вставить("public_key", URL);
Если ЗначениеЗаполнено(Откуда) Тогда
Параметры.Вставить("path", Откуда);
КонецЕсли;
Если ЗначениеЗаполнено(Куда) Тогда
Параметры.Вставить("save_path", Куда);
КонецЕсли;
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
Ответ = OPI_Инструменты.Post(Адрес + Параметры, , Заголовки, Ложь);
URLОтвета = Ответ[Href];
Ответ = OPI_Инструменты.Get(URLОтвета, , Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ЗаголовокАвторизации(Знач Токен)
Заголовки = Новый Соответствие;
Заголовки.Вставить("Authorization", "OAuth " + Токен);
Возврат Заголовки;
КонецФункции
Функция ПереключениеОбщегоДоступа(Знач Токен, Знач Путь, Знач ОбщийДоступ)
Заголовки = ЗаголовокАвторизации(Токен);
Назначение = ?(ОбщийДоступ, "publish", "unpublish");
Href = "href";
URL = "https://cloud-api.yandex.net/v1/disk/resources/" + Назначение;
Параметры = Новый Структура;
Параметры.Вставить("path", Путь);
Параметры = OPI_Инструменты.ПараметрыЗапросаВСтроку(Параметры);
Ответ = OPI_Инструменты.Put(URL + Параметры, , Заголовки, Ложь);
URLОтвета = Ответ[Href];
Ответ = OPI_Инструменты.Get(URLОтвета, , Заголовки);
Возврат Ответ;
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,92 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область ПрограммныйИнтерфейс
// Получить код подтверждения.
//
// Параметры:
// ClientId - Строка - Client id
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Ответ сервера Yandex
Функция ПолучитьКодПодтверждения(Знач ClientId) Экспорт
Параметры = Новый Структура("client_id", ClientId);
Ответ = OPI_Инструменты.Post("https://oauth.yandex.ru/device/code", Параметры, , Ложь);
Возврат Ответ;
КонецФункции
// Преобразовать код в токен.
//
// Параметры:
// ClientId - Строка - Client id
// ClientSecret - Строка - Client secret
// КодУстройства - Строка - device_code из ПолучитьКодПодтверждения()
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Преобразовать код в токен
Функция ПреобразоватьКодВТокен(Знач ClientId, Знач ClientSecret, Знач КодУстройства) Экспорт
Параметры = Новый Структура;
Параметры.Вставить("grant_type" , "device_code");
Параметры.Вставить("code" , КодУстройства);
Параметры.Вставить("client_id" , ClientId);
Параметры.Вставить("client_secret" , ClientSecret);
Ответ = OPI_Инструменты.Post("https://oauth.yandex.ru/token", Параметры, , Ложь);
Возврат Ответ;
КонецФункции
// Обновить токен.
//
// Параметры:
// ClientId - Строка - Client id
// ClientSecret - Строка - Client secret
// RefreshToken - Строка - Refresh token
//
// Возвращаемое значение:
// Строка, Произвольный, Неопределено, ДвоичныеДанные, HTTPОтвет - Обновить токен
Функция ОбновитьТокен(Знач ClientId, Знач ClientSecret, Знач RefreshToken) Экспорт
Параметры = Новый Структура;
Параметры.Вставить("grant_type" , "refresh_token");
Параметры.Вставить("refresh_token" , RefreshToken);
Параметры.Вставить("client_id" , ClientId);
Параметры.Вставить("client_secret" , ClientSecret);
Ответ = OPI_Инструменты.Post("https://oauth.yandex.ru/token", Параметры, , Ложь);
Возврат Ответ;
КонецФункции
#КонецОбласти

View File

@ -0,0 +1,764 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
// BSLLS:Typo-off
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Область СлужебныйПрограммныйИнтерфейс
#Область HTTPМетоды
#Область ЗапросыБезТела
Функция Get(Знач URL, Знач Параметры = "", Знач ДопЗаголовки = "") Экспорт
Возврат ВыполнитьЗапросБезТела(URL, "GET", Параметры, ДопЗаголовки);
КонецФункции
Функция Delete(Знач URL, Знач Параметры = "", Знач ДопЗаголовки = "") Экспорт
Возврат ВыполнитьЗапросБезТела(URL, "DELETE", Параметры, ДопЗаголовки);
КонецФункции
#КонецОбласти
#Область ЗапросыСТелом
Функция Post(Знач URL, Знач Параметры = "", Знач ДопЗаголовки = "", Знач JSON = Истина) Экспорт
Возврат ВыполнитьЗапросСТелом(URL, "POST", Параметры, ДопЗаголовки, JSON);
КонецФункции
Функция Patch(Знач URL, Знач Параметры = "", Знач ДопЗаголовки = "", Знач JSON = Истина) Экспорт
Возврат ВыполнитьЗапросСТелом(URL, "PATCH", Параметры, ДопЗаголовки, JSON);
КонецФункции
Функция Put(Знач URL, Знач Параметры = "", Знач ДопЗаголовки = "", Знач JSON = Истина) Экспорт
Возврат ВыполнитьЗапросСТелом(URL, "PUT", Параметры, ДопЗаголовки, JSON);
КонецФункции
#КонецОбласти
#Область ЗапросыMultipart
Функция PostMultipart(Знач URL
, Знач Параметры
, Знач Файлы = ""
, Знач ТипКонтента = "image/jpeg"
, Знач ДопЗаголовки = "") Экспорт
Возврат ВыполнитьЗапросМультипарт(URL, "POST", Параметры, Файлы, ТипКонтента, ДопЗаголовки);
КонецФункции
Функция PutMultipart(Знач URL
, Знач Параметры
, Знач Файлы = ""
, Знач ТипКонтента = "image/jpeg"
, Знач ДопЗаголовки = "") Экспорт
Возврат ВыполнитьЗапросМультипарт(URL, "PUT", Параметры, Файлы, ТипКонтента, ДопЗаголовки);
КонецФункции
#КонецОбласти
Функция ПараметрыЗапросаВСоответствие(Знач СтрокаПараметров) Экспорт
СоответствиеВозврата = Новый Соответствие;
КоличествоЧастей = 2;
МассивПараметров = СтрРазделить(СтрокаПараметров, "&", Ложь);
Для Каждого Параметр Из МассивПараметров Цикл
МассивКлючЗначение = СтрРазделить(Параметр, "=");
Если МассивКлючЗначение.Количество() = КоличествоЧастей Тогда
СоответствиеВозврата.Вставить(МассивКлючЗначение[0], МассивКлючЗначение[1]);
КонецЕсли;
КонецЦикла;
Возврат СоответствиеВозврата;
КонецФункции
Функция UNIXTime(Знач Дата) Экспорт
Возврат Формат(Дата - Дата(1970, 1, 1, 1, 0, 0), "ЧГ=0");
КонецФункции
Функция ПолучитьТекущуюДата() Экспорт
//@skip-check use-non-recommended-method
Возврат ТекущаяДата();
КонецФункции
Процедура ЗаменитьСпецСимволы(Текст) Экспорт
МассивСимволов = Новый Соответствие;
МассивСимволов.Вставить("<", "&lt;");
МассивСимволов.Вставить(">", "&gt;");
МассивСимволов.Вставить("&", "&amp;");
МассивСимволов.Вставить("_", " ");
МассивСимволов.Вставить("[", "(");
МассивСимволов.Вставить("]", ")");
Для Каждого СимволМассива Из МассивСимволов Цикл
Текст = СтрЗаменить(Текст, СимволМассива.Ключ, СимволМассива.Значение);
КонецЦикла;
КонецПроцедуры
Процедура УдалитьПустыеПоляКоллекции(Коллекция) Экспорт
ТипКоллекции = ТипЗнч(Коллекция);
ВыходнаяКоллекция = Новый(ТипКоллекции);
Если ТипКоллекции = Тип("Соответствие") Или ТипКоллекции = Тип("Структура") Тогда
УдалитьПустыеКлючиЗначения(Коллекция, ВыходнаяКоллекция);
ИначеЕсли ТипКоллекции = Тип("Массив") Тогда
УдалитьПустыеЭлементыМассива(Коллекция, ВыходнаяКоллекция);
Иначе
ВыходнаяКоллекция = Коллекция;
КонецЕсли;
Коллекция = ВыходнаяКоллекция;
КонецПроцедуры
Процедура Пауза(Знач Секунды) Экспорт
Соединение = Новый HTTPСоединение("1C.ru", 11111, , , , Секунды);
Попытка
Соединение.Получить(Новый HTTPЗапрос(""));
Исключение
Возврат;
Конецпопытки;
КонецПроцедуры
#КонецОбласти
#Область Служебные
Функция ПараметрыЗапросаВСтроку(Знач Параметры) Экспорт
Если Параметры.Количество() = 0 Тогда
Возврат "";
КонецЕсли;
СтрокаПараметров = "?";
Для Каждого Параметр Из Параметры Цикл
СтрокаПараметров = СтрокаПараметров
+ Параметр.Ключ
+ "="
+ КодироватьСтроку(Параметр.Значение,
СпособКодированияСтроки.КодировкаURL)
+ "&";
КонецЦикла;
СтрокаПараметров = Лев(СтрокаПараметров, СтрДлина(СтрокаПараметров) - 1);
Возврат СтрокаПараметров;
КонецФункции
Функция РазбитьURL(Знач URL) Экспорт
URL = СтрЗаменить(URL, "https://", "");
URL = СтрЗаменить(URL, "http://", "");
URL = СтрЗаменить(URL, ":443", "");
Адрес = Прав(URL, СтрДлина(URL) - СтрНайти(URL, "/", НаправлениеПоиска.СНачала) + 1);
Сервер = Лев(URL, СтрНайти(URL, "/", НаправлениеПоиска.СНачала) - 1);
Попытка
//@skip-check module-unused-local-variable
SSL = Новый ЗащищенноеСоединениеOpenSSL; // BSLLS:UnusedLocalVariable-off
Исключение
Сервер = "https://" + Сервер;
КонецПопытки;
СтруктураВозврата = Новый Структура;
СтруктураВозврата.Вставить("Сервер", Сервер);
СтруктураВозврата.Вставить("Адрес" , Адрес);
Возврат СтруктураВозврата;
КонецФункции
Функция JsonВСтруктуру(Знач Текст) Экспорт
Если Не ЗначениеЗаполнено(Текст) Тогда
Возврат "";
КонецЕсли;
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ПолучитьСтрокуИзДвоичныхДанных(Текст));
Данные = ПрочитатьJSON(ЧтениеJSON, Истина, Неопределено, ФорматДатыJSON.ISO);
ЧтениеJSON.Закрыть();
Возврат Данные;
КонецФункции
Функция JSONСтрокой(Знач Данные) Экспорт
ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Windows, " ", Истина, ЭкранированиеСимволовJSON.Нет,
Ложь, Ложь, Ложь, Ложь);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
ЗаписатьJSON(ЗаписьJSON, Данные);
Возврат ЗаписьJSON.Закрыть();
КонецФункции
Функция ЧислоВСтроку(Знач Число) Экспорт
Возврат СтрЗаменить(Строка(Число), Символы.НПП, "");
КонецФункции
Функция ПрочитатьJSONФайл(Знач Путь) Экспорт
ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.ОткрытьФайл(Путь);
Значения = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();
Возврат Значения;
КонецФункции
#КонецОбласти
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ВыполнитьЗапросСТелом(Знач URL, Знач Вид, Знач Параметры = "", Знач ДопЗаголовки = "", Знач JSON = Истина)
Если Не ЗначениеЗаполнено(Параметры) Тогда
Параметры = Новый Структура;
КонецЕсли;
ТипДанных = ?(JSON, "application/json", "application/x-www-form-urlencoded");
СтруктураURL = РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"];
Запрос = СоздатьЗапрос(Адрес, ДопЗаголовки, ТипДанных);
Соединение = СоздатьСоединение(Сервер);
УстановитьТелоЗапроса(Запрос, Параметры, JSON);
Ответ = Соединение.ВызватьHTTPМетод(Вид, Запрос);
Если ЭтоПереадресация(Ответ) Тогда
Ответ = ВыполнитьЗапросСТелом(Ответ.Заголовки["Location"], Вид, Параметры, ДопЗаголовки, JSON);
Иначе
ОбработатьОтвет(Ответ);
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ВыполнитьЗапросБезТела(Знач URL, Знач Вид, Знач Параметры = "", Знач ДопЗаголовки = "")
Если Не ЗначениеЗаполнено(Параметры) Тогда
Параметры = Новый Структура;
КонецЕсли;
СтруктураURL = РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"] + ПараметрыЗапросаВСтроку(Параметры);
Запрос = СоздатьЗапрос(Адрес, ДопЗаголовки);
Соединение = СоздатьСоединение(Сервер);
Ответ = Соединение.ВызватьHTTPМетод(Вид, Запрос);
Если ЭтоПереадресация(Ответ) Тогда
Ответ = ВыполнитьЗапросБезТела(Ответ.Заголовки["Location"], Вид, Параметры, ДопЗаголовки);
Иначе
ОбработатьОтвет(Ответ);
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция ВыполнитьЗапросМультипарт(Знач URL
, Знач Вид
, Знач Параметры
, Знач Файлы = ""
, Знач ТипКонтента = "image/jpeg"
, Знач ДопЗаголовки = "")
Если Не ЗначениеЗаполнено(Параметры) Тогда
Параметры = Новый Структура;
КонецЕсли;
Если Не ЗначениеЗаполнено(Файлы) Тогда
Файлы = Новый Соответствие;
КонецЕсли;
Переадресация = 300;
Ошибка = 400;
Boundary = СтрЗаменить(Строка(Новый УникальныйИдентификатор), "-", "");
РазделительСтрок = Символы.ВК + Символы.ПС;
ТипДанных = "multipart/form-data; boundary=" + Boundary;
СтруктураURL = РазбитьURL(URL);
Сервер = СтруктураURL["Сервер"];
Адрес = СтруктураURL["Адрес"];
Запрос = СоздатьЗапрос(Адрес, ДопЗаголовки, ТипДанных);
Соединение = СоздатьСоединение(Сервер);
ТелоЗапроса = Запрос.ПолучитьТелоКакПоток();
ЗаписьТекста = Новый ЗаписьДанных(ТелоЗапроса, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, "", "", Ложь);
ЗаписатьПараметрыМультипарт(ЗаписьТекста, Boundary, Параметры);
ЗаписатьФайлыМультипарт(ЗаписьТекста, Boundary, ТипКонтента, Файлы);
ЗаписьТекста.ЗаписатьСтроку("--" + boundary + "--" + РазделительСтрок);
ЗаписьТекста.Закрыть();
Ответ = Соединение.ВызватьHTTPМетод(Вид, Запрос);
ЭтоПереадресация = Ответ.КодСостояния >= Переадресация И Ответ.КодСостояния < Ошибка;
Если ЭтоПереадресация Тогда
Ответ = ВыполнитьЗапросМультипарт(Ответ.Заголовки["Location"]
, Вид
, Параметры
, Файлы
, ТипКонтента
, ДопЗаголовки);
Иначе
ОбработатьОтвет(Ответ);
КонецЕсли;
Возврат Ответ;
КонецФункции
Функция СоздатьЗапрос(Знач Адрес, Знач ДопЗаголовки = "", Знач ТипДанных = "")
Заголовки = Новый Соответствие;
Заголовки.Вставить("Accept-Encoding", "gzip");
Заголовки.Вставить("Accept" , "*/*");
Заголовки.Вставить("Connection" , "keep-alive");
Если ЗначениеЗаполнено(ТипДанных) Тогда
Заголовки.Вставить("Content-Type", ТипДанных);
КонецЕсли;
Если ТипЗнч(ДопЗаголовки) = Тип("Соответствие") Тогда
Для Каждого Заголовок Из ДопЗаголовки Цикл
Заголовки.Вставить(Заголовок.Ключ, Заголовок.Значение);
КонецЦикла;
КонецЕсли;
НовыйЗапрос = Новый HTTPЗапрос(Адрес, Заголовки);
Возврат НовыйЗапрос;
КонецФункции
Функция СоздатьСоединение(Знач Сервер)
Попытка
SSL = Новый ЗащищенноеСоединениеOpenSSL;
Возврат Новый HTTPСоединение(Сервер, 443, , , , 300, SSL);
Исключение
Возврат Новый HTTPСоединение(Сервер, 443, , , , 300);
КонецПопытки;
КонецФункции
Функция ЭтоПереадресация(Знач Ответ)
Переадресация = 300;
Ошибка = 400;
ЭтоПереадресация = Ответ.КодСостояния >= Переадресация И Ответ.КодСостояния < Ошибка;
Возврат ЭтоПереадресация;
КонецФункции
Процедура ОбработатьОтвет(Ответ)
GZip = "gzip";
НужнаРаспаковка =
Ответ.Заголовки.Получить("Content-Encoding") = GZip
Или Ответ.Заголовки.Получить("content-encoding") = GZip;
Если НужнаРаспаковка Тогда
Ответ = РаспаковатьОтвет(Ответ);
КонецЕсли;
Ответ = ?(ТипЗнч(Ответ) = Тип("HTTPОтвет"), Ответ.ПолучитьТелоКакДвоичныеДанные(), Ответ);
Если ТипЗнч(Ответ) = Тип("ДвоичныеДанные") Тогда
Попытка
Ответ = JsonВСтруктуру(Ответ);
Исключение
Ответ = ПолучитьСтрокуИзДвоичныхДанных(Ответ);
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Процедура УстановитьТелоЗапроса(Запрос, Знач Параметры, Знач JSON)
Если JSON Тогда
Данные = JSONСтрокой(Параметры);
Иначе
СтрокаПараметров = ПараметрыЗапросаВСтроку(Параметры);
Данные = Прав(СтрокаПараметров, СтрДлина(СтрокаПараметров) - 1);
КонецЕсли;
Запрос.УстановитьТелоИзСтроки(Данные);
КонецПроцедуры
Процедура ЗаписатьПараметрыМультипарт(ЗаписьТекста, Знач Boundary, Знач Параметры)
РазделительСтрок = Символы.ВК + Символы.ПС;
Для Каждого Параметр Из Параметры Цикл
Если Параметр.Значение = Неопределено
Или Параметр.Значение = NULL Тогда
Продолжить;
КонецЕсли;
ЗаписьТекста.ЗаписатьСтроку("--" + boundary + РазделительСтрок);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name=""" + Параметр.Ключ + """");
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
Если ТипЗнч(Параметр.Значение) = Тип("Строка")
Или ТипЗнч(Параметр.Значение) = Тип("Число") Тогда
ЗначениеСтрокой = ЧислоВСтроку(Параметр.Значение);
ЗаписьТекста.ЗаписатьСтроку(ЗначениеСтрокой);
ИначеЕсли ТипЗнч(Параметр.Значение) = Тип("Булево") Тогда
ЗаписьТекста.ЗаписатьСтроку(?(Параметр.Значение, "true", "false"));
Иначе
ЗаписьТекста.Записать(Параметр.Значение);
КонецЕсли;
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
КонецЦикла;
КонецПроцедуры
Процедура ЗаписатьФайлыМультипарт(ЗаписьТекста, Знач Boundary, Знач ТипКонтента, Знач Файлы)
РазделительСтрок = Символы.ВК + Символы.ПС;
ЗаменаТочки = "___";
Для Каждого Файл Из Файлы Цикл
ПутьФайл = СтрЗаменить(Файл.Ключ, ЗаменаТочки, ".");
Если ТипКонтента = "image/jpeg" Тогда
ИмяФайлаОтправки = "photo";
Иначе
ИмяФайлаОтправки = СтрЗаменить(Файл.Ключ, ЗаменаТочки, ".");
ИмяФайлаОтправки = Лев(ИмяФайлаОтправки, СтрНайти(ИмяФайлаОтправки, ".") - 1);
ИмяФайлаОтправки = ?(ЗначениеЗаполнено(ИмяФайлаОтправки), ИмяФайлаОтправки, СтрЗаменить(Файл.Ключ,
ЗаменаТочки, "."));
КонецЕсли;
ЗаписьТекста.ЗаписатьСтроку("--" + boundary + РазделительСтрок);
ЗаписьТекста.ЗаписатьСтроку("Content-Disposition: form-data; name="""
+ ИмяФайлаОтправки
+ """; filename="""
+ ПутьФайл
+ """");
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
ЗаписьТекста.ЗаписатьСтроку("Content-Type: " + ТипКонтента);
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
ЗаписьТекста.Записать(Файл.Значение);
ЗаписьТекста.ЗаписатьСтроку(РазделительСтрок);
КонецЦикла;
КонецПроцедуры
Процедура УдалитьПустыеКлючиЗначения(Знач Коллекция, ВыходнаяКоллекция)
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если Не ЭлементКоллекции.Значение = Неопределено И Не ЭлементКоллекции.Значение = NULL Тогда
ВыходнаяКоллекция.Вставить(ЭлементКоллекции.Ключ, ЭлементКоллекции.Значение);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Процедура УдалитьПустыеЭлементыМассива(Знач Коллекция, ВыходнаяКоллекция)
Для Каждого ЭлементКоллекции Из Коллекция Цикл
Если Не ЭлементКоллекции = Неопределено И Не ЭлементКоллекции = NULL Тогда
ВыходнаяКоллекция.Добавить(ЭлементКоллекции);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
#Область GZip
// Описание структур см. здесь https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
// Источник: https://github.com/vbondarevsky/Connector
// Коннектор: удобный HTTP-клиент для 1С:Предприятие 8
//
// Copyright 2017-2023 Vladimir Bondarevskiy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// URL: https://github.com/vbondarevsky/Connector
// e-mail: vbondarevsky@gmail.com
// Версия: 2.4.8
//
// Требования: платформа 1С версии 8.3.10 и выше
// BSLLS:LatinAndCyrillicSymbolInWord-off
Функция РаспаковатьОтвет(Ответ)
Попытка
Возврат ПрочитатьGZip(Ответ.ПолучитьТелоКакДвоичныеДанные());
Исключение
Возврат Ответ;
КонецПопытки;
КонецФункции
Функция ПрочитатьGZip(СжатыеДанные) Экспорт
РазмерПрефиксаGZip = 10;
РазмерПостфиксаGZip = 8;
РазмерДД = ZipРазмерDD();
РазмерСДХ = ZipРазмерCDH();
РазмерЕСД = ZipРазмерEOCD();
РазмерЛФХ = ZipРазмерLFH();
ЧтениеДанных = Новый ЧтениеДанных(СжатыеДанные);
ЧтениеДанных.Пропустить(РазмерПрефиксаGZip);
РазмерСжатыхДанных = ЧтениеДанных.ИсходныйПоток().Размер() - РазмерПрефиксаGZip - РазмерПостфиксаGZip;
ПотокZip = Новый ПотокВПамяти(РазмерЛФХ
+ РазмерСжатыхДанных
+ РазмерДД
+ РазмерСДХ
+ РазмерЕСД);
ЗаписьДанных = Новый ЗаписьДанных(ПотокZip);
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipLFH());
ЧтениеДанных.КопироватьВ(ЗаписьДанных, РазмерСжатыхДанных);
ЗаписьДанных.Закрыть();
ЗаписьДанных = Новый ЗаписьДанных(ПотокZip);
CRC32 = ЧтениеДанных.ПрочитатьЦелое32();
РазмерНесжатыхДанных = ЧтениеДанных.ПрочитатьЦелое32();
ЧтениеДанных.Закрыть();
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipDD(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipCDH(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных));
ЗаписьДанных.ЗаписатьБуферДвоичныхДанных(ZipEOCD(РазмерСжатыхДанных));
ЗаписьДанных.Закрыть();
Возврат ПрочитатьZip(ПотокZip);
КонецФункции
Функция ПрочитатьZip(СжатыеДанные, ТекстОшибки = Неопределено)
Каталог = ПолучитьИмяВременногоФайла();
ЧтениеZip = Новый ЧтениеZipФайла(СжатыеДанные);
ИмяФайла = ЧтениеZip.Элементы[0].Имя;
Попытка
ЧтениеZip.Извлечь(ЧтениеZip.Элементы[0], Каталог, РежимВосстановленияПутейФайловZIP.НеВосстанавливать);
Исключение
// Игнорируем проверку целостности архива, просто читаем результат
ТекстОшибки = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
ЧтениеZip.Закрыть();
Результат = Новый ДвоичныеДанные(Каталог + ПолучитьРазделительПути() + ИмяФайла);
УдалитьФайлы(Каталог);
Возврат Результат;
КонецФункции
Функция ZipРазмерLFH()
Возврат 34;
КонецФункции
Функция ZipРазмерDD()
Возврат 16;
КонецФункции
Функция ZipРазмерCDH()
Возврат 50;
КонецФункции
Функция ZipРазмерEOCD()
Возврат 22;
КонецФункции
Функция ZipLFH()
// Local file header
Буфер = Новый БуферДвоичныхДанных(ZipРазмерLFH());
Буфер.ЗаписатьЦелое32(0, 67324752); // signature 0x04034b50
Буфер.ЗаписатьЦелое16(4, 20); // version
Буфер.ЗаписатьЦелое16(6, 10); // bit flags
Буфер.ЗаписатьЦелое16(8, 8); // compression method
Буфер.ЗаписатьЦелое16(10, 0); // time
Буфер.ЗаписатьЦелое16(12, 0); // date
Буфер.ЗаписатьЦелое32(14, 0); // crc-32
Буфер.ЗаписатьЦелое32(18, 0); // compressed size
Буфер.ЗаписатьЦелое32(22, 0); // uncompressed size
Буфер.ЗаписатьЦелое16(26, 4); // filename legth - "data"
Буфер.ЗаписатьЦелое16(28, 0); // extra field length
Буфер.Записать(30, ПолучитьБуферДвоичныхДанныхИзСтроки("data", "ascii", Ложь));
Возврат Буфер;
КонецФункции
Функция ZipDD(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных)
// Data descriptor
Буфер = Новый БуферДвоичныхДанных(ZipРазмерDD());
Буфер.ЗаписатьЦелое32(0, 134695760);
Буфер.ЗаписатьЦелое32(4, CRC32);
Буфер.ЗаписатьЦелое32(8, РазмерСжатыхДанных);
Буфер.ЗаписатьЦелое32(12, РазмерНесжатыхДанных);
Возврат Буфер;
КонецФункции
Функция ZipCDH(CRC32, РазмерСжатыхДанных, РазмерНесжатыхДанных)
// Central directory header
Буфер = Новый БуферДвоичныхДанных(ZipРазмерCDH());
Буфер.ЗаписатьЦелое32(0, 33639248); // signature 0x02014b50
Буфер.ЗаписатьЦелое16(4, 798); // version made by
Буфер.ЗаписатьЦелое16(6, 20); // version needed to extract
Буфер.ЗаписатьЦелое16(8, 10); // bit flags
Буфер.ЗаписатьЦелое16(10, 8); // compression method
Буфер.ЗаписатьЦелое16(12, 0); // time
Буфер.ЗаписатьЦелое16(14, 0); // date
Буфер.ЗаписатьЦелое32(16, CRC32); // crc-32
Буфер.ЗаписатьЦелое32(20, РазмерСжатыхДанных); // compressed size
Буфер.ЗаписатьЦелое32(24, РазмерНесжатыхДанных); // uncompressed size
Буфер.ЗаписатьЦелое16(28, 4); // file name length
Буфер.ЗаписатьЦелое16(30, 0); // extra field length
Буфер.ЗаписатьЦелое16(32, 0); // file comment length
Буфер.ЗаписатьЦелое16(34, 0); // disk number start
Буфер.ЗаписатьЦелое16(36, 0); // internal file attributes
Буфер.ЗаписатьЦелое32(38, 2176057344); // external file attributes
Буфер.ЗаписатьЦелое32(42, 0); // relative offset of local header
Буфер.Записать(46, ПолучитьБуферДвоичныхДанныхИзСтроки("data", "ascii", Ложь));
Возврат Буфер;
КонецФункции
Функция ZipEOCD(РазмерСжатыхДанных)
// End of central directory
РазмерCDH = 50;
Буфер = Новый БуферДвоичныхДанных(ZipРазмерEOCD());
Буфер.ЗаписатьЦелое32(0, 101010256); // signature 0x06054b50
Буфер.ЗаписатьЦелое16(4, 0); // number of this disk
Буфер.ЗаписатьЦелое16(6, 0); // number of the disk with the start of the central directory
Буфер.ЗаписатьЦелое16(8, 1); // total number of entries in the central directory on this disk
Буфер.ЗаписатьЦелое16(10, 1); // total number of entries in the central directory
Буфер.ЗаписатьЦелое32(12, РазмерCDH); // size of the central directory
// offset of start of central directory with respect to the starting disk number
Буфер.ЗаписатьЦелое32(16, ZipРазмерLFH() + РазмерСжатыхДанных + ZipРазмерDD());
Буфер.ЗаписатьЦелое16(20, 0); // the starting disk number
Возврат Буфер;
КонецФункции
// BSLLS:LatinAndCyrillicSymbolInWord-on
// BSLLS:Typo-on
#КонецОбласти
#КонецОбласти

View File

@ -0,0 +1,82 @@
#Область СлужебныйПрограммныйИнтерфейс
#Область БСП
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
Функция HMACSHA256(Знач Ключ, Знач Данные) Экспорт
Возврат HMAC(Ключ, Данные, ХешФункция.SHA256, 64);
КонецФункции
Функция Хеш(ДвоичныеДанные, Тип) Экспорт
Хеширование = Новый ХешированиеДанных(Тип);
Хеширование.Добавить(ДвоичныеДанные);
Возврат Хеширование.ХешСумма;
КонецФункции
Функция HMAC(Знач Ключ, Знач Данные, Тип, РазмерБлока) Экспорт
Дважды = 2;
Если Ключ.Размер() > РазмерБлока Тогда
Ключ = Хеш(Ключ, Тип);
КонецЕсли;
Если Ключ.Размер() <= РазмерБлока Тогда
Ключ = ПолучитьHexСтрокуИзДвоичныхДанных(Ключ);
Ключ = Лев(Ключ + ПовторитьСтроку("00", РазмерБлока), РазмерБлока * Дважды);
КонецЕсли;
Ключ = ПолучитьБуферДвоичныхДанныхИзДвоичныхДанных(ПолучитьДвоичныеДанныеИзHexСтроки(Ключ));
Ipad = ПолучитьБуферДвоичныхДанныхИзHexСтроки(ПовторитьСтроку("36", РазмерБлока));
Opad = ПолучитьБуферДвоичныхДанныхИзHexСтроки(ПовторитьСтроку("5c", РазмерБлока));
Ipad.ЗаписатьПобитовоеИсключительноеИли(0, Ключ);
Ikeypad = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(ipad);
Opad.ЗаписатьПобитовоеИсключительноеИли(0, Ключ);
Okeypad = ПолучитьДвоичныеДанныеИзБуфераДвоичныхДанных(opad);
Возврат Хеш(СклеитьДвоичныеДанные(okeypad, Хеш(СклеитьДвоичныеДанные(ikeypad, Данные), Тип)), Тип);
КонецФункции
Функция СклеитьДвоичныеДанные(ДвоичныеДанные1, ДвоичныеДанные2) Экспорт
МассивДвоичныхДанных = Новый Массив;
МассивДвоичныхДанных.Добавить(ДвоичныеДанные1);
МассивДвоичныхДанных.Добавить(ДвоичныеДанные2);
Возврат СоединитьДвоичныеДанные(МассивДвоичныхДанных);
КонецФункции
Функция ПовторитьСтроку(Строка, Количество) Экспорт
Части = Новый Массив(Количество);
// BSLLS:UnusedLocalVariable-off
Для к = 1 По Количество Цикл
Части.Добавить(Строка);
КонецЦикла;
// BSLLS:UnusedLocalVariable-on
Возврат СтрСоединить(Части, "");
КонецФункции
#КонецОбласти
#КонецОбласти

View File

@ -0,0 +1,272 @@
// MIT License
// Copyright (c) 2023 Anton Tsitavets
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// https://github.com/Bayselonarrend/OpenIntegrations
//Раскомментировать, если выполняется OneScript
#Использовать ".."
#Использовать asserts
// @skip-check undefined-variable
#Область СлужебныйПрограммныйИнтерфейс
Функция ОжидаетЧто(Значение) Экспорт
Попытка
Модуль = ПолучитьОбщийМодуль("ЮТест");
Ожидаем = ТипЗнч(Модуль) = Тип("ОбщийМодуль");
Возврат Модуль.ОжидаетЧто(Значение);
Исключение
Возврат Ожидаем.Что(Значение);
КонецПопытки;
КонецФункции
Функция СформироватьТестыЯкс() Экспорт
Модуль = ПолучитьОбщийМодуль("ЮТТесты");
МассивРазделов = ПолучитьМассивРазделовТестирования();
ТаблицаТестов = ПолучитьТаблицуТестов();
Для Каждого Раздел Из МассивРазделов Цикл
Отбор = Новый Структура("Раздел", Раздел);
ТестыРаздела = ТаблицаТестов.НайтиСтроки(Отбор);
Набор = Модуль.ДобавитьТестовыйНабор(Раздел);
Для Каждого Тест Из ТестыРаздела Цикл
Набор.ДобавитьСерверныйТест(Тест.Метод, Тест.Синоним);
КонецЦикла;
КонецЦикла;
Возврат "";
КонецФункции
Функция СформироватьТестыАссертс() Экспорт
ТаблицаТестов = ПолучитьТаблицуТестов();
МассивТестов = Новый Массив;
Для Каждого Тест Из ТаблицаТестов Цикл
МассивТестов.Добавить(Тест.Метод);
КонецЦикла;
Возврат МассивТестов;
КонецФункции
Функция ПолучитьПараметр(Параметр) Экспорт
Путь = ПутьКФайлуДанных();
Возврат ПолучитьЗначениеИзФайла(Параметр, Путь);
КонецФункции
Функция ПолучитьДвоичные(Параметр) Экспорт
Путь = ПутьКФайлуДанных();
Значение = ПолучитьЗначениеИзФайла(Параметр, Путь);
Если ТипЗнч(Значение) = Тип("Строка") Тогда
Значение = ПолучитьФайлПути(Значение);
КонецЕсли;
Возврат Значение;
КонецФункции
Функция ПолучитьФайлПути(Знач Путь) Экспорт
Если СтрНайти(Путь, "http") > 0
Или СтрНайти(Путь, "www") > 0 Тогда
ИВФ = ПолучитьИмяВременногоФайла();
КопироватьФайл(Путь, ИВФ);
Путь = ИВФ;
Двоичные = Новый ДвоичныеДанные(Путь);
УдалитьФайлы(ИВФ);
Иначе
Двоичные = Новый ДвоичныеДанные(Путь);
КонецЕсли;
Возврат Двоичные;
КонецФункции
Процедура ЗаписатьПараметр(Параметр, Значение) Экспорт
Путь = ПутьКФайлуДанных();
ЗаписатьПараметрВФайл(Параметр, Значение, Путь);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
Функция ПолучитьЗначениеИзФайла(Параметр, Путь)
Значения = OPI_Инструменты.ПрочитатьJSONФайл(Путь);
Возврат Значения[Параметр];
КонецФункции
Функция ПутьКФайлуДанных()
Возврат "D:\GD\Мой диск\data.json"; // BSLLS:UsingHardcodePath-off
КонецФункции
Функция ПолучитьМассивРазделовТестирования()
МассивРазделов = Новый Массив;
МассивРазделов.Добавить("Телеграм");
МассивРазделов.Добавить("ВКонтакте");
МассивРазделов.Добавить("Яндекс.Диск");
МассивРазделов.Добавить("Google Calendar");
МассивРазделов.Добавить("Twitter");
Возврат МассивРазделов;
КонецФункции
Функция ПолучитьТаблицуТестов()
Телеграм = "Телеграм";
ВКонтакте = "ВКонтакте";
ЯДиск = "Яндекс.Диск";
Календарь = "Google Calendar";
Твиттер = "Twitter";
ТаблицаТестов = Новый ТаблицаЗначений;
ТаблицаТестов.Колонки.Добавить("Метод");
ТаблицаТестов.Колонки.Добавить("Синоним");
ТаблицаТестов.Колонки.Добавить("Раздел");
НовыйТест(ТаблицаТестов, "Телеграм_ПолучитьИнформациюБота" , "Получить информацию бота" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ПолучитьОбновления" , "Получить обновления" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_УстановитьWebhook" , "Установить Webhook" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_УдалитьWebhook" , "Удалить Webhook" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьТекстовоеСообщение" , "Отправить текстовое сообщение" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьКартинку" , "Отправить картинку" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьВидео" , "Отправить видео" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьАудио" , "Отправить аудио" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьДокумент" , "Отправить документ" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьГифку" , "Отправить гифку" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьМедиагруппу" , "Отправить медиагруппу" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьМестоположение" , "Отправить местоположение" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьКонтакт" , "Отправить контакт" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОтправитьОпрос" , "Отправить опрос" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ПереслатьСообщение" , "Переслать сообщение" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_БанРазбан" , "Бан/Разбан" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_СоздатьСсылкуПриглашение" , "Создать ссылку-приглашение" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ЗакрепитьОткрепитьСообщение" , "Закрепить/Открепить сообщение" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ПолучитьЧислоУчастников" , "Получить число участников" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ПолучитьСписокАватаровФорума", "Получить список аватаров форума", Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_СоздатьУдалитьТемуФорума" , "Создать/Удалить тему форума" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ОткрытьЗакрытьГлавнуюТему" , "Открыть/Закрыть главную тему" , Телеграм);
НовыйТест(ТаблицаТестов, "Телеграм_ИзменитьИмяГлавнойТемы" , "Изменить имя главной темы" , Телеграм);
НовыйТест(ТаблицаТестов, "ВК_СоздатьСсылкуТокена" , "Создать ссылку получения токена", ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СоздатьУдалитьПост" , "Создать/Удалить пост" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СоздатьОпрос" , "Создать опрос" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СохранитьУдалитьКартинку" , "Добавить/Удалить картинку" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СоздатьИсторию" , "Создать историю" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_МетодыОбсуждений" , "Действия с обсуждениями" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ЛайкРепостКоммент" , "Лайк/Репост/Комментарий" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьСтатистику" , "Получить статистику" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьСтатистикуПостов" , "Получить статистику постов" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СоздатьРекламнуюКампанию" , "Создать рекламную кампанию" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ОтправитьСообщение" , "Отправить сообщение" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьКатегорииТоваров" , "Получить категории товаров" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СоздатьТоварПодборку" , "Создать товар и подборку" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_СоздатьТоварСоСвойствами" , "Создать товар со свойствами" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьСписокТоваров" , "Получить список товаров" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьСписокПодборок" , "Получить список подборок" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьСписокСвойств" , "Получить список свойств" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ВК_ПолучитьСписокЗаказов" , "Получить список заказов" , ВКонтакте);
НовыйТест(ТаблицаТестов, "ЯДиск_ПолучитьИнформациюОДиске" , "Получить информацию о диске" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_СоздатьПапку" , "Создать папку" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ЗагрузитьПоАдресуПолучитьОбъект", "Загрузить по URL и получить" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ЗагрузитьУдалитьФайл" , "Загрузить/Удалить файл" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_СоздатьКопиюОбъекта" , "Создать копию объекта" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ПолучитьСсылкуНаСкачивание" , "Получить ссылку на скачивание" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ПолучитьСписокФайлов" , "Получить список файлов" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ПереместитьОбъект" , "Переместить объект" , ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ДействияПубличныхОбъектов" , "Действия с публичными объектами", ЯДиск);
НовыйТест(ТаблицаТестов, "ЯДиск_ПолучитьСписокОпубликованных" , "Получить список опубликованных" , ЯДиск);
НовыйТест(ТаблицаТестов, "ГК_ПолучитьСсылкуАвторизации" , "Получить ссылку авторизации" , Календарь);
НовыйТест(ТаблицаТестов, "ГК_ПолучитьТокен" , "Получить токен" , Календарь);
НовыйТест(ТаблицаТестов, "ГК_ОбновитьТокен" , "Обновить токен" , Календарь);
НовыйТест(ТаблицаТестов, "ГК_ПолучитьСписокКалендарей" , "Получить список календарей" , Календарь);
НовыйТест(ТаблицаТестов, "ГК_СоздатьУдалитьКалендарь" , "Создать/Удалить календарь" , Календарь);
НовыйТест(ТаблицаТестов, "ГК_СоздатьУдалитьСобытие" , "Создать/Удалить событие" , Календарь);
НовыйТест(ТаблицаТестов, "ГК_ПолучитьСписокСобытий" , "Получить список событий" , Календарь);
НовыйТест(ТаблицаТестов, "Твиттер_ОбновитьТокен" , "Обновить токен" , Твиттер);
Возврат ТаблицаТестов;
КонецФункции
Функция ПолучитьОбщийМодуль(Знач Имя)
Модуль = Вычислить(Имя); // BSLLS:ExecuteExternalCodeInCommonModule-off
Возврат Модуль;
КонецФункции
Процедура НовыйТест(ТаблицаЗначений, Знач Метод, Знач Синоним, Знач Раздел);
НовыйТест = ТаблицаЗначений.Добавить();
НовыйТест.Метод = Метод;
НовыйТест.Синоним = Синоним;
НовыйТест.Раздел = Раздел;
КонецПроцедуры
Процедура ЗаписатьПараметрВФайл(Знач Параметр, Знач Значение, Знач Путь)
Значения = OPI_Инструменты.ПрочитатьJSONФайл(Путь);
Значения.Вставить(Параметр, Значение);
Запись = Новый ЗаписьJSON;
ПараметрыЗаписиJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Авто, Символы.Таб);
Запись.ОткрытьФайл(Путь, , , ПараметрыЗаписиJSON);
ЗаписатьJSON(Запись, Значения);
Запись.Закрыть();
КонецПроцедуры
#КонецОбласти

File diff suppressed because it is too large Load Diff

View File

@ -44,7 +44,7 @@
Параметры = Новый Структура;
Параметры.Вставить("summary" , Наименование);
Параметры.Вставить("timeZone", ЧасовойПояс());
Параметры.Вставить("timeZone", "Europe/Moscow");
Ответ = OPI_Инструменты.Post(URL, Параметры, Заголовки);
@ -427,7 +427,7 @@
Дата = Формат(Дата, ФорматДаты);
СтруктураДаты.Вставить(Поле , Дата);
СтруктураДаты.Вставить("timeZone", ЧасовойПояс());
СтруктураДаты.Вставить("timeZone", "Europe/Moscow");
Возврат СтруктураДаты;

View File

@ -276,7 +276,7 @@
Ответ = OPI_Инструменты.Get("https://cloud-api.yandex.net/v1/disk/resources/upload", Параметры, Заголовки);
URL = Ответ[Href];
Ответ = OPI_Инструменты.PutMultipart(URL, , Файл, "multipart", Заголовки);
Ответ = OPI_Инструменты.PutMultipart(URL, Новый Структура(), Файл, "multipart", Заголовки);
Возврат Ответ;

View File

@ -201,7 +201,7 @@
Попытка
//@skip-check module-unused-local-variable
SSL = Новый ЗащищенноеСоединениеOpenSSL;
SSL = Новый ЗащищенноеСоединениеOpenSSL; // BSLLS:UnusedLocalVariable-off
Исключение
Сервер = "https://" + Сервер;
КонецПопытки;
@ -235,8 +235,7 @@
ПараметрыJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Windows, " ", Истина, ЭкранированиеСимволовJSON.Нет,
Ложь, Ложь, Ложь, Ложь);
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ПроверятьСтруктуру = Истина;
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку(ПараметрыJSON);
ЗаписатьJSON(ЗаписьJSON, Данные);

View File

@ -142,7 +142,7 @@
КонецФункции
Функция ПутьКФайлуДанных()
Возврат "C:\data.json"; // BSLLS:UsingHardcodePath-off
Возврат "C:\GDrive\Мой диск\data.json"; // BSLLS:UsingHardcodePath-off
КонецФункции
Функция ПолучитьМассивРазделовТестирования()

View File

@ -40,7 +40,7 @@
//Для Asserts
Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт
Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт // BSLLS:UnusedParameters-off
Возврат OPI_ПолучениеДанныхТестов.СформироватьТестыАссертс();
КонецФункции
@ -298,7 +298,7 @@
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).ИмеетТип("Массив").ИмеетДлину(2);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).ИмеетТип("Массив");
КонецЦикла;
@ -586,18 +586,14 @@
Для Каждого Результат Из МассивРезультатов Цикл
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("response.post_id").ИмеетТип("Число").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["post_id"]).ИмеетТип("Число").Заполнено();
ИДПоста = Результат["response"]["post_id"];
Удаление = OPI_VK.УдалитьПост(ИДПоста, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("response").ИмеетТип("Число").Равно(1);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление) .ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление["response"]).ИмеетТип("Число").Равно(1);
КонецЦикла;
@ -617,10 +613,8 @@
Результат = OPI_VK.СоздатьОпрос(Вопрос, МассивВариантов, , Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("response.post_id").ИмеетТип("Число").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["post_id"]).ИмеетТип("Число").Заполнено();
ИДПоста = Результат["response"]["post_id"];
OPI_VK.УдалитьПост(ИДПоста, Параметры);
@ -641,10 +635,8 @@
Альбом = OPI_VK.СоздатьАльбом(Имя, Описание, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Альбом)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство("response.description").Равно(Описание);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Альбом).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Альбом["response"]["description"]).Равно(Описание);
ИДАльбома = Альбом[Response]["id"];
@ -658,28 +650,18 @@
Для Каждого Результат Из МассивРезультатов Цикл
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство("response[0].text").Равно(ОписаниеКартинки)
.Свойство("response[0].album_id").Равно(ИДАльбома);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["text"]).Равно(ОписаниеКартинки);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["album_id"]).Равно(ИДАльбома);
ИДКартинки = Результат[Response][0]["id"];
Удаление = OPI_VK.УдалитьКартинку(ИДКартинки, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип("Число").Равно(1);
Проверка_ВКИстина(Удаление);
КонецЦикла;
Удаление = OPI_VK.УдалитьАльбом(ИДАльбома, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип("Число").Равно(1);
Проверка_ВКИстина(Удаление);
УдалитьФайлы(ИВФ);
@ -703,11 +685,9 @@
Для Каждого Результат Из МассивРезультатов Цикл
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("response.count").ИмеетТип("Число").Равно(1)
.Свойство("response.items").ИмеетТип("Массив").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["count"]).ИмеетТип("Число").Равно(1);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["items"]).ИмеетТип("Массив").Заполнено();
КонецЦикла;
@ -727,41 +707,25 @@
Результат = OPI_VK.СоздатьОбсуждение(Название, Сообщение, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Response]).ИмеетТип(ТипЧисло).Заполнено();
ИДОбсуждения = Результат[Response];
Закрытие = OPI_VK.ЗакрытьОбсуждение(ИДОбсуждения, Ложь, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Закрытие)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Закрытие);
Открытие = OPI_VK.ОткрытьОбсуждение(ИДОбсуждения, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Открытие)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Открытие);
Отправка = OPI_VK.НаписатьВОбсуждение(ИДОбсуждения, Сообщение, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Отправка)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Отправка).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Отправка[Response]).ИмеетТип(ТипЧисло).Заполнено();
Удаление = OPI_VK.ЗакрытьОбсуждение(ИДОбсуждения, Истина, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Удаление);
КонецПроцедуры
@ -780,10 +744,8 @@
Лайк = OPI_VK.ПоставитьЛайк(ИДПоста, , Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Лайк)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство("response.likes").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Лайк).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Лайк["response"]["likes"]).ИмеетТип(ТипЧисло).Заполнено();
ВнешнийПост = 2571;
ВнешняяСтена = -218704372;
@ -791,19 +753,15 @@
Репост = OPI_VK.СделатьРепост(ВнешнийПост, ВнешняяСтена, , , Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство("response.success").ИмеетТип(ТипЧисло).Равно(1)
.Свойство("response.wall_repost_count").ИмеетТип(ТипЧисло).Равно(1);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост["response"]["success"]).ИмеетТип(ТипЧисло).Равно(1);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост["response"]["wall_repost_count"]).ИмеетТип(ТипЧисло).Равно(1);
Комментарий = OPI_VK.НаписатьКомментарий(ИДПоста, Параметры["owner_id"], Сообщение, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Комментарий)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство("response.comment_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Комментарий).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Комментарий["response"]["comment_id"]).ИмеетТип(ТипЧисло).Заполнено();
OPI_VK.УдалитьПост(ИДПоста, Параметры);
OPI_VK.УдалитьПост(Репост[Response]["post_id"], Параметры);
@ -821,11 +779,9 @@
Результат = OPI_VK.ПолучитьСтатистику(Дата0, Дата1, Параметры);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство("response[0].visitors").ИмеетТип(ТипСоответствие).Заполнено()
.Свойство("response[0].reach").ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["visitors"]).ИмеетТип(ТипСоответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["reach"]).ИмеетТип(ТипСоответствие).Заполнено();
КонецПроцедуры
@ -840,9 +796,7 @@
Результат = OPI_VK.ПолучитьСтатистикуПостов(МассивПостов, Параметры);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Массив")
.ИмеетДлину(2);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) .ИмеетТип("Массив").ИмеетДлину(2);
КонецПроцедуры
@ -859,10 +813,9 @@
Результат = OPI_VK.СоздатьРекламнуюКампанию(ИДКабинета, Наименование, Параметры);
Результат = Результат[Response][0];
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("error_code").ИмеетТип(ТипЧисло).Равно(602)
.Свойство(UID).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["error_code"]).ИмеетТип(ТипЧисло).Равно(602);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[UID]).ИмеетТип(ТипЧисло).Заполнено();
ИДКампании = Результат[UID];
ИДКатегории = 126;
@ -879,18 +832,16 @@
, Параметры);
Объявление = Объявление[Response][0];
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление)
.ИмеетТип(ТипСоответствие)
.Свойство("error_code").ИмеетТип(ТипЧисло).Равно(602)
.Свойство(UID).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление["error_code"]).ИмеетТип(ТипЧисло).Равно(602);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление[UID]).ИмеетТип(ТипЧисло).Заполнено();
ИДОбъявления = Объявление[UID];
Остановка = OPI_VK.ПриостановитьРекламноеОбъявление(ИДКабинета, ИДОбъявления, Параметры);
Остановка = Остановка[Response][0];
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Остановка)
.ИмеетТип(ТипСоответствие)
.Свойство(UID).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Остановка).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Остановка[UID]).ИмеетТип(ТипЧисло).Заполнено();
OPI_VK.УдалитьПост(ИДПоста, Параметры);
@ -910,9 +861,8 @@
Клавиатура = OPI_VK.СформироватьКлавиатуру(МассивКнопок);
Результат = OPI_VK.НаписатьСообщение(Текст, Пользователь, Токен, Клавиатура, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Свойство("response").ИмеетТип("Число").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]).ИмеетТип("Число").Заполнено();
КонецПроцедуры
@ -944,19 +894,17 @@
, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.albums_count").ИмеетТип(ТипЧисло).Заполнено()
.Свойство("response.market_album_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["albums_count"]).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_album_id"]).ИмеетТип(ТипЧисло).Заполнено();
ИДПодборки = Результат[Response]["market_album_id"];
Результат = OPI_VK.ИзменитьПодборкуТоваров("Измененная подборка", ИДПодборки, , , , Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Response]).ИмеетТип(ТипЧисло).Равно(1);
МассивКартинок = Новый Массив;
МассивКартинок.Добавить(ИВФ);
@ -981,9 +929,8 @@
Результат = OPI_VK.ДобавитьТовар(Товар, ИДПодборки, Параметры); // Добавление товара
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.market_item_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_item_id"]).ИмеетТип(ТипЧисло).Заполнено();
ИДТовара = Результат[Response]["market_item_id"];
@ -991,38 +938,25 @@
Товар.Вставить("Имя", "Тестовый товар измененный");
Результат = OPI_VK.ИзменитьТовар(ИДТовара, Товар, , Параметры); // Изменение товара
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Результат);
Результат = OPI_VK.ДобавитьТоварВПодборку(ИДТовара, ИДПодборки, Параметры); // Добавление в подборку
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Response).ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Response]).ИмеетТип(ТипЧисло).Заполнено();
Результат = OPI_VK.УдалитьТоварИзПодборки(ИДТовара, ИДПодборки, Параметры); // Удаляет из подборки
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Результат);
Результат = OPI_VK.УдалитьТовар(ИДТовара, Параметры); // Удаление товара
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Результат);
Результат = OPI_VK.УдалитьПодборку(ИДПодборки, Параметры); // Уадление подборки
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Результат);
УдалитьФайлы(ИВФ);
@ -1053,26 +987,21 @@
СоответствиеСвойств = Новый Соответствие;
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.property_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["property_id"]).ИмеетТип(ТипЧисло).Заполнено();
Результат = OPI_VK.ИзменитьСвойствоТовара("Цвет (изм.)", Свойство, Параметры);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Результат);
Для Каждого Вариант Из МассивВариантов Цикл
Результат = OPI_VK.ДобавитьВариантСвойстваТовара(Вариант, Свойство, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.variant_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["variant_id"]).ИмеетТип(ТипЧисло).Заполнено();
ИДВарианта = Результат[Response]["variant_id"];
СоответствиеСвойств.Вставить(Вариант, ИДВарианта);
@ -1082,10 +1011,7 @@
, ИДВарианта
, Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Результат);
КонецЦикла;
@ -1117,9 +1043,8 @@
ИДЖелтого = Результат[Response]["market_item_id"];
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.market_item_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_item_id"]).ИмеетТип(ТипЧисло).Заполнено();
Товар.Вставить("Имя" , "Тестовый товар (" + Красный + ")");
Товар.Вставить("ЗначенияСвойств", СоответствиеСвойств[Красный]);
@ -1129,9 +1054,8 @@
ИДКрасного = Результат[Response]["market_item_id"];
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.market_item_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_item_id"]).ИмеетТип(ТипЧисло).Заполнено();
МассивТоваров = Новый Массив;
МассивТоваров.Добавить(ИДЖелтого);
@ -1140,16 +1064,14 @@
Результат = OPI_VK.ПолучитьТоварыПоИД(МассивТоваров, Параметры);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.items").ИмеетТип("Массив").ИмеетДлину(2);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["items"]).ИмеетТип("Массив").ИмеетДлину(2);
Результат = OPI_VK.СгруппироватьТовары(МассивТоваров, , Параметры);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство("response.item_group_id").ИмеетТип(ТипЧисло).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["item_group_id"]).ИмеетТип(ТипЧисло).Заполнено();
OPI_VK.УдалитьТовар(ИДЖелтого , Параметры);
OPI_VK.УдалитьТовар(ИДКрасного, Параметры);
@ -1158,21 +1080,14 @@
Удаление = OPI_VK.УдалитьВариантСвойстваТовара(Вариант.Значение, Параметры);
OPI_Инструменты.Пауза(5);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Удаление);
КонецЦикла;
Удаление = OPI_VK.УдалитьСвойствоТовара(Свойство, Параметры);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление)
.ИмеетТип(ТипСоответствие)
.Заполнено()
.Свойство(Response).ИмеетТип(ТипЧисло).Равно(1);
Проверка_ВКИстина(Удаление);
УдалитьФайлы(ИВФ);
@ -1272,11 +1187,9 @@
Результат = OPI_YandexDisk.ПолучитьИнформациюОДиске(Токен);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(Соответствие)
.Заполнено()
.Свойство("system_folders").ИмеетТип(Соответствие)
.Свойство("user").ИмеетТип(Соответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(Соответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["system_folders"]).ИмеетТип(Соответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["user"]).ИмеетТип(Соответствие);
КонецПроцедуры
@ -1287,11 +1200,9 @@
Результат = OPI_YandexDisk.СоздатьПапку(Токен, Путь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("type").Равно("dir")
.Свойство("path").Равно("disk:" + Путь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("dir");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + Путь);
OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
@ -1308,11 +1219,9 @@
Результат = OPI_YandexDisk.ПолучитьОбъект(Токен, Путь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("type").Равно("file")
.Свойство("path").Равно("disk:" + Путь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + Путь);
OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
@ -1326,25 +1235,20 @@
ИВФ = ПолучитьИмяВременногоФайла("png");
Картинка.Записать(ИВФ);
МассивРезультатов = Новый Массив;
Результат = OPI_YandexDisk.ЗагрузитьФайл(Токен, Путь, Картинка, Истина);
МассивРезультатов.Добавить(OPI_YandexDisk.ЗагрузитьФайл(Токен, Путь, Картинка, Истина));
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие");
OPI_Инструменты.Пауза(10);
МассивРезультатов.Добавить(OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь));
Результат = OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено);
МассивРезультатов.Добавить(OPI_YandexDisk.ЗагрузитьФайл(Токен, Путь, ИВФ, Истина));
Результат = OPI_YandexDisk.ЗагрузитьФайл(Токен, Путь, ИВФ, Истина);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие");
OPI_Инструменты.Пауза(10);
МассивРезультатов.Добавить(OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь));
Для Каждого Результат Из МассивРезультатов Цикл
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
. ИмеетТип("Строка")
. НеЗаполнено();
КонецЦикла;
Результат = OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено);
УдалитьФайлы(ИВФ);
@ -1364,11 +1268,9 @@
Результат = OPI_YandexDisk.СоздатьКопиюОбъекта(Токен, ПутьОригинала, ПутьКопии, Истина);
OPI_Инструменты.Пауза(10);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("type").Равно("file")
.Свойство("path").Равно("disk:" + ПутьКопии);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + ПутьКопии);
OPI_YandexDisk.УдалитьОбъект(Токен, ПутьОригинала, Ложь);
OPI_YandexDisk.УдалитьОбъект(Токен, ПутьКопии, Ложь);
@ -1386,13 +1288,11 @@
Результат = OPI_YandexDisk.ПолучитьСсылкуДляСкачивания(Токен, Путь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("method").Равно("GET")
.Свойство("href").ИмеетТип("Строка").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["method"]).Равно("GET");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["href"]).ИмеетТип("Строка").Заполнено();
OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
КонецПроцедуры
@ -1404,12 +1304,10 @@
Результат = OPI_YandexDisk.ПолучитьСписокФайлов(Токен, Количество, Отступ, "image");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("limit").Равно(Количество)
.Свойство("offset").Равно(Отступ)
.Свойство("items").ИмеетТип("Массив");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["limit"]).Равно(Количество);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["offset"]).Равно(Отступ);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["items"]).ИмеетТип("Массив");
КонецПроцедуры
@ -1426,14 +1324,12 @@
Результат = OPI_YandexDisk.ПереместитьОбъект(Токен, ПутьОригинала, ПутьКопии, Истина);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("type").Равно("file")
.Свойство("path").Равно("disk:" + ПутьКопии);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + ПутьКопии);
OPI_YandexDisk.УдалитьОбъект(Токен, ПутьОригинала, Ложь);
OPI_YandexDisk.УдалитьОбъект(Токен, ПутьКопии, Ложь);
OPI_YandexDisk.УдалитьОбъект(Токен, ПутьОригинала, Ложь);
OPI_YandexDisk.УдалитьОбъект(Токен, ПутьКопии, Ложь);
КонецПроцедуры
@ -1463,33 +1359,27 @@
Счетчик = 0;
Для Каждого Результат Из МассивРезультатов Цикл
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(Соответствие)
.Заполнено()
.Свойство("type").Равно("file")
.Свойство("path").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(Соответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Заполнено();
Если Счетчик = 0 Тогда
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Свойство(PUrl).ИмеетТип("Строка").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[PUrl]).ИмеетТип("Строка").Заполнено();
Иначе
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).НетСвойства(PUrl);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[PUrl]).ИмеетТип("Неопределено");
КонецЕсли;
Счетчик = Счетчик + 1;
КонецЦикла;
OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания)
.ИмеетТип(Соответствие)
.Заполнено()
.Свойство("method").Равно("GET")
.Свойство("href").ИмеетТип("Строка").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания).ИмеетТип(Соответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания["method"]).Равно("GET");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания["href"]).ИмеетТип("Строка").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект)
.ИмеетТип(Соответствие)
.Заполнено()
.Свойство("type").Равно("file")
.Свойство("path").Равно("/");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект).ИмеетТип(Соответствие).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект["type"]).Равно("file");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект["path"]).Равно("/");
OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь);
@ -1503,12 +1393,10 @@
Результат = OPI_YandexDisk.ПолучитьСписокОпубликованныхОбъектов(Токен, Количество, Отступ);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("limit").Равно(Количество)
.Свойство("offset").Равно(Отступ)
.Свойство("items").ИмеетТип("Массив");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["limit"]).Равно(Количество);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["offset"]).Равно(Отступ);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["items"]).ИмеетТип("Массив");
КонецПроцедуры
@ -1555,11 +1443,10 @@
Результат = OPI_GoogleWorkspace.ОбновитьТокен(ClientID, ClientSecret, RefreshToken);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Свойство("access_token").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["access_token"]).Заполнено();
OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Token" , Результат["access_token"]);
OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Token", Результат["access_token"]);
КонецПроцедуры
@ -1581,17 +1468,15 @@
НаименованиеИзмененное = Наименование + " (изм.)";
ТипСоответствие = Тип("Соответствие");
ТипСтрока = Тип("Строка");
Description = "description";
Summary = "summary";
Черный = "#000000";
Желтый = "#ffd800";
Результат = OPI_GoogleCalendar.СоздатьКалендарь(Токен, Наименование);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(Наименование)
.Свойство("id").ИмеетТип(ТипСтрока).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Summary]).Равно(Наименование);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["id"]).ИмеетТип(ТипСтрока).Заполнено();
Календарь = Результат["id"];
@ -1600,55 +1485,41 @@
, НаименованиеИзмененное
, Описание);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(НаименованиеИзмененное)
.Свойство(Description).Равно(Описание)
.Свойство("id").ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, НаименованиеИзмененное, Описание);
Результат = OPI_GoogleCalendar.ПолучитьМетаданныеКалендаря(Токен, Календарь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(НаименованиеИзмененное)
.Свойство(Description).Равно(Описание)
.Свойство("id").ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, НаименованиеИзмененное, Описание);
Результат = OPI_GoogleCalendar.ДобавитьКалендарьВСписок(Токен, Календарь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(НаименованиеИзмененное)
.Свойство(Description).Равно(Описание)
.Свойство("id").ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, НаименованиеИзмененное, Описание);
Результат = OPI_GoogleCalendar.ИзменитьКалендарьСписка(Токен, Календарь, Черный, Желтый, Ложь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(НаименованиеИзмененное)
.Свойство("foregroundColor").Равно(Черный)
.Свойство("backgroundColor").Равно(Желтый);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Summary]).Равно(НаименованиеИзмененное);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["foregroundColor"]).Равно(Черный);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["backgroundColor"]).Равно(Желтый);
Результат = OPI_GoogleCalendar.ПолучитьКалендарьСписка(Токен, Календарь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(НаименованиеИзмененное)
.Свойство("foregroundColor").Равно(Черный)
.Свойство("backgroundColor").Равно(Желтый);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Summary]).Равно(НаименованиеИзмененное);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["foregroundColor"]).Равно(Черный);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["backgroundColor"]).Равно(Желтый);
Результат = OPI_GoogleCalendar.ОчиститьОсновнойКалендарь(Токен);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).НеЗаполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено);
Результат = OPI_GoogleCalendar.УдалитьКалендарьИзСписка(Токен, Календарь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).НеЗаполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено);
Результат = OPI_GoogleCalendar.УдалитьКалендарь(Токен, Календарь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).НеЗаполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено);
КонецПроцедуры
@ -1660,10 +1531,6 @@
Наименование = "Новое событие";
Описание = "Описание тестового события";
ОписаниеИзм = "Описание тестового события (изм.)";
ТипСоответствие = Тип("Соответствие");
ТипСтрока = Тип("Строка");
Summary = "summary";
Description = "description";
UID = "id";
Час = 3600;
@ -1686,42 +1553,26 @@
Результат = OPI_GoogleCalendar.СоздатьСобытие(Токен, Календарь, СоответствиеСобытия);
Событие = Результат[UID];
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(Наименование)
.Свойство(Description).Равно(Описание)
.Свойство(UID).ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, Наименование, Описание);
СоответствиеСобытия = Новый Соответствие;
СоответствиеСобытия.Вставить("Описание", ОписаниеИзм);
Результат = OPI_GoogleCalendar.ИзменитьСобытие(Токен, Календарь, СоответствиеСобытия, Событие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(Наименование)
.Свойство(Description).Равно(ОписаниеИзм)
.Свойство(UID).ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, Наименование, ОписаниеИзм);
Результат = OPI_GoogleCalendar.ПолучитьСобытие(Токен, Календарь, Событие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(Наименование)
.Свойство(Description).Равно(ОписаниеИзм)
.Свойство(UID).ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, Наименование, ОписаниеИзм);
Результат = OPI_GoogleCalendar.ПереместитьСобытие(Токен, Календарь, Календарь, Событие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип(ТипСоответствие)
.Свойство(Summary).Равно(Наименование)
.Свойство(Description).Равно(ОписаниеИзм)
.Свойство(UID).ИмеетТип(ТипСтрока).Заполнено();
Проверка_ГКОбъект(Результат, Наименование, ОписаниеИзм);
Результат = OPI_GoogleCalendar.УдалитьСобытие(Токен, Календарь, Событие);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).НеЗаполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено);
КонецПроцедуры
@ -1732,8 +1583,7 @@
Результат = OPI_GoogleCalendar.ПолучитьСписокСобытий(Токен, Календарь);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Массив");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Массив");
КонецПроцедуры
@ -1746,11 +1596,9 @@
Параметры = ПолучитьПараметрыТвиттер();
Результат = OPI_Twitter.ОбновитьТокен(Параметры);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат)
.ИмеетТип("Соответствие")
.Заполнено()
.Свойство("access_token").Заполнено()
.Свойство("refresh_token").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["access_token"]).Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["refresh_token"]).Заполнено();
Рефреш = Результат["refresh_token"];
Токен = Результат["acess_token"];
@ -1810,6 +1658,22 @@
КонецПроцедуры
Процедура Проверка_ВКИстина(Знач Результат)
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено();
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]).ИмеетТип("Число").Равно(1);
КонецПроцедуры
Процедура Проверка_ГКОбъект(Знач Результат, Знач Наименование, Знач Описание)
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие");
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["summary"]).Равно(Наименование);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["description"]).Равно(Описание);
OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["id"]).ИмеетТип("Строка").Заполнено();
КонецПроцедуры
#КонецОбласти
#КонецОбласти