NodeMCU ESP8266 y Bot de Telegram - Enviar mensaje

ESP8266 con 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.

Instalando drivers y configurando entorno

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:

Token de Telegram e id de chat

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

Especificación de la API

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.

Enviar mensaje a Telegram desde NodeMCU ESP8266

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).

NodeMCU ESP8266 y Bot de Telegram - Enviar mensaje
NodeMCU ESP8266 y Bot de Telegram – Enviar mensaje

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.

Sobre los certificados SSL

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.

Poniendo todo junto

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.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *