Найти тему
K12 :: О ESP32 и не только

Отправка изображений в Telegram с ESP32 без использования сторонних библиотек

Оглавление
Исходная версия статьи с возможностью копирования кода: https://kotyara12.ru/iot/esp32_telegram_photo/

Добрый день, уважаемый читатель!

В данной статье я расскажу, как отправить изображение (или файл) с вашего устройства на базе ESP32 в канал или чат telegram. Причем сделаем мы это без использования сторонних библиотек: исключительно с использованием встроенного в ESP-IDF API ESP HTTP Client максимально простым способом. Я уже рассказывал, как отправлять в telegram текстовые сообщения, теперь выполним то же самое, но для картинок, фотографий или файлов. В качестве источника изображений может выступать камера на ESP32-CAM или что-то ещё. Приведенный в статье пример вполне годиться не только для платформы ESP-IDF, но и для Arduino32, так как API ESP HTTP Client доступно и там и там.

В сети можно найти достаточно много примеров, данная же задача решается на платформе Arduino с помощью готовых сторонних библиотек ботов. Но во первых, я не давненько уже я не использую Arduino в своих проектах. Во вторых я не стремлюсь использовать “полноценные” библиотеки для telegram-ботов с обратной связью по одной вполне очевидной причине: telegram api отправляет команды в виде JSON-пакетов, а парсинг JSON на микроконтроллере требует значительных ресурсов. Подключая внешнюю библиотеку бота к проекту, вы автоматически тянете в свой проект значительную часть ненужного в большинстве случаев кода. Ну в третьих, и это самое важное, – я предпочитаю минимизировать использование сторонних библиотек в своих проектах. Точнее – я их не использую совсем, исключение только одно – ESP-IDF. Причина проста – сторонний код может быть изменен в любой момент времени или даже заброшен автором, а не желаю зависеть от других авторов (таки да, и предпочитаю делать ошибки в коде самостоятельно, и потом героически их исправлять).

Между тем, примеров отправки изображений в telegram с использованием исключительно ESP-IDF не так уж и много. Точнее – почти совсем нет. Найденные в сети примеры в основном являются копипастами с одного сайта на другой, без попыток какого-либо анализа и устранения недостатков кода, поэтому они просто пестрят костылями и совершенно неразумным расходованием стека и памяти. Например в одном из примеров изображение из буфера, в котором оно храниться изначально, копируется в другой буфер и только после этого отправляется. При этом второй буфер расположен в стеке, что приводит к необходимости выделения задачи огромного стека.

Пришлось брать быка за рога и разбираться самому.

Telegram API для отправки изображений

Для отправки изображений в telegram нам необходимо воспользоваться методом sendPhoto: core.telegram.org/bots/api#sendphoto. Метод может иметь следующие параметры:

-2

Исходя из вышеизложенного, нам понадобятся следующие поля:

  • chat_id – идентификатор чата
  • photo – собственно данные фото
  • caption – подпись к фото (при необходимости)
  • parse_mode – режим разбора caption (html или markdown, при необходимости)

Все это должно быть передано telegram API POST-запросом под адресу https://api.telegram.org/botTOKEN/sendPhoto в виде multipart/form-data:

-3

где:

  • TOKEN – секретный токен вашего бота
  • CHAT_ID – идентификатор чата или канала
  • ПОДПИСЬ <b>К ФОТО</b> – текстовое сообщение, прикрепленное к фото, например в HTML-формате
  • ДВОИЧНЫЕ_ДАННЫЕ – собственно двоичные данные

О том, что такое токен и chat_id, вы можете узнать из другой статьи. Осталось все это реализовать, используя стандартный для ESP32 http – клиент.

Отправляем изображение

Прежде всего напомню, что telegram API принимает запросы только по HTTPS-соединению. Поэтому нам потребуется импортировать в программу корневой сертификат сервера. Как это сделать, можно почитать здесь и здесь, в данной статье я не буду заострять на этом внимания.

Прежде всего, я оформил все необходимые поля в виде макросов (можно сразу объявить их и static const char*, кроме API_TELEGRAM_BOUNDARY):

-4

Затем настраиваем http-соединение:

-5

Формируем необходимые поля:

-6

Затем нам необходимо посчитать длину всего сообщения, которое будет передано:

-7

Теперь уже можно начинать собственно соединение и передачу данных. Открываем соединение

-8
-9
-10

Вот собственно, почти и всё, без особых премудростей и лишних буферов.

Останется только прочитать код ответа API и закрыть соединение.

-11

Полный код функции вы можете скопипастить здесь: https://kotyara12.ru/iot/esp32_telegram_photo/

Похожим образом можно отправлять изображения не только в telegram, но и на различные фотохостинги и прочие сервера, только потребуется, возможно, немного изменить служебные заголовки. Пользуйтесь на здоровье.

Ну а в telegram может приходить примерно такие сообщения:

-12

Благодарю за внимание, с вами был Александр aka kotyara12.

Полный архив статей вы найдете здесь