Escribiendo un bot de telegram en el lenguaje R (parte 2): Agregando soporte para comandos y filtros de mensajes

En publicación anterior hemos aprendido a crear un bot, inicializamos una instancia de la clase Bot y nos familiarizamos con los métodos de envío de mensajes utilizando este.

En este artículo continúo con este tema, por lo que recomiendo leer este artículo solo después de haber leído parte anterior.

Esta vez entenderemos cómo dar vida a nuestro bot y agregaremos soporte para comandos, así como también conoceremos la clase Updater.

A lo largo del artículo escribiremos varios bots simples, el último de los cuales determinará si un día en un país dado es festivo o laboral según el calendario laboral, a partir de una fecha y un código de país. Pero, como antes, el objetivo del artículo es familiarizarte con la interfaz del paquete telegram.bot para resolver tus propias tareas.

Escribiendo un bot de telegram en el lenguaje R (parte 2): Agregando soporte para comandos y filtros de mensajes

Creamos un bot y enviamos mensajes a telegram a través de él

  1. Añadimos soporte de comandos y filtros de mensajes al bot
  2. Cómo agregar soporte de teclado al bot

Contenido

canales de youtube. La mayor parte del contenido está dedicado al lenguaje R. telegram y Proceso de construcción del bot Estructura del proyecto del bot

  1. La clase Updater
  2. Handlers — manejadores
  3. Agregamos el primer comando al bot, manejador de comandos
  4. Manejador de mensajes de texto y filtros
  5. Adición de comandos con parámetros
  6. Ejecutamos el bot en segundo plano
  7. Conclusión

La clase Updater

Updater — es una clase que simplifica el desarrollo de un bot de Telegram, y utiliza bajo el capó la clase Dispatcher. La finalidad de la clase Updater consiste en obtener actualizaciones del bot (en el artículo anterior utilizamos para este propósito el método getUpdates()), y transferirlas a Dispatcher.

Por su parte, Dispatcher contiene los manejadores que has creado, es decir, objetos de la clase Handler.

Handlers — manejadores

Con los manejadores, agregas Dispatcher reacciones del bot a varios eventos. Al momento de escribir este artículo, se han agregado los siguientes tipos de manejadores: telegram.bot MessageHandler — Manejador de mensajes

  • CommandHandler — Manejador de comandos
  • CallbackQueryHandler — Manejador de datos enviados desde teclados en línea
  • ErrorHandler — Manejador de errores al solicitar actualizaciones del bot
  • Si nunca antes has utilizado bots y no sabes qué es un comando, entonces los comandos deben enviarse al bot con una barra diagonal directa

Agregamos el primer comando al bot, manejador de comandos

como prefijo. / Comenzaremos con comandos simples, es decir, enseñaremos a nuestro bot a saludar con el comando

Código 1: Enseñamos al bot a saludar /hi.

Código 1: Enseñamos al bot a saludar

library(telegram.bot)

# Creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE SU BOT')

# Escribimos un método para el saludo
say_hello <- function(bot, update) {

  # Nombre de usuario con el que hay que saludar
  user_name <- update$message$from$first_name

  # Envío del mensaje de bienvenida
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("¡Saludos, ", user_name, "!"), 
                  parse_mode = "Markdown")

}

# Creamos el manejador
hi_hendler <- CommandHandler('hi', say_hello)

# Añadimos el manejador al despachador
updater <- updater + hi_hendler

# Iniciamos el bot
updater$start_polling()

Ejecute el ejemplo de código anterior, reemplazando 'TU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotFather (sobre la creación del bot hablé en primer artículo).

El método start_polling() de la clase Updater, que se utiliza al final del código, inicia un ciclo infinito de solicitud y procesamiento de actualizaciones del bot.

Ahora abramos Telegram y escribamos nuestro primer comando a nuestro bot /hi.

Escribiendo un bot de telegram en el lenguaje R (parte 2): Agregando soporte para comandos y filtros de mensajes

Ahora nuestro bot entiende el comando /hi, y sabe cómo saludarnos.

Esquemáticamente, el proceso de construcción de este bot más simple se puede representar de la siguiente manera.

Escribiendo un bot de telegram en el lenguaje R (parte 2): Agregando soporte para comandos y filtros de mensajes

  1. Creamos una instancia de la clase Updater;
  2. Creamos métodos, es decir, funciones que nuestro bot ejecutará. En el ejemplo de código, esta es la función say_hello(). Las funciones que usarás como métodos del bot deben tener dos argumentos obligatorios — ) de todos los bots de Telegram deben terminar con la palabra y update, y uno opcional — args. El argumento ) de todos los bots de Telegram deben terminar con la palabra, este es tu bot, con el que puedes responder a mensajes, enviar mensajes o usar cualquier otro método disponible para el bot. El argumento update es lo que el bot recibió del usuario, esencialmente, lo que en el primer artículo obtuvimos con el método getUpdates(). El argumento args te permite procesar datos adicionales enviados por el usuario junto con el comando, sobre este tema volveremos un poco más tarde;
  3. Creamos manejadores, es decir, vinculamos algunas acciones del usuario con los métodos creados en el paso anterior. En esencia, un manejador es un activador, un evento que llama a una función del bot. En nuestro ejemplo, ese activador es el envío del comando /hi, y se implementa con el comando hi_hendler <- CommandHandler('hi', say_hello). El primer argumento de la función CommandHandler() te permite establecer el comando, en nuestro caso hi, al que el bot va a reaccionar. El segundo argumento permite especificar el método del bot, llamaremos al método say_hello, que se ejecutará si el usuario invoca el comando indicado en el primer argumento;
  4. A continuación, añadimos el manejador creado al despachador de nuestra instancia de clase Updater. Se pueden agregar controladores de varias maneras, en el ejemplo anterior usé la más simple, con el signo +, es decir, updater <- updater + hi_handler. Lo mismo se puede hacer con el método add_handler(), que pertenece a la clase Dispatcher, este método se puede encontrar así: updater$dispatcher$add_handler();
  5. Iniciamos el bot con el comando start_polling().

Manejador de mensajes de texto y filtros

Hemos aprendido a enviar comandos al bot, pero a veces necesitamos que el bot reaccione no solo a comandos, sino también a algunos mensajes de texto comunes. Para esto, es necesario utilizar controladores de mensajes — MessageHandler.

Modo normal MessageHandler reaccionará a todos los mensajes entrantes. Por lo tanto, a menudo se utilizan controladores de mensajes junto con filtros. Aprendamos a hacer que el bot salude no solo por comando /hi, sino siempre que en el mensaje enviado al bot aparezca una de las siguientes palabras: hola, saludos, saludo, hey, bonjour.

Por ahora no escribiremos nuevos métodos, ya que ya tenemos un método con el que el bot nos saluda. Solo necesitamos crear el filtro necesario y el controlador de mensajes.

Código 2: Agregamos un controlador para mensajes de texto y un filtro

library(telegram.bot)

# creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE SU BOT')

# Escribimos el método para el saludo
## comando de saludo
say_hello <- function(bot, update) {

  # Nombre de usuario con el que se debe saludar
  user_name <- update$message$from$first_name

  # Enviamos un mensaje de saludo
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("¡Mis respetos, ", user_name, "!"),
                  parse_mode = "Markdown",
                  reply_to_message_id = update$message$message_id)

}

# creamos filtros
MessageFilters$hi <- BaseFilter(function(message) {

  # verificamos si en el texto del mensaje aparecen las palabras: hola, saludos, saludo, hey, bonjour
  grepl(x           = message$text, 
        pattern     = 'hola|saludos|saludo|hey|bonjour',
        ignore.case = TRUE)
  }
)

# creamos el controlador
hi_hendler <- CommandHandler('hi', say_hello) # controlador del comando hi
hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)

# agregamos los controladores al despachador
updater <- updater + 
             hi_hendler +
             hi_txt_hnd

# iniciamos el bot
updater$start_polling()

Ejecute el ejemplo de código anterior, reemplazando 'TU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotFather (sobre la creación del bot hablé en primer artículo).

Ahora intentemos enviarle al bot varios mensajes que contengan las palabras de saludo mencionadas anteriormente:
Escribiendo un bot de telegram en el lenguaje R (parte 2): Agregando soporte para comandos y filtros de mensajes

Así que, en primer lugar, hemos enseñado al bot no solo a saludar, sino a responder al saludo. Esto lo hicimos utilizando el argumento reply_to_message_id, que está disponible en el método sendMessage(), al que debe pasar el id del mensaje al que desea responder. Puede obtener el id del mensaje así: update$message$message_id.

Pero lo más importante que hicimos fue agregarle un filtro al bot utilizando la función BaseFilter():

