Показать оглавление

 

Общая информация

Рассылка отчетов — это функциональная возможность, позволяющая автоматически получать отчеты с Аналитического портала (Modus BI), сохранять их в PDF, отправлять в Telegram и на электронную почту. Рассылка выполняется с помощью настроенного шаблона шага сценария на языке 1С. Шаг может быть встроен в любое место сценария — в начало, в середину или после конкретного шага. Это позволяет, например, отправлять уведомление после обновления витрины данных.

Поддерживаемые каналы рассылки:

  • Telegram (отправка файла в чат через бота);
  • Email (отправка письма со вложением по списку рассылки).

Предварительная настройка

Перед созданием шаблона шага сценария необходимо настроить несколько объектов в Modus ETL.

Справочник «Аналитические порталы»

Примечание.

  1. Настройка справочника «Аналитические порталы» выполняется администратором Modus ETL через «Функции технического специалиста».
  2. Пользователям без прав администратора через строку поиска доступны только уже настроенные порталы — для выбора в списке.

 

Перейдите в справочник «Аналитические порталы» или воспользуйтесь строкой поиска.

Рабочий процесс:

  1. В диалоговом окне справочника «Аналитические порталы» нажмите кнопку «Создать».
  2. В диалоговом окне «Аналитический портал (создание)» заполните:
    • «Наименование:» — название портала;
    • «Адрес:» — адрес портала, по умолчанию https://demo.modusbi.ru/;
    • «Путь к API:» — адрес программного интерфейса портала для обращения к данным, по умолчанию /v1/api;
    • «Имя пользователя:» — логин для подключения;
    • «Пароль:» — пароль логина.
  3. После заполнения нажмите кнопку «Проверить подключение», чтобы убедиться в корректности настроек.

Примечание. Наименование портала в дальнейшем указывается в параметрах шага в поле «НаименованиеПортала» и должно точно совпадать, так как поиск выполняется по значению из поля «Наименование».

 

Справочник «Списки рассылок»

Перейдите «Главное/ Настройки/ Списки рассылок» или воспользуйтесь строкой поиска.

Рабочий процесс:

  1. В диалоговом окне справочника «Списки рассылок» нажмите кнопку «Создать».
  2. В диалоговом окне «Список рассылок (создание)» заполните:
    • «Наименование:» — название списка (например, «Отправка отчётов АП на почту»);
    • «Электронная почта:» — адреса получателей. При необходимости добавить еще адреса для рассылки нажмите кнопку «@ Электронная подпись»;
    • Корректность настроек можно проверить нажав иконку «Конверт» (Написать письмо на указанный адрес);
    • Поле «Примечание» заполните при необходимости.
  3. После заполнения нажмите кнопку «Записать и закрыть».

Создание новой учетной записи электронной почты (для отправки на Email)

Перейдите «Администрирование/ Органайзер/ Настройка почты» или воспользуйтесь строкой поиска.

Примечание. Настройка почтового сервера выполняется администратором. Если почтовый сервер не настроен, обратитесь к системному администратору.

 

Рабочий процесс:

  1. В диалоговом окне «Настройка почты» нажмите кнопку «Создать», заполните:
    • «Адрес почты» — адрес, откуда будут поступать уведомления;
    • «Пароль почты» — введите пароль;
    • Установите галочки «Для отправки писем» и/или «Для получения писем»;
    • Установите фокус «Всеми пользователями (общая почта)» или «Только мной»;
    • Заполните поле «Имя отправителя»;
    • Нажмите кнопку «Создать».
  2. Система запустит процесс проверки настроек. В случае если настройки почты нестандартные, перейдите к ручным настройкам, нажав на кнопку «Пропустить проверку».
  3. ​​В диалоговом окне «Настройка почты» заполните параметры электронной почты и нажмите на кнопку «Далее». Для получения настроек обратитесь 

    к администратору почтового сервера.

  4. Система запустит проверку.
  5. Если настройки верны, появится уведомление и будет отправлено тестовое сообщение.
  6. Пример заполнения настроек.

Настройка почты для рассылки уведомлений

Для настройки установленной электронной почты перейдите «Администрирование/ Органайзер/ Настройка почты для рассылок уведомлений» или воспользуйтесь строкой поиска.

Рабочий процесс:

  1. В диалоговом окне установленной почты, измените необходимые настройки, нажмите кнопку «Проверить настройки».
  2. Система запустит процесс проверки настроек. Если настройки верны, появится уведомление и будет отправлено тестовое сообщение.
  3. Нажмите кнопку «Записать и закрыть».

Подробнее о настройках сервисе рассылки отчетов см. стаью «Настройка почты и рассылка отчетов».

Создание шаблона шага сценария

Шаблон шага — это заготовка, в которой хранится скрипт и набор параметров. Создав шаблон один раз, он используется в сценариях, при необходимости изменяются только значения параметров скрипта.

Основные настройки

Перейдите «Главное/ Настройки/ Шаблоны шагов сценария» или воспользуйтесь строкой поиска.

Рабочий процесс:

  1. В диалоговом окне «Шаблоны шагов сценариев» нажмите кнопку «Создать».
  2. В диалоговом окне «Шаблон шага сценария (создание)» заполните:
    • «Наименование» — название шаблона (будет отображаться в сценарии). Например, «Скрипт по отправке отчётов АП в Telegram» или «Скрипт по отправке отчётов АП на почту»;
    • «Тип шага» — из выпадающего списка выберите «EXEC»;
    • «Вид шага» — из выпадающего списка выберите «Произвольный код на языке 1С»;
    • Установите флаг «Показать» (в списке шаблонов)
  3. Перейдите на вкладку «Тексты запросов»:
    • Нажмите кнопку «Добавить»;
    • Из выпадающего списка в поле «Тип БД» выберите тип базы данных, соответствующий базе, которая используется в сценарии.
  4. Вставьте текст скрипта в поле для кода:
  5. Перейдите на вкладку «Параметры запроса» и нажмите кнопку «Дозаполнить параметры». Система проанализирует скрипт и автоматически заполнит имена параметров, которые были указаны в формате {!ИмяПараметра!}. Нажмите кнопку «Записать и закрыть».

  6. После сохранения поместите созданный шаблон в подходящую группу, например «Сервисные операции».

Использование шаблона в сценарии

Добавление шага

Перейдите «Главное/ Сценарии обработки данных» или воспользуйтесь строкой поиска.

Рабочий процесс:

Примечание. Тип базы данных сценария должен совпадать с типом БД, указанным в созданном вами шаблоне!

  1. В диалоговом окне «Сценарии обработки данных» создайте новый сценарий или откройте существующий.
  2. Перейдите в «Шаги сценария».
  3. Найдите созданный шаблон в списке (он находится в той группе, куда вы его поместили) и перетащите его на рабочую область.
  4. Нажмите на иконку «карандаш» на шаге, чтобы открыть настройки. Заполните параметры — их состав и имена возьмите из шаблона:
    • Для Telegram:
      • «ХостПортала» — адрес портала Modus BI;
      • «ТокенTelegramБота» — токен бота, полученный в Telegram;
      • «ЧастьПутиURLОтчета» — адрес отчёта (например, report/1384);
      • «ИдентификаторЧатаTelegram» — идентификатор чата для отправки;
      • «НаименованиеПортала» — наименование элемента справочника «Аналитические порталы».
    • Для почты:
      • «ХостПортала» — адрес портала;
      • «ЧастьПутиURLОтчета» — часть пути к отчёту;
      • «НаименованиеПортала» — наименование элемента справочника «Аналитические порталы»;
      • «НаименованиеСпискаРассылки» — наименование элемента справочника «Списки рассылок».
  5. Нажмите кнопку «Готово».

Ограничения и особенности

  1. Хост портала указывается отдельно, даже если портал уже выбран в справочнике «Аналитические порталы». Это особенность текущей реализации скрипта.
  2. Таймауты и задержки (например, таймаут экспорта 120 секунд, задержка 1000 мс) предустановлены в шаблоне. При необходимости их можно изменить в шаблоне шага, после чего обновите шаг в сценарии.
  3. Пустые отчёты — функция не проверяет, пустой ли отчёт. Если отчёт пустой, он всё равно будет отправлен.
  4. Рассылка статусов — текущий скрипт отправляет содержимое отчёта, а не статус выполнения шага или пакета.
  5. Шаг не привязан к месту — его можно вставить в любое место сценария.
  6. Настройка почтового сервера выполняется администратором. Если почтовый сервер не настроен, обратитесь к системному администратору. Подробнее см. раздел «Создание новой учетной записи электронной почты (для отправки на Email)» и статью «Настройка почты и рассылка отчетов».
  7. Если данные на портале Modus BI кэшируются, перед вызовом шага может потребоваться сброс кэша набора данных. Подробнее см. статью «Кэширование аналитического портала».

