Как программно отправить файл и сообщение в мессенджер MAX из 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В современной корпоративной среде мессенджер MAX (базирующийся на платформе VK Teams/MyTeam) становится важным каналом для оперативной доставки отчетов и уведомлений, расширяя стандартную рассылку отчетов. Интеграция 1С с данным мессенджером напрямую через API позволяет избежать использования сторонних платных шлюзов и обеспечить высокую скорость работы. В этой статье мы подробно разберем, как реализовать механизм отправки файлов «с нуля», используя встроенные средства языка 1С.

Основные этапы взаимодействия с MAX API

Процесс отправки файла в MAX отличается от простой отправки текстового сообщения — для автоматизации этого процесса есть готовый модуль массовой рассылки печатных форм и файлов из 1С в MAX. Он состоит из трех последовательных шагов. Сначала мы запрашиваем у сервера специальный URL для загрузки. Затем мы передаем сам файл по этому адресу, используя формат multipart/form-data. И только после успешной загрузки мы формируем финальное сообщение, прикрепляя к нему полученный идентификатор вложения. Рассмотрим каждый из этих этапов подробнее.

Шаг 1: Авторизация и получение URL для загрузки

Для начала нам необходимо создать защищенное соединение с сервером platform-api.max.ru. Для авторизации используется токен бота (управлять которым можно через BotFather в MAX), который передается в заголовке Authorization. На этом этапе мы сообщаем серверу тип вложения, который планируем загрузить (в нашем случае — file).

Проанализируем фрагмент кода для инициализации процесса:


// Заголовки авторизации
ЗаголовкиАвторизации = Новый Соответствие;
ЗаголовкиАвторизации.Вставить("Authorization", ТокенБота);

// Устанавливаем соединение с API
HTTPСоединение = Новый HTTPСоединение("platform-api.max.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
HTTPЗапрос = Новый HTTPЗапрос("/uploads?type=file", ЗаголовкиАвторизации);

// Отправляем POST запрос для получения метаданных загрузки
HTTPОтвет = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
Если HTTPОтвет.КодСостояния <> 200 Тогда
    ВызватьИсключение "Ошибка при получении URL для загрузки: " + HTTPОтвет.КодСостояния;
КонецЕсли;

В ответ сервер вернет JSON, содержащий поле url (для отладки таких запросов удобно использовать Post1С — аналог Postman). Именно по этому адресу мы будем отправлять бинарные данные нашего файла. Обратите внимание, что эта ссылка временная и обычно действует от нескольких минут до часа.

Шаг 2: Формирование Multipart/Form-Data запроса

Это самый сложный технический этап. Поскольку стандартный объект HTTPЗапрос в 1С не формирует структуру multipart автоматически, нам придется собрать тело запроса вручную, используя ПотокВПамяти и ЗаписьДанных. Нам нужно подготовить разделитель (Boundary), заголовки части данных и корректно вставить двоичные данные файла.

Разберем, как правильно сконструировать тело запроса:


// Формируем уникальный разделитель
Boundary = "----WebKitFormBoundary" + СтрЗаменить(Новый UUID, "-", "");
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);

// Используем поток в памяти для сборки бинарного тела
ПотокВПамяти = Новый ПотокВПамяти;
ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);

// Записываем заголовок части multipart
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""data""; filename=""" + ИмяФайла + """");
ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/octet-stream");
ЗаписьДанных.ЗаписатьСтроку(""); // Пустая строка перед данными

// Вставляем содержимое файла
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку(""); 

// Завершаем запрос
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary + "--");
ЗаписьДанных.Закрыть();

ТелоЗапросаЗагрузки = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();

После подготовки тела запроса мы отправляем его на полученный ранее URL для загрузки. Важно правильно извлечь имя сервера и путь из этого URL, так как серверы хранения (CDN) могут отличаться от основного сервера API.

Шаг 3: Обработка статуса готовности вложения

При работе с MAX API часто возникает ситуация, когда файл уже загружен, но сервер еще не успел его проиндексировать или проверить антивирусом. Если попытаться отправить сообщение немедленно, возникнет ошибка attachment.not.ready.

Для решения этой проблемы в коде рекомендуется реализовать небольшую задержку или цикл ожидания (во время которого можно выводить прогресс-бар). Выясним причину: серверу нужно время на обработку ключа errors.process.attachment.file.not.processed. Простейший способ — использовать паузу в 1-2 секунды, хотя более надежным решением будет цикл из 3-5 попыток отправки финального сообщения с проверкой ответа сервера.

Шаг 4: Отправка сообщения с файлом

Теперь, когда у нас есть структура ДанныеФайла (полученная в ответ на загрузку), мы можем отправить сообщение пользователю или в чат. Для отправки конкретному пользователю используем параметр user_id, для группы — chat_id — также можно использовать расширение для отправки сообщений и файлов из 1С в MAX непосредственно из базы.

Посмотрим на пример формирования финального JSON-пакета:


HTTPЗапросСообщения = Новый HTTPЗапрос("/messages?user_id=" + IDЧата, ЗаголовкиАвторизации);
HTTPЗапросСообщения.Заголовки.Вставить("Content-Type", "application/json");

ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("text");
ЗаписьJSON.ЗаписатьЗначение("Сформирован новый отчет");

ЗаписьJSON.ЗаписатьИмяСвойства("attachments");
ЗаписьJSON.ЗаписатьНачалоМассива();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("type");
ЗаписьJSON.ЗаписатьЗначение("file");

// В payload помещаем объект, полученный после загрузки файла
ЗаписьJSON.ЗаписатьИмяСвойства("payload");
ЗаписатьJSON(ЗаписьJSON, ДанныеФайла); 

ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.ЗаписатьКонецОбъекта();

СтрокаТелаЗапроса = ЗаписьJSON.Закрыть();
HTTPЗапросСообщения.УстановитьТелоИзСтроки(СтрокаТелаЗапроса);
HTTPОтветСообщения = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапросСообщения);

Дополнительные возможности: Упоминания и форматирование

Часто при отправке отчета требуется привлечь внимание конкретного сотрудника. В мессенджере MAX это реализуется через механизм Mentions. Мы можем использовать два формата: HTML или Markdown.

Рассмотрим примеры упоминаний:

  1. Формат Markdown: Для упоминания используйте конструкцию вида [Имя Фамилия](max://user/ID_пользователя). В параметрах запроса обязательно укажите "format": "markdown".
  2. Формат HTML: Используйте тег ссылки: <a href="max://user/12345">Имя</a> с указанием "format": "html".

Важное замечание по правам доступа: Чтобы бот мог успешно отправлять упоминания или читать сообщения в групповых чатах, он обязательно должен быть назначен администратором этого чата. В противном случае ссылки-упоминания могут не подсвечиваться, а запросы на получение обновлений (updates) будут возвращать пустой результат или ошибку по таймауту.

Соблюдение этих правил позволит вам создать надежную систему оповещения пользователей прямо из информационной базы 1С, обеспечивая сотрудников актуальными данными в привычном интерфейсе мессенджера.

← На главную