12/04/2017: He actualizado el tutorial a la nueva versión de la API.

En la primera parte del tutorial aprendimos cómo crear un bot de lo más sencillo que respondía a comandos como holamundo logo y nos mandaba respuestas según dichos comandos. Sin embargo por aquel entonces Telegram aún no había presentado la nueva modalidad de bots llamados bots inline que permiten ser llamados desde cualquier conversación (ya sea grupo o no) sin necesidad de añadirlos ni de hablar directamente con ellos, sino simplemente mencionándolos introduciendo un texto y el bot nos respondería con dicho texto bajo la modificación que haya hecho. Por ejemplo, así responde el bot @bold cuando le llamamos desde una conversación:

Captura de pantalla 2016-05-03 a las 13.05.44

Y cuando pulsamos en alguna de las opciones (en este caso en «Bold») se muestra así en la conversación:

Captura de pantalla 2016-05-03 a las 13.05.53

De este modo nos permiten un modo totalmente nuevo de interactuar con los bots ya que podemos enviar su contenido desde cualquier conversación. Precisamente sobre esto irá esta segunda parte del tutorial, ya que os enseñaré a cómo, partiendo del bot que creamos en la primera parte, añadirle la función inline para que salude al usuario con el texto que haya añadido, tal que así:Captura de pantalla 2016-05-03 a las 13.09.25Y cuando pulsamos en cualquiera de las opciones se manda desde nuestro bot a la conversación en la que estemos:

Captura de pantalla 2016-05-03 a las 13.09.33

Como veréis dentro de escasos momentos el procedimiento para lograr esto es de lo más sencillo con la API de Python que os comentaba en la primera parte. Por tanto, ¡vamos allá!

Requisitos

Puesto que vamos a expandir el bot que creamos en la primera parte es recomendable que ya la hayáis leído y realizado todos los pasos que se indican.

Añadiendo la funcionalidad inline

Antes de ponernos a tocar código necesitaremos primero añadir la funcionalidad inline en BotFather para que nuestro bot pueda ser llamado desde cualquier conversación. Para ello, abriremos de nuevo nuestra conversación con @BotFather y pondremos el comando /setinline. Nos preguntará por qué bot así que seleccionamos el que queramos (en mi caso @BytelixPruebaBot) y después ponemos el texto que queremos que se muestre cuando llamemos al bot desde una conversación:

Captura de pantalla 2016-05-03 a las 12.16.56

Con esto ya lo tenemos configurado para poder responder a peticiones inline, así que vamos a programar a nuestro bot para poder aceptarlas.

Respondiendo a peticiones inline

Para realizar este tipo de peticiones necesitaremos primero añadir un par de librerías necesarias, así que justo después de la que ya añadimos en la primera parte ponemos estas dos:

# Importamos las librerías necesarias
from telegram.ext import Updater, MessageHandler, CommandHandler, InlineQueryHandler, Filters
from telegram import InlineQueryResultArticle, InputTextMessageContent
# Esta librería no es estrictamente necesaria, pero es útil para generar números aleatorios
# que necesitamos al generar el id del inline
from random import getrandbits

Como he puesto en los comentarios de código la segunda no es estrictamente necesaria, pero sí muy útil en el siguiente trozo de código que veréis.

Ahora ya podemos ponernos manos a la obra con nuestro método que se encargará de responder a las peticiones inline, para ello he creado un método llamado inline (muy original, lo sé), que toma dos argumentos: bot update, al igual que todos los métodos que hemos creado hasta ahora.

Todo el proceso se realiza con los objetos InlineQueryResultArticle, los cuales representan las respuestas que habéis visto más arriba cuando llamamos a algún bot desde una conversación. En el ejemplo que os muestro le pasamos un id, título texto. El id lo calculamos con un random (de ahí la librería que os hablaba anteriormente) y el título y texto simplemente es lo creado en alternativax_texto, en el cual hemos puesto una frase junto con el texto que hemos recibido del usuario.

# Método que responderá a las peticiones inline
def inline(bot, update):
    # Sólo procesaremos el inline cuando haya algún texto introducido
    query = update.inline_query.query

    if not query:
        return

    texto_inline = query
    resultados = list()

    # Texto que se enviará y se mostrará al usuario
    alternativa1_texto = 'Hola desde el bot de Bytelix, ' + texto_inline
    alternativa2_texto = 'Bienvenido, ' + texto_inline
    alternativa3_texto = '¿Conoces Bytelix, ' + texto_inline + '?'

    # Resultados que se mostrarán para elegir
    alternativa1 = InlineQueryResultArticle(
        id=hex(getrandbits(64))[2:],
        title=alternativa1_texto,
        input_message_content=InputTextMessageContent(alternativa1_texto))

    alternativa2 = InlineQueryResultArticle(
        id=hex(getrandbits(64))[2:],
        title=alternativa2_texto,
        input_message_content=InputTextMessageContent(alternativa2_texto))

    alternativa3 = InlineQueryResultArticle(
        id=hex(getrandbits(64))[2:],
        title=alternativa3_texto,
        input_message_content=InputTextMessageContent(alternativa3_texto))

    # Añadimos los resultados que hemos creado a la lista de resultados
    resultados.append(alternativa1)
    resultados.append(alternativa2)
    resultados.append(alternativa3)

    # Y mostramos la lista al usuario
    bot.answerInlineQuery(update.inline_query.id, results=resultados)

Finalmente todos estos objetos los hemos añadido a una lista, la cual es la que tenemos que pasar al bot mediante el método answerInlineQuery para que este lo muestre al usuario. Cuando el usuario seleccione alguna de las opciones que se le muestren, en la conversación en la que se encuentre actualmente se enviará el contenido de message_text que hemos puesto anteriormente, concretamente el correspondiente al que haya seleccionado el usuario.

Finalmente, registramos este método para las peticiones inline en el método main que creamos en la primera parte, justo después de la de los comandos:

# Registramos también el modo inline
dispatcher.add_handler(InlineQueryHandler(inline))

Con esto nuestro bot ya debería responder a estas peticiones y podemos probarlo libremente. De nuevo pulsamos en Run:

Bot

Nos vamos a cualquier conversación y ponemos el alias de nuestro bot seguido de un nombre, por ejemplo: @BytelixPruebaBot señor. Nos saldrá este menú en el que podremos seleccionar la respuesta y se enviará:

Captura de pantalla 2016-05-03 a las 13.28.18

¡Y listo!

Con estos simples pasos, como veis, tenemos ya a nuestros bot disponible desde cualquier conversación. Aunque por supuesto esto es sólo una muestra de lo que la API puede hacer, ya que no sólo podéis mandar texto sino también imágenes, pero eso ya nos queda para otra entrega del tutorial.

De nuevo, si tenéis cualquier duda o problema podéis ponerla en los comentarios e intentaré ayudaros con lo que pueda.

Código completo del bot