Как отправить файл из 1С в Telegram: подробное руководство по реализации и исправлению ошибок

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

Интеграция 1С с мессенджером Telegram — одна из самых востребованных задач в современной автоматизации. Отправка отчетов, счетов или уведомлений напрямую клиенту или сотруднику значительно повышает оперативность бизнеса. Однако многие разработчики сталкиваются с трудностями при передаче бинарных данных (файлов), получая в ответ ошибку 400 Bad Request. В этой статье мы подробно разберем, как правильно реализовать отправку файлов, настроить бота и избежать типичных ошибок при формировании HTTP-запросов.

Подготовка бота и авторизация пользователей

Прежде чем переходить к написанию кода, необходимо убедиться в соблюдении архитектурных правил Telegram. Разберем основные причины, по которым сообщения могут не доходить до адресата:

  1. Инициация диалога. Бот не может отправить сообщение пользователю первым. Пользователь обязан найти бота и нажать кнопку /start. Это обязательное условие безопасности против спама.
  2. Права в каналах и группах. Если планируется отправка в канал, бот должен быть добавлен туда в качестве администратора с правом публикации сообщений.
  3. Идентификатор чата (Chat ID). Это числовое значение (например, 172070948), которое уникально для каждого диалога. Для каналов ID часто начинается с префикса -100.

Проанализируем ситуацию: если ваш код работает для одного ID, но возвращает ошибку для другого, скорее всего, этот пользователь просто не подписался на бота или бот не имеет прав в указанном чате.

Метод 1: Профессиональная отправка через поток в памяти (Multipart/form-data)

Самый надежный и современный способ передачи файлов в 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 Тогда
            Сообщить("Ошибка: " + Ответ.ПолучитьТелоКакСтроку());
        КонецЕсли;
    Исключение
        Сообщить("Ошибка связи: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Метод 2: Использование временных файлов и объединения

Если ваша версия платформы не поддерживает ПотокВПамяти (старые релизы 8.3), можно воспользоваться методом объединения временных файлов. Суть заключается в том, что мы создаем текстовый файл с заголовком, берем файл с данными и текстовый файл с "хвостом" запроса, а затем склеиваем их в один POST-запрос.

Проанализируем логику этого метода:

  1. Создаем ФайлОтправкиНачало, куда пишем параметры (chat_id) и заголовок части filename.
  2. Добавляем путь к самому отправляемому файлу в массив.
  3. Создаем ФайлаОтправкиКонец, содержащий закрывающий разделитель (boundary).
  4. Используем стандартную функцию 1С ОбъединитьФайлы.

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

Оптимизация: передача через File_id и URL

Рассмотрим ситуацию, когда один и тот же файл (например, каталог товаров) нужно разослать 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, чтобы ваша обработка не перестала работать в самый неподходящий момент:

Разбор ошибки 400 Bad Request

Если вы все же столкнулись с ошибкой 400, проанализируйте тело ответа сервера (Ответ.ПолучитьТелоКакСтроку()). Обычно Telegram возвращает подробное описание:

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

← На главную