Примечание. Если требуется создать собственный шаблон шага (например, для нового канала рассылки или другой логики), подробнее см. статью «Разработка шаблонов шагов сценария в Modus ETL. Руководство для 1С-разработчика».

Скрипты

Для Telegram

Скрипт для отправки отчётов в Telegram

Примечание. В скрипте объявляются параметры, которые затем будут отображаться в шаге сценария.

ХостПортала = "{!ХостПортала!}";
ТокенTelegramБота = "{!ТокенTelegramБота!}";
ЧастьПутиURLОтчета = "{!ЧастьПутиURLОтчета!}";
ИдентификаторЧатаTelegram = "{!ИдентификаторЧатаTelegram!}";
НаименованиеПортала = "{!НаименованиеПортала!}";

Параметры задаются в формате {!ИмяПараметра!} — по этому шаблону система распознаёт их и выносит в настройки шага.

 

ХостПортала = "{!ХостПортала!}";
ТокенTelegramБота = "{!ТокенTelegramБота!}";
ЧастьПутиURLОтчета = "{!ЧастьПутиURLОтчета!}";
ИдентификаторЧатаTelegram = "{!ИдентификаторЧатаTelegram!}";
НаименованиеПортала = "{!НаименованиеПортала!}";

АналитическийПортал = Справочники.хс_АналитическиеПорталы.НайтиПоНаименованию(НаименованиеПортала);
Если Не ЗначениеЗаполнено(АналитическийПортал) Тогда
	ВызватьИсключение "Не найден аналитический портал.";
КонецЕсли;

ПараметрыОбработки = Новый Структура;
ПараметрыОбработки.Вставить("URLОтчета", "https://" + ХостПортала + "/" + ЧастьПутиURLОтчета);
ПараметрыОбработки.Вставить("ТокенTelegramБота", ТокенTelegramБота);
ПараметрыОбработки.Вставить("ИдентификаторЧатаTelegram", ИдентификаторЧатаTelegram);
ПараметрыОбработки.Вставить("ПутьAPIЭкспорта", "/v1/api/exports");
ПараметрыОбработки.Вставить("ТаймаутHTTP", 500);
ПараметрыОбработки.Вставить("РазмерСтраницыPDF", "A4");
ПараметрыОбработки.Вставить("ОриентацияСтраницыPDF", "landscape");
ПараметрыОбработки.Вставить("ТаймаутЭкспорта", 120);
ПараметрыОбработки.Вставить("ЗадержкаЭкспорта", 1000);
ПараметрыОбработки.Вставить("HeadlessЭкспорта", Истина);
ПараметрыОбработки.Вставить("ОтладкаЭкспорта", Ложь);
ПараметрыОбработки.Вставить("СхемаTelegram", "https");
ПараметрыОбработки.Вставить("ХостTelegram", "api.telegram.org");
ПараметрыОбработки.Вставить("ПортTelegram", 443);
ПараметрыОбработки.Вставить("ИмяФайлаTelegram", "report.pdf");
ПараметрыОбработки.Вставить("ПодписьTelegram", "Отчет сформирован автоматически");
ПараметрыОбработки.Вставить("ИдентификаторТемыTelegram", Неопределено);

ПараметрыПодключения = хс_ВзаимодействиеСАналитическимПорталомСлужебный.ПараметрыПодключения();
хс_ВзаимодействиеСАналитическимПорталомСлужебный.ИнициализироватьПараметрыПодключения(
	АналитическийПортал, ПараметрыПодключения);
	
СоединениеПортала = Новый HTTPСоединение(
	ХостПортала,
	,
	"",
	"",
	,
	ПараметрыОбработки.ТаймаутHTTP
	,Новый ЗащищенноеСоединениеOpenSSL
);
	
ПараметрыПодключения.HTTPСоединение = СоединениеПортала;
		
РезультатАутентификации = хс_ВзаимодействиеСАналитическимПорталомСлужебный.ВыполнитьАутентификацию(
	ПараметрыПодключения);

Если Не РезультатАутентификации.Выполнено Тогда
	ТекстОшибки = СтрШаблон("Ошибка аутентификации на аналитическом портале: %1", РезультатАутентификации.ТекстОшибки);
	ВызватьИсключение ТекстОшибки;
КонецЕсли;
	
ДанныеЭкспорта = Новый Структура;
ДанныеЭкспорта.Вставить("url", ПараметрыОбработки.URLОтчета);
ДанныеЭкспорта.Вставить("output_type", "pdf");
ДанныеЭкспорта.Вставить("page_size", ПараметрыОбработки.РазмерСтраницыPDF);
ДанныеЭкспорта.Вставить("page_orientation", ПараметрыОбработки.ОриентацияСтраницыPDF);
ДанныеЭкспорта.Вставить("debug", ПараметрыОбработки.ОтладкаЭкспорта);
ДанныеЭкспорта.Вставить("timeout", ПараметрыОбработки.ТаймаутЭкспорта);
ДанныеЭкспорта.Вставить("delay", ПараметрыОбработки.ЗадержкаЭкспорта);
ДанныеЭкспорта.Вставить("headless", ПараметрыОбработки.HeadlessЭкспорта);

МассивДанныхЭкспорта = Новый Массив;
МассивДанныхЭкспорта.Добавить(ДанныеЭкспорта);

ТелоЗапросаЭкспорта = Новый Структура(
	"object,command,data",
	Новый Структура("name", "exports"),
	Новый Структура("name", "automated"),
	МассивДанныхЭкспорта
);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ТелоЗапросаЭкспорта);
СтрокаJSONЭкспорта = ЗаписьJSON.Закрыть();

ЗаголовкиПортала = Новый Соответствие;
ЗаголовкиПортала.Вставить("Authorization", "Bearer " + ПараметрыПодключения.ТокенАутентификации);
ЗаголовкиПортала.Вставить("Content-Type", "application/json; charset=utf-8");
ЗаголовкиПортала.Вставить("Accept-Encoding", "identity");

ЗапросПортала = Новый HTTPЗапрос(ПараметрыОбработки.ПутьAPIЭкспорта, ЗаголовкиПортала);
ЗапросПортала.УстановитьТелоИзСтроки(СтрокаJSONЭкспорта, "UTF-8");

ОтветПортала = ПараметрыПодключения.HTTPСоединение.ВызватьHTTPМетод("POST", ЗапросПортала);
ТекстОтветаПортала = ОтветПортала.ПолучитьТелоКакСтроку();

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТекстОтветаПортала);
ОтветJSONПортала = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

Если ОтветПортала.КодСостояния <> 200 Тогда
	Если ОтветJSONПортала <> Неопределено И ОтветJSONПортала.Свойство("message") Тогда
		ВызватьИсключение "Ошибка API экспорта: " + ОтветJSONПортала.message;
	Иначе
		ВызватьИсключение "Ошибка API экспорта. Код состояния: " + Строка(ОтветПортала.КодСостояния);
	КонецЕсли;
КонецЕсли;

Если ОтветJSONПортала = Неопределено
	ИЛИ НЕ ОтветJSONПортала.Свойство("data")
	ИЛИ ТипЗнч(ОтветJSONПортала.data) <> Тип("Массив")
	ИЛИ ОтветJSONПортала.data.Количество() = 0 Тогда
	ВызватьИсключение "API экспорта не вернул data[0].";
КонецЕсли;

ДанныеОтветаЭкспорта = ОтветJSONПортала.data[0];
Если ДанныеОтветаЭкспорта.success <> 1 Тогда
	ВызватьИсключение "Экспорт PDF завершился ошибкой: " + ДанныеОтветаЭкспорта.message;
КонецЕсли;

Если НЕ ЗначениеЗаполнено(ДанныеОтветаЭкспорта.file_data) Тогда
	ВызватьИсключение "API экспорта не вернул file_data.";
КонецЕсли;

ДвоичныеДанныеPDF = Base64Значение(ДанныеОтветаЭкспорта.file_data);
ИмяФайлаPDF = ДанныеОтветаЭкспорта.file_name;
Если ПараметрыОбработки.Свойство("ИмяФайлаTelegram") И ЗначениеЗаполнено(ПараметрыОбработки.ИмяФайлаTelegram) Тогда
	ИмяФайлаPDF = ПараметрыОбработки.ИмяФайлаTelegram;
КонецЕсли;

Если НЕ ЗначениеЗаполнено(ИмяФайлаPDF) Тогда
	ИмяФайлаPDF = "report.pdf";
КонецЕсли;

MIMEТипPDF = ДанныеОтветаЭкспорта.mime_type;
Если НЕ ЗначениеЗаполнено(MIMEТипPDF) Тогда
	MIMEТипPDF = "application/pdf";
КонецЕсли;
	
ГраницаMultipart = СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
ПереходСтрок = Символы.ВК + Символы.ПС;

ПотокТела = Новый ПотокВПамяти;
ЗаписьДанныхТела = Новый ЗаписьДанных(
	ПотокТела,
	КодировкаТекста.UTF8,
	ПорядокБайтов.LittleEndian,
	"",
	"",
	Ложь
);

ЗаписьДанныхТела.ЗаписатьСтроку("--" + ГраницаMultipart + ПереходСтрок);
ЗаписьДанныхТела.ЗаписатьСтроку(
	"Content-Disposition: form-data; name=""chat_id""" + ПереходСтрок + ПереходСтрок
);
ЗаписьДанныхТела.ЗаписатьСтроку(Строка(ПараметрыОбработки.ИдентификаторЧатаTelegram) + ПереходСтрок);

Если ПараметрыОбработки.Свойство("ИдентификаторТемыTelegram")
	И ЗначениеЗаполнено(ПараметрыОбработки.ИдентификаторТемыTelegram) Тогда
	ЗаписьДанныхТела.ЗаписатьСтроку("--" + ГраницаMultipart + ПереходСтрок);
	ЗаписьДанныхТела.ЗаписатьСтроку(
	"Content-Disposition: form-data; name=""message_thread_id""" + ПереходСтрок + ПереходСтрок
	);
	ЗаписьДанныхТела.ЗаписатьСтроку(Строка(ПараметрыОбработки.ИдентификаторТемыTelegram) + ПереходСтрок);
КонецЕсли;

Если ПараметрыОбработки.Свойство("ПодписьTelegram") И ЗначениеЗаполнено(ПараметрыОбработки.ПодписьTelegram) Тогда
	ЗаписьДанныхТела.ЗаписатьСтроку("--" + ГраницаMultipart + ПереходСтрок);
	ЗаписьДанныхТела.ЗаписатьСтроку(
	"Content-Disposition: form-data; name=""caption""" + ПереходСтрок + ПереходСтрок
	);
	ЗаписьДанныхТела.ЗаписатьСтроку(ПараметрыОбработки.ПодписьTelegram + ПереходСтрок);
КонецЕсли;

