From 78fcc4833ba231d84f7d1fe257ae12e50f387d0b Mon Sep 17 00:00:00 2001 From: Anton Titovets Date: Fri, 1 Mar 2024 16:27:30 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A3=D0=BD=D0=B8=D1=84=D0=B8=D0=BA=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=B4=D0=B0=201=D0=A1=20?= =?UTF-8?q?=D0=B8=20OneScript,=20=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- OInt/core/src/Modules/OPI_GoogleCalendar.os | 559 +++++ OInt/core/src/Modules/OPI_GoogleWorkspace.os | 118 ++ OInt/core/src/Modules/OPI_Notion.os | 799 ++++++++ OInt/core/src/Modules/OPI_Telegram.os | 1080 ++++++++++ OInt/core/src/Modules/OPI_Twitter.os | 610 ++++++ OInt/core/src/Modules/OPI_VK.os | 1802 +++++++++++++++++ OInt/core/src/Modules/OPI_Viber.os | 409 ++++ OInt/core/src/Modules/OPI_YandexDisk.os | 500 +++++ OInt/core/src/Modules/OPI_YandexID.os | 92 + OInt/core/src/Modules/OPI_Инструменты.os | 764 +++++++ OInt/core/src/Modules/OPI_Криптография.os | 82 + .../src/Modules/OPI_ПолучениеДанныхТестов.os | 272 +++ OInt/core/tests/OPI_Тесты.os | 1680 +++++++++++++++ .../OPI_GoogleCalendar/Module.bsl | 4 +- .../CommonModules/OPI_YandexDisk/Module.bsl | 2 +- .../CommonModules/OPI_Инструменты/Module.bsl | 5 +- .../OPI_ПолучениеДанныхТестов/Module.bsl | 2 +- OPI/src/CommonModules/OPI_Тесты/Module.bsl | 474 ++--- 18 files changed, 8942 insertions(+), 312 deletions(-) create mode 100644 OInt/core/src/Modules/OPI_GoogleCalendar.os create mode 100644 OInt/core/src/Modules/OPI_GoogleWorkspace.os create mode 100644 OInt/core/src/Modules/OPI_Notion.os create mode 100644 OInt/core/src/Modules/OPI_Telegram.os create mode 100644 OInt/core/src/Modules/OPI_Twitter.os create mode 100644 OInt/core/src/Modules/OPI_VK.os create mode 100644 OInt/core/src/Modules/OPI_Viber.os create mode 100644 OInt/core/src/Modules/OPI_YandexDisk.os create mode 100644 OInt/core/src/Modules/OPI_YandexID.os create mode 100644 OInt/core/src/Modules/OPI_Инструменты.os create mode 100644 OInt/core/src/Modules/OPI_Криптография.os create mode 100644 OInt/core/src/Modules/OPI_ПолучениеДанныхТестов.os create mode 100644 OInt/core/tests/OPI_Тесты.os diff --git a/OInt/core/src/Modules/OPI_GoogleCalendar.os b/OInt/core/src/Modules/OPI_GoogleCalendar.os new file mode 100644 index 000000000..ce4d0d001 --- /dev/null +++ b/OInt/core/src/Modules/OPI_GoogleCalendar.os @@ -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 И ЗначениеЗаполнено(Страница) Тогда + ПолучитьСписокСобытийРекурсивно(Заголовки, МассивСобытий, Страница); + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_GoogleWorkspace.os b/OInt/core/src/Modules/OPI_GoogleWorkspace.os new file mode 100644 index 000000000..b93902004 --- /dev/null +++ b/OInt/core/src/Modules/OPI_GoogleWorkspace.os @@ -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"); + + Возврат СтрСоединить(МассивРазрешений, " "); + +КонецФункции + +#КонецОбласти \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_Notion.os b/OInt/core/src/Modules/OPI_Notion.os new file mode 100644 index 000000000..991a477bc --- /dev/null +++ b/OInt/core/src/Modules/OPI_Notion.os @@ -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", Телефон); +КонецФункции + +#КонецОбласти + +#КонецОбласти \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_Telegram.os b/OInt/core/src/Modules/OPI_Telegram.os new file mode 100644 index 000000000..7708103e1 --- /dev/null +++ b/OInt/core/src/Modules/OPI_Telegram.os @@ -0,0 +1,1080 @@ +// 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 +#Использовать ".." + +#Область ПрограммныйИнтерфейс + +#Область ДанныеИНастройка + +// Получить информацию бота. +// +// Параметры: +// Токен - Строка - Токен +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ПолучитьИнформациюБота(Знач Токен) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/getMe"; + Ответ = OPI_Инструменты.Get(URL); + + Возврат Ответ; + +КонецФункции + +// Получить обновления. +// +// Параметры: +// Токен - Строка - Токен +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ПолучитьОбновления(Знач Токен) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/getUpdates"; + Ответ = OPI_Инструменты.Get(URL); + Возврат Ответ; + +КонецФункции + +// Установить Webhook. +// +// Параметры: +// Токен - Строка - Токен +// URL - Строка - Адрес обработки запросов от Telegram (с https://) +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция УстановитьWebhook(Знач Токен, Знач URL) Экспорт + + Параметры_ = Новый Структура; + Параметры_.Вставить("url", URL); + + URL = "api.telegram.org/bot" + Токен + "/setWebHook"; + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить Webhook. +// +// Параметры: +// Токен - Строка - Токен +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция УдалитьWebhook(Знач Токен) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/deleteWebHook"; + Ответ = OPI_Инструменты.Get(URL); + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область ОтправкаДанных + +// Отправить текстовое сообщение. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Текст - Строка - Текст сообщения +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ОтправитьТекстовоеСообщение(Знач Токен, Знач IDЧата, Знач Текст, Знач Клавиатура = "") Экспорт + + OPI_Инструменты.ЗаменитьСпецСимволы(Текст); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("text" , Текст); + Параметры_.Вставить("reply_markup", Клавиатура); + + ДобавитьИдентификаторЧата(IDЧата, Параметры_); + + URL = "api.telegram.org/bot" + Токен + "/sendMessage"; + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Отправить картинку. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - IDЧата +// Текст - Строка - Текст +// Картинка - ДвоичныеДанные,Строка - Двоичные данные или путь к картинке +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// Строка, Произвольный, HTTPОтвет - Ответ сервера Telegram +Функция ОтправитьКартинку(Знач Токен, Знач IDЧата, Знач Текст, Знач Картинка, Знач Клавиатура = "") Экспорт + + Возврат ОтправитьФайл(Токен, IDЧата, Текст, Картинка, "photo", Клавиатура); + +КонецФункции + +// Отправить видео. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Текст - Строка - Текст +// Видео - ДвоичныеДанные,Строка - Двоичные данные или путь к видео +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// Строка, Произвольный, HTTPОтвет - Ответ сервера Telegram +Функция ОтправитьВидео(Знач Токен, Знач IDЧата, Знач Текст, Знач Видео, Знач Клавиатура = "") Экспорт + + Возврат ОтправитьФайл(Токен, IDЧата, Текст, Видео, "video", Клавиатура); + +КонецФункции + +// Отправить аудио. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Текст - Строка - Текст +// Аудио - ДвоичныеДанные,Строка - Двоичные данные или путь к аудио +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// Строка, Произвольный, HTTPОтвет - Ответ сервера Telegram +Функция ОтправитьАудио(Знач Токен, Знач IDЧата, Знач Текст, Знач Аудио, Знач Клавиатура = "") Экспорт + + Возврат ОтправитьФайл(Токен, IDЧата, Текст, Аудио, "audio", Клавиатура); + +КонецФункции + +// Отправить документ. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Текст - Строка - Текст +// Документ - ДвоичныеДанные,Строка - Двоичные данные или путь к документу +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// Строка, Произвольный, HTTPОтвет - Ответ сервера Telegram +Функция ОтправитьДокумент(Знач Токен, Знач IDЧата, Знач Текст, Знач Документ, Знач Клавиатура = "") Экспорт + + Возврат ОтправитьФайл(Токен, IDЧата, Текст, Документ, "document", Клавиатура); + +КонецФункции + +// Отправить гифку. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Текст - Строка - Текст +// Гифка - ДвоичныеДанные,Строка - Двоичные данные или путь к гифке +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// Строка, Произвольный, HTTPОтвет - Ответ сервера Telegram +Функция ОтправитьГифку(Знач Токен, Знач IDЧата, Знач Текст, Знач Гифка, Знач Клавиатура = "") Экспорт + + Возврат ОтправитьФайл(Токен, IDЧата, Текст, Гифка, "animation", Клавиатура); + +КонецФункции + +// Отправить набор любых файлов. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Текст - Строка - Текст +// СоответствиеФайлов - Соответствие из Строка,ДвоичныеДанные - Коллекция файлов: +// * Ключ - ДвоичныеДанные,Строка - Файл +// * Значение - Строка - Тип файла: audio, document, photo, video +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// Произвольный, HTTPОтвет - Ответ сервера Telegram +// BSLLS:Typo-off +Функция ОтправитьМедиагруппу(Знач Токен, Знач IDЧата, Знач Текст, Знач СоответствиеФайлов, Знач Клавиатура = "") Экспорт + + // СоответствиеФайлов + // Ключ - Файл, Значение - Тип + // Типы: audio, document, photo, video + // Нельзя замешивать разные типы! + + OPI_Инструменты.ЗаменитьСпецсимволы(Текст); + + URL = "api.telegram.org/bot" + Токен + "/sendMediaGroup"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + СтруктураФайлов = Новый Структура; + Медиа = Новый Массив; + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("caption" , Текст); + Параметры_.Вставить("reply_markup", Клавиатура); + + ДобавитьИдентификаторЧата(IDЧата, Параметры_); + СформироватьМассивМедиа(СоответствиеФайлов, Текст, СтруктураФайлов, Медиа); + + Параметры_.Вставить("media", Медиа); + + Ответ = OPI_Инструменты.PostMultipart(URL, Параметры_, СтруктураФайлов, "mixed"); + + Возврат Ответ; + +КонецФункции + +// Отправить местоположение. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Широта - Строка,Число - Географическая широта +// Долгота - Строка,Число - Географическая долгота +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ОтправитьМестоположение(Знач Токен, Знач IDЧата, Знач Широта, Знач Долгота, Знач Клавиатура = "") Экспорт + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + URL = "api.telegram.org/bot" + Токен + "/sendLocation"; + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("latitude" , OPI_Инструменты.ЧислоВСтроку(Широта)); + Параметры_.Вставить("longitude" , OPI_Инструменты.ЧислоВСтроку(Долгота)); + Параметры_.Вставить("reply_markup", Клавиатура); + + ДобавитьИдентификаторЧата(IDЧата, Параметры_); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Отправить контакт. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Имя - Строка - Имя контакта +// Фамилия - Строка - Фамилия контакта +// Телефон - Строка - Телефон контакта +// Клавиатура - Строка - См. СформироватьКлавиатуруПоМассивуКнопок +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ОтправитьКонтакт(Знач Токен, Знач IDЧата, Знач Имя, Знач Фамилия, Знач Телефон, Знач Клавиатура = "") Экспорт + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + URL = "api.telegram.org/bot" + Токен + "/sendContact"; + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("first_name" , Имя); + Параметры_.Вставить("last_name" , Фамилия); + Параметры_.Вставить("phone_number", Строка(Телефон)); + Параметры_.Вставить("reply_markup", Клавиатура); + + ДобавитьИдентификаторЧата(IDЧата, Параметры_); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Отправить опрос. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Вопрос - Строка - Вопрос опроса +// МассивОтветов - Массив из строка - Массив вариантов ответа +// Анонимный - Булево - Анонимность опроса +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ОтправитьОпрос(Знач Токен, Знач IDЧата, Знач Вопрос, Знач МассивОтветов, Знач Анонимный = Истина) Экспорт + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + Ответы = OPI_Инструменты.JSONСтрокой(МассивОтветов); + URL = "api.telegram.org/bot" + Токен + "/sendPoll"; + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode", "Markdown"); + Параметры_.Вставить("question" , Вопрос); + Параметры_.Вставить("options" , Ответы); + + Если Не Анонимный Тогда + Параметры_.Вставить("is_anonymous", Ложь); + КонецЕсли; + + ДобавитьИдентификаторЧата(IDЧата, Параметры_); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Переслать сообщение. +// +// Параметры: +// Токен - Строка - Токен +// IDОригинала - Строка,Число - ID оригинального сообщения +// ОткудаID - Строка,Число - ID чата оригинального сообщения +// КудаID - Строка,Число - ID целевого чата +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ПереслатьСообщение(Знач Токен, Знач IDОригинала, Знач ОткудаID, Знач КудаID) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/forwardMessage"; + IDОригинала = OPI_Инструменты.ЧислоВСтроку(IDОригинала); + ОткудаID = OPI_Инструменты.ЧислоВСтроку(ОткудаID); + КудаID = OPI_Инструменты.ЧислоВСтроку(КудаID); + + Параметры_ = Новый Структура; + Параметры_.Вставить("from_chat_id", ОткудаID); + Параметры_.Вставить("message_id" , IDОригинала); + + ДобавитьИдентификаторЧата(КудаID, Параметры_); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область Администрирование + +// Бан. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// IDПользователя - Строка,Число - ID целевого пользователя +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция Бан(Знач Токен, Знач IDЧата, Знач IDПользователя) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/banChatMember"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + IDПользователя = OPI_Инструменты.ЧислоВСтроку(IDПользователя); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode", "Markdown"); + Параметры_.Вставить("chat_id" , IDЧата); + Параметры_.Вставить("user_id" , IDПользователя); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Разбан. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// IDПользователя - Строка,Число - ID целевого пользователя +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция Разбан(Знач Токен, Знач IDЧата, Знач IDПользователя) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/unbanChatMember"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + IDПользователя = OPI_Инструменты.ЧислоВСтроку(IDПользователя); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("chat_id" , IDЧата); + Параметры_.Вставить("user_id" , IDПользователя); + Параметры_.Вставить("only_if_banned", Истина); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Создать ссылку приглашение. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// Заголовок - Строка - Заголовок приглашения +// ДатаИстечения - Дата - Дата окончания жизни ссылки (безсрочно, если не указано) +// ЛимитПользователей - Число - Лимит пользователей (бесконечно, если не указано) +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция СоздатьСсылкуПриглашение(Знач Токен + , Знач IDЧата + , Знач Заголовок = "" + , Знач ДатаИстечения = "" + , Знач ЛимитПользователей = 0) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/createChatInviteLink"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode", "Markdown"); + Параметры_.Вставить("chat_id" , IDЧата); + Параметры_.Вставить("name" , Заголовок); + + Если ЗначениеЗаполнено(ДатаИстечения) Тогда + ДатаИстечения = OPI_Инструменты.UNIXTime(ДатаИстечения); + Параметры_.Вставить("expire_date", ДатаИстечения); + КонецЕсли; + + Параметры_.Вставить("member_limit", ЛимитПользователей); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Закрепить сообщение. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// IDСообщения - Строка,Число - ID целевого сообщения +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ЗакрепитьСообщение(Знач Токен, Знач IDЧата, Знач IDСообщения) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/pinChatMessage"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + IDСообщения = OPI_Инструменты.ЧислоВСтроку(IDСообщения); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("chat_id" , IDЧата); + Параметры_.Вставить("message_id" , IDСообщения); + Параметры_.Вставить("disable_notification", Истина); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Открепить сообщение. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка - ID целевого чата +// IDСообщения - Строка,Число - ID целевого сообщения +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера Telegram +Функция ОткрепитьСообщение(Знач Токен, Знач IDЧата, Знач IDСообщения) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/unpinChatMessage"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + IDСообщения = OPI_Инструменты.ЧислоВСтроку(IDСообщения); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode", "Markdown"); + Параметры_.Вставить("chat_id" , IDЧата); + Параметры_.Вставить("message_id", IDСообщения); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Получить число участников. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID целевого чата +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Получить число участников +Функция ПолучитьЧислоУчастников(Знач Токен, Знач IDЧата) Экспорт + + URL = "api.telegram.org/bot" + Токен + "/getChatMemberCount"; + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode", "Markdown"); + Параметры_.Вставить("chat_id" , IDЧата); + + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область TelegramMiniApp + +// Обработать данные TMA и определить их достоверность +// +// Параметры: +// СтрокаДанных - Строка - querry из Telegram.WebApp.initData +// Токен - Строка - Токен бота +// +// Возвращаемое значение: +// Соответствие из Строка - Обработанные данные с признаком достоверности +Функция ОбработатьДанныеTMA(Знач СтрокаДанных, Знач Токен) Экспорт + + СтрокаДанных = РаскодироватьСтроку(СтрокаДанных, СпособКодированияСтроки.КодировкаURL); + СтруктураДанных = OPI_Инструменты.ПараметрыЗапросаВСоответствие(СтрокаДанных); + Ключ = "WebAppData"; + Хэш = ""; + + Результат = OPI_Криптография.HMACSHA256(ПолучитьДвоичныеДанныеИзСтроки(Ключ), ПолучитьДвоичныеДанныеИзСтроки(Токен)); + + ТЗнач = Новый ТаблицаЗначений; + ТЗнач.Колонки.Добавить("Ключ"); + ТЗнач.Колонки.Добавить("Значение"); + + Для Каждого Данные Из СтруктураДанных Цикл + + НоваяСтрока = ТЗнач.Добавить(); + НоваяСтрока.Ключ = Данные.Ключ; + НоваяСтрока.Значение = Данные.Значение; + + КонецЦикла; + + ТЗнач.Сортировать("Ключ"); + + СоответствиеВозврата = Новый Соответствие; + DCS = ""; + + Для Каждого СтрокаТЗ Из ТЗнач Цикл + + Если СтрокаТЗ.Ключ <> "hash" Тогда + DCS = DCS + СтрокаТЗ.Ключ + "=" + СтрокаТЗ.Значение + Символы.ПС; + СоответствиеВозврата.Вставить(СтрокаТЗ.Ключ, СтрокаТЗ.Значение); + Иначе + Хэш = СтрокаТЗ.Значение; + КонецЕсли; + + КонецЦикла; + + DCS = Лев(DCS, СтрДлина(DCS) - 1); + Подпись = OPI_Криптография.HMACSHA256(Результат, ПолучитьДвоичныеДанныеИзСтроки(DCS)); + + Финал = ПолучитьHexСтрокуИзДвоичныхДанных(Подпись); + + Если Финал = вРег(Хэш) Тогда + Ответ = Истина; + Иначе + Ответ = Ложь; + КонецЕсли; + + СоответствиеВозврата.Вставить("passed", Ответ); + + Возврат СоответствиеВозврата; + +КонецФункции + +#КонецОбласти + +#Область РежимФорума + +// Получить список иконок аватаров. +// +// Параметры: +// Токен - Строка - Токен +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - Список иконок аватаров +Функция ПолучитьСписокИконокАватаров(Знач Токен) Экспорт + + Result = "result"; + URL = "api.telegram.org/bot" + Токен + "/getForumTopicIconStickers"; + Ответ = OPI_Инструменты.Get(URL); + Иконки = Ответ[Result]; + Коллекция = Новый Соответствие; + + Для Каждого Иконка Из Иконки Цикл + Коллекция.Вставить(Иконка["custom_emoji_id"], Иконка["emoji"]); + КонецЦикла; + + Возврат Коллекция; + +КонецФункции + +// Создать тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата создания темы +// Заголовок - Строка - Заголовок темы +// IDИконки - Строка - См.ПолучитьСписокИконокАватаров +// +// Возвращаемое значение: +// HTTPОтвет - Ответ сервера Telegram +Функция СоздатьТемуФорума(Знач Токен, Знач IDЧата, Знач Заголовок, Знач IDИконки = "") Экспорт + Возврат УправлениеТемойФорума(Токен, IDЧата, Заголовок, IDИконки); +КонецФункции + +// Изменить тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// IDТемы - Строка,Число - ID темы +// Заголовок - Строка - Новый заголовок +// IDИконки - Строка - См.ПолучитьСписокИконокАватаров +// +// Возвращаемое значение: +// HTTPОтвет - Ответ сервера Telegram +Функция ИзменитьТемуФорума(Знач Токен + , Знач IDЧата + , Знач IDТемы + , Знач Заголовок = Неопределено + , Знач IDИконки = Неопределено) Экспорт + + Возврат УправлениеТемойФорума(Токен, IDЧата, Заголовок, IDИконки, IDТемы); +КонецФункции + +// Закрыть тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// IDТемы - Строка,Число - ID темы +// +// Возвращаемое значение: +// Неопределено, HTTPОтвет - Ответ сервера Telegram +Функция ЗакрытьТемуФорума(Знач Токен, Знач IDЧата, Знач IDТемы = "") Экспорт + Возврат УправлениеСостояниемТемыФорума(Токен, IDЧата, 2, IDТемы); +КонецФункции + +// Открыть тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// IDТемы - Строка,Число - ID темы +// +// Возвращаемое значение: +// Неопределено, HTTPОтвет - Ответ сервера Telegram +Функция ОткрытьТемуФорума(Знач Токен, Знач IDЧата, Знач IDТемы = "") Экспорт + Возврат УправлениеСостояниемТемыФорума(Токен, IDЧата, 1, IDТемы); +КонецФункции + +// Удалить тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// IDТемы - Строка,Число - ID темы +// +// Возвращаемое значение: +// Неопределено, HTTPОтвет - Ответ сервера Telegram +Функция УдалитьТемуФорума(Знач Токен, Знач IDЧата, Знач IDТемы) Экспорт + Возврат УправлениеСостояниемТемыФорума(Токен, IDЧата, 3, IDТемы); +КонецФункции + +// Скрыть главную тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// +// Возвращаемое значение: +// HTTPОтвет - Ответ сервера Telegram +Функция СкрытьГлавнуюТемуФорума(Знач Токен, Знач IDЧата) Экспорт + Возврат УправлениеВидимостьюГлавнойТемыФорума(Токен, IDЧата, Истина); +КонецФункции + +// Показать главную тему форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// +// Возвращаемое значение: +// HTTPОтвет - Ответ сервера Telegram +Функция ПоказатьГлавнуюТемуФорума(Знач Токен, Знач IDЧата) Экспорт + Возврат УправлениеВидимостьюГлавнойТемыФорума(Токен, IDЧата, Ложь); +КонецФункции + +// Изменить имя главной темы форума. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID Чата темы +// Заголовок - Строка - Новый заголовок +// +// Возвращаемое значение: +// HTTPОтвет - Ответ сервера Telegram +Функция ИзменитьИмяГлавнойТемыФорума(Знач Токен, Знач IDЧата, Знач Заголовок) Экспорт + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + Параметры_ = Новый Структура; + Параметры_.Вставить("chat_id", IDЧата); + Параметры_.Вставить("name" , Заголовок); + + URL = "api.telegram.org/bot" + Токен + "/editGeneralForumTopic"; + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Очистить список закрепленных сообщений темы. +// +// Параметры: +// Токен - Строка - Токен +// IDЧата - Строка,Число - ID чата темы +// IDТемы - Строка - ID темы. Главная, если не заполнено +// +// Возвращаемое значение: +// HTTPОтвет - Очистить список закрепленных сообщений темы +Функция ОчиститьСписокЗакрепленныхСообщенийТемы(Знач Токен, Знач IDЧата, Знач IDТемы = "") Экспорт + + IDТемы = OPI_Инструменты.ЧислоВСтроку(IDТемы); + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + Параметры_ = Новый Структура; + Параметры_.Вставить("chat_id", IDЧата); + + Если ЗначениеЗаполнено(IDТемы) Тогда + Метод = "/unpinAllForumTopicMessages"; + Параметры_.Вставить("message_thread_id", IDТемы); + Иначе + Метод = "/unpinAllGeneralForumTopicMessages"; + КонецЕсли; + + URL = "api.telegram.org/bot" + Токен + Метод; + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область Прочее + +// Сформировать клавиатуру по массиву кнопок. +// +// Параметры: +// МассивКнопок - Массив из Строка - Массив кнопок +// ПодСообщением - Булево - Клавиатура под сообщением или на нижней панели +// ОднаПодОдной - Булево - Истина - кнопки выводятся в столбик, Ложь - в строку +// +// Возвращаемое значение: +// Строка - JSON клавиатуры +Функция СформироватьКлавиатуруПоМассивуКнопок(Знач МассивКнопок + , Знач ПодСообщением = Ложь + , Знач ОднаПодОдной = Истина) Экспорт + + Если ОднаПодОдной Тогда + Строки = СоздатьВысокуюКлавиатуру(МассивКнопок); + Иначе + Строки = СоздатьДлиннуюКлваиатуру(МассивКнопок); + КонецЕсли; + + Если ПодСообщением Тогда + СтруктураПараметра = Новый Структура("inline_keyboard,rows", Строки, 1); + Иначе + СтруктураПараметра = Новый Структура("keyboard,resize_keyboard", Строки, Истина); + КонецЕсли; + + ЗаписьJSON = Новый ЗаписьJSON; + ПЗJSON = Новый ПараметрыЗаписиJSON(ПереносСтрокJSON.Нет, , , ЭкранированиеСимволовJSON.СимволыВнеASCII); + ЗаписьJSON.УстановитьСтроку(ПЗJSON); + + ЗаписатьJSON(ЗаписьJSON, СтруктураПараметра); + + Возврат ЗаписьJSON.Закрыть(); + +КонецФункции + +#КонецОбласти + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция ОтправитьФайл(Знач Токен, Знач IDЧата, Знач Текст, Знач Файл, Знач Вид, Знач Клавиатура) + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + Расширение = ""; + Метод = ""; + + ОпределитьМетодОтправки(Вид, Метод, Расширение); + OPI_Инструменты.ЗаменитьСпецсимволы(Текст); + + Если Не ТипЗнч(Файл) = Тип("ДвоичныеДанные") Тогда + ТекущийФайл = Новый Файл(Файл); + Расширение = ?(Вид = "document" Или Вид = "animation", ТекущийФайл.Расширение, ""); + Файл = Новый ДвоичныеДанные(Файл); + КонецЕсли; + + Расширение = СтрЗаменить(Расширение, ".", "___"); + + Параметры_ = Новый Структура; + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("caption" , Текст); + Параметры_.Вставить("reply_markup", Клавиатура); + + ДобавитьИдентификаторЧата(IDЧата, Параметры_); + + СтруктураФайлов = Новый Структура; + СтруктураФайлов.Вставить(Вид + Расширение, Файл); + + URL = "api.telegram.org/bot" + Токен + Метод; + Ответ = OPI_Инструменты.PostMultipart(URL, Параметры_, СтруктураФайлов, "mixed"); + + Возврат Ответ; + +КонецФункции + +Функция УправлениеТемойФорума(Знач Токен + , Знач IDЧата + , Знач Заголовок = Неопределено + , Знач IDИконки = Неопределено + , Знач IDТемы = "") + + IDТемы = OPI_Инструменты.ЧислоВСтроку(IDТемы); + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + + Параметры_ = Новый Структура; + Параметры_.Вставить("name" , Заголовок); + Параметры_.Вставить("chat_id" , IDЧата); + Параметры_.Вставить("icon_custom_emoji_id", IDИконки); + + Если ЗначениеЗаполнено(IDТемы) Тогда + Метод = "/editForumTopic"; + Параметры_.Вставить("message_thread_id", IDТемы); + Иначе + Метод = "/createForumTopic"; + КонецЕсли; + + OPI_Инструменты.УдалитьПустыеПоляКоллекции(Параметры_); + Ответ = OPI_Инструменты.Get("api.telegram.org/bot" + Токен + Метод, Параметры_); + + Возврат Ответ; + +КонецФункции + +Функция УправлениеСостояниемТемыФорума(Знач Токен, Знач IDЧата, Знач Статус, Знач IDТемы = "") + + Если ЗначениеЗаполнено(IDТемы) Тогда + Форум = "Forum"; + Иначе + Форум = "GeneralForum"; + КонецЕсли; + + IDТемы = OPI_Инструменты.ЧислоВСтроку(IDТемы); + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + Метод = ОпределитьМетодУправленияФорумом(Статус, Форум); + Параметры_ = Новый Структура; + Параметры_.Вставить("chat_id", IDЧата); + + Если ЗначениеЗаполнено(IDТемы) Тогда + Параметры_.Вставить("message_thread_id", IDТемы); + КонецЕсли; + + URL = "api.telegram.org/bot" + Токен + Метод; + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +Функция УправлениеВидимостьюГлавнойТемыФорума(Знач Токен, Знач IDЧата, Знач Скрыть) + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + + Если Скрыть Тогда + Метод = "/hideGeneralForumTopic"; + Иначе + Метод = "/unhideGeneralForumTopic"; + КонецЕсли; + + Параметры_ = Новый Структура; + Параметры_.Вставить("chat_id", IDЧата); + + URL = "api.telegram.org/bot" + Токен + Метод; + Ответ = OPI_Инструменты.Get(URL, Параметры_); + + Возврат Ответ; + +КонецФункции + +Функция ОпределитьМетодУправленияФорумом(Знач Статус, Знач Форум) + + Открыть = 1; + Закрыть = 2; + Удалить = 3; + + Если Статус = Открыть Тогда + Метод = "/reopen" + Форум + "Topic"; + ИначеЕсли Статус = Закрыть Тогда + Метод = "/close" + Форум + "Topic"; + ИначеЕсли Статус = Удалить Тогда + Метод = "/deleteForumTopic"; + Иначе + ВызватьИсключение "Некорректный статус управления форумом"; + КонецЕсли; + + Возврат Метод; + +КонецФункции + +Функция СоздатьВысокуюКлавиатуру(Знач МассивКнопок) + + Строки = Новый Массив; + + Для Каждого Кнопка Из МассивКнопок Цикл + Кнопки = Новый Массив; + Кнопка = OPI_Инструменты.ЧислоВСтроку(Кнопка); + Кнопки.Добавить(Новый Структура("text,callback_data", Кнопка, Кнопка)); + Строки.Добавить(Кнопки); + КонецЦикла; + + Возврат Строки; + +КонецФункции + +Функция СоздатьДлиннуюКлваиатуру(Знач МассивКнопок) + + Строки = Новый Массив; + Кнопки = Новый Массив; + + Для Каждого Кнопка Из МассивКнопок Цикл + Кнопка = OPI_Инструменты.ЧислоВСтроку(Кнопка); + Кнопки.Добавить(Новый Структура("text,callback_data", Кнопка, Кнопка)); + КонецЦикла; + + Строки.Добавить(Кнопки); + + Возврат Строки; + +КонецФункции + +Процедура СформироватьМассивМедиа(Знач СоответствиеФайлов, Знач Текст, СтруктураФайлов, Медиа) + + Счетчик = 0; + + Для Каждого ТекущийФайл Из СоответствиеФайлов Цикл + + Если Не ТипЗнч(ТекущийФайл.Ключ) = Тип("ДвоичныеДанные") Тогда + ДД = Новый ДвоичныеДанные(ТекущийФайл.Ключ); + ЭтотФайл = Новый Файл(ТекущийФайл.Ключ); + ИмяМедиа = ТекущийФайл.Значение + Строка(Счетчик) + ?(ТекущийФайл.Значение = "document", + ЭтотФайл.Расширение, ""); + ПолноеИмяМедиа = СтрЗаменить(ИмяМедиа, ".", "___"); + Иначе + ДД = ТекущийФайл.Ключ; + ИмяМедиа = ТекущийФайл.Значение + Строка(Счетчик); + ПолноеИмяМедиа = ИмяМедиа; + КонецЕсли; + + СтруктураФайлов.Вставить(ПолноеИмяМедиа, ДД); + + СтруктураМедиа = Новый Структура; + СтруктураМедиа.Вставить("type", ТекущийФайл.Значение); + СтруктураМедиа.Вставить("media", "attach://" + ИмяМедиа); + + Если Счетчик = 0 Тогда + СтруктураМедиа.Вставить("caption", Текст); + КонецЕсли; + + Медиа.Добавить(СтруктураМедиа); + + Счетчик = Счетчик + 1; + + КонецЦикла; + + Медиа = OPI_Инструменты.JSONСтрокой(Медиа); + +КонецПроцедуры + +Процедура ДобавитьИдентификаторЧата(Знач IDЧата, Параметры) + + IDЧата = OPI_Инструменты.ЧислоВСтроку(IDЧата); + МассивЧата = СтрРазделить(IDЧата, "*", Ложь); + + Если МассивЧата.Количество() > 1 Тогда + + IDЧата = МассивЧата[1]; + IDТемы = МассивЧата[2]; + + Параметры.Вставить("message_thread_id", IDТемы); + + КонецЕсли; + + Параметры.Вставить("chat_id", IDЧата); + +КонецПроцедуры + +Процедура ОпределитьМетодОтправки(Знач Вид, Метод, Расширение) + + Если Вид = "photo" Тогда + Метод = "/sendPhoto"; + ИначеЕсли Вид = "video" Тогда + Метод = "/sendVideo"; + ИначеЕсли Вид = "audio" Тогда + Метод = "/sendAudio"; + ИначеЕсли Вид = "document" Тогда + Метод = "/sendDocument"; + ИначеЕсли Вид = "animation" Тогда + Метод = "/sendAnimation"; + Расширение = ".gif"; + Иначе + ВызватьИсключение "Некорректный вид отправки"; + КонецЕсли; + +КонецПроцедуры + +#КонецОбласти + +// BSLLS:Typo-on \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_Twitter.os b/OInt/core/src/Modules/OPI_Twitter.os new file mode 100644 index 000000000..36c6bbf97 --- /dev/null +++ b/OInt/core/src/Modules/OPI_Twitter.os @@ -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 \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_VK.os b/OInt/core/src/Modules/OPI_VK.os new file mode 100644 index 000000000..53bf3c5f4 --- /dev/null +++ b/OInt/core/src/Modules/OPI_VK.os @@ -0,0 +1,1802 @@ +// 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:NumberOfOptionalParams-off + +//Раскомментировать, если выполняется OneScript +#Использовать ".." + +#Область ПрограммныйИнтерфейс + +#Область ПолучениеТокена + +// Получение ссылки для интерактивного получения токена (access_token), который необходим +// для дальнейших действий +// +// Параметры: +// app_id - Строка,Число - app_id из настроек приложения +// +// Возвращаемое значение: +// Строка - URL, по которому необходимо перейти в браузере +Функция СоздатьСсылкуПолученияТокена(Знач App_id) Экспорт + + // access_token нужно будет забрать из параметра в строке адреса браузера + Возврат "https://oauth.vk.com/authorize?client_id=" + OPI_Инструменты.ЧислоВСтроку(App_id) + + "&scope=offline,wall,groups,photos,stats,stories,ads,market" + + "&v=5.131&response_type=token&redirect_uri=https://api.vk.com/blank.html"; + +КонецФункции + +#КонецОбласти + +#Область РаботаСГруппой + +// Создать пост. +// +// Параметры: +// Текст - Строка - Текст +// МассивКартинок - Массив из Строка,ДвоичныеДанные - Массив картинок +// Рекламный - Булево - Признак "Это реклама" +// СсылкаПодЗаписью - Строка - Ссылка под записью, если нужна +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СоздатьПост(Знач Текст + , Знач МассивКартинок + , Знач Рекламный = Ложь + , Знач СсылкаПодЗаписью = "" + , Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + СтрокаВложений = ""; + + Если Не ТипЗнч(МассивКартинок) = Тип("Массив") Тогда + + ОднаКартинка = МассивКартинок; + МассивКартинок = Новый Массив; + МассивКартинок.Добавить(ОднаКартинка); + + КонецЕсли; + + Для Каждого КартинкаПоста Из МассивКартинок Цикл + + Ответ = ЗагрузитьФотоНаСервер(КартинкаПоста, Параметры_); + + ОтветСоответствие = Ответ.Получить("response")[0]; + + ФотоID = "photo" + + OPI_Инструменты.ЧислоВСтроку(ОтветСоответствие.Получить("owner_id")) + + "_" + + OPI_Инструменты.ЧислоВСтроку(ОтветСоответствие.Получить("id")); + + СтрокаВложений = СтрокаВложений + ФотоID + ","; + + КонецЦикла; + + СтрокаВложений = СтрокаВложений + СсылкаПодЗаписью; + + Параметры_.Вставить("message" , Текст); + Параметры_.Вставить("attachments" , СтрокаВложений); + Параметры_.Вставить("mark_as_ads" , ?(Рекламный, 1, 0)); + Параметры_.Вставить("close_comments" , ?(Рекламный, 1, 0)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/wall.post", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить пост. +// +// Параметры: +// IDПоста - Строка,Число - ID поста +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция УдалитьПост(Знач IDПоста, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("post_id", OPI_Инструменты.ЧислоВСтроку(IDПоста)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/wall.delete", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Создать опрос. +// +// Параметры: +// Вопрос - Строка - Вопрос опроса +// МассивОтветов - Массив из Строка - Массив вариантов ответа +// Картинка - Строка,ДвоичныеДанные - Картинка опроса +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СоздатьОпрос(Знач Вопрос, Знач МассивОтветов, Знач Картинка = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Ответ = OPI_Инструменты.Get("api.vk.com/method/polls.getPhotoUploadServer", Параметры_); + Response = "response"; + Hash = "hash"; + Photo = "photo"; + URL = Ответ[Response]["upload_url"]; + IDФото = ""; + + Параметры_.Вставить("upload_url", URL); + + Если Не Картинка = "" Тогда + + Если ТипЗнч(Картинка) = Тип("Строка") Тогда + Путь = Картинка; + Картинка = Новый ДвоичныеДанные(Картинка); + Иначе + //@skip-check missing-temporary-file-deletion + // BSLLS:MissingTemporaryFileDeletion-off + Путь = ПолучитьИмяВременногоФайла("jpeg"); + КонецЕсли; + + Файлы = Новый Соответствие; + Файлы.Вставить(Путь, Картинка); + + Ответ = OPI_Инструменты.PostMultipart(URL, Параметры_, Файлы); + + Параметры_.Вставить(Hash , Ответ[Hash]); + Параметры_.Вставить(Photo , Ответ[Photo]); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/polls.savePhoto", Параметры_); + IDФото = Ответ.Получить(Response)["id"]; + + КонецЕсли; + + Параметры_.Вставить("is_anonymous" , 1); + Параметры_.Вставить("is_multiple" , 0); + + Ответы = "["; + Первый = Истина; + + Для Каждого Ответ Из МассивОтветов Цикл + + Если Первый Тогда + Первый = Ложь; + Иначе + Ответы = Ответы + ", "; + КонецЕсли; + + Ответы = Ответы + """" + Ответ + """"; + + КонецЦикла; + + Ответы = Ответы + "]"; + + Параметры_.Вставить("add_answers" , Ответы); + Параметры_.Вставить("photo_id" , OPI_Инструменты.ЧислоВСтроку(IDФото)); + Параметры_.Вставить("question" , Вопрос); + + Опрос = OPI_Инструменты.Get("api.vk.com/method/polls.create", Параметры_); + ОпросСоответствие = Опрос.Получить(Response); + + ОпросID = "poll" + + OPI_Инструменты.ЧислоВСтроку(ОпросСоответствие.Получить("owner_id")) + + "_" + + OPI_Инструменты.ЧислоВСтроку(ОпросСоответствие.Получить("id")); + + Параметры_.Вставить("attachments", ОпросID); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/wall.post", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Создать альбом. +// +// Параметры: +// Наименование - Строка - Наименование альбома +// Описание - Строка - Описание альбома +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СоздатьАльбом(Знач Наименование, Знач Описание = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + Параметры_.Вставить("title" , Наименование); + Параметры_.Вставить("description" , Описание); + Параметры_.Вставить("upload_by_admins_only", 1); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/photos.createAlbum", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить альбом. +// +// Параметры: +// IDАльбома - Строка,Число - ID альбома +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция УдалитьАльбом(Знач IDАльбома, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("album_id", OPI_Инструменты.ЧислоВСтроку(IDАльбома)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/photos.deleteAlbum", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Создать историю. +// +// Параметры: +// Картинка - Строка,ДвоичныеДанные - Фон истории +// URL - Строка - URL для кнопки под историей +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СоздатьИсторию(Знач Картинка, Знач URL = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("link_text" , "more"); + Параметры_.Вставить("link_url" , URL); + Параметры_.Вставить("add_to_news" , "1"); + + Ответ = ЗагрузитьФотоНаСервер(Картинка, Параметры_, "История"); + Возврат Ответ; + +КонецФункции + +// Сохранить картинку в альбом. +// +// Параметры: +// IDАльбома - Строка,Число - ID альбома +// Картинка - ДвоичныеДанные,Строка - Двоичные данные или путь к картинке +// Описание - Строка - Описание картинки +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СохранитьКартинкуВАльбом(Знач IDАльбома, Знач Картинка, Знач Описание = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + Параметры_.Вставить("album_id" , OPI_Инструменты.ЧислоВСтроку(IDАльбома)); + Параметры_.Вставить("caption" , Описание); + + Возврат ЗагрузитьФотоНаСервер(Картинка, Параметры_, "Альбом"); + +КонецФункции + +// Удалить картинку. +// +// Параметры: +// IDКартинки - Строка,Число - ID картинки +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция УдалитьКартинку(Знач IDКартинки, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("photo_id", OPI_Инструменты.ЧислоВСтроку(IDКартинки)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/photos.delete", Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область РаботаСОбсуждениями + +// Создать обсуждение. +// +// Параметры: +// Наименование - Строка - Наименование обсуждения +// ТекстПервогоСообщения - Строка - Текст первого сообщения +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СоздатьОбсуждение(Знач Наименование, Знач ТекстПервогоСообщения, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("title" , Наименование); + Параметры_.Вставить("text" , ТекстПервогоСообщения); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/board.addTopic", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Закрыть обсуждение. +// +// Параметры: +// IDОбсуждения - Строка,Число - ID обсуждения +// УдалитьПолностью - Булево - Удалить полностью или закрыть (сделать неактивным) +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Закрыть обсуждение +Функция ЗакрытьОбсуждение(Знач IDОбсуждения, Знач УдалитьПолностью = Ложь, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("topic_id", OPI_Инструменты.ЧислоВСтроку(IDОбсуждения)); + + Метод = ?(УдалитьПолностью, "deleteTopic", "closeTopic"); + Ответ = OPI_Инструменты.Get("api.vk.com/method/board." + Метод, Параметры_); + + Возврат Ответ; + +КонецФункции + +// Открыть обсуждение. +// +// Параметры: +// IDОбсуждения - Строка,Число - ID обсуждения +// Параметры - Структура из Строка - См. ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция ОткрытьОбсуждение(Знач IDОбсуждения, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("topic_id", OPI_Инструменты.ЧислоВСтроку(IDОбсуждения)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/board.openTopic", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Написать в обсуждение. +// +// Параметры: +// IDОбсуждения - Строка,Число - ID обсуждения +// Текст - Строка - Текст сообщения +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция НаписатьВОбсуждение(Знач IDОбсуждения, Знач Текст, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("topic_id" , OPI_Инструменты.ЧислоВСтроку(IDОбсуждения)); + Параметры_.Вставить("message" , Текст); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/board.createComment", Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область ИнтерактивныеДействия + +// Поставить лайк. +// +// Параметры: +// IDПоста - Строка,Число - ID поста +// IDСтены - Строка,Число - ID стены расположения поста +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция ПоставитьЛайк(Знач IDПоста, Знач IDСтены = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + IDСтены = ?(ЗначениеЗаполнено(IDСтены), IDСтены, Параметры_["owner_id"]); + ОбъектВК = "wall" + OPI_Инструменты.ЧислоВСтроку(IDСтены) + "_" + OPI_Инструменты.ЧислоВСтроку(IDПоста); + + Параметры_.Вставить("type" , "post"); + Параметры_.Вставить("object" , ОбъектВК); + Параметры_.Вставить("item_id" , OPI_Инструменты.ЧислоВСтроку(IDПоста)); + Параметры_.Вставить("owner_id" , OPI_Инструменты.ЧислоВСтроку(IDСтены)); + Параметры_.Вставить("from_group" , 0); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/likes.add", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Сделать репост. +// +// Параметры: +// IDПоста - Строка,Число - ID поста +// IDСтены - Строка,Число - ID стены расположения поста +// ЦелеваяСтена - Строка,Число - ID целевой стены/группы +// Рекламный - Булево - Признак рекламного поста +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +//@skip-check method-too-many-params +// BSLLS:NumberOfOptionalParams-off +Функция СделатьРепост(Знач IDПоста + , Знач IDСтены = "" + , Знач ЦелеваяСтена = "" + , Знач Рекламный = Ложь + , Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + Источник = ?(ЗначениеЗаполнено(IDСтены) + , OPI_Инструменты.ЧислоВСтроку(IDСтены) + , OPI_Инструменты.ЧислоВСтроку(Параметры_["owner_id"])); + + Приемник = ?(ЗначениеЗаполнено(ЦелеваяСтена) + , СтрЗаменить(OPI_Инструменты.ЧислоВСтроку(ЦелеваяСтена), "-", "") + , OPI_Инструменты.ЧислоВСтроку(Параметры_["group_id"])); + + Параметры_.Вставить("object" , "wall" + Источник + "_" + OPI_Инструменты.ЧислоВСтроку(IDПоста)); + Параметры_.Вставить("group_id" , Приемник); + Параметры_.Вставить("mark_as_ads" , ?(Рекламный, 1, 0)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/wall.repost", Параметры_); + + Возврат Ответ; + +КонецФункции +// BSLLS:NumberOfOptionalParams-on + +// Написать сообщение. +// +// Параметры: +// Текст - Строка - Текст сообщения +// IDПользователя - Строка - ID пользователя-адресата +// Communitytoken - Строка - Токен бота чата сообщества, котрый можно получить в настройках +// Клавиатура - Строка - JSON клавиатуры. См.СформироватьКлавиатуру +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция НаписатьСообщение(Знач Текст + , Знач IDПользователя + , Знач Communitytoken + , Знач Клавиатура = "" + , Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("access_token", Communitytoken); + + Параметры_.Вставить("user_id" , OPI_Инструменты.ЧислоВСтроку(IDПользователя)); + Параметры_.Вставить("peer_id" , OPI_Инструменты.ЧислоВСтроку(IDПользователя)); + Параметры_.Вставить("parse_mode" , "Markdown"); + Параметры_.Вставить("random_id" , 0); + Параметры_.Вставить("message" , Текст); + + Если ЗначениеЗаполнено(Клавиатура) Тогда + Параметры_.Вставить("keyboard", Клавиатура); + КонецЕсли; + + Ответ = OPI_Инструменты.Get("api.vk.com/method/messages.send", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Написать комментарий. +// +// Параметры: +// IDПоста - Строка,Число - ID целевого поста +// IDСтены - Строка,Число - ID стены расположения поста +// Текст - Строка - Текст комментария +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция НаписатьКомментарий(Знач IDПоста, Знач IDСтены, Знач Текст, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + Параметры_.Вставить("owner_id" , OPI_Инструменты.ЧислоВСтроку(IDСтены)); + Параметры_.Вставить("from_group" , OPI_Инструменты.ЧислоВСтроку(Параметры_["group_id"])); + Параметры_.Вставить("post_id" , OPI_Инструменты.ЧислоВСтроку(IDПоста)); + Параметры_.Вставить("message" , Текст); + + Параметры_.Удалить("group_id"); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/wall.createComment", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Сократить ссылку. +// +// Параметры: +// URL - Строка - URL для сокращения +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Строка - Сокращенный URL +Функция СократитьСсылку(Знач URL, Знач Параметры = "") Экспорт + + Response = "response"; + Параметры_ = Новый Структура; + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("url", URL); + + Ответ = OPI_Инструменты.Get("https://api.vk.com/method/utils.getShortLink", Параметры_); + + Возврат Ответ[Response]["short_url"]; + +КонецФункции + +#КонецОбласти + +#Область Статистика + +// Получить статистику. +// +// Параметры: +// ДатаНачала - Дата - Дата начала периода +// ДатаОкончания - Дата - Дата окончания периода +// Параметры - Структура из Строка - Параметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция ПолучитьСтатистику(Знач ДатаНачала, Знач ДатаОкончания, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + ДатаНачала = Формат(ДатаНачала - Дата(1970, 1, 1, 1, 0, 0), "ЧГ=0"); + ДатаОкончания = Формат(ДатаОкончания - дата(1970, 1, 1, 1, 0, 0), "ЧГ=0"); + + Параметры_.Вставить("timestamp_from" , ДатаНачала); + Параметры_.Вставить("timestamp_to" , ДатаОкончания); + Параметры_.Вставить("stats_groups" , "visitors, reach, activity"); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/stats.get", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Получить статистику постов. +// +// Параметры: +// МассивИДПостов - Массив из Строка,Число - Массив ID постов +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Массив из Произвольный - Массив данных статистики по постам +Функция ПолучитьСтатистикуПостов(Знач МассивИДПостов, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + МассивОтветов = Новый Массив; + МассивНабора = Новый Массив; + МаксимумПостов = 30; + Response = "response"; + + Для Каждого Пост Из МассивИДПостов Цикл + + МассивНабора.Добавить(OPI_Инструменты.ЧислоВСтроку(Пост)); + + Если МассивНабора.Количество() = МаксимумПостов Тогда + + СтрокаНомеров = СтрСоединить(МассивНабора, ","); + Параметры_.Вставить("post_ids", СтрокаНомеров); + + Статистика = OPI_Инструменты.Get("api.vk.com/method/stats.getPostReach", Параметры_); + МассивСтатистики = Статистика[Response]; + + Для Каждого ЭлементСтатистики Из МассивСтатистики Цикл + МассивОтветов.Добавить(ЭлементСтатистики); + КонецЦикла; + + МассивНабора = Новый Массив; + + КонецЕсли; + + КонецЦикла; + + СтрокаНомеров = СтрСоединить(МассивНабора, ","); + Параметры_.Вставить("post_ids", СтрокаНомеров); + + Статистика = OPI_Инструменты.Get("api.vk.com/method/stats.getPostReach", Параметры_); + МассивСтатистики = Статистика[Response]; + + Для Каждого ЭлементСтатистики Из МассивСтатистики Цикл + МассивОтветов.Добавить(ЭлементСтатистики); + КонецЦикла; + + Возврат МассивОтветов; + +КонецФункции + +#КонецОбласти + +#Область РаботаСРекламнымКабинетом + +// Создать рекламную кампанию. +// +// Параметры: +// IDКабинета - Строка,Число - ID рекламного кабинета +// Наименование - Строка - Наименование кампании +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция СоздатьРекламнуюКампанию(Знач IDКабинета, Знач Наименование, Знач Параметры = "") Экспорт + + ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДата(); + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("account_id", OPI_Инструменты.ЧислоВСтроку(IDКабинета)); + + МассивСтруктур = Новый Массив; + ДатаСтарт = Формат(ТекущаяДата - Дата(1970, 1, 1, 1, 0, 0), "ЧГ=0"); + ДатаСтоп = Формат(ДобавитьМесяц(ТекущаяДата, 24) - Дата(1970, 1, 1, 1, 0, 0), "ЧГ=0"); + + СтруктураКампании = Новый Структура; + СтруктураКампании.Вставить("type" , "promoted_posts"); + СтруктураКампании.Вставить("name" , Наименование); + СтруктураКампании.Вставить("day_limit" , 0); + СтруктураКампании.Вставить("all_limit" , 0); + СтруктураКампании.Вставить("start_time" , ДатаСтарт); + СтруктураКампании.Вставить("stop_time" , ДатаСтоп); + СтруктураКампании.Вставить("status" , 1); + + МассивСтруктур.Добавить(СтруктураКампании); + + JSONДата = OPI_Инструменты.JSONСтрокой(МассивСтруктур); + + Параметры_.Вставить("data", JSONДата); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/ads.createCampaigns", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Создать рекламное объявление. +// +// Параметры: +// НомерКампании - Строка,Число - ID рекламной кампании +// ДневнойЛимит - Строка,Число - Дневной лимит в рублях +// НомерКатегории - Строка,Число - Номер рекламной категории +// IDПоста - Строка,Число - ID поста, используемого в качетсве рекламы +// IDКабинета - Строка,Число - ID рекламного кабинета +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция СоздатьРекламноеОбъявление(Знач НомерКампании + , Знач ДневнойЛимит + , Знач НомерКатегории + , Знач IDПоста + , Знач IDКабинета + , Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Линк = "https://vk.com/wall-" + + Параметры_["group_id"] + + "_" + + OPI_Инструменты.ЧислоВСтроку(IDПоста); + + МассивСтруктур = Новый Массив; + СтруктураКампании = Новый Структура; + СтруктураКампании.Вставить("campaign_id" , OPI_Инструменты.ЧислоВСтроку(НомерКампании)); + СтруктураКампании.Вставить("ad_format" , 9); + СтруктураКампании.Вставить("conversion_event_id" , 1); + СтруктураКампании.Вставить("autobidding" , 1); + СтруктураКампании.Вставить("cost_type" , 3); + СтруктураКампании.Вставить("goal_type" , 2); + СтруктураКампании.Вставить("ad_platform" , "all"); + СтруктураКампании.Вставить("publisher_platforms" , "vk"); + СтруктураКампании.Вставить("publisher_platforms_auto" , "1"); + СтруктураКампании.Вставить("day_limit" , OPI_Инструменты.ЧислоВСтроку(ДневнойЛимит)); + СтруктураКампании.Вставить("all_limit" , "0"); + СтруктураКампании.Вставить("category1_id" , OPI_Инструменты.ЧислоВСтроку(НомерКатегории)); + СтруктураКампании.Вставить("age_restriction" , 0); + СтруктураКампании.Вставить("status" , 1); + СтруктураКампании.Вставить("name" , "Объявление"); + СтруктураКампании.Вставить("link_url" , Линк); + + МассивСтруктур.Добавить(СтруктураКампании); + + JSONДата = OPI_Инструменты.JSONСтрокой(МассивСтруктур); + + Параметры_.Вставить("data" , JSONДата); + Параметры_.Вставить("account_id" , OPI_Инструменты.ЧислоВСтроку(IDКабинета)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/ads.createAds", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Приостановить рекламное объявление. +// +// Параметры: +// IDКабинета - Строка,Число - ID рекламного кабинета +// IDОбъявления - Строка,Число - ID объявления +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера ВК +Функция ПриостановитьРекламноеОбъявление(Знач IDКабинета, Знач IDОбъявления, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + Параметры_.Вставить("account_id", OPI_Инструменты.ЧислоВСтроку(IDКабинета)); + + МассивСтруктур = Новый Массив; + СтруктураКампании = Новый Структура; + СтруктураКампании.Вставить("ad_id" , OPI_Инструменты.ЧислоВСтроку(IDОбъявления)); + СтруктураКампании.Вставить("status" , 0); + + МассивСтруктур.Добавить(СтруктураКампании); + + JSONДата = OPI_Инструменты.JSONСтрокой(МассивСтруктур); + + Параметры_.Вставить("data", JSONДата); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/ads.updateAds", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Получить список рекламных категорий. +// +// Параметры: +// Параметры - Структура из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Строка, Произвольный, ДвоичныеДанные, Неопределено - Получить список рекламных категорий +Функция ПолучитьСписокРекламныхКатегорий(Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Ответ = OPI_Инструменты.Get("api.vk.com/method/ads.getCategories", Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область РаботаСТоварами + +// Получить список категорий товаров. +// +// Параметры: +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Соответствие Из Строка - Ключ - ID, Значение - Имя +Функция ПолучитьСписокКатегорийТоваров(Знач Параметры = "") Экспорт + + Response = "response"; + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getCategories", Параметры_); + Количество = Ответ[Response]["count"]; + + Параметры_.Вставить("count", Количество); + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getCategories", Параметры_); + Категории = Ответ[Response]["items"]; + + СоответствиеКатегорий = Новый Соответствие; + + Для Каждого Категория Из Категории Цикл + СоответствиеКатегорий.Вставить(Категория["id"], Категория["name"]); + КонецЦикла; + + Возврат СоответствиеКатегорий; + +КонецФункции + +// Получить список товаров. +// +// Параметры: +// Альбом - Строка,Число - ID альбома, если нужен +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - Массив соответствий товаров +Функция ПолучитьСписокТоваров(Знач Альбом = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("count" , 200); + Параметры_.Вставить("extended" , 1); + Параметры_.Вставить("with_disabled", 1); + + Если ЗначениеЗаполнено(Альбом) Тогда + Параметры_.Вставить("album_id", OPI_Инструменты.ЧислоВСтроку(Альбом)); + КонецЕсли; + + МассивТоваров = Новый Массив; + ПолучитьСписокТоваровРекурсивно(МассивТоваров, Параметры_); + + Возврат МассивТоваров; + +КонецФункции + +// Получить товары по ИД. +// +// Параметры: +// Товары - Строка, Массив Из Строка - ID товара или массив ID товаров +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ПолучитьТоварыПоИД(Знач Товары, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + СтрокаТоваров = ""; + Owner = "owner_id"; + + Если ТипЗнч(Товары) <> Тип("Массив") Тогда + Товар = Товары; + Товары = Новый Массив; + Товары.Добавить(Товар); + КонецЕсли; + + Для Каждого Товар Из Товары Цикл + ТекущийТовар = Параметры[Owner] + "_" + Товар; + ТекущийТовар = OPI_Инструменты.ЧислоВСтроку(ТекущийТовар); + СтрокаТоваров = СтрокаТоваров + ТекущийТовар + ","; + КонецЦикла; + + СтрокаТоваров = Лев(СтрокаТоваров, СтрДлина(СтрокаТоваров) - 1); + Параметры_.Вставить("item_ids", СтрокаТоваров); + Параметры_.Вставить("extended", 1); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getById", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Добавить товар. +// +// Параметры: +// ОписаниеТовара - Соответствие Из КлючИЗначение - См.ПолучитьОписаниеТовара +// Подборка - Строка - Подборка +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ДобавитьТовар(Знач ОписаниеТовара, Знач Подборка = "", Знач Параметры = "") Экспорт + Возврат УправлениеТоваром(ОписаниеТовара, , Подборка, Параметры); +КонецФункции + +// Изменить товар. +// +// Параметры: +// Товар - Число,Строка - Идентификатор изменяемого товара +// ОписаниеТовара - Соответствие Из КлючИЗначение - См.ПолучитьОписаниеТовара +// Подборка - Строка - Идентификатор новой подборки +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ИзменитьТовар(Знач Товар, Знач ОписаниеТовара, Знач Подборка = "", Знач Параметры = "") Экспорт + Возврат УправлениеТоваром(ОписаниеТовара, Товар, Подборка, Параметры); +КонецФункции + +// Удалить товар. +// +// Параметры: +// Товар - Строка,Число - ID товара +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция УдалитьТовар(Знач Товар, Знач Параметры = "") Экспорт + + Товар = OPI_Инструменты.ЧислоВСтроку(Товар); + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("item_id", Товар); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.delete", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Сгруппировать товары. +// +// Параметры: +// МассивТоваров - Массив Из Строка - Массив ID товаров +// СуществующаяГруппа - Строка - ID существующей группы, если необходимо +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция СгруппироватьТовары(Знач МассивТоваров, Знач СуществующаяГруппа = "", Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + МассивТоваров_ = Новый Массив; + + Для Каждого Товар Из МассивТоваров Цикл + МассивТоваров_.Добавить(OPI_Инструменты.ЧислоВСтроку(Товар)); + КонецЦикла; + + Товары = СтрСоединить(МассивТоваров_, ","); + + Параметры_.Вставить("item_ids", Товары); + + Если ЗначениеЗаполнено(СуществующаяГруппа) Тогда + Параметры_.Вставить("item_group_id", OPI_Инструменты.ЧислоВСтроку(СуществующаяГруппа)); + КонецЕсли; + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.groupItems", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Получить описание товара. +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - Пустое описание товара: +// *Имя - Строка - Имя товара +// *Описание - Строка - Описание товара +// *Категория - Строка - См. ПолучитьСписокКатегорийТоваров +// *Цена - Число - Цена товара +// *СтараяЦена - Число - Для отображения скидки/изменения цены +// *ОсновноеФото - Строка,ДвоичныеДанные - Двоичные данные или путь к фото +// *URL - Строка - Ссылка на страницу сайта магазина +// *ДополнительныеФото - Массив Из Строка - Двоичные данные или пути к фото +// *ЗначенияСвойств - Массив Из Строка - См.ДобавитьВариантСвойстваТовара +// *ГлавныйВГруппе - Булево - Главный в группе, если есть в группе +// *Ширина - Число - Ширина товара в мм. +// *Высота - Число - Высота товара в мм. +// *Глубина - Число - Глубина товара в мм. +// *Вес - Число - Вес в гр. +// *SKU - Строка - SKU +// *ДоступныйОстаток - Число - Остаток. -1 - не ограничено +Функция ПолучитьОписаниеТовара() Экспорт + + Товар = Новый Соответствие(); + Товар.Вставить("Имя" , "Новый товар"); // Имя товара + Товар.Вставить("Описание" , "Описание товара"); // Описание товара + Товар.Вставить("Категория" , "20173"); // См ПолучитьСписокКатегорийТоваров() + Товар.Вставить("Цена" , 1); // Цена. + Товар.Вставить("СтараяЦена" , Неопределено); // Для отражения изменения цены + Товар.Вставить("ОсновноеФото" , Неопределено); // ДД или путь к осн. фото + Товар.Вставить("URL" , Неопределено); // Ссылка на страницу магазина + Товар.Вставить("ДополнительныеФото" , Новый Массив); // Массив путей или ДД для доп. фото + Товар.Вставить("ЗначенияСвойств" , Новый Массив); // Значения свойств (варианты). Максимум 2 + Товар.Вставить("ГлавныйВГруппе" , Ложь); // Сделать главным в своей группе + Товар.Вставить("Ширина" , Неопределено); // В миллиметрах + Товар.Вставить("Высота" , Неопределено); // В миллиметрах + Товар.Вставить("Глубина" , Неопределено); // В миллиметрах + Товар.Вставить("Вес" , Неопределено); // В граммах + Товар.Вставить("SKU" , Неопределено); // Артикул + Товар.Вставить("ДоступныйОстаток" , 1); + + Возврат Товар; + +КонецФункции + +#КонецОбласти + +#Область РаботаСПодборкамиТоваров + +// Получить список подборок. +// +// Параметры: +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - Массив соответствий подборок +Функция ПолучитьСписокПодборок(Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("count", 100); + + МассивАльбомов = Новый Массив; + ПолучитьСписокАльбомовРекурсивно(МассивАльбомов, Параметры_); + + Возврат МассивАльбомов; + +КонецФункции + +// Получить подборки по ИД. +// +// Параметры: +// Подборки - Строка, Массив Из Строка - ID подборки(-ок) +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ПолучитьПодборкиПоИД(Знач Подборки, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + СтрокаПодборок = ""; + + Если ТипЗнч(Подборки) <> Тип("Массив") Тогда + + Подборка = Подборки; + Подборки = Новый Массив; + Подборки.Добавить(Подборка); + + КонецЕсли; + + Для Каждого Подборка Из Подборки Цикл + + ТекущаяПодборка = OPI_Инструменты.ЧислоВСтроку(Подборка); + СтрокаПодборок = СтрокаПодборок + ТекущаяПодборка + ","; + + КонецЦикла; + + СтрокаПодборок = Лев(СтрокаПодборок, СтрДлина(СтрокаПодборок) - 1); + Параметры_.Вставить("album_ids", СтрокаПодборок); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getAlbumById", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Создать подборку товаров. +// +// Параметры: +// Название - Строка - Название подборки +// Картинка - Строка,ДвоичныеДанные - Путь или двоичные данные картинки +// Основная - Булево - Основная +// Скрытая - Булево - Скрытая +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция СоздатьПодборкуТоваров(Знач Название + , Знач Картинка + , Знач Основная = Ложь + , Знач Скрытая = Ложь + , Знач Параметры = "") Экспорт + + Возврат УправлениеПодборкой(Название, Картинка, , Основная, Скрытая, Параметры); + +КонецФункции + +// Изменить подборку товаров. +// +// Параметры: +// Название - Строка - Название подборки +// Подборка - Строка - ID подборки +// Картинка - Строка,ДвоичныеДанные - Новая картинка подборки +// Основная - Булево - Основная +// Скрытая - Булево - Скрытая +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +//@skip-check method-too-many-params +Функция ИзменитьПодборкуТоваров(Знач Название + , Знач Подборка + , Знач Картинка = "" + , Знач Основная = Ложь + , Знач Скрытая = Ложь + , Знач Параметры = "") Экспорт + + Возврат УправлениеПодборкой(Название, Картинка, Подборка, Основная, Скрытая, Параметры); + +КонецФункции + +// Добавить товар в подборку. +// +// Параметры: +// МассивТовар - Строка, Число - Массив товаров или товар +// Подборка - Строка - ID подборки +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ДобавитьТоварВПодборку(Знач МассивТовар, Знач Подборка, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Подборка = OPI_Инструменты.ЧислоВСтроку(Подборка); + МассивТовар_ = Новый Массив; + + Если Не ТипЗнч(МассивТовар) = Тип("Массив") Тогда + + Товар = МассивТовар; + МассивТовар = Новый Массив; + МассивТовар.Добавить(Товар); + + КонецЕсли; + + Для Каждого Товар Из МассивТовар Цикл + МассивТовар_.Добавить(OPI_Инструменты.ЧислоВСтроку(Товар)); + КонецЦикла; + + СписокТоваров = СтрСоединить(МассивТовар_, ","); + + Параметры_.Вставить("item_ids" , СписокТоваров); + Параметры_.Вставить("album_ids", Подборка); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.addToAlbum", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить товар из подборки. +// +// Параметры: +// Товар - Строка - ID товара +// Подборка - Строка - ID подборки +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция УдалитьТоварИзПодборки(Знач Товар, Знач Подборка, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Подборка = OPI_Инструменты.ЧислоВСтроку(Подборка); + + Параметры_.Вставить("item_id" , OPI_Инструменты.ЧислоВСтроку(Товар)); + Параметры_.Вставить("album_ids", Подборка); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.removeFromAlbum", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить подборку. +// +// Параметры: +// Подборка - Строка - ID подборки +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция УдалитьПодборку(Знач Подборка, Знач Параметры = "") Экспорт + + Подборка = OPI_Инструменты.ЧислоВСтроку(Подборка); + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("album_id", Подборка); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.deleteAlbum", Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область РаботаСоСвойствамиТоваров + +// Получить список свойств. +// +// Параметры: +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ПолучитьСписокСвойств(Знач Параметры = "") Экспорт + + Response = "response"; + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getProperties", Параметры_); + Свойства = Ответ[Response]["items"]; + + Возврат Свойства; + +КонецФункции + +// Создать свойство товара. +// +// Параметры: +// Название - Строка - Название свойства +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция СоздатьСвойствоТовара(Знач Название, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("title", Название); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.addProperty", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Изменить свойство товара. +// +// Параметры: +// Название - Строка - Название +// Свойство - Строка,Число - ID свойства +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ИзменитьСвойствоТовара(Знач Название, Знач Свойство, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("title" , Название); + Параметры_.Вставить("property_id", OPI_Инструменты.ЧислоВСтроку(Свойство)); + Параметры_.Вставить("type" , "text"); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.editProperty", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить свойство товара. +// +// Параметры: +// Свойство - Строка,Число - ID свойства +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция УдалитьСвойствоТовара(Знач Свойство, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("property_id", OPI_Инструменты.ЧислоВСтроку(Свойство)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.deleteProperty", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Добавить вариант свойства товара. +// +// Параметры: +// Значение - Строка - Значение свойства +// Свойство - Строка,Число - ID свойства, куда добавляется вариант +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ДобавитьВариантСвойстваТовара(Знач Значение, Знач Свойство, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("property_id", OPI_Инструменты.ЧислоВСтроку(Свойство)); + Параметры_.Вставить("title" , Значение); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.addPropertyVariant", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Изменить вариант свойства товара. +// +// Параметры: +// Значение - Строка - Новое значение свойства +// Свойство - Строка,Число - ID свойства +// Вариант - Строка,Число - ID варианта +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция ИзменитьВариантСвойстваТовара(Знач Значение, Знач Свойство, Знач Вариант, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("property_id", OPI_Инструменты.ЧислоВСтроку(Свойство)); + Параметры_.Вставить("variant_id" , OPI_Инструменты.ЧислоВСтроку(Вариант)); + Параметры_.Вставить("title" , Значение); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.editPropertyVariant", Параметры_); + + Возврат Ответ; + +КонецФункции + +// Удалить вариант свойства товара. +// +// Параметры: +// Вариант - Строка,Число - ID варианта +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// ДвоичныеДанные, Неопределено, Произвольный - Ответ сервера +Функция УдалитьВариантСвойстваТовара(Знач Вариант, Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("variant_id", OPI_Инструменты.ЧислоВСтроку(Вариант)); + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.deletePropertyVariant", Параметры_); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти + +#Область РаботаСЗаказами + +// Получить список заказов. +// +// Параметры: +// Параметры - Структура Из Строка - См.ПолучитьСтандартныеПараметры +// +// Возвращаемое значение: +// Соответствие Из КлючИЗначение - Массив соответствий заказов +Функция ПолучитьСписокЗаказов(Знач Параметры = "") Экспорт + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("count", 50); + + МассивЗаказов = Новый Массив; + ПолучитьСписокЗаказовРекурсивно(МассивЗаказов, Параметры_); + + Возврат МассивЗаказов; + +КонецФункции + +#КонецОбласти + +#Область Прочие + +// Сформировать клавиатуру. +// +// Параметры: +// МассивКнопок - Массив из Строка - Массив заголовков кнопок +// +// Возвращаемое значение: +// Строка - JSON клавиатуры +Функция СформироватьКлавиатуру(Знач МассивКнопок) Экспорт + + Клавиатура = Новый Структура; + МассивКлавиатуры = Новый Массив; + МассивБлока = Новый Массив; + + Для Каждого Действие Из МассивКнопок Цикл + + Кнопка = Новый Структура; + Выражение = Новый Структура; + + Выражение.Вставить("type" , "text"); + Выражение.Вставить("label", Действие); + + Кнопка.Вставить("action", Выражение); + МассивБлока.Добавить(Кнопка); + + КонецЦикла; + + МассивКлавиатуры.Добавить(МассивБлока); + + Клавиатура.Вставить("buttons" , МассивКлавиатуры); + Клавиатура.Вставить("one_time", Ложь); + + Возврат OPI_Инструменты.JSONСтрокой(Клавиатура); + +КонецФункции + +#КонецОбласти + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции +// BSLLS:MissingReturnedValueDescription-off +// BSLLS:MissingParameterDescription-off + +Функция ПолучитьСтандартныеПараметры(Знач Параметры = "") + + // Здесь собрано определение данных для работы с VK API + // Вы можете переопределять их, передавая в качестве параметра + // Совпадающие поля будут перезаписаны с приоритетом параметра функции + + Параметры_ = Новый Структура; + + // access_token - можно получить в браузере по URL из функции СоздатьСсылкуПолученияТокена() + // from_group - действия будут выполняться от лица группы + // owner_id - id группы с "-" в начале. Можно найти в настройках группы ВК или в ее URL, если не был + // установлен свой + // app_id - id приложения, которое необходимо создать в профиле на странице для разработчиков + // group_id - owner_id, но без "-" + + Параметры_.Вставить("access_token" , ""); + Параметры_.Вставить("from_group" , "1"); + Параметры_.Вставить("owner_id" , ""); + Параметры_.Вставить("v" , "5.131"); + Параметры_.Вставить("app_id" , ""); + Параметры_.Вставить("group_id" , ""); + + Если ТипЗнч(Параметры) = Тип("Структура") Тогда + Для Каждого ПереданныйПараметр Из Параметры Цикл + Параметры_.Вставить(ПереданныйПараметр.Ключ, OPI_Инструменты.ЧислоВСтроку(ПереданныйПараметр.Значение)); + КонецЦикла; + КонецЕсли; + + Возврат Параметры_; + +КонецФункции + +Функция ЗагрузитьФотоНаСервер(Знач Картинка, Параметры, Знач Вид = "Пост") + + Response = "response"; + Файлы = Новый Соответствие; + Метод = ОпределитьМетодЗагрузкиИзображений(Вид); + URL = "api.vk.com/method/"; + Загрузка = URL + Метод["Загрузка"]; + Сохранение = URL + Метод["Сохранение"]; + + Если ТипЗнч(Картинка) = Тип("Строка") Тогда + КлючКартинка = СтрЗаменить(Картинка, ".", "___"); + ЗначениеКартинка = Новый ДвоичныеДанные(Картинка); + Иначе + //@skip-check missing-temporary-file-deletion + // BSLLS:MissingTemporaryFileDeletion-off + КлючКартинка = СтрЗаменить(ПолучитьИмяВременногоФайла("jpeg"), ".", "___"); + ЗначениеКартинка = Картинка; + КонецЕсли; + + Файлы.Вставить(КлючКартинка, ЗначениеКартинка); + + Ответ = OPI_Инструменты.Get(Загрузка, Параметры); + URL = Ответ[Response]["upload_url"]; + Параметры.Вставить("upload_url", URL); + + Ответ = OPI_Инструменты.PostMultipart(URL, Параметры, Файлы); + ЗаполнитьПараметрыЗагрузкиФото(Метод, Ответ, Параметры); + + Ответ = OPI_Инструменты.Get(Сохранение, Параметры); + + Возврат Ответ; + +КонецФункции + +Функция ОпределитьМетодЗагрузкиИзображений(Знач Вид) + + СоответствиеМетодов = Новый Соответствие; + Загрузка = "Загрузка"; + Сохранение = "Сохранение"; + Способ = "Способ"; + Фото = "Фото"; + + Если Вид = "Пост" Тогда + + СоответствиеМетодов.Вставить(Загрузка , "photos.getWallUploadServer"); + СоответствиеМетодов.Вставить(Сохранение, "photos.saveWallPhoto"); + СоответствиеМетодов.Вставить(Фото , "photo"); + СоответствиеМетодов.Вставить(Способ , 1); + + ИначеЕсли Вид = "Товар" Тогда + + СоответствиеМетодов.Вставить(Загрузка , "market.getProductPhotoUploadServer"); + СоответствиеМетодов.Вставить(Сохранение, "market.saveProductPhoto"); + СоответствиеМетодов.Вставить(Способ , 2); + + ИначеЕсли Вид = "История" Тогда + + СоответствиеМетодов.Вставить(Загрузка , "stories.getPhotoUploadServer"); + СоответствиеМетодов.Вставить(Сохранение, "stories.save"); + СоответствиеМетодов.Вставить(Способ , 3); + + Иначе + + СоответствиеМетодов.Вставить(Загрузка , "photos.getUploadServer"); + СоответствиеМетодов.Вставить(Сохранение, "photos.save"); + СоответствиеМетодов.Вставить(Фото , "photos_list"); + СоответствиеМетодов.Вставить(Способ , 1); + + КонецЕсли; + + Возврат СоответствиеМетодов; + +КонецФункции + +Функция ПолучитьСоответствиеПараметровТовара() + + Поля = Новый Соответствие(); + Поля.Вставить("Имя" , "name"); + Поля.Вставить("Описание" , "description"); + Поля.Вставить("Категория" , "category_id"); + Поля.Вставить("Цена" , "price"); + Поля.Вставить("СтараяЦена" , "old_price"); + Поля.Вставить("URL" , "url"); + Поля.Вставить("ГлавныйВГруппе" , "is_main_variant"); + Поля.Вставить("Ширина" , "dimension_width"); + Поля.Вставить("Высота" , "dimension_height"); + Поля.Вставить("Глубина" , "dimension_length"); + Поля.Вставить("Вес" , "weight"); + Поля.Вставить("SKU" , "sku"); + Поля.Вставить("ДоступныйОстаток" , "stock_amount"); + + Возврат Поля; + +КонецФункции + +Функция УправлениеТоваром(Знач ОписаниеТовара, Знач ИДТовара = "", Знач Подборка = "", Знач Параметры = "") + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + Параметры_.Вставить("v", "5.199"); + + Response = "response"; + Подборка = OPI_Инструменты.ЧислоВСтроку(Подборка); + + ЗаполнитьПоляЗапросаТовара(ОписаниеТовара, Параметры_); + + Если ЗначениеЗаполнено(ИДТовара) Тогда + Параметры_.Вставить("item_id", OPI_Инструменты.ЧислоВСтроку(ИДТовара)); + Метод = "edit"; + Иначе + Метод = "add"; + КонецЕсли; + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market." + Метод, Параметры_); + + Если Не ЗначениеЗаполнено(ИДТовара) Тогда + ИДТовара = Ответ[Response]["market_item_id"]; + ИДТовара = OPI_Инструменты.ЧислоВСтроку(ИДТовара); + КонецЕсли; + + Если ЗначениеЗаполнено(Подборка) Тогда + ДобавитьТоварВПодборку(ИДТовара, Подборка, Параметры_); + КонецЕсли; + + Возврат Ответ; + +КонецФункции + +//@skip-check method-too-many-params +Функция УправлениеПодборкой(Знач Название + , Знач Картинка = "" + , Знач ИДПодборки = "" + , Знач Основная = Ложь + , Знач Скрытая = Ложь + , Знач Параметры = "") + + Параметры_ = ПолучитьСтандартныеПараметры(Параметры); + PhotoID = "photo_id"; + Response = "response"; + + Если ЗначениеЗаполнено(Картинка) Тогда + + Ответ = ЗагрузитьФотоНаСервер(Картинка, Параметры_, "Товар"); + ИДФото = Ответ[Response][PhotoID]; + ИДФото = OPI_Инструменты.ЧислоВСтроку(ИДФото); + + Параметры_.Вставить(PhotoID, ИДФото); + + Иначе + + Если ЗначениеЗаполнено(ИДПодборки) Тогда + + Подборки = ПолучитьПодборкиПоИД(ИДПодборки, Параметры_); + Подборки = Подборки[Response]["items"]; + + Если Не Подборки.Количество() = 0 Тогда + ИДФото = Подборки[0]["photo"]["id"]; + ИДФото = OPI_Инструменты.ЧислоВСтроку(ИДФото); + Параметры_.Вставить(PhotoID, ИДФото); + КонецЕсли; + + КонецЕсли; + + КонецЕсли; + + Параметры_.Вставить("title" , Название); + Параметры_.Вставить("main_album" , ?(Основная, 1, 0)); + Параметры_.Вставить("is_hidden" , ?(Скрытая, 1, 0)); + + Если ЗначениеЗаполнено(ИДПодборки) Тогда + Параметры_.Вставить("album_id", OPI_Инструменты.ЧислоВСтроку(ИДПодборки)); + Метод = "editAlbum"; + Иначе + Метод = "addAlbum"; + КонецЕсли; + + Ответ = OPI_Инструменты.Get("api.vk.com/method/market." + Метод, Параметры_); + + Возврат Ответ; + +КонецФункции + +Процедура ЗаполнитьПараметрыЗагрузкиФото(Знач Метод, Знач Ответ, Параметры) + + Response = "response"; + Способ = Метод["Способ"]; + СтандартныйСпособ = 1; + НовыйСпособ = 2; + + Если Способ = СтандартныйСпособ Тогда + + Hash = "hash"; + Serv = "server"; + Aid = "aid"; + Фото = Метод["Фото"]; + + СерверФото = OPI_Инструменты.ЧислоВСтроку(Ответ[Serv]); + + Параметры.Вставить(Hash , Ответ[Hash]); + Параметры.Вставить(Фото , Ответ[Фото]); + Параметры.Вставить(Serv , СерверФото); + + Идентификатор = Ответ.Получить(Aid); + Идентификатор = OPI_Инструменты.ЧислоВСтроку(Идентификатор); + + Если ЗначениеЗаполнено(Идентификатор) Тогда + Параметры.Вставить(Aid , Идентификатор); + КонецЕсли; + + ИначеЕсли Способ = НовыйСпособ Тогда + + ОтветСтрокой = OPI_Инструменты.JSONСтрокой(Ответ); + Параметры.Вставить("upload_response", ОтветСтрокой); + + Иначе + + Параметры.Вставить("upload_results", Ответ[Response]["upload_result"]); + + КонецЕсли; + +КонецПроцедуры + +Процедура ЗаполнитьПоляЗапросаТовара(Знач ОписаниеТовара, Параметры) + + Response = "response"; + ОсновноеФото = ОписаниеТовара["ОсновноеФото"]; + ДопФото = ОписаниеТовара["ДополнительныеФото"]; + Свойства = ОписаниеТовара["ЗначенияСвойств"]; + + Если ЗначениеЗаполнено(ОсновноеФото) Тогда + Ответ = ЗагрузитьФотоНаСервер(ОсновноеФото, Параметры, "Товар"); + ИДФото = Ответ[Response]["photo_id"]; + ИДФото = OPI_Инструменты.ЧислоВСтроку(ИДФото); + Параметры.Вставить("main_photo_id", ИДФото); + КонецЕсли; + + Если ТипЗнч(Свойства) = Тип("Массив") Тогда + + Свойства_ = Новый Массив; + + Для Каждого Свойство Из Свойства Цикл + Свойства_.Добавить(OPI_Инструменты.ЧислоВСтроку(Свойство)); + КонецЦикла; + + Свойства = СтрСоединить(Свойства_, ","); + + КонецЕсли; + + Если ЗначениеЗаполнено(Свойства) Тогда + Параметры.Вставить("variant_ids", OPI_Инструменты.ЧислоВСтроку(Свойства)); + КонецЕсли; + + ДобавитьДополнительныеФотоТовара(ДопФото, Параметры); + + Для Каждого Поле Из ПолучитьСоответствиеПараметровТовара() Цикл + + Значение = ОписаниеТовара[Поле.Ключ]; + + Если Значение <> Неопределено Тогда + Параметры.Вставить(Поле.Значение, ОписаниеТовара[Поле.Ключ]); + КонецЕсли; + + КонецЦикла; + +КонецПроцедуры + +Процедура ДобавитьДополнительныеФотоТовара(Знач МассивФото, Параметры) + + Если ТипЗнч(МассивФото) = Тип("Массив") Тогда + Если МассивФото.Количество() > 0 Тогда + + СтрокаФотографий = ""; + Response = "response"; + + Для Каждого Фото Из МассивФото Цикл + + Ответ = ЗагрузитьФотоНаСервер(Фото, Параметры, "Товар"); + ИДФото = Ответ[Response]["photo_id"]; + ИДФото = OPI_Инструменты.ЧислоВСтроку(ИДФото); + СтрокаФотографий = СтрокаФотографий + ИДФото + ","; + + КонецЦикла; + + СтрокаФотографий = Лев(СтрокаФотографий, СтрДлина(СтрокаФотографий) - 1); + Параметры.Вставить("photo_ids", СтрокаФотографий); + КонецЕсли; + КонецЕсли; + +КонецПроцедуры + +Процедура ПолучитьСписокТоваровРекурсивно(МассивТоваров, Параметры, Сдвиг = 0) + + Response = "response"; + МаксимумВЗапросе = 200; + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.get", Параметры); + Товары = Ответ[Response]["items"]; + + Если Товары.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + Для Каждого Товар Из Товары Цикл + МассивТоваров.Добавить(Товар); + КонецЦикла; + + Сдвиг = Сдвиг + МаксимумВЗапросе; + Параметры.Вставить("offset", Сдвиг); + ПолучитьСписокТоваровРекурсивно(МассивТоваров, Параметры, Сдвиг); + +КонецПроцедуры + +Процедура ПолучитьСписокАльбомовРекурсивно(МассивАльбомов, Параметры, Сдвиг = 0) + + Response = "response"; + МаксимумВЗапросе = 100; + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getAlbums", Параметры); + Альбомы = Ответ[Response]["items"]; + + Если Альбомы.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + Для Каждого Альбом Из Альбомы Цикл + МассивАльбомов.Добавить(Альбом); + КонецЦикла; + + Сдвиг = Сдвиг + МаксимумВЗапросе; + Параметры.Вставить("offset", Сдвиг); + ПолучитьСписокАльбомовРекурсивно(МассивАльбомов, Параметры, Сдвиг); + +КонецПроцедуры + +Процедура ПолучитьСписокЗаказовРекурсивно(МассивЗаказов, Параметры, Сдвиг = 0) + + Response = "response"; + МаксимумВЗапросе = 50; + Ответ = OPI_Инструменты.Get("api.vk.com/method/market.getGroupOrders", Параметры); + Заказы = Ответ[Response]["items"]; + + Если Заказы.Количество() = 0 Тогда + Возврат; + КонецЕсли; + + Для Каждого Заказ Из Заказы Цикл + МассивЗаказов.Добавить(Заказ); + КонецЦикла; + + Сдвиг = Сдвиг + МаксимумВЗапросе; + Параметры.Вставить("offset", Сдвиг); + ПолучитьСписокЗаказовРекурсивно(МассивЗаказов, Параметры, Сдвиг); + +КонецПроцедуры + +// BSLLS:MissingParameterDescription-on +// BSLLS:MissingReturnedValueDescription-on +#КонецОбласти + +// BSLLS:NumberOfOptionalParams-on \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_Viber.os b/OInt/core/src/Modules/OPI_Viber.os new file mode 100644 index 000000000..b49b7bca6 --- /dev/null +++ b/OInt/core/src/Modules/OPI_Viber.os @@ -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", Токен); + Возврат СтруктураЗаголовков; + +КонецФункции + +#КонецОбласти diff --git a/OInt/core/src/Modules/OPI_YandexDisk.os b/OInt/core/src/Modules/OPI_YandexDisk.os new file mode 100644 index 000000000..e17d9f044 --- /dev/null +++ b/OInt/core/src/Modules/OPI_YandexDisk.os @@ -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Ответа, , Заголовки); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_YandexID.os b/OInt/core/src/Modules/OPI_YandexID.os new file mode 100644 index 000000000..dd1b4b79f --- /dev/null +++ b/OInt/core/src/Modules/OPI_YandexID.os @@ -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", Параметры, , Ложь); + + Возврат Ответ; + +КонецФункции + +#КонецОбласти diff --git a/OInt/core/src/Modules/OPI_Инструменты.os b/OInt/core/src/Modules/OPI_Инструменты.os new file mode 100644 index 000000000..a6fb23c5d --- /dev/null +++ b/OInt/core/src/Modules/OPI_Инструменты.os @@ -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 + Возврат ТекущаяДата(); + +КонецФункции + +Процедура ЗаменитьСпецСимволы(Текст) Экспорт + + МассивСимволов = Новый Соответствие; + МассивСимволов.Вставить("<", "<"); + МассивСимволов.Вставить(">", ">"); + МассивСимволов.Вставить("&", "&"); + МассивСимволов.Вставить("_", " "); + МассивСимволов.Вставить("[", "("); + МассивСимволов.Вставить("]", ")"); + + Для Каждого СимволМассива Из МассивСимволов Цикл + Текст = СтрЗаменить(Текст, СимволМассива.Ключ, СимволМассива.Значение); + КонецЦикла; + +КонецПроцедуры + +Процедура УдалитьПустыеПоляКоллекции(Коллекция) Экспорт + + ТипКоллекции = ТипЗнч(Коллекция); + ВыходнаяКоллекция = Новый(ТипКоллекции); + + Если ТипКоллекции = Тип("Соответствие") Или ТипКоллекции = Тип("Структура") Тогда + + УдалитьПустыеКлючиЗначения(Коллекция, ВыходнаяКоллекция); + + ИначеЕсли ТипКоллекции = Тип("Массив") Тогда + + УдалитьПустыеЭлементыМассива(Коллекция, ВыходнаяКоллекция); + + Иначе + + ВыходнаяКоллекция = Коллекция; + + КонецЕсли; + + Коллекция = ВыходнаяКоллекция; + +КонецПроцедуры + +Процедура Пауза(Знач Секунды) Экспорт + + Соединение = Новый 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 + +#КонецОбласти + +#КонецОбласти \ No newline at end of file diff --git a/OInt/core/src/Modules/OPI_Криптография.os b/OInt/core/src/Modules/OPI_Криптография.os new file mode 100644 index 000000000..a254bbc0a --- /dev/null +++ b/OInt/core/src/Modules/OPI_Криптография.os @@ -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 + + Возврат СтрСоединить(Части, ""); + +КонецФункции + +#КонецОбласти + +#КонецОбласти diff --git a/OInt/core/src/Modules/OPI_ПолучениеДанныхТестов.os b/OInt/core/src/Modules/OPI_ПолучениеДанныхТестов.os new file mode 100644 index 000000000..1017b1d03 --- /dev/null +++ b/OInt/core/src/Modules/OPI_ПолучениеДанныхТестов.os @@ -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(Запись, Значения); + Запись.Закрыть(); + +КонецПроцедуры + +#КонецОбласти diff --git a/OInt/core/tests/OPI_Тесты.os b/OInt/core/tests/OPI_Тесты.os new file mode 100644 index 000000000..43579a8ac --- /dev/null +++ b/OInt/core/tests/OPI_Тесты.os @@ -0,0 +1,1680 @@ +// 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 + +// Набор тестов для YAxUnit +// @skip-check undefined-variable +// BSLLS:Typo-off + +//Раскомментировать, если выполняется OneScript +#Использовать ".." +#Использовать asserts + +#Область СлужебныйПрограммныйИнтерфейс + +//Для YaxUnit + +Процедура ИсполняемыеСценарии() Экспорт + OPI_ПолучениеДанныхТестов.СформироватьТестыЯкс(); +КонецПроцедуры + +//Для Asserts + +Функция ПолучитьСписокТестов(ЮнитТестирование) Экспорт // BSLLS:UnusedParameters-off + Возврат OPI_ПолучениеДанныхТестов.СформироватьТестыАссертс(); +КонецФункции + +#Область Тесты + +#Область Telegram + +Процедура Телеграм_ПолучитьИнформациюБота() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Результат = OPI_Telegram.ПолучитьИнформациюБота(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["username"]).Заполнено(); + +КонецПроцедуры + +Процедура Телеграм_ПолучитьОбновления() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Результат = OPI_Telegram.ПолучитьОбновления(Токен); + + OPI_Telegram.УдалитьWebhook(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие") .Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).ИмеетТип("Массив"); + +КонецПроцедуры + +Процедура Телеграм_УстановитьWebhook() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + URL = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_URL"); + Результат = OPI_Telegram.УстановитьWebhook(Токен, URL); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["description"]).Равно("Webhook was set"); + +КонецПроцедуры + +Процедура Телеграм_УдалитьWebhook() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Результат = OPI_Telegram.УдалитьWebhook(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["description"]).Равно("Webhook was deleted"); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьТекстовоеСообщение() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьТекстовоеСообщение(Токен, IDЧата, Текст)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьТекстовоеСообщение(Токен, IDКанала, Текст)); + + IDСообщения = OPI_Инструменты.ЧислоВСтроку(МассивРезультатов[1]["result"]["message_id"]); + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Телеграм_IDСообщенияКанала", IDСообщения); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["text"]).Равно(Текст); + + КонецЦикла; + +КонецПроцедуры + +Процедура Телеграм_ОтправитьКартинку() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьКартинку(Токен, IDЧата , Текст, Картинка)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьКартинку(Токен, IDКанала, Текст, Картинка)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьКартинку(Токен, IDЧата , Текст, ИВФ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьКартинку(Токен, IDКанала, Текст, ИВФ)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие") .Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["caption"]).Равно(Текст); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["photo"]).ИмеетТип("Массив"); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьВидео() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + Видео = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Видео"); + ИВФ = ПолучитьИмяВременногоФайла("mp4"); + Видео.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьВидео(Токен, IDЧата , Текст, Видео)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьВидео(Токен, IDКанала, Текст, Видео)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьВидео(Токен, IDЧата , Текст, ИВФ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьВидео(Токен, IDКанала, Текст, ИВФ)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["caption"]).Равно(Текст); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["video"]["mime_type"]).Равно("video/mp4"); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьАудио() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + Аудио = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Аудио"); + ИВФ = ПолучитьИмяВременногоФайла("mp3"); + Аудио.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьАудио(Токен, IDЧата , Текст, Аудио)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьАудио(Токен, IDКанала, Текст, Аудио)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьАудио(Токен, IDЧата , Текст, ИВФ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьАудио(Токен, IDКанала, Текст, ИВФ)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["caption"]).Равно(Текст); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["audio"]["mime_type"]).Равно("audio/mpeg"); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьДокумент() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + Документ = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Документ"); + ИВФ = ПолучитьИмяВременногоФайла("docx"); + Документ.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьДокумент(Токен, IDЧата , Текст, Документ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьДокумент(Токен, IDКанала, Текст, Документ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьДокумент(Токен, IDЧата , Текст, ИВФ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьДокумент(Токен, IDКанала, Текст, ИВФ)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["caption"]).Равно(Текст); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["document"]).ИмеетТип("Соответствие").Заполнено(); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьГифку() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + Гифка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Гифка"); + ИВФ = ПолучитьИмяВременногоФайла("gif"); + Гифка.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьГифку(Токен, IDЧата , Текст, Гифка)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьГифку(Токен, IDКанала, Текст, Гифка)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьГифку(Токен, IDЧата , Текст, ИВФ)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьГифку(Токен, IDКанала, Текст, ИВФ)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["caption"]).Равно(Текст); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["document"]).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["animation"]["mime_type"]).Равно("video/mp4"); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьМедиагруппу() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Текст = "Сообщение из автоматического теста"; + + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ_Картинка = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ_Картинка); + + Видео = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Видео"); + ИВФ_Видео = ПолучитьИмяВременногоФайла("mp4"); + Видео.Записать(ИВФ_Видео); + + МедиагруппаЧат = Новый Соответствие; + МедиагруппаЧат.Вставить(Картинка , "photo"); + МедиагруппаЧат.Вставить(ИВФ_Видео, "video"); + + МедиагруппаКанал = Новый Соответствие; + МедиагруппаКанал.Вставить(ИВФ_Картинка, "photo"); + МедиагруппаКанал.Вставить(Видео , "video"); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьМедиагруппу(Токен, IDЧата, Текст, МедиагруппаЧат)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьМедиагруппу(Токен, IDКанала, Текст, МедиагруппаКанал)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).ИмеетТип("Массив"); + + КонецЦикла; + + УдалитьФайлы(ИВФ_Картинка); + УдалитьФайлы(ИВФ_Видео); + +КонецПроцедуры + +Процедура Телеграм_ОтправитьМестоположение() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Ширина = "48.87373649724122"; + Долгота = "48.87373649724122"; + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьМестоположение(Токен, IDЧата , Ширина, Долгота)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьМестоположение(Токен, IDКанала, Ширина, Долгота)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["location"]).ИмеетТип("Соответствие").Заполнено(); + + КонецЦикла; + +КонецПроцедуры + +Процедура Телеграм_ОтправитьКонтакт() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Имя = "Петр"; + Фамилия = "Петров"; + Телефон = "88005553535"; + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьКонтакт(Токен, IDЧата , Имя, Фамилия, Телефон)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьКонтакт(Токен, IDКанала, Имя, Фамилия, Телефон)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["contact"]).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["contact"]["first_name"]).Равно(Имя); + + КонецЦикла; + +КонецПроцедуры + +Процедура Телеграм_ОтправитьОпрос() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + + Вопрос = "Какой ваш любимый цвет?"; + + МассивОтветов = Новый Массив; + МассивОтветов.Добавить("Красный"); + МассивОтветов.Добавить("Желтый"); + МассивОтветов.Добавить("Зеленый"); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьОпрос(Токен, IDЧата , Вопрос, МассивОтветов, Ложь)); + МассивРезультатов.Добавить(OPI_Telegram.ОтправитьОпрос(Токен, IDКанала, Вопрос, МассивОтветов, Истина)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["poll"]).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["poll"]["question"]).Равно(Вопрос); + + КонецЦикла; + +КонецПроцедуры + +Процедура Телеграм_ПереслатьСообщение() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + IDСообщения = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_IDСообщенияКанала"); + IDСообщения = Число(IDСообщения); + + Результат = OPI_Telegram.ПереслатьСообщение(Токен, IDСообщения, IDКанала, IDЧата); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["forward_origin"]["message_id"]).Равно(IDСообщения); + +КонецПроцедуры + +Процедура Телеграм_БанРазбан() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDЧата = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Чат"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.Бан(Токен, IDКанала, IDЧата)); + МассивРезультатов.Добавить(OPI_Telegram.Разбан(Токен, IDКанала, IDЧата)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["description"]).Равно("Bad Request: can't remove chat owner"); + + КонецЦикла; + +КонецПроцедуры + +Процедура Телеграм_СоздатьСсылкуПриглашение() Экспорт + + Час = 3600; + ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДата(); + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + Заголовок = "Ссылка " + Строка(ТекущаяДата); + Истечение = ТекущаяДата + Час; + UnixИстечение = Число(OPI_Инструменты.UNIXTime(Истечение)); + + Результат = OPI_Telegram.СоздатьСсылкуПриглашение(Токен, IDКанала, Заголовок, Истечение, 200); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["member_limit"]).Равно(200); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["name"]).Равно(Заголовок); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]["expire_date"]).Равно(UnixИстечение); + +КонецПроцедуры + +Процедура Телеграм_ЗакрепитьОткрепитьСообщение() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + IDСообщения = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_IDСообщенияКанала"); + + МассивРезультатов = Новый Массив; + МассивРезультатов.Добавить(OPI_Telegram.ЗакрепитьСообщение(Токен, IDКанала, IDСообщения)); + МассивРезультатов.Добавить(OPI_Telegram.ОткрепитьСообщение(Токен, IDКанала, IDСообщения)); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).Равно(Истина); + + КонецЦикла; + +КонецПроцедуры + +Процедура Телеграм_ПолучитьЧислоУчастников() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + IDКанала = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Канал"); + + Результат = OPI_Telegram.ПолучитьЧислоУчастников(Токен, IDКанала); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).ИмеетТип("Число"); + +КонецПроцедуры + +Процедура Телеграм_ПолучитьСписокАватаровФорума() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Результат = OPI_Telegram.ПолучитьСписокИконокАватаров(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + +КонецПроцедуры + +Процедура Телеграм_СоздатьУдалитьТемуФорума() Экспорт + + Ok_ = "ok"; + Result = "result"; + ТипСоответствие = Тип("Соответствие"); + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Чат = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Форум"); + Имя = "Тестовая тема"; + НовоеИмя = "Новый тестовый заголовок"; + Иконка = "5357419403325481346"; + НовяИконка = "5310132165583840589"; + + Результат = OPI_Telegram.СоздатьТемуФорума(Токен, Чат, Имя, Иконка); + Тема = Результат[Result]["message_thread_id"]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Ok_]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Result]["name"]).Равно(Имя); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Result]["icon_custom_emoji_id"]).Равно(Иконка); + + Результат = OPI_Telegram.ИзменитьТемуФорума(Токен, Чат, Тема, НовоеИмя, НовяИконка); + Проверка_ТелеграмИстина(Результат); + + OPI_Инструменты.Пауза(10); + + Результат = OPI_Telegram.ЗакрытьТемуФорума(Токен, Чат, Тема); + Проверка_ТелеграмИстина(Результат); + + OPI_Инструменты.Пауза(25); + + Результат = OPI_Telegram.ОткрытьТемуФорума(Токен, Чат, Тема); + Проверка_ТелеграмИстина(Результат); + + OPI_Инструменты.Пауза(25); + + Результат = OPI_Telegram.УдалитьТемуФорума(Токен, Чат, Тема); + Проверка_ТелеграмИстина(Результат); + +КонецПроцедуры + +Процедура Телеграм_ОткрытьЗакрытьГлавнуюТему() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Чат = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Форум"); + + Результат = OPI_Telegram.ЗакрытьТемуФорума(Токен, Чат); + Проверка_ТелеграмИстина(Результат); + + OPI_Инструменты.Пауза(10); + + Результат = OPI_Telegram.ОткрытьТемуФорума(Токен, Чат); + Проверка_ТелеграмИстина(Результат); + + OPI_Инструменты.Пауза(10); + + Результат = OPI_Telegram.ОчиститьСписокЗакрепленныхСообщенийТемы(Токен, Чат); + Проверка_ТелеграмИстина(Результат); + + OPI_Инструменты.Пауза(10) + +КонецПроцедуры + +Процедура Телеграм_ИзменитьИмяГлавнойТемы() Экспорт + + Заголовок = "Новое имя главной темы " + Строка(Новый УникальныйИдентификатор); + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Токен"); + Чат = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Телеграм_Форум"); + + Результат = OPI_Telegram.ИзменитьИмяГлавнойТемыФорума(Токен, Чат, Заголовок); + Проверка_ТелеграмИстина(Результат); + +КонецПроцедуры + +#КонецОбласти + +#Область ВК + +Процедура ВК_СоздатьСсылкуТокена() Экспорт + + Приложение = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_Приложение"); + Результат = OPI_VK.СоздатьСсылкуПолученияТокена(Приложение); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Строка") + .Заполнено(); + +КонецПроцедуры + +Процедура ВК_СоздатьУдалитьПост() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Текст = "Пост из автотеста"; + URL = "https://github.com/Bayselonarrend/OpenIntegrations"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + + МассивРезультатов.Добавить(OPI_VK.СоздатьПост(Текст, Картинка, Ложь , , Параметры)); + OPI_Инструменты.Пауза(10); + + МассивРезультатов.Добавить(OPI_VK.СоздатьПост(Текст, ИВФ , Истина, URL, Параметры)); + OPI_Инструменты.Пауза(10); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["post_id"]).ИмеетТип("Число").Заполнено(); + + ИДПоста = Результат["response"]["post_id"]; + Удаление = OPI_VK.УдалитьПост(ИДПоста, Параметры); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление) .ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Удаление["response"]).ИмеетТип("Число").Равно(1); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура ВК_СоздатьОпрос() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Вопрос = "Вопрос из автотеста"; + + МассивВариантов = Новый Массив; + МассивВариантов.Добавить("Вариант 1"); + МассивВариантов.Добавить("Вариант 2"); + МассивВариантов.Добавить("Вариант 3"); + + Результат = OPI_VK.СоздатьОпрос(Вопрос, МассивВариантов, , Параметры); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["post_id"]).ИмеетТип("Число").Заполнено(); + + ИДПоста = Результат["response"]["post_id"]; + OPI_VK.УдалитьПост(ИДПоста, Параметры); + +КонецПроцедуры + +Процедура ВК_СохранитьУдалитьКартинку() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Имя = "Альбом из автотеста"; + Описание = "Новый альбом из автотеста"; + ОписаниеКартинки = "Картинка автотест"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + ТипСоответствие = Тип("Соответствие"); + Response = "response"; + Картинка.Записать(ИВФ); + + Альбом = OPI_VK.СоздатьАльбом(Имя, Описание, Параметры); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Альбом).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Альбом["response"]["description"]).Равно(Описание); + + ИДАльбома = Альбом[Response]["id"]; + + МассивРезультатов = Новый Массив; + + МассивРезультатов.Добавить(OPI_VK.СохранитьКартинкуВАльбом(ИДАльбома, Картинка, ОписаниеКартинки, Параметры)); + OPI_Инструменты.Пауза(10); + + МассивРезультатов.Добавить(OPI_VK.СохранитьКартинкуВАльбом(ИДАльбома, ИВФ , ОписаниеКартинки, Параметры)); + OPI_Инструменты.Пауза(10); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["text"]).Равно(ОписаниеКартинки); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["album_id"]).Равно(ИДАльбома); + + ИДКартинки = Результат[Response][0]["id"]; + Удаление = OPI_VK.УдалитьКартинку(ИДКартинки, Параметры); + Проверка_ВКИстина(Удаление); + + КонецЦикла; + + Удаление = OPI_VK.УдалитьАльбом(ИДАльбома, Параметры); + Проверка_ВКИстина(Удаление); + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура ВК_СоздатьИсторию() Экспорт + + Параметры = ПолучитьПараметрыВК(); + URL = "https://github.com/Bayselonarrend/OpenIntegrations"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ); + + МассивРезультатов = Новый Массив; + + МассивРезультатов.Добавить(OPI_VK.СоздатьИсторию(ИВФ , URL, Параметры)); + OPI_Инструменты.Пауза(10); + + МассивРезультатов.Добавить(OPI_VK.СоздатьИсторию(Картинка, , Параметры)); + OPI_Инструменты.Пауза(10); + + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["count"]).ИмеетТип("Число").Равно(1); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["items"]).ИмеетТип("Массив").Заполнено(); + + КонецЦикла; + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура ВК_МетодыОбсуждений() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Название = "Обсуждение из автотеста"; + Сообщение = "Сообщение из автотеста"; + ТипСоответствие = Тип("Соответствие"); + ТипЧисло = Тип("Число"); + Response = "response"; + + Результат = OPI_VK.СоздатьОбсуждение(Название, Сообщение, Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Response]).ИмеетТип(ТипЧисло).Заполнено(); + + ИДОбсуждения = Результат[Response]; + Закрытие = OPI_VK.ЗакрытьОбсуждение(ИДОбсуждения, Ложь, Параметры); + Проверка_ВКИстина(Закрытие); + + Открытие = OPI_VK.ОткрытьОбсуждение(ИДОбсуждения, Параметры); + OPI_Инструменты.Пауза(5); + + Проверка_ВКИстина(Открытие); + + Отправка = OPI_VK.НаписатьВОбсуждение(ИДОбсуждения, Сообщение, Параметры); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Отправка).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Отправка[Response]).ИмеетТип(ТипЧисло).Заполнено(); + + Удаление = OPI_VK.ЗакрытьОбсуждение(ИДОбсуждения, Истина, Параметры); + OPI_Инструменты.Пауза(5); + Проверка_ВКИстина(Удаление); + +КонецПроцедуры + +Процедура ВК_ЛайкРепостКоммент() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Текст = "Пост из автотеста"; + Сообщение = "Сообщение из автотеста"; + ТипСоответствие = Тип("Соответствие"); + ТипЧисло = Тип("Число"); + Response = "response"; + + Результат = OPI_VK.СоздатьПост(Текст, Новый Массив, , , Параметры); + + ИДПоста = Результат[Response]["post_id"]; + Лайк = OPI_VK.ПоставитьЛайк(ИДПоста, , Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Лайк).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Лайк["response"]["likes"]).ИмеетТип(ТипЧисло).Заполнено(); + + ВнешнийПост = 2571; + ВнешняяСтена = -218704372; + + Репост = OPI_VK.СделатьРепост(ВнешнийПост, ВнешняяСтена, , , Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост["response"]["success"]).ИмеетТип(ТипЧисло).Равно(1); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Репост["response"]["wall_repost_count"]).ИмеетТип(ТипЧисло).Равно(1); + + Комментарий = OPI_VK.НаписатьКомментарий(ИДПоста, Параметры["owner_id"], Сообщение, Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Комментарий).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Комментарий["response"]["comment_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + OPI_VK.УдалитьПост(ИДПоста, Параметры); + OPI_VK.УдалитьПост(Репост[Response]["post_id"], Параметры); + +КонецПроцедуры + +Процедура ВК_ПолучитьСтатистику() Экспорт + + ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДата(); + Параметры = ПолучитьПараметрыВК(); + Дата0 = НачалоДня(ТекущаяДата); + Дата1 = КонецДня(Дата0); + ТипСоответствие = Тип("Соответствие"); + + Результат = OPI_VK.ПолучитьСтатистику(Дата0, Дата1, Параметры); + OPI_Инструменты.Пауза(10); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["visitors"]).ИмеетТип(ТипСоответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"][0]["reach"]).ИмеетТип(ТипСоответствие).Заполнено(); + +КонецПроцедуры + +Процедура ВК_ПолучитьСтатистикуПостов() Экспорт + + Параметры = ПолучитьПараметрыВК(); + + МассивПостов = Новый Массив; + МассивПостов.Добавить(214); + МассивПостов.Добавить(215); + + Результат = OPI_VK.ПолучитьСтатистикуПостов(МассивПостов, Параметры); + OPI_Инструменты.Пауза(10); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) .ИмеетТип("Массив").ИмеетДлину(2); + +КонецПроцедуры + +Процедура ВК_СоздатьРекламнуюКампанию() Экспорт + + Параметры = ПолучитьПараметрыВК(); + ИДКабинета = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_Кабинет"); + Наименование = "Тестовая кампания"; + ТипСоответствие = Тип("Соответствие"); + ТипЧисло = Тип("Число"); + Response = "response"; + UID = "id"; + + Результат = OPI_VK.СоздатьРекламнуюКампанию(ИДКабинета, Наименование, Параметры); + Результат = Результат[Response][0]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["error_code"]).ИмеетТип(ТипЧисло).Равно(602); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[UID]).ИмеетТип(ТипЧисло).Заполнено(); + + ИДКампании = Результат[UID]; + ИДКатегории = 126; + Лимит = 150; + + Результат = OPI_VK.СоздатьПост(Наименование, Новый Массив, , , Параметры); + ИДПоста = Результат[Response]["post_id"]; + + Объявление = OPI_VK.СоздатьРекламноеОбъявление(ИДКампании + , Лимит + , ИДКатегории + , ИДПоста + , ИДКабинета + , Параметры); + Объявление = Объявление[Response][0]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление["error_code"]).ИмеетТип(ТипЧисло).Равно(602); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Объявление[UID]).ИмеетТип(ТипЧисло).Заполнено(); + + ИДОбъявления = Объявление[UID]; + Остановка = OPI_VK.ПриостановитьРекламноеОбъявление(ИДКабинета, ИДОбъявления, Параметры); + Остановка = Остановка[Response][0]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Остановка).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Остановка[UID]).ИмеетТип(ТипЧисло).Заполнено(); + + OPI_VK.УдалитьПост(ИДПоста, Параметры); + +КонецПроцедуры + +Процедура ВК_ОтправитьСообщение() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Пользователь = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_Пользователь"); + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_КТ"); + Текст = "Сообщение из автотеста"; + + МассивКнопок = Новый Массив; + МассивКнопок.Добавить("Кнопка 1"); + МассивКнопок.Добавить("Кнопка 2"); + + Клавиатура = OPI_VK.СформироватьКлавиатуру(МассивКнопок); + Результат = OPI_VK.НаписатьСообщение(Текст, Пользователь, Токен, Клавиатура, Параметры); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]).ИмеетТип("Число").Заполнено(); + +КонецПроцедуры + +Процедура ВК_ПолучитьКатегорииТоваров() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Результат = OPI_VK.ПолучитьСписокКатегорийТоваров(Параметры); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Соответствие") + .Заполнено(); + +КонецПроцедуры + +Процедура ВК_СоздатьТоварПодборку() Экспорт + + Параметры = ПолучитьПараметрыВК(); + ТипСоответствие = Тип("Соответствие"); + ТипЧисло = Тип("Число"); + Response = "response"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ); + + Результат = OPI_VK.СоздатьПодборкуТоваров("Тестовая подборка" + , Картинка + , Истина + , Ложь + , Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["albums_count"]).ИмеетТип(ТипЧисло).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_album_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + ИДПодборки = Результат[Response]["market_album_id"]; + + Результат = OPI_VK.ИзменитьПодборкуТоваров("Измененная подборка", ИДПодборки, , , , Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Response]).ИмеетТип(ТипЧисло).Равно(1); + + МассивКартинок = Новый Массив; + МассивКартинок.Добавить(ИВФ); + МассивКартинок.Добавить(Картинка); + + Товар = Новый Соответствие(); + Товар.Вставить("Имя" , "Тестовый товар"); + Товар.Вставить("Описание" , "Описание товара"); + Товар.Вставить("Категория" , "20173"); + Товар.Вставить("Цена" , 1); + Товар.Вставить("СтараяЦена" , 15); + Товар.Вставить("ОсновноеФото" , Картинка); + Товар.Вставить("URL" , "https://github.com/Bayselonarrend/OpenIntegrations"); + Товар.Вставить("ДополнительныеФото" , МассивКартинок); + Товар.Вставить("ГлавныйВГруппе" , Истина); + Товар.Вставить("Ширина" , 20); + Товар.Вставить("Высота" , 30); + Товар.Вставить("Глубина" , 40); + Товар.Вставить("Вес" , 100); + Товар.Вставить("SKU" , "12345"); + Товар.Вставить("ДоступныйОстаток" , "10"); + + Результат = OPI_VK.ДобавитьТовар(Товар, ИДПодборки, Параметры); // Добавление товара + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_item_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + ИДТовара = Результат[Response]["market_item_id"]; + + Товар = Новый Соответствие; + Товар.Вставить("Имя", "Тестовый товар измененный"); + + Результат = OPI_VK.ИзменитьТовар(ИДТовара, Товар, , Параметры); // Изменение товара + Проверка_ВКИстина(Результат); + + Результат = OPI_VK.ДобавитьТоварВПодборку(ИДТовара, ИДПодборки, Параметры); // Добавление в подборку + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Response]).ИмеетТип(ТипЧисло).Заполнено(); + + Результат = OPI_VK.УдалитьТоварИзПодборки(ИДТовара, ИДПодборки, Параметры); // Удаляет из подборки + OPI_Инструменты.Пауза(5); + Проверка_ВКИстина(Результат); + + Результат = OPI_VK.УдалитьТовар(ИДТовара, Параметры); // Удаление товара + OPI_Инструменты.Пауза(5); + Проверка_ВКИстина(Результат); + + Результат = OPI_VK.УдалитьПодборку(ИДПодборки, Параметры); // Уадление подборки + OPI_Инструменты.Пауза(5); + Проверка_ВКИстина(Результат); + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура ВК_СоздатьТоварСоСвойствами() Экспорт + + Параметры = ПолучитьПараметрыВК(); + ТипСоответствие = Тип("Соответствие"); + ТипЧисло = Тип("Число"); + Response = "response"; + Желтый = "Желтый"; + Красный = "Красный"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ); + + МассивВариантов = Новый Массив; + МассивВариантов.Добавить(Желтый); + МассивВариантов.Добавить("Синий"); + МассивВариантов.Добавить(Красный); + + Результат = OPI_VK.СоздатьСвойствоТовара("Цвет", Параметры); + OPI_Инструменты.Пауза(10); + + Свойство = Результат[Response]["property_id"]; + Свойство = OPI_Инструменты.ЧислоВСтроку(Свойство); + + СоответствиеСвойств = Новый Соответствие; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["property_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + Результат = OPI_VK.ИзменитьСвойствоТовара("Цвет (изм.)", Свойство, Параметры); + OPI_Инструменты.Пауза(10); + + Проверка_ВКИстина(Результат); + + Для Каждого Вариант Из МассивВариантов Цикл + + Результат = OPI_VK.ДобавитьВариантСвойстваТовара(Вариант, Свойство, Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["variant_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + ИДВарианта = Результат[Response]["variant_id"]; + СоответствиеСвойств.Вставить(Вариант, ИДВарианта); + + Результат = OPI_VK.ИзменитьВариантСвойстваТовара(Вариант + " (изм.)" + , Свойство + , ИДВарианта + , Параметры); + + Проверка_ВКИстина(Результат); + + КонецЦикла; + + МассивКартинок = Новый Массив; + МассивКартинок.Добавить(ИВФ); + МассивКартинок.Добавить(Картинка); + + Товар = Новый Соответствие(); + Товар.Вставить("Имя" , "Тестовый товар (" + Желтый + ")"); + Товар.Вставить("Описание" , "Описание товара"); + Товар.Вставить("Категория" , "20173"); + Товар.Вставить("Цена" , 1); + Товар.Вставить("СтараяЦена" , 15); + Товар.Вставить("ОсновноеФото" , Картинка); + Товар.Вставить("URL" , "https://github.com/Bayselonarrend/OpenIntegrations"); + Товар.Вставить("ДополнительныеФото" , МассивКартинок); + Товар.Вставить("ГлавныйВГруппе" , Истина); + Товар.Вставить("НомерГруппы" , Неопределено); + Товар.Вставить("Ширина" , 20); + Товар.Вставить("Высота" , 30); + Товар.Вставить("Глубина" , 40); + Товар.Вставить("Вес" , 100); + Товар.Вставить("SKU" , 12345); + Товар.Вставить("ДоступныйОстаток" , "10"); + Товар.Вставить("ЗначенияСвойств" , СоответствиеСвойств[Желтый]); + + Результат = OPI_VK.ДобавитьТовар(Товар, , Параметры); // Добавление товара + OPI_Инструменты.Пауза(10); + + ИДЖелтого = Результат[Response]["market_item_id"]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_item_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + Товар.Вставить("Имя" , "Тестовый товар (" + Красный + ")"); + Товар.Вставить("ЗначенияСвойств", СоответствиеСвойств[Красный]); + + Результат = OPI_VK.ДобавитьТовар(Товар, , Параметры); // Добавление товара + OPI_Инструменты.Пауза(10); + + ИДКрасного = Результат[Response]["market_item_id"]; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["market_item_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + МассивТоваров = Новый Массив; + МассивТоваров.Добавить(ИДЖелтого); + МассивТоваров.Добавить(ИДКрасного); + + Результат = OPI_VK.ПолучитьТоварыПоИД(МассивТоваров, Параметры); + OPI_Инструменты.Пауза(10); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["items"]).ИмеетТип("Массив").ИмеетДлину(2); + + Результат = OPI_VK.СгруппироватьТовары(МассивТоваров, , Параметры); + OPI_Инструменты.Пауза(10); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]["item_group_id"]).ИмеетТип(ТипЧисло).Заполнено(); + + OPI_VK.УдалитьТовар(ИДЖелтого , Параметры); + OPI_VK.УдалитьТовар(ИДКрасного, Параметры); + + Для Каждого Вариант Из СоответствиеСвойств Цикл + + Удаление = OPI_VK.УдалитьВариантСвойстваТовара(Вариант.Значение, Параметры); + OPI_Инструменты.Пауза(5); + Проверка_ВКИстина(Удаление); + + КонецЦикла; + + Удаление = OPI_VK.УдалитьСвойствоТовара(Свойство, Параметры); + OPI_Инструменты.Пауза(10); + + Проверка_ВКИстина(Удаление); + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура ВК_ПолучитьСписокТоваров() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + + МассивКартинок = Новый Массив; + МассивКартинок.Добавить(Картинка); + + Товар = Новый Соответствие(); + Товар.Вставить("Имя" , "Тестовый товар 2"); + Товар.Вставить("Описание" , "Описание товара"); + Товар.Вставить("Категория" , "20173"); + Товар.Вставить("Цена" , 1); + Товар.Вставить("СтараяЦена" , 15); + Товар.Вставить("ОсновноеФото" , Картинка); + Товар.Вставить("URL" , "https://github.com/Bayselonarrend/OpenIntegrations"); + Товар.Вставить("ДополнительныеФото" , МассивКартинок); + Товар.Вставить("ГлавныйВГруппе" , Истина); + Товар.Вставить("НомерГруппы" , Неопределено); + Товар.Вставить("Ширина" , 20); + Товар.Вставить("Высота" , 30); + Товар.Вставить("Глубина" , 40); + Товар.Вставить("Вес" , 100); + Товар.Вставить("SKU" , 12345); + Товар.Вставить("ДоступныйОстаток" , "10"); + + Результат = OPI_VK.ДобавитьТовар(Товар, , Параметры); + ИДТовара = Результат["response"]["market_item_id"]; + OPI_Инструменты.Пауза(5); + + Результат = OPI_VK.ПолучитьСписокТоваров(, Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Массив").Заполнено(); + + OPI_VK.УдалитьТовар(ИДТовара, Параметры); + +КонецПроцедуры + +Процедура ВК_ПолучитьСписокПодборок() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + Результат = OPI_VK.СоздатьПодборкуТоваров("Тестовая подборка" + , Картинка + , Истина + , Ложь + , Параметры); + + ИДПодборки = Результат["response"]["market_album_id"]; + Результат = OPI_VK.ПолучитьСписокПодборок(Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Массив").Заполнено(); + + OPI_VK.УдалитьПодборку(ИДПодборки, Параметры); + +КонецПроцедуры + +Процедура ВК_ПолучитьСписокСвойств() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Результат = OPI_VK.ПолучитьСписокСвойств(Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Массив").Заполнено(); + +КонецПроцедуры + +Процедура ВК_ПолучитьСписокЗаказов() Экспорт + + Параметры = ПолучитьПараметрыВК(); + Результат = OPI_VK.ПолучитьСписокЗаказов(Параметры); + OPI_Инструменты.Пауза(5); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Массив").Заполнено(); + +КонецПроцедуры + +#КонецОбласти + +#Область YandexDisk + +Процедура ЯДиск_ПолучитьИнформациюОДиске() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Соответствие = "Соответствие"; + + Результат = OPI_YandexDisk.ПолучитьИнформациюОДиске(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(Соответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["system_folders"]).ИмеетТип(Соответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["user"]).ИмеетТип(Соответствие); + +КонецПроцедуры + +Процедура ЯДиск_СоздатьПапку() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Путь = "/" + Строка(Новый УникальныйИдентификатор); + + Результат = OPI_YandexDisk.СоздатьПапку(Токен, Путь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("dir"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + Путь); + + OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь); + +КонецПроцедуры + +Процедура ЯДиск_ЗагрузитьПоАдресуПолучитьОбъект() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Путь = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + URL = "https://raw.githubusercontent.com/Bayselonarrend/OpenIntegrations/main/Media/logo.png"; + + OPI_YandexDisk.ЗагрузитьФайлПоURL(Токен, Путь, URL); + OPI_Инструменты.Пауза(10); + + Результат = OPI_YandexDisk.ПолучитьОбъект(Токен, Путь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + Путь); + + OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь); + +КонецПроцедуры + +Процедура ЯДиск_ЗагрузитьУдалитьФайл() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Путь = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + Картинка = OPI_ПолучениеДанныхТестов.ПолучитьДвоичные("Картинка"); + ИВФ = ПолучитьИмяВременногоФайла("png"); + Картинка.Записать(ИВФ); + + Результат = OPI_YandexDisk.ЗагрузитьФайл(Токен, Путь, Картинка, Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие"); + OPI_Инструменты.Пауза(10); + + Результат = OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено); + + Результат = OPI_YandexDisk.ЗагрузитьФайл(Токен, Путь, ИВФ, Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие"); + OPI_Инструменты.Пауза(10); + + Результат = OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено); + + УдалитьФайлы(ИВФ); + +КонецПроцедуры + +Процедура ЯДиск_СоздатьКопиюОбъекта() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + ПутьОригинала = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + ПутьКопии = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + URL = "https://raw.githubusercontent.com/Bayselonarrend/" + + "OpenIntegrations/main/Media/logo.png"; + + OPI_YandexDisk.ЗагрузитьФайлПоURL(Токен, ПутьОригинала, URL); + OPI_Инструменты.Пауза(10); + + Результат = OPI_YandexDisk.СоздатьКопиюОбъекта(Токен, ПутьОригинала, ПутьКопии, Истина); + OPI_Инструменты.Пауза(10); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + ПутьКопии); + + OPI_YandexDisk.УдалитьОбъект(Токен, ПутьОригинала, Ложь); + OPI_YandexDisk.УдалитьОбъект(Токен, ПутьКопии, Ложь); + +КонецПроцедуры + +Процедура ЯДиск_ПолучитьСсылкуНаСкачивание() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Путь = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + URL = "https://raw.githubusercontent.com/Bayselonarrend/OpenIntegrations/main/Media/logo.png"; + + OPI_YandexDisk.ЗагрузитьФайлПоURL(Токен, Путь, URL); + OPI_Инструменты.Пауза(10); + + Результат = OPI_YandexDisk.ПолучитьСсылкуДляСкачивания(Токен, Путь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["method"]).Равно("GET"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["href"]).ИмеетТип("Строка").Заполнено(); + + OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь); + +КонецПроцедуры + +Процедура ЯДиск_ПолучитьСписокФайлов() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Количество = 2; + Отступ = 1; + + Результат = OPI_YandexDisk.ПолучитьСписокФайлов(Токен, Количество, Отступ, "image"); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["limit"]).Равно(Количество); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["offset"]).Равно(Отступ); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["items"]).ИмеетТип("Массив"); + +КонецПроцедуры + +Процедура ЯДиск_ПереместитьОбъект() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + ПутьОригинала = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + ПутьКопии = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + URL = "https://raw.githubusercontent.com/Bayselonarrend/" + + "OpenIntegrations/main/Media/logo.png"; + + OPI_YandexDisk.ЗагрузитьФайлПоURL(Токен, ПутьОригинала, URL); + OPI_Инструменты.Пауза(15); + + Результат = OPI_YandexDisk.ПереместитьОбъект(Токен, ПутьОригинала, ПутьКопии, Истина); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Равно("disk:" + ПутьКопии); + + OPI_YandexDisk.УдалитьОбъект(Токен, ПутьОригинала, Ложь); + OPI_YandexDisk.УдалитьОбъект(Токен, ПутьКопии, Ложь); + +КонецПроцедуры + +Процедура ЯДиск_ДействияПубличныхОбъектов() Экспорт + + PUrl = "public_url"; + Соответствие = "Соответствие"; + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Путь = "/" + Строка(Новый УникальныйИдентификатор) + ".png"; + URL = "https://raw.githubusercontent.com/Bayselonarrend/OpenIntegrations/main/Media/logo.png"; + + OPI_YandexDisk.ЗагрузитьФайлПоURL(Токен, Путь, URL); + OPI_Инструменты.Пауза(10); + + МассивРезультатов = Новый Массив; + + МассивРезультатов.Добавить(OPI_YandexDisk.ОпубликоватьОбъект(Токен, Путь)); + ПубличныйURL = МассивРезультатов[0][PUrl]; + + МассивРезультатов.Добавить(OPI_YandexDisk.СохранитьПубличныйОбъектНаДиск(Токен, ПубличныйURL)); + + ПубличныйОбъект = OPI_YandexDisk.ПолучитьПубличныйОбъект(Токен, ПубличныйURL); + СсылкаСкачивания = OPI_YandexDisk.ПолучитьСсылкуСкачиванияПубличногоОбъекта(Токен, ПубличныйURL); + + МассивРезультатов.Добавить(OPI_YandexDisk.ОтменитьПубликациюОбъекта(Токен, Путь)); + + Счетчик = 0; + Для Каждого Результат Из МассивРезультатов Цикл + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(Соответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["type"]).Равно("file"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["path"]).Заполнено(); + + Если Счетчик = 0 Тогда + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[PUrl]).ИмеетТип("Строка").Заполнено(); + Иначе + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[PUrl]).ИмеетТип("Неопределено"); + КонецЕсли; + + Счетчик = Счетчик + 1; + + КонецЦикла; + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания).ИмеетТип(Соответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания["method"]).Равно("GET"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(СсылкаСкачивания["href"]).ИмеетТип("Строка").Заполнено(); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект).ИмеетТип(Соответствие).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект["type"]).Равно("file"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(ПубличныйОбъект["path"]).Равно("/"); + + OPI_YandexDisk.УдалитьОбъект(Токен, Путь, Ложь); + +КонецПроцедуры + +Процедура ЯДиск_ПолучитьСписокОпубликованных() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ЯДиск_Токен"); + Количество = 2; + Отступ = 1; + + Результат = OPI_YandexDisk.ПолучитьСписокОпубликованныхОбъектов(Токен, Количество, Отступ); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["limit"]).Равно(Количество); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["offset"]).Равно(Отступ); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["items"]).ИмеетТип("Массив"); + +КонецПроцедуры + +#КонецОбласти + +#Область GoogleCalendar + +Процедура ГК_ПолучитьСсылкуАвторизации() Экспорт + + ClientID = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_ClientID"); + Результат = OPI_GoogleWorkspace.СформироватьСсылкуПолученияКода(ClientID); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Строка") + .Заполнено(); + + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Link", Результат); + +КонецПроцедуры + +Процедура ГК_ПолучитьТокен() Экспорт + + ClientID = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_ClientID"); + ClientSecret = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_ClientSecret"); + Code = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Code"); + + Результат = OPI_GoogleWorkspace.ПолучитьТокенПоКоду(ClientID, ClientSecret, Code); + + Если ЗначениеЗаполнено(Результат["access_token"]) + И ЗначениеЗаполнено(Результат["refresh_token"]) Тогда + + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Token" , Результат["access_token"]); + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Refresh", Результат["refresh_token"]); + + КонецЕсли; + +КонецПроцедуры + +Процедура ГК_ОбновитьТокен() Экспорт + + ClientID = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_ClientID"); + ClientSecret = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_ClientSecret"); + RefreshToken = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Refresh"); + + Результат = OPI_GoogleWorkspace.ОбновитьТокен(ClientID, ClientSecret, RefreshToken); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["access_token"]).Заполнено(); + + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Google_Token", Результат["access_token"]); + +КонецПроцедуры + +Процедура ГК_ПолучитьСписокКалендарей() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Token"); + Результат = OPI_GoogleCalendar.ПолучитьСписокКалендарей(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат) + .ИмеетТип("Массив"); + +КонецПроцедуры + +Процедура ГК_СоздатьУдалитьКалендарь() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Token"); + Наименование = "Тестовый календарь"; + Описание = "Тестовое описание"; + НаименованиеИзмененное = Наименование + " (изм.)"; + ТипСоответствие = Тип("Соответствие"); + ТипСтрока = Тип("Строка"); + Summary = "summary"; + Черный = "#000000"; + Желтый = "#ffd800"; + + Результат = OPI_GoogleCalendar.СоздатьКалендарь(Токен, Наименование); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Summary]).Равно(Наименование); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["id"]).ИмеетТип(ТипСтрока).Заполнено(); + + Календарь = Результат["id"]; + + Результат = OPI_GoogleCalendar.ИзменитьМетаданныеКалендаря(Токен + , Календарь + , НаименованиеИзмененное + , Описание); + + Проверка_ГКОбъект(Результат, НаименованиеИзмененное, Описание); + + Результат = OPI_GoogleCalendar.ПолучитьМетаданныеКалендаря(Токен, Календарь); + + Проверка_ГКОбъект(Результат, НаименованиеИзмененное, Описание); + + Результат = OPI_GoogleCalendar.ДобавитьКалендарьВСписок(Токен, Календарь); + + Проверка_ГКОбъект(Результат, НаименованиеИзмененное, Описание); + + Результат = OPI_GoogleCalendar.ИзменитьКалендарьСписка(Токен, Календарь, Черный, Желтый, Ложь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Summary]).Равно(НаименованиеИзмененное); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["foregroundColor"]).Равно(Черный); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["backgroundColor"]).Равно(Желтый); + + Результат = OPI_GoogleCalendar.ПолучитьКалендарьСписка(Токен, Календарь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип(ТипСоответствие); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат[Summary]).Равно(НаименованиеИзмененное); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["foregroundColor"]).Равно(Черный); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["backgroundColor"]).Равно(Желтый); + + Результат = OPI_GoogleCalendar.ОчиститьОсновнойКалендарь(Токен); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено); + + Результат = OPI_GoogleCalendar.УдалитьКалендарьИзСписка(Токен, Календарь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено); + + Результат = OPI_GoogleCalendar.УдалитьКалендарь(Токен, Календарь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено); + +КонецПроцедуры + +Процедура ГК_СоздатьУдалитьСобытие() Экспорт + + ТекущаяДата = OPI_Инструменты.ПолучитьТекущуюДата(); + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Token"); + Календарь = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Календарь"); + Наименование = "Новое событие"; + Описание = "Описание тестового события"; + ОписаниеИзм = "Описание тестового события (изм.)"; + UID = "id"; + Час = 3600; + + Вложения = Новый Соответствие; + + Вложения.Вставить("Картинка1" + , "https://opi.neocities.org/assets/images/logo_long-e8fdcca6ff8b32e679ea49a1ccdd3eac.png"); + Вложения.Вставить("Картинка2" + , "https://github.com/Bayselonarrend/OpenIntegrations/raw/main/Media/logo.png?v1"); + + СоответствиеСобытия = Новый Соответствие; + СоответствиеСобытия.Вставить("Описание" , Описание); + СоответствиеСобытия.Вставить("Заголовок" , Наименование); + СоответствиеСобытия.Вставить("МестоПроведения" , "В офисе"); + СоответствиеСобытия.Вставить("ДатаНачала" , ТекущаяДата); + СоответствиеСобытия.Вставить("ДатаОкончания" , СоответствиеСобытия["ДатаНачала"] + Час); + СоответствиеСобытия.Вставить("МассивURLФайловВложений" , Вложения); + СоответствиеСобытия.Вставить("ОтправлятьУведомления" , Истина); + + Результат = OPI_GoogleCalendar.СоздатьСобытие(Токен, Календарь, СоответствиеСобытия); + Событие = Результат[UID]; + + Проверка_ГКОбъект(Результат, Наименование, Описание); + + СоответствиеСобытия = Новый Соответствие; + СоответствиеСобытия.Вставить("Описание", ОписаниеИзм); + + Результат = OPI_GoogleCalendar.ИзменитьСобытие(Токен, Календарь, СоответствиеСобытия, Событие); + + Проверка_ГКОбъект(Результат, Наименование, ОписаниеИзм); + + Результат = OPI_GoogleCalendar.ПолучитьСобытие(Токен, Календарь, Событие); + + Проверка_ГКОбъект(Результат, Наименование, ОписаниеИзм); + + Результат = OPI_GoogleCalendar.ПереместитьСобытие(Токен, Календарь, Календарь, Событие); + + Проверка_ГКОбъект(Результат, Наименование, ОписаниеИзм); + + Результат = OPI_GoogleCalendar.УдалитьСобытие(Токен, Календарь, Событие); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).Равно(Неопределено); + +КонецПроцедуры + +Процедура ГК_ПолучитьСписокСобытий() Экспорт + + Токен = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Token"); + Календарь = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Google_Календарь"); + + Результат = OPI_GoogleCalendar.ПолучитьСписокСобытий(Токен, Календарь); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Массив"); + +КонецПроцедуры + +#КонецОбласти + +#Область Twitter + +Процедура Твиттер_ОбновитьТокен() Экспорт + + Параметры = ПолучитьПараметрыТвиттер(); + Результат = OPI_Twitter.ОбновитьТокен(Параметры); + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["access_token"]).Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["refresh_token"]).Заполнено(); + + Рефреш = Результат["refresh_token"]; + Токен = Результат["acess_token"]; + + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Twitter_Refresh", Рефреш); + OPI_ПолучениеДанныхТестов.ЗаписатьПараметр("Twitter_Token" , Токен); + +КонецПроцедуры + +#КонецОбласти + +#КонецОбласти + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +Функция ПолучитьПараметрыВК() + + Параметры = Новый Структура; + НомерГруппы = OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_НомерГруппы"); + + Параметры.Вставить("access_token" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_Токен")); + Параметры.Вставить("owner_id" , "-" + НомерГруппы); + Параметры.Вставить("app_id" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("ВК_Приложение")); + Параметры.Вставить("group_id" , НомерГруппы); + + Возврат Параметры; + +КонецФункции + +Функция ПолучитьПараметрыТвиттер() + + Параметры = Новый Соответствие; + + Параметры.Вставить("redirect_uri" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_Redirect")); + Параметры.Вставить("client_id" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_ClinetID")); + Параметры.Вставить("client_secret" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_ClientSecret")); + Параметры.Вставить("access_token" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_Token")); + Параметры.Вставить("refresh_token" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_Refresh")); + Параметры.Вставить("oauth_token" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_OAuthToken")); + Параметры.Вставить("oauth_token_secret" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_OAuthSecret")); + Параметры.Вставить("oauth_consumer_key" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_OAuthConsumerKey")); + Параметры.Вставить("oauth_consumer_secret" , OPI_ПолучениеДанныхТестов.ПолучитьПараметр("Twitter_OAuthConsumerSecret")); + + Возврат Параметры; + +КонецФункции + +#Область Проверки + +Процедура Проверка_ТелеграмИстина(Знач Результат) + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["ok"]).Равно(Истина); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["result"]).Равно(Истина); + +КонецПроцедуры + +Процедура Проверка_ВКИстина(Знач Результат) + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие").Заполнено(); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["response"]).ИмеетТип("Число").Равно(1); + +КонецПроцедуры + +Процедура Проверка_ГКОбъект(Знач Результат, Знач Наименование, Знач Описание) + + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат).ИмеетТип("Соответствие"); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["summary"]).Равно(Наименование); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["description"]).Равно(Описание); + OPI_ПолучениеДанныхТестов.ОжидаетЧто(Результат["id"]).ИмеетТип("Строка").Заполнено(); + +КонецПроцедуры + +#КонецОбласти + +#КонецОбласти + +// BSLLS:Typo-on \ No newline at end of file diff --git a/OPI/src/CommonModules/OPI_GoogleCalendar/Module.bsl b/OPI/src/CommonModules/OPI_GoogleCalendar/Module.bsl index 2f0f19ca1..7c0943793 100644 --- a/OPI/src/CommonModules/OPI_GoogleCalendar/Module.bsl +++ b/OPI/src/CommonModules/OPI_GoogleCalendar/Module.bsl @@ -44,7 +44,7 @@ Параметры = Новый Структура; Параметры.Вставить("summary" , Наименование); - Параметры.Вставить("timeZone", ЧасовойПояс()); + Параметры.Вставить("timeZone", "Europe/Moscow"); Ответ = OPI_Инструменты.Post(URL, Параметры, Заголовки); @@ -427,7 +427,7 @@ Дата = Формат(Дата, ФорматДаты); СтруктураДаты.Вставить(Поле , Дата); - СтруктураДаты.Вставить("timeZone", ЧасовойПояс()); + СтруктураДаты.Вставить("timeZone", "Europe/Moscow"); Возврат СтруктураДаты; diff --git a/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl b/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl index ad885a998..05733029b 100644 --- a/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl +++ b/OPI/src/CommonModules/OPI_YandexDisk/Module.bsl @@ -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", Заголовки); Возврат Ответ; diff --git a/OPI/src/CommonModules/OPI_Инструменты/Module.bsl b/OPI/src/CommonModules/OPI_Инструменты/Module.bsl index 4c4538552..f7dc51449 100644 --- a/OPI/src/CommonModules/OPI_Инструменты/Module.bsl +++ b/OPI/src/CommonModules/OPI_Инструменты/Module.bsl @@ -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, Данные); diff --git a/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl b/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl index 04554a276..cefa9d243 100644 --- a/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl +++ b/OPI/src/CommonModules/OPI_ПолучениеДанныхТестов/Module.bsl @@ -142,7 +142,7 @@ КонецФункции Функция ПутьКФайлуДанных() - Возврат "C:\data.json"; // BSLLS:UsingHardcodePath-off + Возврат "C:\GDrive\Мой диск\data.json"; // BSLLS:UsingHardcodePath-off КонецФункции Функция ПолучитьМассивРазделовТестирования() diff --git a/OPI/src/CommonModules/OPI_Тесты/Module.bsl b/OPI/src/CommonModules/OPI_Тесты/Module.bsl index 031ac72b6..7ff06f5d2 100644 --- a/OPI/src/CommonModules/OPI_Тесты/Module.bsl +++ b/OPI/src/CommonModules/OPI_Тесты/Module.bsl @@ -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,26 +1235,21 @@ ИВФ = ПолучитьИмяВременногоФайла("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"]).ИмеетТип("Строка").Заполнено(); + +КонецПроцедуры + #КонецОбласти #КонецОбласти