Перейти к содержимому

Отправка сообщений в Telegram на ESP8266 (и ESP32) с использованием фреймворка Arduino

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

В этой статье я расскажу, как достаточно просто отправлять сообщения в мессенджер Telegram из микроконтроллеров ESP8266 (и ESP32) и устройств на их основе без использования сторонних библиотек. Как мы выяснили из предыдущей статьи, только для отправки сообщений не требуется сложных манипуляций, достаточно вызвать один-единственный метод sendMessage. Чем мы и займемся в данной статье. Кроме того, я расскажу как это сделать разными вполне рабочими способами, а уж Вы сами выберете для себя наиболее удобный. А заодно расскажу и о грабельках, которые притаились на данном пути.

Когда-то достаточно давно я уже написал статью, как зарегистрировать своего собственного т.н. бота (или робота) Telegram и научиться отправлять сообщения с помощью скрипта на промежуточном сайте. Написана она была в те далекие и темные времена, когда Роскомнадзор блокировал мессенджер на территории матушки России, и приходилось “извращаться”, чтобы получить доступ к вожделенному Telegram API, в том числе и с “умных” и не очень устройств. Но времена идут, ситуация меняется, и рецепт, изложенной в той статье, стал далеко не актуален. Наоборот, далеко не каждый любитель имеет свой личный сайт и доступ к хостингу. А между тем, тема эта пользуется неизменно высокой популярностью, судя по поисковым запросам на данном сайте. Поэтому я и решил написать новую статью, где хочу “углубить и расширить” данную тему (как говаривал один небезызвестный исторически отмеченный персонаж). 

Все манипуляции и жестокие опыты я буду проводить над прошивкой с MQTT-управлением, которую я описывал в статье: Телеметрия на ESP8266 и MQTT. Пошаговое руководство по созданию DIY-проекта с удаленным управлением. По сути данная статья может служить официальным продолжением этой статьи. Но Вы можете, конечно, встроить код и в Ваши наработки.

 

Кроме того, могу ответственно заявить (когда-то проверял лично), что всё то же самое можно применить и на микроконтроллерах ESP32, если вы пишете код для них на фреймворке Arduino. Но после соответствующей “доработки напильником”, так как сетевые классы WiFi и SSL у них немного отличаются. В остальном приведенный в данной статье код останется вполне работоспособен.

 


Что потребуется для отправки уведомлений?

1. Само собой, Вам потребуется микроконтроллер ESP8266 или ESP32, то есть любая плата на их основе. Программировать я буду в VSCode + PlatformIO, но всё то же самое можно проделать и ArduinoIDE, только с меньшим комфортом. В любом случае я буду использовать “стандартную” платформу ESP8266 Arduino Core. Для ESP32 потребуется немного другая платформа.

2. Прежде чем мы с вами начнем обсуждать программную реализацию, Вы должны создать бота, получить его токен и chat id. Как это сделать, я рассказывал в прошлой статье: Создание (регистрация) telegram-бота для отправки уведомлений из устройств умного дома и не только. Если Вы ещё не читали и не знаете как это делается – начните с этой статьи.

3. Неплохо бы знать, что такое HTTP-запросы и с чем их кушают. А поскольку Telegram API принимает только TLS-соединения, Вы должны знать что это такое и как их использовать в Вашей программе. 

У Вас всё готово? Токен сгенерировали, статьи прочитали? Достаем плату, открываем проект и начинаем!

 


Подготовительные операции 

Как я уже написал выше, для примера я буду использовать код, про который я рассказывал ранее в статье Телеметрия на ESP8266 и MQTT. Пошаговое руководство по созданию DIY-проекта с удаленным управлением. Давайте просто добавим туда функцию отправки сообщений. Но прежде чем мы это сделаем, нам придется отключить TLS-соединение с MQTT-брокером! Как так? Почему?

