Un bot en Python para Telegram (y en una sola línea)

Este es uno de los capítulos del tutorial Exprimiendo Telegram. Crea tu propio bot para Telegram.. Encontrarás los enlaces a todos los de capítulos, al final de este artículo.

Hace unos pocos días Angel, en uGeek, publicó un interesante artículo sobre como crear un bot de telegram con Bash. Igualmente, por mi parte, la semana anterior había publicado un artículo sobre como podías crear tu propio bot con PHP. En este contexto y en el grupo de telegram de uGeek, comenté que se podía hacer de forma similar, un bot en Python para Telegram. Fue justo en ese momento, donde Pedro, MosqueteroWeb, nos propuso un duelo.

Y es que no lo puedo evitar. Ya lo comenté en el capítulo número 1 del podcast titulado el peligro de las apuestas. Y es que no puedo resistirme a un reto. Y esta es la razón de este nuevo artículo, que irá encasillado en el tutorial sobre bots para Telegram.

En este nuevo capítulo del tutorial, te explicaré como puedes utilizar Python para enviar mensajes, imágenes y audios, de forma relativamente sencilla a un canal o grupo de Telegram. Eso si, el objetivo de este capítulo es hacerlo sin ninguna librería extra.

Un bot de Telegram en Python (y en una sola línea)

Un bot en Python para Telegram

Tal y como te he comentado en la introducción, el objetivo de este nuevo capítulo del tutorial es implementar un bot en Python, sin necesidad de utilizar ninguna librería externa. Me refiero claramente a una librería cuyo objetivo sea facilitar el acceso a la API de bots de Telegram. Comento este punto, porque si que utilizaré una librería para realizar las llamadas GET y POST, me refiero a Requests.

Por otro lado, lo que verás en este capítulo no es un bot en si. Se trata de llamadas a la API. Implementar un bot, considero que es algo mas complejo que una simple llamada. Un bot, debería permitir interactuar con el usuario. Es decir, el bot debe ser capaz de responder ante las acciones del usuario. Incluso, implementar botones, para facilitar esa interrelación entre bot y usuario.

Ahora bien, esto último, esta interrelación no es mas que seguir el capítulo 10 de este tutorial en el que te explico lo relacionado con bots, Flask y Nginx.

Requests

Requests es una librería para HTTP, liberada bajo licencia Apache2, que tal y como la definen sus propios desarrolladores, escrita en Python para seres humanos. La ventaja de utilizar esta librería es que evita las complicaciones de trabajar con HTTP, haciendo que una llamada sea muy, pero que muy, sencilla.

Esta librería está disponible tanto para las versiones 2 y 3 de Python. Sin embargo, lo recomendable es utilizar Python 3, y en este sentido, utilizaré esta versión.

Instalar Requests para Python 3 en Ubuntu, y en derivadas de Debian, es tan sencillo como ejecutar,

sudo apt install python3-requests

Aunque dependiendo de lo que quieras hacer, es posible que lo recomendable sea crearte un entorno virtual en Python, lo que te permitirá olvidarte del sistema en el que estés trabajando.

Pasos previos

Con independencia del lenguaje de programación o si utilizas librería o no, es necesario crear el bot. Con este objetivo, Telegram dispone de un bot para crer bots. Se trata de BotFather. Te recomiendo que leas el primer capítulo del tutorial sobre crear tu propio bot para Telegram.

Enviar mensajes a Telegram con tu bot en Python

Una vez te he comentado los puntos de partida, y ya has creado tu bot con BotFather, ya puedes enviar tu mensaje. En python es tan sencillo como crear un archivo de texto, que puede ser mensaje.py, con el siguiente contenido,

#!/usr/bin/env python3
import requests

requests.post('https://api.telegram.org/bot<TOKEN>/sendMessage',
              data={'chat_id': '<CHAT_ID>', 'text': '<TEXTO>'})

Donde,

  • <TOKEN> token que te ha propocionado BotFather.
  • <CHAT_ID> identificador del canal o grupo donde envías el mensaje.
  • <TEXTO> texto del mensaje que quieres enviar.

Como ves, el compromiso lo he cumplido, en una línea he conseguido enviar un mensaje sin necesidad de librerías externas, a excepción de Requests. Si, es realmente sencillo.

Si quieres ver la respuesta de Telegram, hay que modificar ligeramente el script, tal y como te indico a continuación,

#!/usr/bin/env python3
import requests

r = requests.post('https://api.telegram.org/bot<TOKEN>/sendMessage',
              data={'chat_id': '<CHAT_ID>', 'text': '<TEXTO>'})
print(r.text)

Dado que lo que nos devuelve es un json, si quieres aprovechar las facilidades que te da Python, puedes utilizar directamente el módulo json para conocer si la respuesta es correcta. Así, de nuevo, modificamos el script, añadiendo estas matizaciones,

#!/usr/bin/env python3
import requests
import json

r = requests.post('https://api.telegram.org/bot<TOKEN>/sendMessage',
                  data={'chat_id': '<CHAT_ID>', 'text': '<TEXTO>'})
data = json.loads(r.text)
print(data['ok'])

Parámetros opcionales

Además del parámetro text también se pueden enviar algunos parámetros opcionales que te van a permitir adaptar el mensaje a tus necesidades. Estos parámetros, comunes a otros métodos, son los siguientes,

  • parse_mode se refiere al formato del mensaje. Aquí tienes dos opciones o Markdown o HTML. Mi consejo es que utilices HTML porque en mi caso he tenido algunos problemas con el guión bajo del markdown.
  • disable_web_page_preview. Cuando se ponen enlaces en los mensajes, Telegram por defecto te muestra una previsualización de la página correspondiente. Con esta opción puedes habilitar o deshabilitar esa previsualización.
  • disable_notification. Cada vez que recibes un mensaje en un grupo un canal, como bien sabes, recibes una notificación, salvo que lo hayas limitado temporal o definitivamente. Sin embargo, tu puedes con este parámetro que no se envie notificación.
  • reply_to_message_id. Esto parámetro lo puedes utilizar para el caso de que estés respondiendo a otro mensaje. Por ejemplo, te puede ser de utilidad para una cadena de mensajes.
  • reply_markup. En esta opción puedes introducir parámetros adicionales, como puede ser un teclado en línea. Esto lo veremos en un capítulo posterior.

Pasando argumentos

Esta solución para enviar siempre el mismo mensaje no está mal. Sin embargo, si lo que queremos es enviar diferentes mensajes a diferentes canales, lo suyo es que pasemos, tanto el identificador del canal o grupo, como el mensaje al script. Igualmente esto es muy sencillo. Tan solo tenemos que introducir algunas ligeras modificaciones en nuestro script.

#!/usr/bin/env python3
import requests
import sys

if __name__ == '__main__':
    if len(sys.argv) > 2:
        requests.post('https://api.telegram.org/bot<TOKEN>/sendMessage',
                      data={'chat_id': sys.argv[1], 'text': sys.argv[2]})

Como primer parámetro pasaremos el identificador del chat, mientras que como segundo parámetro el texto. En este caso el texto debe ir entre comillas.

Enviar imágenes a Telegram con tu bot en Python

Una vez que ya has visto lo sencillo que es enviar un mensaje de texto utilizando Python, vamos a algo ligeramente mas complicado. Vamos a enviar una imagen. En este caso tenemos dos opciones, o bien, enviamos la url de la imagen, en el caso de que ya esté en subida a algún servidor, o como segunda opción la subimos. Esto, con requests es realmente sencillo.

  • Primer caso. Utilizamos una imagen disponible en algún alojamiento web,
requests.post('https://api.telegram.org/bot<TOKEN>/sendPhoto',
              data={'chat_id': <CHAT_ID>, 'photo': <PHOTO_URL>, 'caption': <TEXT>})

En este caso debes indicar la ruta donde está alojada la imagen, así como el título o un texto que acompañe la imagen. Esto último es opcional, si no le quieres añadir un texto, simplemente, no pongas ese último parámetro.

  • Segundo caso. Subimos nuestra propia imagen,
requests.post('https://api.telegram.org/bot<TOKEN>/sendPhoto',
              files={'photo': (<ARCHIVO>, open(<ARCHIVO>, 'rb'))},
              data={'chat_id': <CHAT_ID>, 'caption': <TEXT>})

Aquí <ARCHIVO> se corresponde con la ruta donde se encuentra el archivo de la imagen que queremos subir a Telegram.

¿Fácil verdad?

Enviar audio y voz a Telegram con tu bot en Python

Una vez hemos superado las opciones para enviar mensajes e imágenes, vamos al siguiente paso, de este artículo, que es enviar audio.

En este caso, también tienes dos opciones para enviar audio. La primera de las opciones es enviarla como un mensaje de voz, mientras que la segunda es como un archivo de audio. Así, en el primer caso, como mensaje de voz sería tal y como ves a continuación,

requests.post('https://api.telegram.org/bot<TOKEN>/sendVoice',
              files={'voice': (<ARCHIVO>, open(<ARCHIVO>, 'rb')),
                     'thumb': (<ARCHIVO2>, open(<ARCHIVO2>, 'rb'))},
              data={'chat_id': <CHAT_ID>, 'caption': <TEXT>})

En este caso, también es posible añadir un parámetro extra que es la duración del mensaje de voz en segundos. Para esto utiliza duration.

Mientras que el segundo, como archivo de audio, será de la siguiente forma,

requests.post('https://api.telegram.org/bot<TOKEN>/sendAudio',
              files={'audio': (<ARCHIVO>, open(<ARCHIVO>, 'rb')),
                     'thumb': (<ARCHIVO2>, open(<ARCHIVO2>, 'rb'))},
              data={'chat_id': <CHAT_ID>, 'caption': <TEXT>})

Además de los parámetros anteriores, es posible enviar un nuevo un nuevo archivo. Este tipo de archivo es lo que se conoce como una miniatura o en inglés thumbnail. Y es la típica imagen que acompaña al mensaje de voz. Aunque lo cierto es que lo he visto en pocas ocasiones.

La parte de la miniatura es completamente opcional, y por tanto la puede omitir. Al igual que en otros casos, también se puede utilizar un enlace a una imagen que ya esté disponible desde un servidor. Así, en ese caso, el método tendría el siguiente aspecto,

requests.post('https://api.telegram.org/bot<TOKEN>/sendAudio',
              files={'voice': (<ARCHIVO>, open(<ARCHIVO>, 'rb'))},
              data={'chat_id': <CHAT_ID>, 'caption': <TEXT>, 'thumb': <THUMB>})

Indicarte que las características de las miniaturas están fijadas. En este sentido el archivo tiene que ser en formato JPEG y tener un peso máximo de 200 kB, y unas dimensiones iguales o inferiores a 90 px.

En ambos casos la parte del título es opcional, con lo que de nuevo, la puedes omitir. Además es posible, añadir algunos parámetros opcionales, como puede ser el formato del texto. En cualquier caso, te recomiendo una visita a la documentación de la API de bots, para tener siempre la última documentación.

Enviar una video nota

Desde hace recientemente poco, en referencia a la publicación de este capítulo del tutorial, es posible enviar vídeos desde Telegram con una duración inferior a un minuto. El método que tienes que utilizar será el siguiente,

requests.post('https://api.telegram.org/bot<TOKEN>/sendVideoNote',
              files={'video_note': (<ARCHIVO>, open(<ARCHIVO>, 'rb')),
                     'thumb': (<ARCHIVO2>, open(<ARCHIVO2>, 'rb'))},
              data={'chat_id': <CHAT_ID>, 'caption': <TEXT>,
                    'duration': <DURATION>, 'length': <LENGTH>})

Los únicos parámetros obligatorios son el archivo de vídeo y el identificador del chat. El resto de parámetros son totalmente opcionales. Como ves, aquí he incluido dos nuevos. Por un lado la duración del vídeo y la dimensión del vídeo. Este caso se corresponde con el diámetro.

Enviar cualquier tipo de archivo a Telegram con tu bot en Python

Si en lugar de una imagen o un audio quieres enviar cualquier otro tipo de documento, existe un método específico para ello. El uso es el siguiente,

requests.post('https://api.telegram.org/bot<TOKEN>/sendDocument',
              files={'document': (<ARCHIVO>, open(<ARCHIVO>, 'rb')),
                     'thumb': (<ARCHIVO2>, open(<ARCHIVO2>, 'rb'))},
              data={'chat_id': <CHAT_ID>, 'caption': <TEXT>})

Al igual que en el caso de enviar un archivo de audio, también es posible mostrar una pequeña miniatura que se corresponda con el documento que estamos enviando. De nuevo, esto es completamente opcional.

Conclusiones

Como puedes ver, en una sóla línea de código, o casi, es posible enviar un mensaje utilizando los bots de Telegram. La cuestión es que poco a poco, esto se va complicando a medida que quieres enviar otro tipo de archivos y documento. Aunque tampoco en exceso, como tu mismo has visto.

Dado lo extenso de los métodos del API de bots de Telegram, dejo para un nuevo capítulo otros métodos, que seguro te serán de utilidad. Y para un tercer capítulo dentro de esta mini serie, el uso de teclados en línea.

Deja un comentario

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