Desde la aparición de los bots de telegram, se han creado una cantidad inmensa de bibliotecas para poder crear un bot propio. En este post están los pasos para poder crear uno utilizando Python.

Qué es un bot en Telegram

Los bots de telegram son programas accesibles desde los diferentes clientes de telegram. Dentro de la aplicación, actuan como un usuario más aunque podemos indicarles que para cada mensaje actúen de una determinada forma. Por ejemplo, que si les enviamos la ubicación nos muestre los sitios de interés mas cercanos o que al mandar una nota de voz nos la guarde y nos recuerde más adelante.

Lo atractivo es que no tenemos que montar ni mantener toda la infraestructura que haría falta si no tuvieramos estos bots. Por ejemplo un servidor que acepte mensajes, los trate y responda y un cliente desde el cual mandarlos.

Un ejemplo concreto

El primer bot que programé surgió a raiz de dos necesidades al comenzar la universidad.

  • Saber cuándo tenía que asistir a las clases y en que aula se impartian.
  • Saber los horarios de los tranvías de la ciudad para cada parada.

Desde entonces he ido añadiendo distintas funcionalidades conforme las necesitaba, incluso tenía un comando para resolver integrales… También he ido rediseñando los diferentes bots que he ido haciendo consiguiendo que fueran cada vez más versátiles y mantenibles.

Primeros pasos

Como ya he comentado antes, el lenguaje elegido para este bot es Python en su versión 3.5. Existen varias bibliotecas que nos ofrecen la posibilidad de realizar un bot, durante mucho tiempo he utilizado telepot y la recomiendo ya que, al menos en mi caso, no he tenido ningún problema y es muy sencilla de utilizar. Sin embargo estos últimos meses he estado utilizando python-telegram-bot y es la que voy a utilizar en este caso ya que me ha resultado más fácil de usar.

Una vez elegida la biblioteca, para instalarla se utiliza el siguiente comando:

  pip3 install python-telegram-bot

Como este es un bot muy sencillo, con un solo fichero será mas que suficiente, aunque es recomendable tener una estructura un poco mas compleja en caso de que nuestro bot crezca ya que eso lo hace mucho más mantenible.

Dicho esto, la estructura del bot será la siguiente:

telegram-bot/
└── main.py

Obtener un token para nuestro bot

Para que nuestro bot funcione, es necesario crearlo. Irónicamente el proceso de creación de un bot de telegram es llevado a cabo por un bot de telegram. Este bot se llama BotFather y los pasos para la creación son los siguientes:

Primero comenzamos una nueva conversación con el bot para ello le damos a /start

conversación botfather nada mas abrir el chat

Tras este paso, el bot nos mostrará una serie de opciones entre las cuales se encuentra la que nos interesa: /newbot.

conversación botfather tras ejecutar el comando /help

Siguiendo las instrucciones, le damos un nombre a nuestro bot:

conversación botfather nada más obtener el token del nuevo bot

Con esto nuestro bot ya esta creado, y el BotFather nos devuelve el token que necesitamos para que nuestro bot pueda acceder a los mensajes que le mandamos.

Objetivos del bot

Para este ejemplo, nuestro bot va a contar con tres comandos muy sencillos:

  • /start: Este comando es el que se ejecuta por defecto al entrar por primera vez en el bot y normalmente sirve para explicar a nuestro usuario como utilizar el bot.
  • /hello: Comando con el cual el bot devolverá un mensaje de saludo.
  • /add: Este comando sumara los numeros que se le pasen como parametro devolviendo el resultado en un mensaje. Ej. /add 1 2 3 nos devolverá 6

Tambíen contará el numero de palabras y de letras si le mandamos solamente texto

Manos a la obra

Manejadores de los mensajes

def start(bot, update):
    """ This function will be executed when '/start' command is received """
    message = "Welcome to the coolest bot ever!"
    bot.send_message(chat_id=update.message.chat_id, text=message)


def hello(bot, update):
    """ This function will be executed when '/hello' command is received """
    greeting = "Hi there, {}".format(update.effective_user.username)
    bot.send_message(chat_id=update.message.chat_id, text=greeting)


def add(bot, update, args):
    """ This function will be executed when '/add arg1, arg2, ...' command is received """

    # First converts the string list to a int list and then add all the elems
    result = sum(map(int, args))
    message = "The result is: {}".format(result)
    bot.send_message(chat_id=update.message.chat_id, text=message)


def plain_text(bot, update):
    """ This function will be executed when plain text message is received """
    text = update.message.text
    words_count = len(text.split())
    letters_count = len(''.join(text).replace(' ', ''))
    message = "Your message has {words} words and {letters} letters".format(
        words=words_count, letters=letters_count)
    bot.send_message(chat_id=update.message.chat_id,
                     parse_mode='markdown', text=message)

Estas funciones serán las que se ejecuten cuando el texto correspondiente llegue a nuestro bot. Pueden tener cualquier nombre, aunque es recomendable poner nombres descriptivos para que sea todo más legible. Lo que si que describe la biblioteca es que estas funciones, que hacen de manejadores, reciben como primer parámetro un objeto bot el cual se usa para interactuar con la api de telegram para mandar mensajes descargar archivos, subir archivos, etc… y como segundo parámetro un objeto update el cual contiene el mensaje.

Un caso especial es la funcion add que tiene un tercer parámetro con la lista de argumentos.

Función principal

def main(bot_token):
    """ Main function of the bot """
    updater = Updater(token=bot_token)
    dispatcher = updater.dispatcher

    # Command handlers
    start_handler = CommandHandler('start', start)
    hello_handler = CommandHandler('hello', hello)
    add_handler = CommandHandler('add', add, pass_args=True)

    # Other handlers
    plain_text_handler = MessageHandler(Filters.text, plain_text)

    # Add the handlers to the bot
    dispatcher.add_handler(start_handler)
    dispatcher.add_handler(hello_handler)
    dispatcher.add_handler(add_handler)
    dispatcher.add_handler(plain_text_handler)

    # Starting the bot
    updater.start_polling()

En la función principal se define un objeto updates que estará realizando peticiones a la api de telegram obteniendo todos los nuevos mensajes que lleguen al bot. Para ello se define utilizando el token obtenido con el BotFather.

También es donde le indicamos qué funciones tiene que ejecutar cuando lleguen los distintos tipos de mensajes.

Los CommandHandler definen manejadores para los comandos. El primer parámetro indica el texto del comando y el segundo parámetro indica la función a ejecutar cuando se le mande dicho comando. En caso de que el comando tenga parámetros, como el comando add se le indica mediante el parametro pass_args.

El MessageHandler define un manejador para diferentes tipos de mensajes. En este caso, el primer parametro indica que si llega texto plano, la funcion que se debe ejecutar sea plain_text. Existen diferentes tipos de mensajes en telegram y se indican mediante el objeto Filter. Los tipos de filtros en la documentación de la biblioteca.

Código completo de nuestro bot

from telegram.ext import Updater
from telegram.ext import CommandHandler
from telegram.ext import MessageHandler, Filters

def start(bot, update):
  """ This function will be executed when '/start' command is received """
  message = "Welcome to the coolest bot ever!"
  bot.send_message(chat_id=update.message.chat_id, text=message)


def hello(bot, update):
  """ This function will be executed when '/hello' command is received """
  greeting = "Hi there, {}".format(update.effective_user.username)
  bot.send_message(chat_id=update.message.chat_id, text=greeting)


def add(bot, update, args):
  """ This function will be executed when '/add arg1, arg2, ...' command is received """

  # First converts the string list to a int list and then add all the elems
  result = sum(map(int, args))
  message = "The result is: {}".format(result)
  bot.send_message(chat_id=update.message.chat_id, text=message)

def main(bot_token):
  """ Main function of the bot """
  updater = Updater(token=bot_token)
  dispatcher = updater.dispatcher

  # Command handlers
  start_handler = CommandHandler('start', start)
  hello_handler = CommandHandler('hello', hello)
  add_handler = CommandHandler('add', add, pass_args=True)

  # Other handlers
  plain_text_handler = MessageHandler(Filters.text, plain_text)

  # Add the handlers to the bot
  dispatcher.add_handler(start_handler)
  dispatcher.add_handler(hello_handler)
  dispatcher.add_handler(add_handler)
  dispatcher.add_handler(plain_text_handler)

  # Starting the bot
  updater.start_polling()

if __name__ == "__main__":
  TOKEN = "YOUR_TOKEN_HERE"
  main(TOKEN)

Categorías: Tutorial

0 commentarios

Deja un comentario

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