Дело в том, что Telegram API обрабатывает запросы только через защищенные соединения. И никак иначе. Все запросы, отправленные на порт HTTP (80) автоматически перенаправляются на порт HTTPS (443). То есть чтобы воспользоваться Telegram API, волей-неволей придется играть по их правилам. И это была бы не большая проблема, если бы не одно но, которое решительно меняет ситуацию.

Дело в том, что для установки и поддержания защищенного соединения требуется достаточно много памяти. Протокол TLS был разработан для настольных систем с большим объемом памяти, поэтому им по умолчанию требуется буфер размером как минимум 16 КБ для приема и передачи. А всего на одно TLS-соединение библиотекой BearSSL может расходоваться аж до 22 КБ оперативной памяти (пруфы здесь). Поэтому для ESP8266, у которого общая доступная куча составляет что-то около 40 КБ, просто не хватит памяти для нескольких соединений одновременно, и в каждый момент времени возможно использовать только одно защищенное соединение.

Исходя из этого мы не можем одновременно поддерживать защищенное соединение с MQTT-брокером и отправлять сообщения в Telegram. Придется пожертвовать MQTT, хоть это и не желательно. Справедливости ради стоит отметить, что иногда защищенное подключение к брокеру и вовсе не требуется. Например, если вы планируете “поднять” свой личный локальный MQTT-брокер, или подключаетесь к локальному брокеру Home Assistant.

Это и есть одни из тех самых граблей, про которые я упомянул выше.

Для ESP32 + Arduino, это выполнять не нужно!

Итак, модифицируем ранее сделанную прошивку.

1. Первым делом убираем глобальную переменную типа BearSSL::X509List и WiFiClientSecure заменяем на простой WiFiClient:

/**************************************************************************
 * Глобальные переменные
 *************************************************************************/

// Подключение к MQTT брокеру (серверу)
// !!! Поскольку у ESP8266 памяти очень мало (~40 kB), нам придется пожертвовать "постоянным" TLS-подключением к MQTT
// BearSSL::X509List certISRG(ISRG_Root_x1);

 

WiFiClient wifiMqtt; // BearSSL::WiFiClientSecure wifiClient;

PubSubClient mqttClient(wifiMqtt);

 

2. Затем убираем привязку хранилища сертификата certISRG к wifiClient в теле функции bool wifiConnected(). Я специально закомментировал ненужные функции, а не удалил их, дабы было понятно, как и что убирать.

  Serial.print("Current time: ");
  Serial.print(asctime(&timeinfo));

  // Теперь можно привязать корневой сертификат к клиенту WiFi
  // wifiClient.setTrustAnchors(&certISRG);
};

 

3. Не спешите удалять сам сертификат ISRG_Root_x1

Он нам еще пригодится для OTA! Для возможности OTA через TLS просто перенесем нужный код в функции обработки обновлений OTA otaStart() (с использованием локальных переменных, дабы они были автоматически удалены из памяти после использования):

// ОТА обновление 
void otaStart(const char* linkOTA) 
{
  Serial.print("OTA :: Receiving OTA: ");
  Serial.print(linkOTA);
  Serial.println("...");
  // Настраиваем безопасное подключение к серверу
  BearSSL::WiFiClientSecure wifiOTA;
  BearSSL::X509List certISRG(ISRG_Root_x1);
  wifiOTA.setTrustAnchors(&certISRG);
  ...

 

4. Не забудьте также заменить порт MQTT-брокера обратно на обычный:

// Настраиваем MQTT клиент
mqttClient.setServer(mqttServer, mqttPort);

 

Отлично! Можно загрузить модифицированную в микроконтроллер и убедиться, что все работает, но без TLS.

Работает? Идем далее…

 


Добавляем сертификат ЦС для Telegram API

Прежде всего нам нужно добавить сертификат центра сертификации (ЦС) в нашу программу. Если бы Telegram API использовал бы тот же самый ЦС ISRG Root X1, то ничего не потребовалось бы, но увы – у них другой ЦС, и нам придется добавить его сертификат в прошивку. Как это сделать, я писал ранее в другой статье. Но вы можете не мучаться, а просто скопировать готовый код в свою программу отсюда (или из кода на GitHub):

// Корневой сертификат для Telegram API, действителен до 29 июня 2034
static const char TG_API_Root[] PROGMEM = R"CERT(
-----BEGIN CERTIFICATE-----
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
ReYNnyicsbkqWletNw+vHX/bvZ8=
-----END CERTIFICATE-----
)CERT";

