Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Отправка картинки в Телеграм

Отправка картинки в Телеграм
Я
   телега
 
11.11.20 - 11:43
Отправляю картинку с помощью вот этого кода:
        Токен = текПараметрыСеанса.Токен;
        СерверTg = текПараметрыСеанса.Сервер;
        
        ИмяФайла = ПолучитьИмяВременногоФайла("jpg");
        
        мТекущееОсновноеИзображение.Записать(ИмяФайла);
        
        ФайлСФото = Новый Файл(ИмяФайла);
        
        СтрокаСоединения = "bot" + Токен + "/sendPhoto?chat_id=" + СтрЗаменить(Формат(chat_id, "ЧДЦ=0; ЧС=; ЧРГ=.; ЧГ=0"), ".", "") + "photo=";
        
        Boundary = "----"+Строка(Новый УникальныйИдентификатор());
        
        //Определяем массив для процедуры ОбъединитьФайлы
        МассивФайловДляОбъединения = Новый Массив;
        
        //Формируем начальный фрагмент файла POST-запроса
        ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
        ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.UTF8);
        
        //Формируем конечный фрагмент файла POST-запроса
        ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
        ФайлаОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.UTF8);
        
        ТекстДляОтправки = "";
        
        ТекстДляОтправки = ТекстДляОтправки + Boundary + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""photo""; filename=/""" + ИмяФайла + """" + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Type: image/jpeg";
        
        ФайлОтправкиНачало.ЗаписатьСтроку(ТекстДляОтправки );
        ФайлОтправкиНачало.Закрыть();
        
        МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
        
        МассивФайловДляОбъединения.Добавить(СокрЛП(ИмяФайла));
        
        ТекстДляОтправки = "" + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + Boundary;
        
        ФайлаОтправкиКонец.ЗаписатьСтроку(ТекстДляОтправки);
        ФайлаОтправкиКонец.Закрыть();
        МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);
        
        ИмяФайлаОтправки = ПолучитьИмяВременногоФайла("txt");
        ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
        
        HTTPЗапрос = Новый HTTPЗапрос;
        Заголовки = Новый Соответствие;
        
        HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
        HTTPЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary="+Boundary);
        
        HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);
        HTTPЗапрос.АдресРесурса = СтрокаСоединения;
        
        HTTPСоединение = Новый HTTPСоединение(СерверTg,443,,,,,Новый ЗащищенноеСоединениеOpenSSL());
        
        Попытка
            Ответ = HTTPСоединение.Получить(HTTPЗапрос);
            
            КодСостояния     = Ответ.КодСостояния;
            СтрокаОтвета     = Ответ.ПолучитьТелоКакСтроку();

            
            Если КодСостояния=200 тогда
                ЧтениеОтвета = Новый ЧтениеJSON;
                ЧтениеОтвета.УстановитьСтроку(СтрокаОтвета);
                РезультатСтруктура = ПрочитатьJSON(ЧтениеОтвета);
                Если РезультатСтруктура.ok = Истина Тогда
                    СтруктураMessage = РезультатСтруктура.result;
                КонецЕсли;
            Иначе
                Сообщить("КодСостояния "+КодСостояния);
                Сообщить(СтрокаОтвета);
            КонецЕсли;
        Исключение
            Сообщить(ОписаниеОшибки());
        КонецПопытки;

Однако ответ {"ok":false,"error_code":400,"description":"Bad Request: there is no photo in the request"}
Смотрю состояние файла ИмяФайлаОтправки и вижу что он внутри содержит все необходимые данные:

----1a9121fc-3358-4ff3-9117-f26721d66194
Content-Disposition: form-data; name="photo"; filename="/C:/EVE/111.jpg"
Content-Type: image/jpeg

<тут куча двоичных данных>

----1a9121fc-3358-4ff3-9117-f26721d66194


В Postman сделал отправку, преобразовал в HTTP и вижу:

GET /bot<ТОКЕН>/sendPhoto?chat_id=<ID Чата>&photo= HTTP/1.1
Host: api.telegram.org
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="photo"; filename="/C:/EVE/111.jpg"
Content-Type: image/jpeg

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW

что в целом совпадает с моими данными. Что же не так?
   Dzenn
 
1 - 11.11.20 - 11:49
попробуй убрать строку
Content-Type: image/jpeg

и последня строка должна быть ----WebKitFormBoundary7MA4YWxkTrZu0gW--, а не ----WebKitFormBoundary7MA4YWxkTrZu0gW
   Dzenn
 
2 - 11.11.20 - 11:50
ну и плюс, через файлы уже не феншуй, а феншуй через потоки
   телега
 
3 - 11.11.20 - 11:54
Попробовал, результат тот же. Итоговый файл:
----e11508aa-d3da-4eef-ba31-d02c61b203fc
Content-Disposition: form-data; name="photo"; filename="/<Тут путь к файлу>"

<тут куча двоичных данных>
----e11508aa-d3da-4eef-ba31-d02c61b203fc--

Но почему эти данные есть в сформированном Постманом? Там есть и указание на тип данных и отсутствует "--" в конце, и работает!
   телега
 
4 - 11.11.20 - 11:57
(2) Нет ли кусочечка образца?
   телега
 
5 - 11.11.20 - 12:01
Ещё один вопрос: почему в Постмане перед путём стоит "/" и имеет ли значение "/" или "\" в самом пути к файлу ("C:\" или "C:/")? Учитывая что в теле уже содержатся двоичные данные.
   Dzenn
 
6 - 11.11.20 - 12:04
(4) на инфостарте есть примеры, так ссылку сразу не найду

плюс, по коду заметил, что другие параметры типа chat_id передаются не через мультипарт, а через строку соединения, что тоже не факт что правильно. у меня в http://catalog.mista.ru/public/627500/ все параметры передаются через мультипарт
   телега
 
7 - 11.11.20 - 12:05
Я именно с инфостарта и брал образец, даже тупое копирование у меня не заработало, потом я его переделал с оглядкой на отработавший пример HTTP из Постмана.
Сейчас посмотрю, спасибо большое.
   телега
 
8 - 11.11.20 - 12:27
Увы ни перенос в мультипарт, ни удаление "photo=" из строки соединения ситуацию не изменили.
   телега
 
9 - 11.11.20 - 12:54
Кстати, кто знает как простым способом проверить HTTP запрос? В Firefox через консоль можно?
   телега
 
