NodeMCU ESP8266 y Bot de Telegram - Enviar mensaje
En este tutorial de programación con la NodeMCU ESP8266 vamos a ver cómo enviar un mensaje en nombre de un Bot de Telegram a cualquier usuario, grupo o canal de Telegram.
Solo vas a necesitar tu tarjeta ESP8266 para conectarte al Wi-Fi y enviar mensajes a la API de Telegram. Debido a que la API de Bots de Telegram usa HTTP, puedes enviar mensajes a Telegram desde una ESP8266.
En caso de que no hayas instalado tu NodeMCU ni le hayas cargado código por favor revisa el siguiente vídeo para una guía:
En este post asumo que ya tienes tu token del Bot, mismo que el BotFather te debió brindar. Si no, solo habla con él en https://t.me/botfather y crea un nuevo Bot para obtener tu token.
También estoy suponiendo que ya conoces el id de chat, grupo o canal. Si no lo tienes puedes obtener el id de usuario reenviando un mensaje al Bot https://t.me/get_id_bot o https://t.me/JsonDumpBot (no estoy afiliado ni tengo relación con ellos) y estoy seguro de que debe haber distintas maneras de obtenerlo
El proceso para comunicar la ESP8266 con Telegram es realmente sencillo. Solo debemos hacer una petición HTTP de tipo POST a la siguiente URL:
https://api.telegram.org/botTU_TOKEN/sendMessage
Enviando, codificado como JSON, los valores chat_id
y text
que corresponden al id de chat y contenido del mensaje respectivamente.
Un ejemplo de dichos datos (ya codificados) se ve así:
String cargaUtil = "{\"chat_id\":\"123\",\"text\":\"Hola mundo\"}";
La carga útil que se debe enviar a la API de Telegram es un objeto JSON con las propiedades previamente definidas. No he investigado si existe una librería para codificar JSON en esta tarjeta, pero podemos codificar manualmente.
Nota: la API de Telegram puede ser consumida en varios lenguajes de programación. Este mismo ejemplo ya lo hice con JavaScript.
Entonces solo debemos hacer una petición a esa URL enviando los datos codificados como JSON. Puedes armar el mensaje con cualquier cantidad de variables.
El código importante es el siguiente:
String mensaje = "Hola Telegram desde ESP8266!";
String url = "https://api.telegram.org/bot" + tokenTelegram + "/sendMessage";
String cargaUtil = "{\"chat_id\":\"" + idChat + "\",\"text\":\"" + mensaje + "\"}";
if (clienteHttp.begin(*clienteWifi, url))
{
clienteHttp.addHeader("Content-Type", "application/json", false, true);
int httpCode = clienteHttp.POST(cargaUtil);
if (httpCode > 0)
{
String respuestaDelServidor = clienteHttp.getString();
if (httpCode == HTTP_CODE_OK)
{
Serial.println("Petición OK. Respuesta: " + respuestaDelServidor);
}
Primero definimos el mensaje como cadena. Este mensaje puede venir de cualquier lugar; podría ser el resultado de concatenar la lectura de algún sensor, por ejemplo.
Después definimos la carga útil que será enviada al servidor; esto se hace concatenando los valores y codificando como JSON “manualmente”. Dicho JSON es enviado al invocar a clienteHttp.POST
, no sin antes indicarle al servidor de Telegram que le estamos enviando JSON usando addHeader
.
Al hacer la petición POST para enviar un mensaje en nombre de un Bot de Telegram desde la NodeMCU ESP8266 se nos devolverá un código. Si el código es mayor a 0 es porque la petición fue exitosa (incluso si hubo un error de servidor).
Si el código de respuesta es menor a 0 es debido a que hubo otro error, así que lo estamos imprimiendo para depurar.
Recordemos que una petición HTTP exitosa es la que devuelve el código 200. La API de Telegram está muy bien programada y en caso de que todo sea correcto nos devolverá el código 200, que es el valor de la constante HTTP_CODE_OK
.
Para mantener las cosas simples, yo no estoy verificando los certificados del servidor de Telegram. Si bien la información estará encriptada, no sabremos si el servidor es realmente quien dice ser.
Recuerda que estamos haciendo la petición desde un sistema embebido. No es tan simple hacer peticiones seguras y verificar los certificados como cuando lo hacemos con cURL o JavaScript, mismos que se ejecutan en un sistema operativo completo.
Yo he preferido confiar para mantener las cosas simples, pero siempre es posible agregar un certificado. Vas a encontrar más información en: https://randomnerdtutorials.com/esp8266-nodemcu-https-requests/
Te repito: a mí me funciona perfectamente y no tengo ningún problema; no estoy enviando información confidencial o descargando datos importantes del servidor.
Anteriormente te mostré el código más importante, pero no es el código completo. El código completo queda como se ve a continuación.
Solo debes configurar el nombre de tu red, contraseña, id de chat al que se le enviarán los mensajes y el token del Bot de Telegram.
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
// Puede ser de un usuario, canal o grupo
const String idChat = "";
// Obtenido con el @Botfather
const String tokenTelegram = "";
// Red WiFi para conectarse
const char *NOMBRE_RED_WIFI = "";
const char *CLAVE_RED_WIFI = "";
void setup()
{
Serial.begin(9600);
WiFi.mode(WIFI_STA);
WiFi.begin(NOMBRE_RED_WIFI, CLAVE_RED_WIFI);
while (WiFi.status() != WL_CONNECTED)
{
delay(1000);
}
}
void loop()
{
if ((WiFi.status() == WL_CONNECTED))
{
std::unique_ptr<BearSSL::WiFiClientSecure> clienteWifi(new BearSSL::WiFiClientSecure);
clienteWifi->setInsecure();
HTTPClient clienteHttp;
String mensaje = "Hola Telegram desde ESP8266!";
String url = "https://api.telegram.org/bot" + tokenTelegram + "/sendMessage";
String cargaUtil = "{\"chat_id\":\"" + idChat + "\",\"text\":\"" + mensaje + "\"}";
if (clienteHttp.begin(*clienteWifi, url))
{
clienteHttp.addHeader("Content-Type", "application/json", false, true);
int httpCode = clienteHttp.POST(cargaUtil);
if (httpCode > 0)
{
String respuestaDelServidor = clienteHttp.getString();
if (httpCode == HTTP_CODE_OK)
{
Serial.println("Petición OK. Respuesta: " + respuestaDelServidor);
}
else
{
Serial.printf(
"Petición realizada pero hubo un error en el servidor. Código HTTP: %d. Respuesta: %s\n",
httpCode,
respuestaDelServidor.c_str());
}
}
else
{
// Petición Ok pero código no es 200
Serial.printf("Error haciendo petición: %s\n", clienteHttp.errorToString(httpCode).c_str());
}
clienteHttp.end();
}
else
{
Serial.println("Error con clienteHttp.begin");
}
}
else
{
Serial.println("No hay WiFi");
}
// Esperar 10 segundos antes de enviar el siguiente mensaje
delay(10000);
}
En próximos tutoriales te voy a enseñar a enviar información de sensores a Telegram desde este mismo chip.
En el ejercicio de programación de hoy vamos a trabajar con ANSI C para leer…
Hoy te quiero compartir una herramienta en línea para generar números aleatorios directamente en el…
Comprimir un PDF con Telegram es posible gracias a los Bots. Anteriormente en mi blog…
En este post te voy a enseñar a guardar solo algunos días de la semana…
En este post te enseñaré a usar tu impresora térmica comenzando en el paso de…
Hoy voy a tratar de solucionar el error ERR_SSL_CIPHER_OPERATION_FAILED que aparece al usar npm install…
Esta web usa cookies.
Ver comentarios
Exelente, muchas gracias