Все готово, можно писать функцию кода отправки сообщения. Я написал аж четыре разных варианте – просто для того, чтобы продемонстрировать возможные варианты работы с запросами. А вы можете выбрать оптимальный на ваш взгляд.

Повторюсь ещё раз, для отправки сообщения нам нужно отправить к API GET или POST запрос. По идее, мы можем воспользоваться классом HTTPClient, который объявлен в модуле <ESP8266HTTPClient.h> и “не делать себе моск”. И мы этот вариант обязательно рассмотрим, но в конце. Но лично на мой взгляд, HTTPClient явно избыточен для наших целей, обычный WiFiClientSecure легко справится и сам – тем более что нам и не особо важно обрабатывать коды ответа.

 


Способ 1. Отправляем GET-запрос “по простому”

Вначале нужно настроить безопасное подключение к серверу Telegram API.

void telegramSendMessage_Get_Raw(const char* chatId, char* message)
{
  // Настраиваем безопасное подключение к API
  WiFiClientSecure wifiTg;
  // wifiTg.setInsecure();
  X509List certTg(TG_API_Root);
  wifiTg.setTrustAnchors(&certTg);
  ...

Важно! Для отправки уведомлений здесь и далее следует использовать только локальные переменные X509List и WiFiClientSecure. Это позволит освободить память после того, как сообщение будет отправлено. Если этого не сделать, память будет использована постоянно и OTA через TLS работать не будет.

По большому счёту, вы можете “забить болт с левой резьбой” на сертификат и использовать опцию wifiTg.setInsecure(); при подключении к API. В этом случае TLS соединение устанавливается, но сертификат сервера никак не проверяется. Однако экономию памяти это почти не дает, так что особого смысла не имеет – разве что за сроками действия сертификатов следить не нужно. Пока вы только отправляете сообщения, особых проблем с безопасностью от “подмены сервера” ожидать не приходится. Поэтому  я оставил этот вариант в тексте функций, но не действительным. Поступайте по своему разумению. 

Далее пробуем подключиться к серверу и порту 443:

// Пробуем подключиться к Telegram API: обратите внимание - API принимает входящие запросы только по HTTPS на 443 порту
if (wifiTg.connect("api.telegram.org", 443)) {
  ...
  // Закрываем соединение
  wifiTg.stop();
} else {
  Serial.printf("#ERROR# :: Failed to connect to Telegram API: %d\r\n", wifiTg.getLastSSLError());
};

Если подключение не выполнено – проверяем код ошибки через getLastSSLError(). Если он равен -1000 – то это означает, что МК не хватает памяти для установки TLS соединения. Скорее всего, TLS-соединение уже где-то существует.

Теперь можно сформировать нужный запрос:

// Формируем и отправляем GET-запрос для отправки сообщения
wifiTg.printf("GET https://api.telegram.org/bot%s/sendMessage?chat_id=%s&parse_mode=HTML&text=%s HTTP/1.1\r\n", tgToken, chatId, message);
// Отправляем служебные HTTP-заголовки
wifiTg.println(F("Host: api.telegram.org"));
wifiTg.println(F("User-Agent: ESP8266"));
// Отправляем пустую строку, которая указывает серверу, что запрос полностью отправлен
wifiTg.println();

// Читаем ответ сервера (только первую строку)
Serial.print(F("TG :: API responce: "));
Serial.println(wifiTg.readStringUntil('\n'));

// Закрываем соединение
wifiTg.stop();

 

Полный текст всех функций вы найдете в конце статьи на GitHub-е.

Проверяем созданную функцию. Я подготовил многострочное текстовое сообщение такого вида:

Версия функции отправки

Жирный шрифт

Наклонный шрифт

Подчеркнутый шрифт

Это позволяет оценить правильность работы функции. Я вставил код отправки сообщения сразу после подключения к MQTT. Разумеется, вы должны вставить его в нужном вам месте, например при изменении температуры в доме или в других случаях. Но для примера сойдет и так.

telegramSendMessage_Get_Raw(tgChatId, (char*)"Версия telegramSendMessage_Get_Raw (не правильно)\n<b>Жирный шрифт</b>\n<i>Наклонный шрифт</i>\n<u>Подчеркнутый шрифт</u>");
Ага! Что-то блямкнуло, сообщение пришло. Только как-то не так - пришла только первая строка:

Произошло так потому, что заголовки запроса передаются на сервер построчно, и строки текста были восприняты сервером как отдельные заголовки запроса. Как же быть?  

Нужно применить “процентный” способ кодирования символов в URI, когда вместо символа передается его код в HEX-виде и символом % впереди. Например пробел обозначается как %20, а символ переноса строки – %0A. Но в данном случае пробелы кодировать не нужно. Тогда наш текст мы должны записать так:

telegramSendMessage_Get_Raw(tgChatId, (char*)"Версия telegramSendMessage_Get_Raw (правильно)%0A<b>Жирный шрифт</b>%0A<i>Наклонный шрифт</i>%0A<u>Подчеркнутый шрифт</u>");
Проверяем. Теперь все работает корректно.

Но это не очень удобно. Давайте сделаем эту замену программным способом, а заодно и функцию немного “оптимизируем”.

 


Способ 2. Оптимизируем GET-запрос

Во первых, сразу добавим преобразование текста запроса. Я использовал замену только служебных символов переноса, хотя percent-encoding предусматривает больше символов под замену:

void telegramSendMessage_Get_Encoded(const char* chatId, char* message)
{
  // Percent-encoding символов в URI на HTML-коды %XX
  String msg = String(message);
  msg.replace("\n", "%0A");
  msg.replace("\r", "%0D");

Ещё давайте перенесем наши локальные переменные для подключения wifiTg и certTg из стека в кучу (heap). В предыдущем варианте я объявил их как самые обычные локальные переменные, и при выполнении функции они попадут в стек. Я предлагаю перенести их в общую кучу (heap) или динамическую память.

Зачем это нужно? Просто для демонстрации, что “так можно было”. С точки зрения памяти почти ничего не меняется – стек растет “сверху”, куча – “снизу”, но общий объем у них один на двоих. Фрагментации при короткоживущих переменных практически не будет. В общем, особого смысла в переносе переменных лично я не вижу. Но в сети часто встречаются примеры и такого применения. Поэтому я решил использовать такой вариант – для демонстрации.

// Настраиваем безопасное подключение к API с размещением временных объектов в куче (heap)
WiFiClientSecure *wifiTg = new WiFiClientSecure;
// wifiTg->setInsecure();
X509List *certTg = new X509List(TG_API_Root);
wifiTg->setTrustAnchors(certTg);

 

Обратите внимание – теперь наши переменные это указатели. И вместо точки при вызове методов класса следует использовать стрелку ->. Ну и нужно обязательно не забыть удалить эти переменные “вручную” в конце работы функции, иначе сразу же произойдет утечка большого объема памяти.

// Не забываем удалить данные, размещенные в куче
delete wifiTg;
delete certTg;

Кроме того, допустим я решил, что передавать заголовки запроса отдельно – это слишком утомительно, и подготовил шаблон запроса целиком:

static const char* tgGetRequest = "GET https://api.telegram.org/bot%s/sendMessage?chat_id=%s&parse_mode=HTML&text=%s HTTP/1.1\r\n"
                                  "Host: api.telegram.org\r\n"
                                  "User-Agent: ESP8266\r\n\r\n";

Теперь отправка сообщения сводится к одной строчке:

// Формируем и отправляем GET-запрос для отправки сообщения (сразу целиком, по шаблону)
wifiTg->printf(tgGetRequest, tgToken, chatId, msg.c_str());

Проверяем:

Всё работает. Конечно, все эти оптимизации спорны, но так тоже можно. Можно было бы на этом и остановиться, но….

 


Способ 3. Используем POST и JSON

Но всё-таки взаимодействие с Telegram API GET-запросами – это не совсем правильно. API рассчитан на применение POST-запросов и JSON-пакетов, которые представляют собой объекты, “упакованные” специальным образом в строки. Это позволит не думать о кодировках и символах, а отправлять текст в любом виде.

Вначале необходимо этот JSON сформировать. Можно, конечно, надыбать специальную библиотечку для работы с JSON, но для генерации она нам не нужна. Сделаем все гораздо проще, “ручками”, с помощью банального класса String:

// Формируем JSON-пакет с данными
String sJSON = "{\"chat_id\":" + String(chatId) + ",\"parse_mode\":\"HTML\",\"disable_notification\":false,\"text\":\"" + String(message) + "\"}";

Дополнительно JSON позволяет передавать любое количество полей и опций запроса – просто загляните в документацию к sendMessage.

Теперь можно отправить эту строку, воспользовавшись предыдущим способом:

static const char* tgPostRequest = "POST https://api.telegram.org/bot%s/sendMessage HTTP/1.1\r\n"
                                   "Host: api.telegram.org\r\n"
                                   "User-Agent: ESP8266\r\n"
                                   "Content-Type: application/json\r\n"
                                   "Content-Length: %d\r\n\r\n"
                                   "%s\r\n\r\n";

Обратите внимание на шаблон HTML-запроса: перед самими POST-данными (это последний аргумент %s в шаблоне) и после него должна быть пустая строка (два раза \r\n). А кроме того, мы должны передать серверу формат передаваемых данных и длину этой строки JSON.

// Формируем и отправляем POST-запрос для отправки сообщения (сразу целиком, по шаблону)
wifiTg->printf(tgPostRequest, tgToken, sJSON.length(), sJSON.c_str());

Вот, в общем-то и все отличия. Зато гораздо правильнее. Подумав, можно добавить отключение звука ( disable_notification=true ) и прочие опции при отправке сообщения. Но это Вам на “домашнее задание”.

Полный текст новой функции выглядит так:

void telegramSendMessage_Post(const char* chatId, char* message)
{
  Serial.print("TG :: Send message: ");
  Serial.print(message);
  Serial.println("...");

  // Формируем JSON-пакет с данными
  String sJSON = "{\"chat_id\":" + String(chatId) + ",\"parse_mode\":\"HTML\",\"disable_notification\":false,\"text\":\"" + String(message) + "\"}";
  Serial.println(sJSON.c_str());

  // Настраиваем безопасное подключение к API с размещением временных объектов в куче (heap)
  WiFiClientSecure *wifiTg = new WiFiClientSecure;
  // wifiTg->setInsecure();
  X509List *certTg = new X509List(TG_API_Root);
  wifiTg->setTrustAnchors(certTg);

  // Пробуем подключиться к Telegram API: обратите внимание - API принимает входящие запросы только по HTTPS на 443 порту
  if (wifiTg->connect("api.telegram.org", 443)) {
    // Формируем и отправляем POST-запрос для отправки сообщения (сразу целиком, по шаблону)
    wifiTg->printf(tgPostRequest, tgToken, sJSON.length(), sJSON.c_str());
    
    // Читаем ответ сервера (только первую строку)
    Serial.print(F("TG :: API responce code: "));
    Serial.println(wifiTg->readStringUntil('\n'));
    // Закрываем соединение
    wifiTg->stop();
  } else {
    Serial.printf("#ERROR# :: Failed to connect to Telegram API: %d\r\n", wifiTg->getLastSSLError());
  };

  // Не забываем удалить данные, размещенные в куче
  delete wifiTg;
  delete certTg;
}

 

В общем, формирование HTTP-запросов “вручную” не представляет из себя ничего сложного, но можно воспользоваться и готовыми объектами…

 


Способ 4. Используем класс HTTP Client

Если Вам все-таки лень собирать запрос “вручную”, то можно воспользоваться готовым классом HTTPClient. Он позволяет сформировать и GET и POST запросы, но формат данных все равно придется указать. Кроме того, придется предварительно сформировать URI для отправки данных.

Я не буду детально расписывать происходящее, думаю и там все будет ясно-понятно, а просто приведу всю функцию целиком:

void telegramSendMessage_Post_Http(const char* chatId, char* message)
{
  Serial.print("TG :: Send message: ");
  Serial.print(message);
  Serial.println("...");

  // Формируем JSON-пакет с данными
  String sJSON = "{\"chat_id\":" + String(chatId) + ",\"parse_mode\":\"HTML\",\"disable_notification\":false,\"text\":\"" + String(message) + "\"}";
  Serial.println(sJSON.c_str());

  // Настраиваем безопасное подключение к API
  WiFiClientSecure wifiTg;
  HTTPClient tgHttp;
  // wifiTg.setInsecure();
  X509List certTg(TG_API_Root);
  wifiTg.setTrustAnchors(&certTg);

  // Формируем динамическую URI
  String sURI = "https://api.telegram.org/bot" + String(tgToken) + "/sendMessage";
  // Пробуем подключиться к Telegram API
  if (tgHttp.begin(wifiTg, sURI.c_str())) {
    // Добавляем заголовок с типом данных
    tgHttp.addHeader("Content-Type", "application/json");
    // Формируем и отправляем POST-запрос для отправки сообщения
    int httpCode = tgHttp.POST(sJSON);
    // Выводим в лог код ответа сервера (только первую строку)
    Serial.printf("TG :: API responce code: %d\r\n", httpCode);
    // Закрываем соединение
    tgHttp.end();
  } else {
    Serial.printf("#ERROR# :: Failed to connect to Telegram API: %d\r\n", wifiTg.getLastSSLError());
  };
}

Сообщение будет также успешно доставлено, но размер скомпилированного bin-файла прошивки будет чуть больше. Да и код функции не стал короче и понятнее… Поэтому это не мой выбор.

 


Какой способ передачи сообщений использовать – выбирайте сами. Хоть все сразу. Вам и карты в руки. Все эти функции одновременно представлены в репозитории проекта на GitHub: github.com/kotyara12/arduino. PS: Чувствительные данные токена и все пароли намеренно испорчены перед публикацией, поэтому не советую их использовать, а подставить свои.

Скачать файлы проекта можно совершенно бесплатно. Но если Вы вдруг пожелаете меня отблагодарить за труды, то Вы можете это сделать – просто откройте одно или несколько рекламных объявлений на данном сайте и “посмотрите” их пару минут. Этого будет вполне достаточно.


А что, если хочется обратной связи – то есть управлять ESP через Telegram?

Как я уже писал в предыдущей статье, для этого придется использовать другой метод – getUpdates(), затем распарсить полученный JSON, проанализировать команды и обработать их.

Но в этом случае я Вам не советую делать это “самостоятельно” – слишком громоздко и сложно. Советую Вам воспользоваться любой готовой библиотекой, например FastBot. Единственное, что мне в ней не очень нравится – setInsecure(), но это дело не строго обязательное. И я понимаю, почему автору пришлось это сделать – другого выхода у него и не было.

Ещё одна сложность, которая может вас подстерегать – если Вы захотите отправлять команды нескольким устройствам, которые находятся в одной и той же группе, то сделать это будет не очень просто. Но это из-за особенностей самого Telegram, а не библиотеки.


Ну этом позвольте откланяться, с вами был ваш Александр ака kotyara12. До следующих встреч. Ваши вопросы или комментарии вы можете оставить под статьей или в telegram-чате https://t.me/k12chat

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


Пожалуйста, оцените статью:
[ 5 из 5, всего 4 оценок ]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *