Исходная версия статьи с возможностью копирования кода: 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. Метод может иметь следующие параметры:
Исходя из вышеизложенного, нам понадобятся следующие поля:
- chat_id – идентификатор чата
- photo – собственно данные фото
- caption – подпись к фото (при необходимости)
- parse_mode – режим разбора caption (html или markdown, при необходимости)
Все это должно быть передано telegram API POST-запросом под адресу https://api.telegram.org/botTOKEN/sendPhoto в виде multipart/form-data:
где:
- TOKEN – секретный токен вашего бота
- CHAT_ID – идентификатор чата или канала
- ПОДПИСЬ <b>К ФОТО</b> – текстовое сообщение, прикрепленное к фото, например в HTML-формате
- ДВОИЧНЫЕ_ДАННЫЕ – собственно двоичные данные
О том, что такое токен и chat_id, вы можете узнать из другой статьи. Осталось все это реализовать, используя стандартный для ESP32 http – клиент.
Отправляем изображение
Прежде всего напомню, что telegram API принимает запросы только по HTTPS-соединению. Поэтому нам потребуется импортировать в программу корневой сертификат сервера. Как это сделать, можно почитать здесь и здесь, в данной статье я не буду заострять на этом внимания.
Прежде всего, я оформил все необходимые поля в виде макросов (можно сразу объявить их и static const char*, кроме API_TELEGRAM_BOUNDARY):
Затем настраиваем http-соединение:
Формируем необходимые поля:
Затем нам необходимо посчитать длину всего сообщения, которое будет передано:
Теперь уже можно начинать собственно соединение и передачу данных. Открываем соединение
Вот собственно, почти и всё, без особых премудростей и лишних буферов.
Останется только прочитать код ответа API и закрыть соединение.
Полный код функции вы можете скопипастить здесь: https://kotyara12.ru/iot/esp32_telegram_photo/
Похожим образом можно отправлять изображения не только в telegram, но и на различные фотохостинги и прочие сервера, только потребуется, возможно, немного изменить служебные заголовки. Пользуйтесь на здоровье.
Ну а в telegram может приходить примерно такие сообщения:
Благодарю за внимание, с вами был Александр aka kotyara12.