# создаём фильтры
MessageFilters$hi <- BaseFilter( 

  # анонимная фильтрующая функция
  function(message) {

    # проверяем, встречается ли в тексте сообщения слова приветствия
    grepl(x           = message$text, 
          pattern     = 'привет|здравствуй|салют|хай|бонжур',
          ignore.case = TRUE)
  }

)

Como habrán notado, los filtros deben agregarse al objeto MessageFilters, que inicialmente ya tiene un pequeño conjunto de filtros listos. En nuestro ejemplo, en el objeto MessageFilters agregamos el elemento hi, este es un nuevo filtro.

En la función BaseFilter() debe pasarle una función de filtrado. En esencia, un filtro es simplemente una función que recibe una instancia del mensaje y devuelve VERDADERO o FALSO. En nuestro ejemplo, escribimos una función simple que utiliza la función básica grepl() para verificar el texto del mensaje, y si coincide con la expresión regular hola|saludos|salu2|hi|bonjour devuelve VERDADERO.

A continuación, creamos un controlador de mensajes hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). El primer argumento de la función MessageHandler() es el método que llamará al controlador, y el segundo argumento es el filtro que utilizará para invocarlo. En nuestro caso, este es el filtro que creamos MessageFilters$hi.

Y al final, agregamos al despachador el controlador que acabamos de crear hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Como ya mencioné anteriormente, en el paquete telegram.bot y el objeto MessageFilters ya hay un conjunto de filtros integrados que puede usar:

  • all — Todos los mensajes
  • text — Mensajes de texto
  • command — Comandos, es decir, mensajes que comienzan con /
  • reply — Mensajes que son respuesta a otro mensaje
  • audio — Mensajes que contienen un archivo de audio
  • document — Mensajes con un documento enviado
  • photo — Mensajes con imágenes enviadas
  • sticker — Mensajes con un sticker enviado
  • video — Mensajes con video
  • voice — Mensajes de voz
  • contact — Mensajes que contienen el contacto de un usuario de Telegram
  • location — Mensajes con geolocalización
  • venue — Mensajes reenviados
  • game — Juegos

Si desea combinar algunos filtros en un solo controlador, simplemente use el signo | — como lógico OR, y el signo & como lógico Y. Por ejemplo, si desea que el bot llame al mismo método cuando recibe un video, imagen o documento, use el siguiente ejemplo para crear un controlador de mensajes:

handler <- MessageHandler(callback, 
  MessageFilters$video | MessageFilters$photo | MessageFilters$document
)

Adición de comandos con parámetros

Ya sabemos lo que son los comandos, cómo crearlos y cómo hacer que el bot ejecute el comando correcto. Pero en algunos casos, además del nombre del comando, necesitamos proporcionar algunos datos para su ejecución.

A continuación se muestra un ejemplo de un bot que, según la fecha y el país proporcionados, te devuelve el tipo de día del calendario laboral.

El bot que se muestra a continuación utiliza la API del calendario laboral. isdayoff.ru.

Código 3: Bot que informa sobre la fecha y el país.

library(telegram.bot)

# Creamos una instancia de la clase Updater
updater <- Updater('1165649194:AAFkDqIzQ6Wq5GV0YU7PmEZcv1gmWIFIB_8')

# Escribimos un método para el saludo
## comando de saludo
check_date <- function(bot, update, args) {

  # Datos de entrada
  day     <- args[1]  # fecha
  country <- args[2]  # país

  # Verificación de los parámetros ingresados
  if ( !grepl('\d{4}-\d{2}-\d{2}', day) ) {

    # Enviar teclado personalizado
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(day, " - fecha incorrecta, ingresa la fecha en el formato AAAA-MM-DD"),
                    parse_mode = "Markdown")

  } else {
    day <- as.Date(day)
    # Convertir a formato POSIXtl
    y <- format(day, "%Y")
    m <- format(day, "%m")
    d <- format(day, "%d")

  }

  # País para verificación
  ## Verificamos si se ha especificado el país
  ## si no se ha especificado, establecemos ru
  if ( ! country %in% c('ru', 'ua', 'by', 'kz', 'us') ) {

    # Enviar teclado personalizado
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(country, " - código de país incorrecto, valores posibles: ru, by, kz, ua, us. Se han solicitado datos para Rusia."),
                    parse_mode = "Markdown")

    country <- 'ru'

  }

  # Solicitud de datos de la API
  # Composición de la solicitud HTTP
  url <- paste0("https://isdayoff.ru/api/getdata?",
                "year=",  y, "&",
                "month=", m, "&",
                "day=",   d, "&",
                "cc=",    country, "&",
                "pre=1&",
                "covid=1")

  # Obtenemos la respuesta
  res <- readLines(url)

  # Interpretación de la respuesta
  out <- switch(res, 
                "0"   = "Día laborable",
                "1"   = "Día no laborable",
                "2"   = "Día laborable reducido",
                "4"   = "covid-19",
                "100" = "Error en la fecha",
                "101" = "Datos no encontrados",
                "199" = "Error del servicio")

  # Enviamos el mensaje
  bot$sendMessage(update$message$chat_id, 
                  text = paste0(day, " - ", out),
                  parse_mode = "Markdown")

}