ЗаписьДанныхТела.ЗаписатьСтроку("--" + ГраницаMultipart + ПереходСтрок);
ЗаписьДанныхТела.ЗаписатьСтроку(
"Content-Disposition: form-data; name=""document""; filename=""" + ИмяФайлаPDF + """" + ПереходСтрок
);
ЗаписьДанныхТела.ЗаписатьСтроку("Content-Type: " + MIMEТипPDF + ПереходСтрок + ПереходСтрок);
ЗаписьДанныхТела.Записать(ДвоичныеДанныеPDF);
ЗаписьДанныхТела.ЗаписатьСтроку(ПереходСтрок);
ЗаписьДанныхТела.ЗаписатьСтроку("--" + ГраницаMultipart + "--" + ПереходСтрок);

ДвоичноеТелоТelegram = ПотокТела.ЗакрытьИПолучитьДвоичныеДанные();
ЗаписьДанныхТела.Закрыть();

СоединениеTelegram = Новый HTTPСоединение(
	ПараметрыОбработки.ХостTelegram,
	ПараметрыОбработки.ПортTelegram,
	"",
	"",
	Неопределено,
	ПараметрыОбработки.ТаймаутHTTP
	,Новый ЗащищенноеСоединениеOpenSSL
);

ЗаголовкиTelegram = Новый Соответствие;
ЗаголовкиTelegram.Вставить("Content-Type", "multipart/form-data; boundary=" + ГраницаMultipart);
ЗаголовкиTelegram.Вставить("Accept-Encoding", "identity");

ЗапросTelegram = Новый HTTPЗапрос(
	"/bot" + ПараметрыОбработки.ТокенTelegramБота + "/sendDocument",
	ЗаголовкиTelegram
);
ЗапросTelegram.УстановитьТелоИзДвоичныхДанных(ДвоичноеТелоТelegram);

ОтветTelegram = СоединениеTelegram.ВызватьHTTPМетод("POST", ЗапросTelegram);
ТекстОтветаTelegram = ОтветTelegram.ПолучитьТелоКакСтроку();

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТекстОтветаTelegram);
ОтветJSONTelegram = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

Если ОтветJSONTelegram = Неопределено Тогда
	ВызватьИсключение "Telegram API вернул пустой JSON-ответ.";
КонецЕсли;

Если ОтветTelegram.КодСостояния <> 200 Тогда
	Если ОтветJSONTelegram.Свойство("description") Тогда
		ВызватьИсключение "Ошибка Telegram API: " + ОтветJSONTelegram.description;
	Иначе
		ВызватьИсключение "Ошибка Telegram API. Код состояния: " + Строка(ОтветTelegram.КодСостояния);
	КонецЕсли;
КонецЕсли;

Если НЕ ОтветJSONTelegram.Свойство("ok") ИЛИ ОтветJSONTelegram.ok <> Истина Тогда
	ВызватьИсключение "Telegram API вернул ошибку: " + ОтветJSONTelegram.description;
КонецЕсли;

Результат = Новый Структура;
Результат.Вставить("token", ПараметрыПодключения.ТокенАутентификации);
Результат.Вставить("report_id", ДанныеОтветаЭкспорта.report_id);
Результат.Вставить("file_name", ИмяФайлаPDF);
Результат.Вставить("mime_type", MIMEТипPDF);
Результат.Вставить("file_size", ДанныеОтветаЭкспорта.file_size);
Результат.Вставить("elapsed", ДанныеОтветаЭкспорта.elapsed);
Результат.Вставить("telegram_status", ОтветTelegram.КодСостояния);

Если ОтветJSONTelegram.Свойство("result") Тогда
	Результат.Вставить("telegram_result", ОтветJSONTelegram.result);
КонецЕсли;

Для почты

Скрипт для отправки отчётов на почту

Примечание. В скрипте объявляются параметры, которые затем будут отображаться в шаге сценария.

ХостПортала = "{!ХостПортала!}";
ЧастьПутиURLОтчета = "{!ЧастьПутиURLОтчета!}";
НаименованиеПортала = "{!НаименованиеПортала!}";
НаименованиеСпискаРассылки = "{!НаименованиеСпискаРассылки!}";

Параметры задаются в формате {!ИмяПараметра!} — по этому шаблону система распознаёт их и выносит в настройки шага.

 

ХостПортала = "{!ХостПортала!}";
ЧастьПутиURLОтчета = "{!ЧастьПутиURLОтчета!}";
НаименованиеПортала = "{!НаименованиеПортала!}";
НаименованиеСпискаРассылки = "{!НаименованиеСпискаРассылки!}";

АналитическийПортал = Справочники.хс_АналитическиеПорталы.НайтиПоНаименованию(НаименованиеПортала);
Если Не ЗначениеЗаполнено(АналитическийПортал) Тогда
ВызватьИсключение "Не найден аналитический портал.";
КонецЕсли;

СписокРассылки = Справочники.ХС_СпискиРассылок.НайтиПоНаименованию(НаименованиеСпискаРассылки);
Если Не ЗначениеЗаполнено(СписокРассылки) Тогда
ВызватьИсключение "Не найден список рассылки.";
КонецЕсли;

ПараметрыОбработки = Новый Структура;
ПараметрыОбработки.Вставить("URLОтчета", "https://" + ХостПортала + "/" + ЧастьПутиURLОтчета);
ПараметрыОбработки.Вставить("ПутьAPIЭкспорта", "/v1/api/exports");
ПараметрыОбработки.Вставить("ТаймаутHTTP", 300);
ПараметрыОбработки.Вставить("РазмерСтраницыPDF", "A4");
ПараметрыОбработки.Вставить("ОриентацияСтраницыPDF", "landscape");
ПараметрыОбработки.Вставить("ТаймаутЭкспорта", 120);
ПараметрыОбработки.Вставить("ЗадержкаЭкспорта", 1000);
ПараметрыОбработки.Вставить("HeadlessЭкспорта", Истина);
ПараметрыОбработки.Вставить("ОтладкаЭкспорта", Ложь);
ПараметрыОбработки.Вставить("ИмяФайлаВложения", "report.pdf");
ПараметрыОбработки.Вставить("ТемаПисьма", "Отчет в PDF");
ПараметрыОбработки.Вставить("ТекстПисьма", "Во вложении подготовленный PDF-отчет.");

ПараметрыПодключения = хс_ВзаимодействиеСАналитическимПорталомСлужебный.ПараметрыПодключения();
хс_ВзаимодействиеСАналитическимПорталомСлужебный.ИнициализироватьПараметрыПодключения(
АналитическийПортал, ПараметрыПодключения);

СоединениеПортала = Новый HTTPСоединение(
ХостПортала,
,
"",
"",
,
ПараметрыОбработки.ТаймаутHTTP
,Новый ЗащищенноеСоединениеOpenSSL
);

ПараметрыПодключения.HTTPСоединение = СоединениеПортала;

РезультатАутентификации = хс_ВзаимодействиеСАналитическимПорталомСлужебный.ВыполнитьАутентификацию(
ПараметрыПодключения);

Если Не РезультатАутентификации.Выполнено Тогда
ТекстОшибки = СтрШаблон("Ошибка аутентификации на аналитическом портале: %1", РезультатАутентификации.ТекстОшибки);
ВызватьИсключение ТекстОшибки;
КонецЕсли;

ДанныеЭкспорта = Новый Структура;
ДанныеЭкспорта.Вставить("url", ПараметрыОбработки.URLОтчета);
ДанныеЭкспорта.Вставить("output_type", "pdf");
ДанныеЭкспорта.Вставить("page_size", ПараметрыОбработки.РазмерСтраницыPDF);
ДанныеЭкспорта.Вставить("page_orientation", ПараметрыОбработки.ОриентацияСтраницыPDF);
ДанныеЭкспорта.Вставить("debug", ПараметрыОбработки.ОтладкаЭкспорта);
ДанныеЭкспорта.Вставить("timeout", ПараметрыОбработки.ТаймаутЭкспорта);
ДанныеЭкспорта.Вставить("delay", ПараметрыОбработки.ЗадержкаЭкспорта);
ДанныеЭкспорта.Вставить("headless", ПараметрыОбработки.HeadlessЭкспорта);

МассивДанныхЭкспорта = Новый Массив;
МассивДанныхЭкспорта.Добавить(ДанныеЭкспорта);

ТелоЗапросаЭкспорта = Новый Структура(
"object,command,data",
Новый Структура("name", "exports"),
Новый Структура("name", "automated"),
МассивДанныхЭкспорта
);

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, ТелоЗапросаЭкспорта);
СтрокаJSONЭкспорта = ЗаписьJSON.Закрыть();

ЗаголовкиПортала = Новый Соответствие;
ЗаголовкиПортала.Вставить("Authorization", "Bearer " + ПараметрыПодключения.ТокенАутентификации);
ЗаголовкиПортала.Вставить("Content-Type", "application/json; charset=utf-8");
ЗаголовкиПортала.Вставить("Accept-Encoding", "identity");

ЗапросПортала = Новый HTTPЗапрос(ПараметрыОбработки.ПутьAPIЭкспорта, ЗаголовкиПортала);
ЗапросПортала.УстановитьТелоИзСтроки(СтрокаJSONЭкспорта, "UTF-8");

ОтветПортала = ПараметрыПодключения.HTTPСоединение.ВызватьHTTPМетод("POST", ЗапросПортала);
ТекстОтветаПортала = ОтветПортала.ПолучитьТелоКакСтроку();

ЧтениеJSON = Новый ЧтениеJSON;
ЧтениеJSON.УстановитьСтроку(ТекстОтветаПортала);
ОтветJSONПортала = ПрочитатьJSON(ЧтениеJSON);
ЧтениеJSON.Закрыть();

Если ОтветПортала.КодСостояния <> 200 Тогда
Если ОтветJSONПортала <> Неопределено И ОтветJSONПортала.Свойство("message") Тогда
  ВызватьИсключение "Ошибка API экспорта: " + ОтветJSONПортала.message;
Иначе
  ВызватьИсключение "Ошибка API экспорта. Код состояния: " + Строка(ОтветПортала.КодСостояния);
КонецЕсли;
КонецЕсли;

Если ОтветJSONПортала = Неопределено
ИЛИ НЕ ОтветJSONПортала.Свойство("data")
ИЛИ ТипЗнч(ОтветJSONПортала.data) <> Тип("Массив")
ИЛИ ОтветJSONПортала.data.Количество() = 0 Тогда
ВызватьИсключение "API экспорта не вернул data[0].";
КонецЕсли;

ДанныеОтветаЭкспорта = ОтветJSONПортала.data[0];
Если ДанныеОтветаЭкспорта.success <> 1 Тогда
ВызватьИсключение "Экспорт PDF завершился ошибкой: " + ДанныеОтветаЭкспорта.message;
КонецЕсли;

Если НЕ ЗначениеЗаполнено(ДанныеОтветаЭкспорта.file_data) Тогда
ВызватьИсключение "API экспорта не вернул file_data.";
КонецЕсли;

ДвоичныеДанныеPDF = Base64Значение(ДанныеОтветаЭкспорта.file_data);
ИмяФайлаPDF = ДанныеОтветаЭкспорта.file_name;
Если ПараметрыОбработки.Свойство("ИмяФайлаВложения") И ЗначениеЗаполнено(ПараметрыОбработки.ИмяФайлаВложения) Тогда
ИмяФайлаPDF = ПараметрыОбработки.ИмяФайлаВложения;
КонецЕсли;

Если НЕ ЗначениеЗаполнено(ИмяФайлаPDF) Тогда
ИмяФайлаPDF = "report.pdf";
КонецЕсли;

MIMEТипPDF = ДанныеОтветаЭкспорта.mime_type;
Если НЕ ЗначениеЗаполнено(MIMEТипPDF) Тогда
MIMEТипPDF = "application/pdf";
КонецЕсли;

Если НЕ ПараметрыОбработки.Свойство("ТемаПисьма") ИЛИ НЕ ЗначениеЗаполнено(ПараметрыОбработки.ТемаПисьма) Тогда
ПараметрыОбработки.Вставить("ТемаПисьма", "Отчет " + ИмяФайлаPDF);
КонецЕсли;

Если НЕ ПараметрыОбработки.Свойство("ТекстПисьма") ИЛИ НЕ ЗначениеЗаполнено(ПараметрыОбработки.ТекстПисьма) Тогда
ПараметрыОбработки.Вставить("ТекстПисьма", "Во вложении отчет " + ИмяФайлаPDF + ".");
КонецЕсли;

Результат = Новый Структура;
Результат.Вставить("report_id", ДанныеОтветаЭкспорта.report_id);
Результат.Вставить("file_name", ИмяФайлаPDF);
Результат.Вставить("mime_type", MIMEТипPDF);
Результат.Вставить("file_size", ДанныеОтветаЭкспорта.file_size);
Результат.Вставить("elapsed", ДанныеОтветаЭкспорта.elapsed);
Результат.Вставить("ТемаПисьма", ПараметрыОбработки.ТемаПисьма);
Результат.Вставить("ТекстПисьма", ПараметрыОбработки.ТекстПисьма);
Результат.Вставить("ИмяФайлаВложения", ИмяФайлаPDF);
Результат.Вставить("MIMEТипВложения", MIMEТипPDF);
Результат.Вставить("ДвоичныеДанныеВложения", ДвоичныеДанныеPDF);
Результат.Вставить("Base64ДанныеВложения", ДанныеОтветаЭкспорта.file_data);

Вложения = Новый Соответствие;
ПотокВПамяти = Новый ПотокВПамяти;
ФайлPDF = ДвоичныеДанныеPDF;
Вложения.Вставить(ИмяФайлаPDF, ФайлPDF); 

Адресаты = Справочники.ХС_СпискиРассылок.АдресаРассылки(СписокРассылки);

УчетнаяЗапись = РаботаСПочтовымиСообщениями.СистемнаяУчетнаяЗапись();

ПараметрыПисьма = Новый Структура("Кому, Тема, Тело, Вложения", Адресаты, Результат.ТемаПисьма, Результат.ТекстПисьма, Вложения);
Соединение = Неопределено;
РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(УчетнаяЗапись, ПараметрыПисьма, Соединение);

 

Связи контента