Отправить двоичные данные в телеграм (zip/pdf/gif)

FOX 30 2

https://gist.github.com/PlugFox/4499132c45b73ae5bc8dda52a1218dff
Готовая обработка бинарником Send2Telegram.epf

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

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Объект.ПроксиПротокол           = "https";
    Объект.ИспользоватьПрокси       = Ложь;
КонецПроцедуры // ПриСозданииНаСервере()
//************************************************************
&НаКлиенте
Процедура ВыбратьФайлКоманда(Команда)
    ДВФ                     = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
    ДВФ.Фильтр              = "Portable Document Format (*.pdf)|*.pdf";
    ДВФ.МножественныйВыбор  = Ложь;
    ооПослеВыбораФайла      = Новый ОписаниеОповещения("ПослеВыбораФайла"
                            , ЭтотОбъект
                            , Новый Структура());
    ДВФ.Показать(ооПослеВыбораФайла);
КонецПроцедуры // ВыбратьФайлКоманда()
//************************************************************
&НаКлиенте
Процедура ПослеВыбораФайла(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
    Если ВыбранныеФайлы.Количество() <> 1 Или ПустаяСтрока(ВыбранныеФайлы[0]) Тогда Возврат КонецЕсли;
    Файл                                = Новый Файл(ВыбранныеФайлы[0]);
    ЭтотОбъект.ПутьФайла                = Файл.ПолноеИмя; 
    ЭтотОбъект.ИмяФайла                 = Файл.Имя;
    Элементы.ОтправитьФайл.Доступность  = Истина;
КонецПроцедуры // ПослеВыбораФайла()
//************************************************************
&НаКлиенте
Процедура ОтправитьСообщениеКоманда(Команда)
    ОтправитьСообщение();    
КонецПроцедуры // ОтправитьСообщениеКоманда()
//************************************************************
&НаСервере
Процедура ОтправитьСообщение()
    МодульОбъекта   = РеквизитФормыВЗначение("Объект");
    МодульОбъекта.ОтправитьСообщение(ЭтотОбъект.СообщениеДляОтправки);
КонецПроцедуры // ОтправитьСообщение() 
//************************************************************
&НаКлиенте
Процедура ОтправитьФайлКоманда(Команда)
    ДД  = Новый ДвоичныеДанные(ЭтотОбъект.ПутьФайла);
    ОтправитьФайл(ДД);    
КонецПроцедуры // ОтправитьФайлКоманда()
//************************************************************
&НаСервере
Процедура ОтправитьФайл(ДвоичныеДанные)
    МодульОбъекта   = РеквизитФормыВЗначение("Объект");
    МодульОбъекта.ОтправитьФайл(ДвоичныеДанные, ЭтотОбъект.ИмяФайла, ЭтотОбъект.СообщениеДляОтправки);
КонецПроцедуры // ОтправитьФайл()

 image.png

////////////////////////////////////////////////////////////////////////////////
/// The MIT License
/// 
/// Copyright (c) 2020 @PlugFox
/// 
/// Permission is hereby granted, free of charge, to any person obtaining a copy
/// of this software and associated documentation files (the "Software"), to deal
/// in the Software without restriction, including without limitation the rights
/// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
/// copies of the Software, and to permit persons to whom the Software is
/// furnished to do so, subject to the following conditions:
/// 
/// The above copyright notice and this permission notice shall be included in
/// all copies or substantial portions of the Software.
/// 
/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
/// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
/// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
/// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
/// THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

//////////////////////////////////////////////////////////////
#Область ПрограммныйИнтерфейс

//
Процедура Конструктор(Токен
    , ИдентификаторПолучателя
    , ПроксиПротокол = Неопределено
    , ПроксиСервер = Неопределено
    , ПроксиПорт = Неопределено
    , ПроксиПользователь = Неопределено
    , ПроксиПароль = Неопределено
    , ИспользоватьПрокси = Ложь) Экспорт
    ЭтотОбъект.Токен                    = Токен;
    ЭтотОбъект.ИдентификаторПолучателя  = ИдентификаторПолучателя;
    ЭтотОбъект.ПроксиПротокол           = ПроксиПротокол;
    ЭтотОбъект.ПроксиСервер             = ПроксиСервер;
    ЭтотОбъект.ПроксиПорт               = ПроксиПорт;
    ЭтотОбъект.ПроксиПользователь       = ПроксиПользователь;
    ЭтотОбъект.ПроксиПароль             = ПроксиПароль;
    ЭтотОбъект.ИспользоватьПрокси       = ИспользоватьПрокси;
КонецПроцедуры // Конструктор()

//
Процедура ОтправитьСообщение(Сообщение) Экспорт
    // Глобальные переменные в процедуре:
    // + Токен
    // + ИдентификаторПолучателя
    
    // Сформировать соединение и запрос
    Соединение  = ПолучитьСоединение();
    Адрес       = СтрШаблон("/bot%1/sendMessage?chat_id=%2&parse_mode=HTML&text=%3"
                , Токен
                , ИдентификаторПолучателя
                , КодироватьСтроку(Сообщение, СпособКодированияСтроки.КодировкаURL, "UTF8"));
    Заголовки   = Новый Соответствие;
    Запрос      = Новый HTTPЗапрос(Адрес, Заголовки);
    
    // GET
    Ответ       = Соединение.Получить(Запрос);
    
    // Разбор ответа
    Если Ответ.КодСостояния <> 200 Тогда
        ОтветСтрокой    = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        ВызватьИсключение СтрШаблон("Ошибка отправки вложения в телеграм.
            |Код состояния: %1
            |Тело: %2"
            , Ответ.КодСостояния
            , ОтветСтрокой
        ); 
    КонецЕсли;  
КонецПроцедуры // ОтправитьСообщение()

//
Процедура ОтправитьФайл(ДвоичныеДанные, ИмяФайла = "", Сообщение = "") Экспорт 
    // Сформировать тело запроса
    Разделитель     = Строка(Новый УникальныйИдентификатор());
    
    // Формируем основное составное сообщение
    Тело            = Новый ПотокВПамяти();
    ЗаписьДанных    = Новый ЗаписьДанных(Тело, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, Символы.ВК + Символы.ПС, Символы.ПС, Истина);
    
    // chat_id
    ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
    ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""chat_id""");
    ЗаписьДанных.ЗаписатьСтроку("");
    ЗаписьДанных.ЗаписатьСтроку(ИдентификаторПолучателя);
    
    // disable_notification
    ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
    ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""disable_notification""");
    ЗаписьДанных.ЗаписатьСтроку("");
    ЗаписьДанных.ЗаписатьСтроку("True");
        
    Если Не ПустаяСтрока(Сообщение) Тогда 
        // caption
        ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
        ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""caption""");
        ЗаписьДанных.ЗаписатьСтроку("");
        ЗаписьДанных.ЗаписатьСтроку(Сообщение);        
        
        // parse_mode
        ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
        ЗаписьДанных.ЗаписатьСтроку("Content-Disposition: form-data; name=""parse_mode""");
        ЗаписьДанных.ЗаписатьСтроку("");
        ЗаписьДанных.ЗаписатьСтроку("HTML");
    КонецЕсли;
    
    // document    
    ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель);
    ЗаписьДанных.ЗаписатьСтроку(СтрШаблон("Content-Disposition: form-data; name=""document""; filename=""%1.pdf""", ?(ПустаяСтрока(ИмяФайла), "document_" + Строка(Новый УникальныйИдентификатор()) + ".pdf", ИмяФайла)));
    ЗаписьДанных.ЗаписатьСтроку("Content-Type: application/pdf");
    ЗаписьДанных.ЗаписатьСтроку("");   
    //ЗаписьДанных.Закрыть();    
    
    // Добавим файл
    //ЗаписьДанных    = Новый ЗаписьДанных(...);
    ЗаписьДанных.Записать(ДвоичныеДанные);
    //ЗаписьДанных.Закрыть();
    
    // Завершение записи
    //ЗаписьДанных    = Новый ЗаписьДанных(Тело, КодировкаТекста.UTF8, ПорядокБайтов.LittleEndian, Символы.ВК + Символы.ПС, Символы.ПС, Ложь);
    ЗаписьДанных.ЗаписатьСтроку("");
    ЗаписьДанных.ЗаписатьСтроку("--" + Разделитель + "--");
    ЗаписьДанных.Закрыть();
    
    ДанныеТела          = Тело.ЗакрытьИПолучитьДвоичныеДанные();   

    // Сформировать соединение и запрос
    Соединение  = ПолучитьСоединение();
    Заголовки   = Новый Соответствие;
    Заголовки.Вставить("Content-Type",      "multipart/form-data; boundary=" + Разделитель);
    Заголовки.Вставить("Accept",            "*/*");
    Заголовки.Вставить("Cache-Control",     "no-cache");
    Заголовки.Вставить("Host",              "api.telegram.org");
    Заголовки.Вставить("Accept-Encoding",   "gzip, deflate");
    Заголовки.Вставить("Content-Length",    Формат(ДанныеТела.Размер(), "ЧДЦ=0; ЧН=0; ЧГ=0"));
    Заголовки.Вставить("Connection",        "close");
    Адрес       = СтрШаблон("/bot%1/sendDocument", Токен);
    Запрос      = Новый HTTPЗапрос(Адрес, Заголовки);
    Запрос.УстановитьТелоИзДвоичныхДанных(ДанныеТела);

    // POST
    Ответ       = Соединение.ОтправитьДляОбработки(Запрос);

    // Разбор ответа
    Если Ответ.КодСостояния <> 200 Тогда
        ОтветСтрокой    = Ответ.ПолучитьТелоКакСтроку(КодировкаТекста.UTF8);
        ВызватьИсключение СтрШаблон("Ошибка отправки вложения в телеграм.
            |Код состояния: %1
            |Тело: %2"
            , Ответ.КодСостояния
            , ОтветСтрокой
        ); 
    КонецЕсли;
КонецПроцедуры // ОтправитьФайлВТелеграм()
#КонецОбласти
//////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////
#Область СлужебныеПроцедурыИФункции
Функция ПолучитьСоединение()   
    Прокси      = Новый ИнтернетПрокси(Истина);
    Если ИспользоватьПрокси И ТипЗнч(ПроксиПротокол) = Тип("Строка") И Не ПустаяСтрока(ПроксиПротокол) Тогда
        Прокси.Установить(ПроксиПротокол, ПроксиСервер, ПроксиПорт, ПроксиПользователь, ПроксиПароль, Ложь);
    КонецЕсли;
    SSL         = Новый ЗащищенноеСоединениеOpenSSL();
    Соединение  = Новый HTTPСоединение("api.telegram.org", 443,,, Прокси, 30, SSL, Ложь); 
    Возврат Соединение;
КонецФункции // ПолучитьСоединение()
#КонецОбласти
//////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////
#Область Комментарии
/// Author: Plague Fox
/// Site: https://PlugFox.dev  
/// Infostart: https://infostart.ru/profile/PlugFox/
/// Telegram: @PlugFox
/// Email: PlugFox@gmail.com
/// Github: https://github.com/PlugFox
#КонецОбласти
//////////////////////////////////////////////////////////////

#Иначе
ВызватьИсключение НСтр("ru = 'Недопустимый вызов объекта на клиенте.'");
#КонецЕсли
2

Комментарии

FOX
#1, 17 апреля 2020 02:17

https://gist.github.com/PlugFox/4499132c45b73ae5bc8dda52a1218dff


Fiodorserp
#2, 09 февраля 2024 17:28

Спасибо за статью!
использовал для отправки картинки
Заменил строку
ЗаписьДанных.ЗаписатьСтроку(СтрШаблон("Content-Disposition: form-data; name=""photo""; filename=""%1.png""", ?(ПустаяСтрока(ИмяФайла), "image_" + Строка(Новый УникальныйИдентификатор()) + ".png", ИмяФайла)));
и метод
Адрес = СтрШаблон("/bot%1/sendphoto", Токен);


См. также

Отправить сообщение или табличный документ в телеграм

ТекстВДвоичныхДанных (БСП)

Отправить документ в чат телеграм

ДвоичныеДанныеФайла (БСП)

ДанныеФайлаИДвоичныеДанные (БСП)

ИзвлечьДвоичныеДанныеПриНеобходимости (БСП)

ДвоичныеДанныеВBase64ПриНеобходимости (БСП)

ПреобразоватьДвоичныеДанныеВBase64 (БСП)

Модератору