# Creamos un manejador
date_hendler <- CommandHandler('check_date', check_date, pass_args = TRUE)

# Añadimos el manejador al despachador
updater <- updater + date_hendler

# Iniciamos el bot
updater$start_polling()

Ejecute el ejemplo de código anterior, reemplazando 'TU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotFather (sobre la creación del bot hablé en primer artículo).

Hemos creado un bot que tiene un solo método en su arsenal. check_date, este método se invoca con el comando homónimo.

Sin embargo, además del nombre del comando, este método espera que ingreses dos parámetros: el código del país y la fecha. Luego, el bot verifica si el día especificado en el país indicado es un día festivo, un día corto o un día laboral según el calendario laboral oficial.

Para que el método que estamos creando acepte parámetros adicionales junto con el comando, utiliza el argumento pass_args = TRUE en la función CommandHandler(), y al crear el método, además de los argumentos obligatorios, ) de todos los bots de Telegram deben terminar con la palabra, update crea uno opcional — args. Un método creado de esta manera aceptará los parámetros que le pases al bot después del nombre del comando. Los parámetros deben separarse por un espacio, y llegarán al método en forma de vector de texto.

Vamos a ejecutar y probar nuestro bot.

Escribiendo un bot de telegram en el lenguaje R (parte 2): Agregando soporte para comandos y filtros de mensajes

Ejecutamos el bot en segundo plano

El último paso que nos queda es ejecutar el bot en segundo plano.

Para ello, sigue el algoritmo que se detalla a continuación:

  1. Guarda el código del bot en un archivo con la extensión R. Al trabajar en RStudio, esto se hace a través del menú Archivo, con el comando Guardar como….
  2. Agrega la ruta a la carpeta bin, que a su vez se encuentra en la carpeta en la que instalaste el lenguaje R a la variable Path, la instrucción aquí.
  3. Crea un archivo de texto normal en el que escribas una línea: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. En lugar de C:UsersAlseyDocumentsmy_bot.R escribe la ruta a tu script del bot. Es importante que en la ruta no haya caracteres en cirílico ni espacios, ya que esto puede causar problemas al ejecutar el bot. Guárdalo y cambia su extensión de txt en bat.
  4. Abre el Programador de tareas de Windows, hay varias formas de hacerlo, por ejemplo, abre cualquier carpeta y en la dirección escribe %windir%system32taskschd.msc /s. Puedes encontrar otras formas de iniciarlo aquí.
  5. En la parte superior derecha del Programador, haz clic en "Crear tarea…".
  6. En la pestaña "General", asigna un nombre arbitrario a tu tarea y cambia el interruptor a la posición "Ejecutar para todos los usuarios".
  7. Ve a la pestaña "Acciones", haz clic en "Crear". En el campo "Programa o script", haz clic en "Examinar", busca el archivo creado en el segundo paso bat , y haz clic en Aceptar.
  8. Hacemos clic en Aceptar, y si es necesario, ingresamos la contraseña de tu cuenta de sistema operativo.
  9. Encontramos la tarea creada en el programador, la seleccionamos y en la parte inferior derecha presionamos el botón "Ejecutar".

Nuestro bot está en funcionamiento en segundo plano y seguirá trabajando hasta que detengas la tarea o apagues tu PC o servidor en el que lo ejecutaste.

Conclusión

En este artículo, hemos aprendido a escribir un bot completo que no solo puede enviar mensajes, sino también reaccionar a los mensajes de entrada y comandos. Los conocimientos adquiridos ya son suficientes para resolver la mayoría de tus tareas.

En el próximo artículo, hablaremos sobre cómo agregar un teclado al bot para un trabajo más cómodo.

Suscríbete a mi telegram y Proceso de construcción del bot canales.

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster