Este es el tercer artículo de la serie "Escribiendo un bot de Telegram en R". En las publicaciones anteriores, aprendimos a crear un bot de Telegram, a enviarle mensajes, añadimos comandos y filtros de mensajes. Por lo tanto, antes de comenzar a leer este artículo, recomiendo encarecidamente familiarizarse con , ya que aquí no me detendré en los fundamentos del desarrollo de bots que se describieron anteriormente.
En este artículo mejoraremos la usabilidad de nuestro bot mediante la adición de un teclado que hará que la interfaz del bot sea intuitiva y fácil de usar.

Creamos un bot y enviamos mensajes a telegram a través de él
Contenido
canales de youtube. La mayor parte del contenido está dedicado al lenguaje R. y Estructura del proyecto del bot
3.1.
3.2.
3.3.
Qué tipos de teclados soporta un bot de Telegram
En el momento de escribir este artículo telegram.bot te permite crear teclados de dos tipos:
- Reply — Teclado principal, que se encuentra debajo de la barra de entrada de texto del mensaje. Este teclado simplemente envía un mensaje de texto al bot, y como texto enviará lo que está escrito en el botón.
- Inline — Teclado vinculado a un mensaje específico del bot. Este teclado envía al bot datos relacionados con el botón presionado, los cuales pueden diferir del texto escrito en el botón. Y tales botones se procesan a través de CallbackQueryHandler.
Para que el bot abra el teclado, es necesario, al enviar un mensaje a través del método sendMessage(), pasar el teclado creado anteriormente como argumento reply_markup.
A continuación, analizaremos varios ejemplos.
Teclado de respuesta
Como mencioné anteriormente, este es el teclado principal de control del bot.
Ejemplo de creación de un teclado de respuesta de la documentación oficial
bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"
# Crear Teclado Personalizado
text <- "¿No son geniales esos teclados personalizados?"
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton("¡Sí, ciertamente lo son!")),
list(KeyboardButton("No estoy muy seguro")),
list(KeyboardButton("No..."))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
# Enviar Teclado Personalizado
bot$sendMessage(chat_id, text, reply_markup = RKM)El ejemplo anterior es de la documentación oficial del paquete telegram.bot. Para crear un teclado se utiliza la función ReplyKeyboardMarkup(), que a su vez acepta una lista de listas de botones, que se crean con la función KeyboardButton().
Por qué en ReplyKeyboardMarkup() ¿Es necesario enviar no solo una lista, sino una lista de listas? La cuestión es que envía una lista principal, y en ella, como listas separadas, se definen cada una de las filas de botones, ya que se pueden colocar varios botones en una fila.
El argumento resize_keyboard permite ajustar automáticamente el tamaño óptimo de los botones del teclado, y el argumento one_time_keyboard permite ocultar el teclado después de cada pulsación en un botón.
Escribamos un bot simple que tendrá 3 botones:
- Chat ID - Solicitar el chat ID del diálogo con el bot
- Mi nombre - Solicitar mi nombre
- Mi usuario - Solicitar mi nombre de usuario en Telegram
Código 1: Bot simple con teclado de respuesta
library(telegram.bot)
# Creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE SU BOT')
# Creamos métodos
## Método para lanzar el teclado
start <- function(bot, update) {
# Creamos el teclado
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton("Chat ID")),
list(KeyboardButton("Mi nombre")),
list(KeyboardButton("Mi usuario"))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
# Enviamos el teclado
bot$sendMessage(update$message$chat_id,
text = 'Seleccione un comando',
reply_markup = RKM)
}
## Método que devuelve el id del chat
chat_id <- function(bot, update) {
bot$sendMessage(update$message$chat_id,
text = paste0("El id del chat de este diálogo: ", update$message$chat_id),
parse_mode = "Markdown")
}
## Método que devuelve el nombre
my_name <- function(bot, update) {
bot$sendMessage(update$message$chat_id,
text = paste0("Su nombre es ", update$message$from$first_name),
parse_mode = "Markdown")
}
## Método que devuelve el usuario
my_username <- function(bot, update) {
bot$sendMessage(update$message$chat_id,
text = paste0("Su usuario es ", update$message$from$username),
parse_mode = "Markdown")
}
# Creamos filtros
## Mensajes con el texto Chat ID
MessageFilters$chat_id <- BaseFilter(function(message) {
# Verificamos el texto del mensaje
message$text == "Chat ID"
}
)
## Mensajes con el texto Mi nombre
MessageFilters$name <- BaseFilter(function(message) {
# Verificamos el texto del mensaje
message$text == "Mi nombre"
}
)
## Mensajes con el texto Mi usuario
MessageFilters$username <- BaseFilter(function(message) {
# Verificamos el texto del mensaje
message$text == "Mi usuario"
)
# Creamos manejadores
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)
# Agregamos manejadores al despachador
updater <- updater +
h_start +
h_chat_id +
h_name +
h_username
# 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 ).
Después de iniciar, asigne al bot el comando /start, ya que es el que definimos para activar el teclado.

Si en este momento le resulta difícil entender el ejemplo de código que se proporciona, con la creación de métodos, filtros y manejadores, debe volver a la anterior , en la que describí todo esto en detalle.
Hemos creado 4 métodos:
- start — Activar el teclado
- chat_id — Solicitar el identificador del chat
- my_name — Solicitar su nombre
- my_username — Solicitar su nombre de usuario
En el objeto MessageFilters agregamos 3 filtros de mensajes, según su texto:
- chat_id — Mensajes con el texto
"Chat ID" - name — Mensajes con el texto
"Mi nombre" - username — Mensajes con el texto
"Mi nombre de usuario"
Y creamos 4 manejadores, 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() con el comando ReplyKeyboardMarkup().
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton("Chat ID")),
list(KeyboardButton("Mi nombre")),
list(KeyboardButton("Mi nombre de usuario"))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)En nuestro caso, hemos colocado todas las botones uno debajo del otro, pero podemos organizarlos en una fila, haciendo cambios en la lista de listas de botones. Dado que una fila dentro del teclado se crea a través de una lista anidada de botones, para mostrar nuestros botones en una fila debemos reescribir parte del código para construir el teclado así:
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("Chat ID"),
KeyboardButton("Mi nombre"),
KeyboardButton("Mi nombre de usuario")
)
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
El teclado se envía al chat mediante el método sendMessage(), en el argumento reply_markup.
bot$sendMessage(update$message$chat_id,
text = 'Elija un comando',
reply_markup = RKM)Teclado en línea
Como mencioné anteriormente, el teclado Inline está vinculado a un mensaje específico. Trabajar con él es un poco más complicado que con el teclado principal.
Inicialmente, debe agregar un método al bot para invocar el teclado Inline.
Para responder a la presión del botón Inline, también puede utilizar el método del bot answerCallbackQuery(), que puede mostrar una notificación en la interfaz de telegram al usuario que pulsó el botón Inline.
Los datos enviados con el botón Inline no son texto, por lo que para procesarlos es necesario crear un manejador especial utilizando el comando CallbackQueryHandler().
Código para construir un teclado en línea que se presenta en la documentación oficial del paquete telegram.bot.
Código para construir un teclado en línea desde la documentación 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)Para construir un teclado en línea, es necesario usar el comando InlineKeyboardMarkup(), de forma similar a como se hace con el teclado de respuesta. En InlineKeyboardMarkup() se debe pasar una lista de listas de botones en línea, cada botón se crea con la función InlineKeyboardButton().
Un botón en línea puede enviar datos al bot utilizando el argumento callback_data, o abrir una página HTML especificada mediante el argumento url.
Como resultado, habrá una lista, donde cada elemento también es una lista de botones en línea que se deben unir en una sola fila.
A continuación, veremos algunos ejemplos de bots con botones en línea.
Ejemplo de un bot simple con soporte para botones en línea
Para empezar, escribiremos un bot para realizar pruebas rápidas de covid-19. Con el comando /test, enviará un teclado con dos botones, y dependiendo del botón presionado, le enviará un mensaje con los resultados de su prueba.
Código 2: Bot simple con teclado en línea
library(telegram.bot)
# Creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE SU BOT')
# Método para enviar teclado en línea
test <- function(bot, update) {
# Creamos el teclado en línea
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton("Sí", callback_data = 'yes'),
InlineKeyboardButton("No", callback_data = 'no')
)
)
)
# Enviamos el teclado al chat
bot$sendMessage(update$message$chat_id,
text = "¿Tienes coronavirus?",
reply_markup = IKM)
}
# Método para manejar la pulsación del botón
answer_cb <- function(bot, update) {
# Datos recibidos del botón
data <- update$callback_query$data
# Obtenemos el nombre del usuario que pulsó el botón
uname <- update$effective_user()$first_name
# Procesar el resultado
if ( data == 'no' ) {
msg <- paste0(uname, ", felicidades, su prueba de covid-19 es negativa.")
} else {
msg <- paste0(uname, ", lamentablemente su prueba de covid-19 es positiva.")
}
# Enviar mensaje
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
# Informar al bot que la solicitud del botón ha sido aceptada
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# Creamos los manejadores
inline_h <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)
# Añadimos los manejadores al despachador
updater <- updater + inline_h + query_handler
# 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 ).
Resultado:

Hemos creado dos métodos:
- test — Para enviar un teclado en línea al chat
- answer_cb — Para procesar los datos enviados desde el teclado.
Los datos que se enviarán con cada botón se establecen en el argumento callback_data, al crear el botón. Los datos enviados desde el botón se pueden obtener mediante la construcción update$callback_query$data, dentro del método answer_cb.
Para que el bot responda a la tecla Inline, el método answer_cb es procesado por un manejador especial: CallbackQueryHandler(answer_cb). Que ejecuta el método especificado al pulsar el botón Inline. El manejador CallbackQueryHandler recibe dos argumentos:
callback— El método que debe ejecutarsepattern— Filtro por los datos que están vinculados al botón mediante el argumentocallback_data.
Por lo tanto, mediante el argumento pattern podemos escribir un método separado para cada botón presionado:
Código 3: Separamos los métodos para cada botón Inline
library(telegram.bot)
# Creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE TU BOT')
# Método para enviar teclado InLine
test <- function(bot, update) {
# Creamos el teclado InLine
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton("Sí", callback_data = 'yes'),
InlineKeyboardButton("No", callback_data = 'no')
)
)
)
# Enviamos el teclado al chat
bot$sendMessage(update$message$chat_id,
text = "¿Tienes coronavirus?",
reply_markup = IKM)
}
# Método para procesar la pulsación del botón Sí
answer_cb_yes <- function(bot, update) {
# Obtenemos el nombre de usuario que pulsó el botón
uname <- update$effective_user()$first_name
# Procesamiento del resultado
msg <- paste0(uname, ", lamentablemente tu resultado para covid-19 es positivo.")
# Envío de mensaje
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
# Informamos al bot que la solicitud del botón ha sido aceptada
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# Método para procesar la pulsación del botón No
answer_cb_no <- function(bot, update) {
# Obtenemos el nombre de usuario que pulsó el botón
uname <- update$effective_user()$first_name
msg <- paste0(uname, ", felicidades, tu resultado para covid-19 es negativo.")
# Envío de mensaje
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
# Informamos al bot que la solicitud del botón ha sido aceptada
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# Creamos manejadores
inline_h <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no <- CallbackQueryHandler(answer_cb_no, pattern = 'no')
# Agregamos los manejadores al despachador
updater <- updater +
inline_h +
query_handler_yes +
query_handler_no
# 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 ).
Ahora hemos escrito 2 métodos separados, es decir, uno para cada botón que se presiona, y hemos utilizado el argumento pattern, al crear sus manejadores:
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no <- CallbackQueryHandler(answer_cb_no, pattern = 'no')El código del método está por terminar. answer_cb con el comando bot$answerCallbackQuery(callback_query_id = update$callback_query$id), que informa al bot que se han recibido los datos del teclado inline.
Ejemplo de un bot que informa sobre el clima actual en una ciudad seleccionada
Vamos a intentar escribir un bot que solicita datos sobre el clima.
La lógica de funcionamiento será la siguiente. Inicialmente, con el comando /start llamas al teclado principal, que tiene solo un botón "Clima". Al presionar este botón recibirás un mensaje con el teclado inline, para seleccionar la ciudad de la que deseas conocer el clima actual. Seleccionas una de las ciudades y obtienes el clima actual.
En este ejemplo de código, utilizaremos varios paquetes adicionales:
httr— un paquete para trabajar con solicitudes HTTP, en el que se basa la interacción con cualquier API. En nuestro caso utilizaremos la API gratuita .stringr— un paquete para trabajar con texto, y en nuestro caso lo utilizaremos para crear el mensaje sobre el clima en la ciudad seleccionada.
Código 4: Bot que informa sobre el clima actual en la ciudad seleccionada
library(telegram.bot)
library(httr)
library(stringr)
# Creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE SU BOT')
# Creamos métodos
## Método para iniciar el teclado principal
start <- function(bot, update) {
# Creamos el teclado
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("Clima")
)
),
resize_keyboard = TRUE,
one_time_keyboard = TRUE
)
# Enviamos el teclado
bot$sendMessage(update$message$chat_id,
text = 'Seleccione un comando',
reply_markup = RKM)
}
## Método para llamar al teclado Inline
weather <- function(bot, update) {
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton(text = 'Moscú', callback_data = 'New York,us'),
InlineKeyboardButton(text = 'San Petersburgo', callback_data = 'Saint Petersburg'),
InlineKeyboardButton(text = 'Nueva York', callback_data = 'New York')
),
list(
InlineKeyboardButton(text = 'Ekaterimburgo', callback_data = 'Yekaterinburg,ru'),
InlineKeyboardButton(text = 'Berlín', callback_data = 'Berlin,de'),
InlineKeyboardButton(text = 'París', callback_data = 'Paris,fr')
),
list(
InlineKeyboardButton(text = 'Roma', callback_data = 'Rome,it'),
InlineKeyboardButton(text = 'Odesa', callback_data = 'Odessa,ua'),
InlineKeyboardButton(text = 'Kiev', callback_data = 'Kyiv,fr')
),
list(
InlineKeyboardButton(text = 'Tokio', callback_data = 'Tokyo'),
InlineKeyboardButton(text = 'Ámsterdam', callback_data = 'Amsterdam,nl'),
InlineKeyboardButton(text = 'Washington', callback_data = 'Washington,us')
)
)
)
# Enviar teclado Inline
bot$sendMessage(chat_id = update$message$chat_id,
text = "Seleccione una ciudad",
reply_markup = IKM)
}
# Método para el mensaje del clima
answer_cb <- function(bot, update) {
# Obtenemos de mensaje la ciudad
city <- update$callback_query$data
# Enviamos la consulta
ans <- GET('https://api.openweathermap.org/data/2.5/weather',
query = list(q = city,
lang = 'es',
units = 'metric',
appid = '4776568ccea136ffe4cda9f1969af340'))
# Parseamos la respuesta
result <- content(ans)
# Formamos el mensaje
msg <- str_glue("{result$name} clima:n",
"Temperatura actual: {result$main$temp}n",
"Velocidad del viento: {result$wind$speed}n",
"Descripción: {result$weather[[1]]$description}")
# Enviamos la información del clima
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# Creamos filtros
## Mensajes con texto Clima
MessageFilters$weather <- BaseFilter(function(message) {
# Verificamos el texto del mensaje
message$text == "Clima"
}
)
# Creamos manejadores
h_start <- CommandHandler('start', start)
h_weather <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)
# Agregamos manejadores al despachador
updater <- updater +
h_start +
h_weather +
h_query_handler
# 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 ).
Como resultado, nuestro bot funcionará aproximadamente así:

Esquemáticamente, este bot se puede representar así:

Hemos creado 3 métodos disponibles dentro de nuestro bot del clima:
- start — Activación del teclado principal del bot
- weather — Activación del teclado Inline para seleccionar la ciudad
- answer_cb — Método principal que solicita el clima a la API para la ciudad dada y lo envía al chat.
El método start se activa con el comando /start, lo que es implementado por el manejador CommandHandler('start', start).
Para activar el método weather hemos creado un filtro homónimo:
# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {
# проверяем текст сообщения
message$text == "Погода"
}
)Y llamamos a este método con el siguiente manejador de mensajes: MessageHandler(weather, filters = MessageFilters$weather).
Y, finalmente, nuestro método principal answer_cb reacciona a la pulsación de botones Inline, lo que se implementa mediante un manejador especial: CallbackQueryHandler(answer_cb).
Dentro del método answer_cb, leemos los datos enviados desde el teclado y los almacenamos en la variable city: city <- update$callback_query$data. Después, solicitamos datos sobre el clima desde la API, formulamos y enviamos el mensaje, y al final utilizamos el método answerCallbackQuery para informar al bot que hemos procesado la pulsación del botón Inline.
Ejemplo de un bot que muestra una lista de los artículos más recientes con enlaces del Hub indicado de .
Traigo este bot para mostrarte cómo generar botones Inline que llevan a páginas web.
La lógica de este bot es similar a la anterior, inicialmente activamos el teclado principal con el comando /start. Luego, el bot nos ofrece una lista de 6 hubs, seleccionamos el hub que nos interesa y recibimos 5 de las publicaciones más recientes de ese Hub.
Como puedes imaginar, en este caso necesitamos obtener una lista de artículos, y para ello utilizaremos un paquete especial habR, que permite solicitar artículos de Habr y algunas estadísticas sobre ellos en R.
El paquete habR solo se puede instalar desde github, para lo cual necesitarás un paquete adicional devtools. Para la instalación usa el siguiente código.
install.packages('devtools')
devtools::install_github('selesnow/habR')Ahora revisemos el código para construir el bot descrito anteriormente:
Código 5: Bot que muestra una lista de los artículos más recientes del Hub seleccionado
library(telegram.bot)
library(habR)
# Creamos una instancia de la clase Updater
updater <- Updater('TOKEN DE SU BOT')
# Creamos métodos
## Método para iniciar el teclado principal
start <- function(bot, update) {
# Creamos el teclado
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("Lista de artículos")
)
),
resize_keyboard = TRUE,
one_time_keyboard = TRUE
)
# Enviamos el teclado
bot$sendMessage(update$message$chat_id,
text = 'Seleccione un comando',
reply_markup = RKM)
}
## Método para llamar al teclado 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 = 'Visualización de datos', callback_data = 'data_visualization')
)
)
)
# Enviar teclado en línea
bot$sendMessage(chat_id = update$message$chat_id,
text = "Seleccione un Hub",
reply_markup = IKM)
}
# Método para el mensaje sobre el clima
answer_cb <- function(bot, update) {
# Obtenemos la ciudad del mensaje
hub <- update$callback_query$data
# Mensaje indicando que los datos del botón han sido recibidos
bot$answerCallbackQuery(callback_query_id = update$callback_query$id,
text = 'Espere unos minutos, la solicitud se está procesando')
# Mensaje indicando que debe esperar a que el bot obtenga los datos
mid <- bot$sendMessage(chat_id = update$from_chat_id(),
text = "Espere unos minutos mientras recojo los datos del Hub seleccionado")
# Parseamos Habr
posts <- head(habr_hub_posts(hub, 1), 5)
# Eliminamos el mensaje de espera
bot$deleteMessage(update$from_chat_id(), mid$message_id)
# Formamos la lista de botones
keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))
# Formamos el teclado
IKM <- InlineKeyboardMarkup(
inline_keyboard = keys
)
# Enviamos la información sobre el clima
bot$sendMessage(chat_id = update$from_chat_id(),
text = paste0("Los 5 artículos más recientes del Hub ", hub),
reply_markup = IKM)
}
# Creamos filtros
## Mensajes con texto Clima
MessageFilters$hubs <- BaseFilter(function(message) {
# Verificamos el texto del mensaje
message$text == "Lista de artículos"
}
)
# Creamos manejadores
h_start <- CommandHandler('start', start)
h_hubs <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)
# Agregamos manejadores al despachador
updater <- updater +
h_start +
h_hubs +
h_query_handler
# 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 ).
Al final, obtendremos este resultado:

La lista de hubs disponibles para elegir la hemos codificado de manera fija 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 la lista de artículos del hub especificado con el comando habr_hub_posts(), del paquete habR. Al hacerlo, especificamos que no necesitamos la lista de artículos de todo el tiempo, sino solo la primera página en la que se encuentran 20 artículos. De la tabla obtenida, con el comando head() dejamos solo los 5 superiores, que son los artículos más recientes.
# парсим Хабр
posts <- head(habr_hub_posts(hub, 1), 5)La lógica es muy similar a la del bot anterior, pero en este caso generamos dinámicamente el teclado en línea con la lista de artículos mediante la función lapply().
# формируем список кнопок
keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))
# формируем клавиатуру
IKM <- InlineKeyboardMarkup(
inline_keyboard = keys
)En el texto del botón, insertamos el título del artículo posts$title[x], y en el argumento url el enlace al artículo: url = posts$link[x].
Luego, creamos el filtro, los manejadores y ejecutamos nuestro bot.
Conclusión
Ahora, los bots que ustedes han escrito serán significativamente más convenientes de usar, ya que la gestión se realizará a través del teclado, en lugar de ingresar comandos. Al menos al interactuar con el bot a través de un smartphone, el teclado simplificará notablemente el proceso de uso.
En el siguiente artículo, exploraremos cómo construir un diálogo lógico con el bot y trabajar con bases de datos.
Fuente: habr.com
