1С 8.3 Отправка файла в MAX
Данные > Примеры кода 1С > 1С 8.3 HTTP
Перейти в раздел примеры кода 1С 8.3:
Пример использования API-методов платформы Max для отправки файлов в чат через бота. В основе лежит взаимодействие с эндпоинтом POST /uploads и последующая отправка сообщения с вложением. Метод используется для получения временного URL-адреса, на который необходимо загрузить файл перед его отправкой в чат. В ответе приходит объект с полем url. Загрузка файла выполняется отдельным запросом на этот URL.
Основные шаги отправки файла:
- Получение URL для загрузки – запрос к GET /uploads?type=file, который возвращает временный адрес для выкладки файла.
- Загрузка файла – POST на полученный URL с типом содержимого multipart/form-data.
- Отправка сообщения – POST /messages с JSON-телом, содержащим текст и массив вложений, где в payload передаются метаданные загруженного файла.
Документация:
Пример кода:
// Отправляет файл в чат Max (platform-api.max.ru) через API бота.
//
// Параметры:
// ПутьКФайлу - Строка - полный путь к отправляемому файлу.
// IDЧата - Строка - идентификатор чата/пользователя.
// ТокенБота - Строка - авторизационный токен бота.
// ТипФайла - Строка - тип вложения (по умолчанию "file").
// ТекстСообщения - Строка - текст сообщения (в текущей реализации не используется,
// отправляется фиксированный текст "Отправляю файл").
//
Процедура ОтправитьФайлВMax(ПутьКФайлу, IDЧата, ТокенБота, ТипФайла = "file", ТекстСообщения = "") Экспорт
// Формируем имя файла для отправки (включает текущую дату/время)
ИмяФайла = "ФайлОтчета_" + СтрЗаменить(ТекущаяДата(), ":", "") + ".xls";
// Заголовки авторизации для всех запросов
ЗаголовкиАвторизации = Новый Соответствие;
ЗаголовкиАвторизации.Вставить("Authorization", ТокенБота);
// ===================================================================
// 1. Получение URL для загрузки файла (запрос к /uploads?type=file)
// ===================================================================
ОсновноеСоединение = Новый HTTPСоединение("platform-api.max.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
ЗапросМетаЗагрузки = Новый HTTPЗапрос("/uploads?type=file", ЗаголовкиАвторизации);
ОтветМетаЗагрузки = ОсновноеСоединение.ОтправитьДляОбработки(ЗапросМетаЗагрузки);
Если ОтветМетаЗагрузки.КодСостояния <> 200 Тогда
ВызватьИсключение "Ошибка при получении URL для загрузки: " + ОтветМетаЗагрузки.КодСостояния + " - " + ОтветМетаЗагрузки.ПолучитьТелоКакСтроку();
КонецЕсли;
// Разбираем JSON ответ (должен содержать поле "url")
ЧтениеJSONМета = Новый ЧтениеJSON;
ЧтениеJSONМета.УстановитьСтроку(ОтветМетаЗагрузки.ПолучитьТелоКакСтроку());
ОтветЗагрузки = ПрочитатьJSON(ЧтениеJSONМета);
ЧтениеJSONМета.Закрыть();
URLДляЗагрузки = ОтветЗагрузки.url;
// ===================================================================
// 2. Загрузка файла на полученный URL (multipart/form-data)
// ===================================================================
// Примитивный разбор URL для выделения сервера и пути.
// Пример URL: "https://storage.max.ru/upload/12345"
ЧастиURL = СтрРазделить(URLДляЗагрузки, "/", Ложь);
СерверЗагрузки = ЧастиURL[1]; // например, "storage.max.ru"
// Склеиваем путь, удаляя возможный мусор (костыль для специфики сервера)
ПутьЗагрузки = СтрЗаменить("/" + СтрСоединить(ЧастиURL, "/"), "/https:/forms.tatneft.ru", "");
// Подготовка multipart-тела
Boundary = "----WebKitFormBoundary" + СтрЗаменить(Новый UUID, "-", "");
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
ПотокВПамяти = Новый ПотокВПамяти;
ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);
// Заголовки части с файлом
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""data""; filename=""" + ИмяФайла + """");
ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/octet-stream");
ЗаписьДанных.ЗаписатьСтроку(""); // пустая строка между заголовками и данными
// Бинарные данные файла
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку(""); // перенос строки после данных
// Завершающий boundary
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary + "--");
ЗаписьДанных.Закрыть();
ТелоMultipart = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
// Отправка файла на выделенный сервер
СоединениеЗагрузки = Новый HTTPСоединение(СерверЗагрузки, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
ЗапросЗагрузки = Новый HTTPЗапрос(ПутьЗагрузки);
ЗапросЗагрузки.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
ЗапросЗагрузки.УстановитьТелоИзДвоичныхДанных(ТелоMultipart);
ОтветЗагрузкиФайла = СоединениеЗагрузки.ОтправитьДляОбработки(ЗапросЗагрузки);
Если ОтветЗагрузкиФайла.КодСостояния <> 200 Тогда
ВызватьИсключение "Ошибка при загрузке файла: " + ОтветЗагрузкиФайла.КодСостояния;
КонецЕсли;
// Парсим ответ загрузки (содержит метаинформацию о загруженном файле)
ЧтениеJSONОтвета = Новый ЧтениеJSON;
ЧтениеJSONОтвета.УстановитьСтроку(ОтветЗагрузкиФайла.ПолучитьТелоКакСтроку());
МетаФайла = ПрочитатьJSON(ЧтениеJSONОтвета);
ЧтениеJSONОтвета.Закрыть();
// Небольшая пауза, чтобы файл успел обработаться на сервере.
// Без паузы возникает ошибка: "attachment.not.ready"
ВызватьПаузу(1000); // замена цикла ожидания на корректную паузу
// ===================================================================
// 3. Отправка сообщения с прикреплённым файлом
// ===================================================================
ЗапросСообщения = Новый HTTPЗапрос("/messages?user_id=" + IDЧата, ЗаголовкиАвторизации);
ЗапросСообщения.Заголовки.Вставить("Content-Type", "application/json");
// Формируем JSON-тело
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("text");
ЗаписьJSON.ЗаписатьЗначение("Отправляю файл");
ЗаписьJSON.ЗаписатьИмяСвойства("attachments");
ЗаписьJSON.ЗаписатьНачалоМассива();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("type");
ЗаписьJSON.ЗаписатьЗначение(ТипФайла); // используем переданный тип вложения
ЗаписьJSON.ЗаписатьИмяСвойства("payload");
ЗаписатьJSON(ЗаписьJSON, МетаФайла); // в payload передаём ответ предыдущего шага
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.ЗаписатьКонецОбъекта();
ТелоJSON = ЗаписьJSON.Закрыть();
ЗапросСообщения.УстановитьТелоИзСтроки(ТелоJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
ОтветСообщения = ОсновноеСоединение.ОтправитьДляОбработки(ЗапросСообщения);
Если ОтветСообщения.КодСостояния = 200 Тогда
Сообщить("Файл успешно отправлен!");
Иначе
Сообщить("Ошибка отправки сообщения: " + ОтветСообщения.ПолучитьТелоКакСтроку());
КонецЕсли;
КонецПроцедуры
//
// Параметры:
// ПутьКФайлу - Строка - полный путь к отправляемому файлу.
// IDЧата - Строка - идентификатор чата/пользователя.
// ТокенБота - Строка - авторизационный токен бота.
// ТипФайла - Строка - тип вложения (по умолчанию "file").
// ТекстСообщения - Строка - текст сообщения (в текущей реализации не используется,
// отправляется фиксированный текст "Отправляю файл").
//
Процедура ОтправитьФайлВMax(ПутьКФайлу, IDЧата, ТокенБота, ТипФайла = "file", ТекстСообщения = "") Экспорт
// Формируем имя файла для отправки (включает текущую дату/время)
ИмяФайла = "ФайлОтчета_" + СтрЗаменить(ТекущаяДата(), ":", "") + ".xls";
// Заголовки авторизации для всех запросов
ЗаголовкиАвторизации = Новый Соответствие;
ЗаголовкиАвторизации.Вставить("Authorization", ТокенБота);
// ===================================================================
// 1. Получение URL для загрузки файла (запрос к /uploads?type=file)
// ===================================================================
ОсновноеСоединение = Новый HTTPСоединение("platform-api.max.ru", 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
ЗапросМетаЗагрузки = Новый HTTPЗапрос("/uploads?type=file", ЗаголовкиАвторизации);
ОтветМетаЗагрузки = ОсновноеСоединение.ОтправитьДляОбработки(ЗапросМетаЗагрузки);
Если ОтветМетаЗагрузки.КодСостояния <> 200 Тогда
ВызватьИсключение "Ошибка при получении URL для загрузки: " + ОтветМетаЗагрузки.КодСостояния + " - " + ОтветМетаЗагрузки.ПолучитьТелоКакСтроку();
КонецЕсли;
// Разбираем JSON ответ (должен содержать поле "url")
ЧтениеJSONМета = Новый ЧтениеJSON;
ЧтениеJSONМета.УстановитьСтроку(ОтветМетаЗагрузки.ПолучитьТелоКакСтроку());
ОтветЗагрузки = ПрочитатьJSON(ЧтениеJSONМета);
ЧтениеJSONМета.Закрыть();
URLДляЗагрузки = ОтветЗагрузки.url;
// ===================================================================
// 2. Загрузка файла на полученный URL (multipart/form-data)
// ===================================================================
// Примитивный разбор URL для выделения сервера и пути.
// Пример URL: "https://storage.max.ru/upload/12345"
ЧастиURL = СтрРазделить(URLДляЗагрузки, "/", Ложь);
СерверЗагрузки = ЧастиURL[1]; // например, "storage.max.ru"
// Склеиваем путь, удаляя возможный мусор (костыль для специфики сервера)
ПутьЗагрузки = СтрЗаменить("/" + СтрСоединить(ЧастиURL, "/"), "/https:/forms.tatneft.ru", "");
// Подготовка multipart-тела
Boundary = "----WebKitFormBoundary" + СтрЗаменить(Новый UUID, "-", "");
ДвоичныеДанныеФайла = Новый ДвоичныеДанные(ПутьКФайлу);
ПотокВПамяти = Новый ПотокВПамяти;
ЗаписьДанных = Новый ЗаписьДанных(ПотокВПамяти);
// Заголовки части с файлом
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""data""; filename=""" + ИмяФайла + """");
ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/octet-stream");
ЗаписьДанных.ЗаписатьСтроку(""); // пустая строка между заголовками и данными
// Бинарные данные файла
ЗаписьДанных.Записать(ДвоичныеДанныеФайла);
ЗаписьДанных.ЗаписатьСтроку(""); // перенос строки после данных
// Завершающий boundary
ЗаписьДанных.ЗаписатьСтроку("--" + Boundary + "--");
ЗаписьДанных.Закрыть();
ТелоMultipart = ПотокВПамяти.ЗакрытьИПолучитьДвоичныеДанные();
// Отправка файла на выделенный сервер
СоединениеЗагрузки = Новый HTTPСоединение(СерверЗагрузки, 443, , , , , Новый ЗащищенноеСоединениеOpenSSL());
ЗапросЗагрузки = Новый HTTPЗапрос(ПутьЗагрузки);
ЗапросЗагрузки.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Boundary);
ЗапросЗагрузки.УстановитьТелоИзДвоичныхДанных(ТелоMultipart);
ОтветЗагрузкиФайла = СоединениеЗагрузки.ОтправитьДляОбработки(ЗапросЗагрузки);
Если ОтветЗагрузкиФайла.КодСостояния <> 200 Тогда
ВызватьИсключение "Ошибка при загрузке файла: " + ОтветЗагрузкиФайла.КодСостояния;
КонецЕсли;
// Парсим ответ загрузки (содержит метаинформацию о загруженном файле)
ЧтениеJSONОтвета = Новый ЧтениеJSON;
ЧтениеJSONОтвета.УстановитьСтроку(ОтветЗагрузкиФайла.ПолучитьТелоКакСтроку());
МетаФайла = ПрочитатьJSON(ЧтениеJSONОтвета);
ЧтениеJSONОтвета.Закрыть();
// Небольшая пауза, чтобы файл успел обработаться на сервере.
// Без паузы возникает ошибка: "attachment.not.ready"
ВызватьПаузу(1000); // замена цикла ожидания на корректную паузу
// ===================================================================
// 3. Отправка сообщения с прикреплённым файлом
// ===================================================================
ЗапросСообщения = Новый HTTPЗапрос("/messages?user_id=" + IDЧата, ЗаголовкиАвторизации);
ЗапросСообщения.Заголовки.Вставить("Content-Type", "application/json");
// Формируем JSON-тело
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("text");
ЗаписьJSON.ЗаписатьЗначение("Отправляю файл");
ЗаписьJSON.ЗаписатьИмяСвойства("attachments");
ЗаписьJSON.ЗаписатьНачалоМассива();
ЗаписьJSON.ЗаписатьНачалоОбъекта();
ЗаписьJSON.ЗаписатьИмяСвойства("type");
ЗаписьJSON.ЗаписатьЗначение(ТипФайла); // используем переданный тип вложения
ЗаписьJSON.ЗаписатьИмяСвойства("payload");
ЗаписатьJSON(ЗаписьJSON, МетаФайла); // в payload передаём ответ предыдущего шага
ЗаписьJSON.ЗаписатьКонецОбъекта();
ЗаписьJSON.ЗаписатьКонецМассива();
ЗаписьJSON.ЗаписатьКонецОбъекта();
ТелоJSON = ЗаписьJSON.Закрыть();
ЗапросСообщения.УстановитьТелоИзСтроки(ТелоJSON, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);
ОтветСообщения = ОсновноеСоединение.ОтправитьДляОбработки(ЗапросСообщения);
Если ОтветСообщения.КодСостояния = 200 Тогда
Сообщить("Файл успешно отправлен!");
Иначе
Сообщить("Ошибка отправки сообщения: " + ОтветСообщения.ПолучитьТелоКакСтроку());
КонецЕсли;
КонецПроцедуры
0
комментарии
____________________
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник