Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Este es el tercer artículo de la serie "Escribir un bot de Telegram en R". En publicaciones anteriores, aprendimos cómo crear un bot de Telegram, enviar mensajes a través de él, agregar comandos y filtros de mensajes al bot. Por lo tanto, antes de comenzar a leer este artículo, le recomiendo encarecidamente que lea anterior, porque Aquí ya no me detendré en los conceptos básicos de creación de bots descritos anteriormente.

En este artículo, mejoraremos la usabilidad de nuestro bot agregando un teclado, lo que hará que la interfaz del bot sea intuitiva y fácil de usar.

Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Todos los artículos de la serie "Escribir un bot de Telegram en R"

  1. Creamos un bot y lo usamos para enviar mensajes en Telegram.
  2. Agregue soporte de comandos y filtros de mensajes al bot
  3. Cómo agregar soporte de teclado a un bot

contenido

Si te interesa el análisis de datos, quizás te interese mi Telegram. и Youtube canales La mayor parte del contenido está dedicado al lenguaje R.

  1. ¿Qué tipos de teclados admite el bot de Telegram?
  2. Responder teclado
  3. Teclado en línea
    3.1. Un ejemplo de un bot simple compatible con botones InLine
    3.2. Un ejemplo de un bot que informa el clima actual de una ciudad seleccionada
    3.3. Un ejemplo de un bot que muestra una lista de los artículos más recientes con enlaces al Hub especificado desde habr.com
  4. Conclusión

¿Qué tipos de teclados admite el bot de Telegram?

Al momento de escribir telegram.bot le permite crear dos tipos de teclados:

  • Responder: el teclado principal normal, que se encuentra debajo del panel de entrada de texto del mensaje. Un teclado de este tipo simplemente envía un mensaje de texto al bot y, como texto, enviará el texto escrito en el botón.
  • En línea: teclado asociado con un mensaje de bot específico. Este teclado envía los datos del bot asociados con el botón presionado; estos datos pueden diferir del texto escrito en el botón mismo. Y esos botones se procesan a través de Controlador de consultas de devolución de llamada.

Para que el bot abra el teclado, es necesario al enviar un mensaje mediante el método sendMessage(), pasa el teclado creado previamente como argumento reply_markup.

A continuación veremos varios ejemplos.

Responder teclado

Como escribí anteriormente, este es el teclado principal de control del bot.

Un ejemplo de creación de un teclado de respuesta a partir de la ayuda oficial.

bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Create Custom Keyboard
text <- "Aren't those custom keyboards cool?"
RKM <- ReplyKeyboardMarkup(
  keyboard = list(
    list(KeyboardButton("Yes, they certainly are!")),
    list(KeyboardButton("I'm not quite sure")),
    list(KeyboardButton("No..."))
  ),
  resize_keyboard = FALSE,
  one_time_keyboard = TRUE
)

# Send Custom Keyboard
bot$sendMessage(chat_id, text, reply_markup = RKM)

Lo anterior es un ejemplo de la ayuda oficial del paquete. telegram.bot. Para crear un teclado, use la función ReplyKeyboardMarkup(), que a su vez toma una lista de listas de botones creados por la función KeyboardButton().

Porque en ReplyKeyboardMarkup() ¿Necesita pasar no sólo una lista, sino una lista de listas? El hecho es que pasas la lista principal y en ella defines cada fila de botones en listas separadas, porque Puedes colocar varios botones en una fila.

Argumento resize_keyboard le permite seleccionar automáticamente el tamaño óptimo de los botones del teclado y el argumento one_time_keyboard le permite ocultar el teclado después de presionar cada botón.

Escribamos un bot simple que tendrá 3 botones:

  • ID de chat: solicitar ID de chat del diálogo con el bot
  • Mi nombre - Solicita tu nombre
  • Mi inicio de sesión - Solicita tu nombre de usuario en telegram

Código 1: Bot simple con teclado de respuesta

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# создаём методы
## метод для запуска клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## метод возвразающий id чата
chat_id <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Чат id этого диалога: ", update$message$chat_id),
                  parse_mode = "Markdown")

}

## метод возвращающий имя
my_name <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Вас зовут ", update$message$from$first_name),
                  parse_mode = "Markdown")

}

## метод возвращающий логин
my_username <- function(bot, update) {

  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Ваш логин ", update$message$from$username),
                  parse_mode = "Markdown")

}

# создаём фильтры
## сообщения с текстом Чат ID
MessageFilters$chat_id <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Чат ID"

}
)

## сообщения с текстом Моё имя
MessageFilters$name <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Моё имя"

}
)

## сообщения с текстом Мой логин
MessageFilters$username <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Мой логин"
)

# создаём обработчики
h_start    <- CommandHandler('start', start)
h_chat_id  <- MessageHandler(chat_id, filters = MessageFilters$chat_id)
h_name     <- MessageHandler(my_name, filters = MessageFilters$name)
h_username <- MessageHandler(my_username, filters = MessageFilters$username)

# добавляем обработчики в диспетчер
updater <- updater + 
            h_start +
            h_chat_id +
            h_name +
            h_username

# запускаем бота 
updater$start_polling()

Ejecute el código de ejemplo anterior, después de reemplazar 'SU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotPadre (Hablé sobre la creación de un bot en primer artículo).

Después del lanzamiento, dale una orden al bot. /start, porque Esto es exactamente lo que definimos para iniciar el teclado.

Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Si en este momento le resulta difícil analizar el ejemplo de código dado, con la creación de métodos, filtros y controladores, entonces debería volver al anterior. статье, en el que describí todo esto en detalle.

Creamos 4 métodos:

  • inicio: inicia el teclado
  • chat_id — Solicitar ID de chat
  • my_name — Solicita tu nombre
  • my_username — Solicita tu inicio de sesión

Al objeto Filtros de mensajes Se agregaron 3 filtros de mensajes según su texto:

  • chat_id — Mensajes con texto "Чат ID"
  • nombre — Mensajes con texto "Моё имя"
  • nombre de usuario — Mensajes con texto "Мой логин"

Y creamos 4 controladores que, según los comandos y filtros dados, ejecutarán los métodos especificados.

# создаём обработчики
h_start    <- CommandHandler('start', start)
h_chat_id  <- MessageHandler(chat_id, filters = MessageFilters$chat_id)
h_name     <- MessageHandler(my_name, filters = MessageFilters$name)
h_username <- MessageHandler(my_username, filters = MessageFilters$username)

El teclado en sí se crea dentro del método. start() el equipo ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

En nuestro caso, colocamos todos los botones uno debajo del otro, pero podemos organizarlos en una fila realizando cambios en la lista de listas de botones. Porque una fila dentro del teclado se crea a través de una lista anidada de botones, luego, para mostrar nuestros botones en una fila, necesitamos reescribir parte del código para construir el teclado de esta manera:

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("Чат ID"),
          KeyboardButton("Моё имя"),
          KeyboardButton("Мой логин")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

El teclado se envía al chat mediante el método. sendMessage(), en el argumento reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

Teclado en línea

Como escribí anteriormente, el teclado en línea está vinculado a un mensaje específico. Es algo más difícil trabajar con él que con el teclado principal.

Inicialmente, debe agregar un método al bot para llamar al teclado en línea.

Para responder a un clic en un botón en línea, también puede utilizar el método bot answerCallbackQuery(), que puede mostrar una notificación en la interfaz de Telegram al usuario que presiona el botón Inline.

Los datos enviados desde el botón en línea no son texto, por lo que para procesarlos es necesario crear un controlador especial usando el comando CallbackQueryHandler().

El código para construir un teclado en línea que se proporciona en la ayuda oficial del paquete. telegram.bot.

Código para construir un teclado en línea de la ayuda oficial

# Initialize bot
bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"

# Create Inline Keyboard
text <- "Could you type their phone number, please?"
IKM <- InlineKeyboardMarkup(
  inline_keyboard = list(
    list(
      InlineKeyboardButton(1),
      InlineKeyboardButton(2),
      InlineKeyboardButton(3)
    ),
    list(
      InlineKeyboardButton(4),
      InlineKeyboardButton(5),
      InlineKeyboardButton(6)
    ),
    list(
      InlineKeyboardButton(7),
      InlineKeyboardButton(8),
      InlineKeyboardButton(9)
    ),
    list(
      InlineKeyboardButton("*"),
      InlineKeyboardButton(0),
      InlineKeyboardButton("#")
    )
  )
)

# Send Inline Keyboard
bot$sendMessage(chat_id, text, reply_markup = IKM)

Necesitas crear un teclado en línea usando el comando InlineKeyboardMarkup(), siguiendo el mismo principio que el teclado de respuesta. EN InlineKeyboardMarkup() es necesario pasar una lista de listas de botones en línea, cada botón individual es creado por la función InlineKeyboardButton().

Un botón en línea puede pasar algunos datos al bot usando un argumento callback_data, o abra cualquier página HTML especificada usando el argumento url.

El resultado será una lista en la que cada elemento es también una lista de botones en línea que deben combinarse en una fila.

A continuación veremos varios ejemplos de bots con botones en línea.

Un ejemplo de un bot simple compatible con botones InLine

Primero, escribiremos un bot para pruebas rápidas de covid-19. Por comando /test, te enviará un teclado con dos botones, dependiendo del botón presionado te enviará un mensaje con los resultados de tu prueba.

Código 2: el bot más simple con teclado en línea

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# метод для отправки InLine клавиатуры
test <- function(bot, update) {

  # создаём InLine клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Да", callback_data = 'yes'),
        InlineKeyboardButton("Нет", callback_data = 'no')
      )
    )
  )

  # Отправляем клавиатуру в чат
  bot$sendMessage(update$message$chat_id, 
                  text = "Вы болете коронавирусом?", 
                  reply_markup = IKM)
}

# метод для обработки нажатия кнопки
answer_cb <- function(bot, update) {

  # полученные данные с кнопки
  data <- update$callback_query$data

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  # обработка результата
  if ( data == 'no' ) {

    msg <- paste0(uname, ", поздравляю, ваш тест на covid-19 отрицательный.")

  } else {

    msg <- paste0(uname, ", к сожалени ваш тест на covid-19 положительный.")

  }

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём обработчики
inline_h      <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)

# добавляем обработчики в диспетчер
updater <- updater + inline_h + query_handler

# запускаем бота
updater$start_polling()

Ejecute el código de ejemplo anterior, después de reemplazar 'SU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotPadre (Hablé sobre la creación de un bot en primer artículo).

Resultado:
Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Creamos dos métodos:

  • test — Para enviar al chat Teclado en línea
  • respuesta_cb — Para procesar datos enviados desde el teclado.

Los datos que se enviarán desde cada botón se especifican en el argumento. callback_data, al crear un botón. Puede recibir los datos enviados desde el botón utilizando la construcción update$callback_query$data, dentro del método respuesta_cb.

Para que el bot reaccione al teclado en línea, método respuesta_cb procesado por un controlador especial: CallbackQueryHandler(answer_cb). Que ejecuta el método especificado cuando se hace clic en el botón Inline. Manipulador Controlador de consultas de devolución de llamada toma dos argumentos:

  • callback — El método que debe ejecutarse
  • pattern — Filtrar por datos vinculados al botón mediante un argumento callback_data.

En consecuencia, utilizando el argumento pattern Podemos escribir un método separado para presionar cada botón:

Código 3: métodos separados para cada botón en línea

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# метод для отправки InLine клавиатуры
test <- function(bot, update) {  

  # создаём InLine клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton("Да", callback_data = 'yes'),
        InlineKeyboardButton("Нет", callback_data = 'no')
      )
    )
  )

  # Отправляем клавиатуру в чат
  bot$sendMessage(update$message$chat_id, 
                  text = "Вы болете коронавирусом?", 
                  reply_markup = IKM)
}

# метод для обработки нажатия кнопки Да
answer_cb_yes <- function(bot, update) {

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  # обработка результата
  msg <- paste0(uname, ", к сожалени ваш текст на covid-19 положительный.")

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# метод для обработки нажатия кнопки Нет
answer_cb_no <- function(bot, update) {

  # получаем имя пользователя, нажавшего кнопку
  uname <- update$effective_user()$first_name

  msg <- paste0(uname, ", поздравляю, ваш текст на covid-19 отрицательный.")

  # Отправка сообщения
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text = msg)

  # сообщаем боту, что запрос с кнопки принят
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём обработчики
inline_h          <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

# добавляем обработчики в диспетчер
updater <- updater + 
            inline_h + 
            query_handler_yes +
            query_handler_no

# запускаем бота
updater$start_polling()

Ejecute el código de ejemplo anterior, después de reemplazar 'SU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotPadre (Hablé sobre la creación de un bot en primer artículo).

Ahora hemos escrito 2 métodos separados, es decir. un método, para cada pulsación de botón, y utilizó el argumento pattern, al crear sus controladores:

query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

El código del método termina respuesta_cb el equipo bot$answerCallbackQuery(callback_query_id = update$callback_query$id), que le indica al bot que se han recibido datos del teclado en línea.

Un ejemplo de un bot que informa el clima actual de una ciudad seleccionada

Intentemos escribir un bot que solicite datos meteorológicos.

La lógica de su trabajo será la siguiente. Inicialmente por el equipo /start llamas al teclado principal, que tiene solo un botón "Tiempo". Al hacer clic en este botón recibirás un mensaje con el teclado Inline para seleccionar la ciudad de la que deseas conocer el clima actual. Seleccione una de las ciudades y obtenga el clima actual.

En este ejemplo de código usaremos varios paquetes adicionales:

  • httr — un paquete para trabajar con solicitudes HTTP, a partir del cual se construye el trabajo con cualquier API. En nuestro caso usaremos la API gratuita. openweathermap.org.
  • stringr — un paquete para trabajar con texto, en nuestro caso lo usaremos para generar un mensaje sobre el clima en la ciudad seleccionada.

Código 4: un bot que informa el clima actual de la ciudad seleccionada

library(telegram.bot)
library(httr)
library(stringr)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# создаём методы
## метод для запуска основной клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Погода")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## Метод вызова Inine клавиатуры
weather <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'Москва', callback_data = 'New York,us'),
        InlineKeyboardButton(text = 'Санкт-Петербург', callback_data = 'Saint Petersburg'),
        InlineKeyboardButton(text = 'Нью-Йорк', callback_data = 'New York')
      ),
      list(
        InlineKeyboardButton(text = 'Екатеринбург', callback_data = 'Yekaterinburg,ru'),
        InlineKeyboardButton(text = 'Берлин', callback_data = 'Berlin,de'),
        InlineKeyboardButton(text = 'Париж', callback_data = 'Paris,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Рим', callback_data = 'Rome,it'),
        InlineKeyboardButton(text = 'Одесса', callback_data = 'Odessa,ua'),
        InlineKeyboardButton(text = 'Киев', callback_data = 'Kyiv,fr')
      ),
      list(
        InlineKeyboardButton(text = 'Токио', callback_data = 'Tokyo'),
        InlineKeyboardButton(text = 'Амстердам', callback_data = 'Amsterdam,nl'),
        InlineKeyboardButton(text = 'Вашингтон', callback_data = 'Washington,us')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите город", 
                  reply_markup = IKM)
}

# метод для сообщения погоды
answer_cb <- function(bot, update) {

  # получаем из сообщения город
  city <- update$callback_query$data

  # отправляем запрос
  ans <- GET('https://api.openweathermap.org/data/2.5/weather', 
             query = list(q     = city,
                          lang  = 'ru',
                          units = 'metric',
                          appid = '4776568ccea136ffe4cda9f1969af340')) 

  # парсим ответ
  result <- content(ans)

  # формируем сообщение
  msg <- str_glue("{result$name} погода:n",
                  "Текущая температура: {result$main$temp}n",
                  "Скорость ветра: {result$wind$speed}n",
                  "Описание: {result$weather[[1]]$description}")

  # отправляем информацию о погоде
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = msg)

  bot$answerCallbackQuery(callback_query_id = update$callback_query$id) 
}

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

# создаём обработчики
h_start         <- CommandHandler('start', start)
h_weather       <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)

# добавляем обработчики в диспетчер
updater <- updater + 
              h_start +
              h_weather +
              h_query_handler

# запускаем бота
updater$start_polling()

Ejecute el código de ejemplo anterior, después de reemplazar 'SU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotPadre (Hablé sobre la creación de un bot en primer artículo).

Como resultado, nuestro bot funcionará de la siguiente manera:
Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Esquemáticamente, este robot se puede representar así:
Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Hemos creado 3 métodos disponibles dentro de nuestro bot meteorológico:

  • comienzo — Inicie el teclado del bot principal
  • tiempo — Inicie el teclado en línea para seleccionar una ciudad
  • respuesta_cb — El método principal que solicita el clima de la API para una ciudad determinada y lo envía al chat.

método comienzo lo lanzamos con el comando /start, que es implementado por el controlador CommandHandler('start', start).

Para ejecutar un método tiempo Creamos un filtro con el mismo nombre:

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

Y llamamos a este método con el siguiente controlador de mensajes: MessageHandler(weather, filters = MessageFilters$weather).

Y al final, nuestro método principal. respuesta_cb reacciona al presionar botones en línea, que se implementa mediante un controlador especial: CallbackQueryHandler(answer_cb).

Dentro de un método respuesta_cb, leemos los datos enviados desde el teclado y los escribimos en una variable city: city <- update$callback_query$data. Luego solicitamos datos meteorológicos de la API, generamos y enviamos un mensaje y finalmente usamos el método answerCallbackQuery para informar al bot que procesamos el clic del botón Inline.

Un ejemplo de un bot que muestra una lista de los últimos artículos con enlaces al Hub especificado desde habr.com.

Les presento este bot para mostrarles cómo mostrar botones en línea que conducen a páginas web.

La lógica de este bot es similar al anterior, inicialmente lanzamos el teclado principal con el comando /start. A continuación, el bot nos da una lista de 6 hubs para elegir, seleccionamos el hub que nos interesa y recibimos las 5 publicaciones más recientes del Hub seleccionado.

Como comprenderá, en este caso necesitamos obtener una lista de artículos, y para ello usaremos un paquete especial. habR, que permite solicitar artículos de Habra y algunas estadísticas sobre ellos en R.

Paquete de instalación habR solo es posible desde github, para lo cual necesitarás un paquete adicional devtools. Para instalar, utilice el siguiente código.

install.packages('devtools')
devtools::install_github('selesnow/habR')

Ahora veamos el código para construir el bot descrito anteriormente:

Código 5: un bot que muestra una lista de los artículos más recientes en el Hub seleccionado

library(telegram.bot)
library(habR)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# создаём методы
## метод для запуска основной клавиатуры
start <- function(bot, update) {

  # создаём клавиатуру
  RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
        KeyboardButton("Список статей")
      )
    ),
    resize_keyboard = TRUE,
    one_time_keyboard = TRUE
  )

  # отправляем клавиатуру
  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

}

## Метод вызова Inine клавиатуры
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'R'),
        InlineKeyboardButton(text = 'Data Mining', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Data Engineering', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Big Data', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Визуализация данных', callback_data = 'data_visualization')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите Хаб", 
                  reply_markup = IKM)
}

# метод для сообщения погоды
answer_cb <- function(bot, update) {

  # получаем из сообщения город
  hub <- update$callback_query$data

  # сообщение о том, что данные по кнопке получены
  bot$answerCallbackQuery(callback_query_id = update$callback_query$id, 
                          text = 'Подождите несколько минут, запрос обрабатывается') 

  # сообщение о том, что надо подождать пока бот получит данные
  mid <- bot$sendMessage(chat_id = update$from_chat_id(),
                         text    = "Подождите несколько минут пока, я соберу данные по выбранному Хабу")

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

  # удаляем сообщение о том, что надо подождать
  bot$deleteMessage(update$from_chat_id(), mid$message_id) 

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

  # отправляем информацию о погоде
  bot$sendMessage(chat_id = update$from_chat_id(),
                  text    = paste0("5 наиболее свежих статей из Хаба ", hub),
                  reply_markup = IKM)

}

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$hubs <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Список статей"

}
)

# создаём обработчики
h_start         <- CommandHandler('start', start)
h_hubs          <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)

# добавляем обработчики в диспетчер
updater <- updater + 
  h_start +
  h_hubs  +
  h_query_handler

# запускаем бота
updater$start_polling()

Ejecute el código de ejemplo anterior, después de reemplazar 'SU TOKEN DE BOT' con el token real que recibió al crear el bot a través de BotPadre (Hablé sobre la creación de un bot en primer artículo).

Como resultado, obtendremos este resultado:
Escribiendo un bot de Telegram en R (parte 3): Cómo agregar soporte de teclado a un bot

Codificamos la lista de Hubs disponibles para su selección en el método habs:

## Метод вызова Inine клавиатуры
habs <- function(bot, update) {

  IKM <- InlineKeyboardMarkup(
    inline_keyboard = list(
      list(
        InlineKeyboardButton(text = 'R', callback_data = 'r'),
        InlineKeyboardButton(text = 'Data Mining', callback_data = 'data_mining'),
        InlineKeyboardButton(text = 'Data Engineering', callback_data = 'data_engineering')
      ),
      list(
        InlineKeyboardButton(text = 'Big Data', callback_data = 'bigdata'),
        InlineKeyboardButton(text = 'Python', callback_data = 'python'),
        InlineKeyboardButton(text = 'Визуализация данных', callback_data = 'data_visualization')
      )
    )
  )

  # Send Inline Keyboard
  bot$sendMessage(chat_id = update$message$chat_id, 
                  text = "Выберите Хаб", 
                  reply_markup = IKM)
}

Obtenemos una lista de artículos del Hub especificado con el comando habr_hub_posts(), del paquete habR. Al mismo tiempo, señalamos que no necesitamos una lista de artículos para todo el tiempo, sino solo la primera página en la que se encuentran 20 artículos. De la tabla resultante usando el comando head() Dejamos sólo el top 5, que son los artículos más recientes.

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

La lógica es muy similar al bot anterior, pero en este caso generamos un teclado Inline con una lista de artículos de forma dinámica usando la función lapply().

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

Insertamos el título del artículo en el texto del botón. posts$title[x], y en el argumento url enlace al artículo: url = posts$link[x].

A continuación, creamos un filtro, controladores y lanzamos nuestro bot.

Conclusión

Ahora los bots que escribas serán mucho más cómodos de usar, debido a que se controlarán desde el teclado, en lugar de ingresar comandos. Como mínimo, al interactuar con un bot a través de un teléfono inteligente, el teclado simplificará significativamente el proceso de uso.

En el próximo artículo, descubriremos cómo construir un diálogo lógico con un bot y trabajar con bases de datos.

Fuente: habr.com

Añadir un comentario