10 - 11.11.20 - 14:06
Заработало. Я не знаю, чёрт возьми как, но заработало.
Это работает:

        Токен = текПараметрыСеанса.Токен;
        СерверTg = текПараметрыСеанса.Сервер;
        
        ИмяФайла = ПолучитьИмяВременногоФайла("jpg");
        
        мТекущееОсновноеИзображение.Записать(ИмяФайла);
        
        ФайлСФото = Новый Файл(ИмяФайла);
        
        СтрокаСоединения = "bot" + Токен + "/sendPhoto";
        
        Boundary = "----"+Строка(Новый УникальныйИдентификатор());
        
        //Определяем массив для процедуры ОбъединитьФайлы

        МассивФайловДляОбъединения = Новый Массив;
        
        //Формируем начальный фрагмент файла POST-запроса

        ИмяФайлаОтправкиНачало = ПолучитьИмяВременногоФайла("txt");
        ФайлОтправкиНачало = Новый ЗаписьТекста(ИмяФайлаОтправкиНачало, КодировкаТекста.UTF8);
        
        //Формируем конечный фрагмент файла POST-запроса

        ИмяФайлаОтправкиКонец = ПолучитьИмяВременногоФайла("txt");
        ФайлаОтправкиКонец = Новый ЗаписьТекста(ИмяФайлаОтправкиКонец, КодировкаТекста.UTF8);
        
        ТекстДляОтправки = "";
        
        ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""chat_id""" + Символы.ПС + Символы.ПС + СтрЗаменить(Формат(chat_id, "ЧДЦ=0; ЧС=; ЧРГ=.; ЧГ=0"), ".", "") + Символы.ПС;
        
        ТекстДляОтправки = ТекстДляОтправки + "--" + Boundary + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Disposition: form-data; name=""photo""; filename=""/" + ФайлСФото.Имя + """" + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "Content-Type: image/jpeg" + Символы.ПС;
        
        ФайлОтправкиНачало.ЗаписатьСтроку(ТекстДляОтправки);
        ФайлОтправкиНачало.Закрыть();
        
        МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиНачало);
        
        МассивФайловДляОбъединения.Добавить(СокрЛП(ИмяФайла));
        
        ТекстДляОтправки = "" + Символы.ПС;
        ТекстДляОтправки = ТекстДляОтправки + "--" +  Boundary+"--";
        
        ФайлаОтправкиКонец.ЗаписатьСтроку(ТекстДляОтправки);
        ФайлаОтправкиКонец.Закрыть();
        МассивФайловДляОбъединения.Добавить(ИмяФайлаОтправкиКонец);
        
        ИмяФайлаОтправки = ПолучитьИмяВременногоФайла("txt");
        ОбъединитьФайлы(МассивФайловДляОбъединения, ИмяФайлаОтправки);
        
        HTTPЗапрос = Новый HTTPЗапрос;
        Заголовки = Новый Соответствие;
        
        HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
        HTTPЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary="+Boundary);
        
        HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);
        HTTPЗапрос.АдресРесурса = СтрокаСоединения;
        
        HTTPСоединение = Новый HTTPСоединение(СерверTg,443,,,,,Новый ЗащищенноеСоединениеOpenSSL());
        
        Попытка
            Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
            
            КодСостояния     = Ответ.КодСостояния;
            СтрокаОтвета     = Ответ.ПолучитьТелоКакСтроку();

            
            Если КодСостояния=200 тогда
                ЧтениеОтвета = Новый ЧтениеJSON;
                ЧтениеОтвета.УстановитьСтроку(СтрокаОтвета);
                РезультатСтруктура = ПрочитатьJSON(ЧтениеОтвета);
                Если РезультатСтруктура.ok = Истина Тогда
                    СтруктураMessage = РезультатСтруктура.result;
                КонецЕсли;
            Иначе
                Сообщить("КодСостояния "+КодСостояния);
                Сообщить(СтрокаОтвета);
            КонецЕсли;
        Исключение
            Сообщить(ОписаниеОшибки());
        КонецПопытки;
   Kassern
 
11 - 11.11.20 - 14:47
(10) я могу конечно ошибаться, но скорее всего проблема была именно в строчке  HTTPСоединение.Получить(HTTPЗапрос);
На https ресурсах данный метод может косячить, лучше всего использовать ОтправитьДляОбработки или ВызватьHTTPМетод (что на мой взгляд еше лучше, так как сам указываешь нужный метод, а не 1ска за тебя решает)
   oleg_km
 
12 - 11.11.20 - 15:58
Так HTTPСоединение.Получить(HTTPЗапрос); - это GET запрос,
а HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос); - это POST запрос.

В гет запросах нет тела, только урл. Странно что 1С просто выкидывает все данные, которые ты так старательно готовил и как не в чем ни бывало отправляет запрос. .NET например кидает исключение.
   Kassern
 
13 - 11.11.20 - 16:36
(12) Это конечно все понятно и в СП это дело прописано, но тогда объясни какого художника через метод получить получается скачивать картинки к примеру для незащищенных соединений?
вот к примеру, накодил на коленке с первой попавшейся картинкой в инете:
Соединение=Новый HTTPСоединение("v.900igr.net",10);
Запрос=Новый HTTPЗапрос("/datas/schjot/Slozhenie-do-10-1.files/0007-007-22-4.jpg");
ФайлКартинки=Соединение.Получить(Запрос);
ДД=ФайлКартинки.ПолучитьТелоКакДвоичныеДанные();
ДД.Записать(КаталогЗаписи+"\тест_картинки.jpeg");
   Kassern
 
14 - 11.11.20 - 16:41
(13) чет я туплю, для https только что проверил тоже канает. Раньше помню проблема была, приходилось код переделывать, может что поменялось. Но лучше все же явно прописывать метод, который хочешь вызвать
   oleg_km
 
15 - 11.11.20 - 19:16
Не знаю. С инетом работаю через .NET HTTPClient
   телега
 
16 - 12.11.20 - 15:27
(11) Да, вполне возможно. Просто тот же Постман отправлял полностью рабочую картинку и гетом и постом, это меня и ввело в заблуждение, ну и плюс: когда я получал тело как строку, то видел все свои денные в 1С, не ожидал такой подлости от программы.
   телега
 
17 - 13.11.20 - 19:05
В очередной раз убеждаюсь в том насколько 1С криво работает с Интернетом, хотя они типа и пытаются быть модными и интернетными.

В общем решил отправить мультипартом обычное сообщение. Опять же - Постман, все дела...
Далее собираю в 1С, запускаю... 504 таймаут.
секция chat_id есть, секция text есть, баундри установлены, в конце "--", отправка через HTTPСоединение.ВызватьHTTPМетод("POST",HTTPЗапрос), хотя и просто ОтправитьДляОбработки то же самое.
Геты не работают: 1С тогда режет тело.
Какая гадость эта ваша заливная рыба.
   acht
 
18 - 13.11.20 - 20:03
(17) > В очередной раз убеждаюсь
Бееееедненький
   acht
 
19 - 13.11.20 - 20:07
У тебя UTF-то с BOM, без BOM, специалист?
   телега
 
20 - 13.11.20 - 20:35
(19) Я делаю через УстановитьИмяФайлаТела там нет BOM. Сделано это для универсальности: как для сообщений, так и для файлов.
Но даже если через УстановитьТелоИзСтроки то ни так ни так не работает.
вот образец:

------ca4f33c0-6b9e-4d79-a9c5-bbc69478f139
Content-Disposition: form-data; name="chat_id"

376868390
------ca4f33c0-6b9e-4d79-a9c5-bbc69478f139
Content-Disposition: form-data; name="text"

get
------ca4f33c0-6b9e-4d79-a9c5-bbc69478f139--

кусок кода:

    HTTPЗапрос = Новый HTTPЗапрос;
    Заголовки = Новый Соответствие;
    
    HTTPЗапрос.Заголовки.Вставить("Connection", "keep-alive");
    HTTPЗапрос.Заголовки.Вставить("Content-Type", "multipart/form-data; boundary="+Boundary);
    
    //HTTPЗапрос.УстановитьИмяФайлаТела(ИмяФайлаОтправки);

    HTTPЗапрос.УстановитьТелоИзСтроки(ТекстДляОтправки,КодировкаТекста.UTF8,ИспользованиеByteOrderMark.НеИспользовать);//тут было и использовать и не использовать

    HTTPЗапрос.АдресРесурса = СтрокаСоединения;
    
    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL(Новый СертификатКлиентаWindows, Новый СертификатыУдостоверяющихЦентровWindows);
    HTTPСоединение = Новый HTTPСоединение(СерверTg,443,,,,3,ЗащищенноеСоединение);
    
    Ответ = HTTPСоединение.ОтправитьДляОбработки(HTTPЗапрос);
   oleg_km
 
21 - 13.11.20 - 20:40
Посмотри через фиддлер, увидишь в чем разница
   телега
 
22 - 13.11.20 - 21:36
(21) Забавно...  + Символы.ВК + Символы.ПС а не + Символы.ПС
Почему же везде пишут только ПС?


Список тем форума
Рекламное место пустует  Рекламное место пустует
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.