Интеграция 1С с мессенджером Telegram — одна из самых востребованных задач в современной автоматизации. Отправка отчетов, счетов или уведомлений напрямую клиенту или сотруднику значительно повышает оперативность бизнеса. Однако многие разработчики сталкиваются с трудностями при передаче бинарных данных (файлов), получая в ответ ошибку 400 Bad Request. В этой статье мы подробно разберем, как правильно реализовать отправку файлов, настроить бота и избежать типичных ошибок при формировании HTTP-запросов.
Прежде чем переходить к написанию кода, необходимо убедиться в соблюдении архитектурных правил Telegram. Разберем основные причины, по которым сообщения могут не доходить до адресата:
172070948), которое уникально для каждого диалога. Для каналов ID часто начинается с префикса -100.Проанализируем ситуацию: если ваш код работает для одного ID, но возвращает ошибку для другого, скорее всего, этот пользователь просто не подписался на бота или бот не имеет прав в указанном чате.
Самый надежный и современный способ передачи файлов в 1С — это использование объекта ПотокВПамяти и ЗаписьДанных. Этот метод позволяет корректно сформировать структуру запроса multipart/form-data, которая требуется для метода sendDocument. Рассмотрим по шагам реализацию универсальной процедуры.
Для начала создадим вспомогательную функцию для установки защищенного соединения:
Функция ПолучитьСоединение()
SSL = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение("api.telegram.org", 443,,,, 30, SSL, Ложь);
Возврат Соединение;
КонецФункции
Теперь разберем основную процедуру отправки файла. Обратите внимание на использование последовательности Символы.ВК + Символы.ПС (CRLF) — это критически важно для корректного парсинга запроса серверами Telegram.
Процедура ОтправитьФайлВТелеграм(Токен, ИдентификаторПолучателя, ДвоичныеДанные, ИмяФайла, Сообщение = "") Экспорт
Разделитель = Строка(Новый УникальныйИдентификатор());
// Формируем тело запроса через поток
Тело = Новый ПотокВПамяти();
ЗаписьДанных = Новый ЗаписьДанных(Тело, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, Символы.ВК + Символы.ПС, Символы.ПС, Истина);
// Передаем chat_id
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""chat_id""");
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку(ИдентификаторПолучателя);
// Добавляем описание (caption), если оно есть
Если Не ПустаяСтрока(Сообщение) Тогда
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""caption""");
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку(Сообщение);
КонецЕсли;
// Основная часть: передача файла
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
ЗаписьДанных.ЗаписатьСтроку(СтрШаблон("Content-Disposition: form-data; name=""document""; filename=""%1""", ИмяФайла));
ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/octet-stream"); // Универсальный тип
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.Записать(ДвоичныеДанные); // Записываем сами данные файла
// Финализируем запрос
ЗаписьДанных.ЗаписатьСтроку("");
ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель + "--");
ЗаписьДанных.Закрыть();
ДанныеТела = Тело.ЗакрытьИПолучитьДвоичныеДанные();
Соединение = ПолучитьСоединение();
Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "multipart/form-data; boundary=" + Разделитель);
Заголовки.Вставить("Content-Length", Формат(ДанныеТела.Размер(), "ЧДЦ=0; ЧН=0; ЧГ=0"));
АдресРесурса = СтрШаблон("/bot%1/sendDocument", Токен);
Запрос = Новый HTTPЗапрос(АдресРесурса, Заголовки);
Запрос.УстановитьТелоИзДвоичныхДанных(ДанныеТела);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния <> 200 Тогда
Сообщить("Ошибка: " + Ответ.ПолучитьТелоКакСтроку());
КонецЕсли;
Исключение
Сообщить("Ошибка связи: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Если ваша версия платформы не поддерживает ПотокВПамяти (старые релизы 8.3), можно воспользоваться методом объединения временных файлов. Суть заключается в том, что мы создаем текстовый файл с заголовком, берем файл с данными и текстовый файл с "хвостом" запроса, а затем склеиваем их в один POST-запрос.
Проанализируем логику этого метода:
ФайлОтправкиНачало, куда пишем параметры (chat_id) и заголовок части filename.ФайлаОтправкиКонец, содержащий закрывающий разделитель (boundary).ОбъединитьФайлы.Этот способ более громоздкий, но он позволяет работать с очень большими файлами, не загружая их целиком в оперативную память сервера 1С.
Рассмотрим ситуацию, когда один и тот же файл (например, каталог товаров) нужно разослать 1000 пользователям. Повторная загрузка бинарных данных при каждой отправке — плохая практика, которая нагружает сеть и сервер.
Использование File_id:
При первой успешной отправке файла Telegram возвращает JSON-ответ. Внутри него находится параметр file_id. Сохраните его в своей базе данных. При следующей отправке вместо передачи multipart/form-data просто укажите этот ID в параметре document:
// Пример упрощенной отправки, если есть file_id
АдресРесурса = СтрШаблон("/bot%1/sendDocument?chat_id=%2&document=%3", Токен, ChatID, СохраненныйFileID);
Отправка по URL:
Если файл уже выгружен на ваш сайт или в публичное облако, вы можете просто передать прямую ссылку на него. Telegram сам скачает файл со стороннего сервера. Это значительно экономит ресурсы сервера 1С.
Выясним, какие ограничения накладывает Telegram Bot API, чтобы ваша обработка не перестала работать в самый неподходящий момент:
sendDocument можно отправлять практически любые форматы: .pdf, .xls, .zip, .gif. Если вы отправляете изображение как документ, оно придет без сжатия.Если вы все же столкнулись с ошибкой 400, проанализируйте тело ответа сервера (Ответ.ПолучитьТелоКакСтроку()). Обычно Telegram возвращает подробное описание:
"description": "Bad Request: chat not found" — неверный Chat ID или пользователь не добавил бота."description": "Bad Request: file must be non-empty" — вы передали пустой файл или путь к файлу указан неверно."description": "Bad Request: wrong remote file identifier specified" — ошибка при попытке отправить файл через file_id, которого не существует.Соблюдение этих правил и использование приведенных примеров кода позволит вам создать надежный механизм взаимодействия 1С с Telegram, который будет работать стабильно и эффективно.