Este es el tercer artĂculo de la serie "Escribir un bot de telegrama en lenguaje R". En publicaciones anteriores, aprendimos cĂłmo crear un bot de telegramas, enviar mensajes a travĂ©s de Ă©l, agregar comandos y filtros de mensajes al bot. Por eso, antes de comenzar a leer este artĂculo, te recomiendo que te familiarices con los anteriores , porque aquĂ no me detendrĂ© en las bases de la construcciĂłn de bots descritas anteriormente.
En este artĂculo, mejoraremos la usabilidad de nuestro bot al agregar un teclado que hará que la interfaz del bot sea intuitiva y fácil de usar.

Todos los artĂculos de la serie "Escribir un bot de telegrama en lenguaje R"
- Creamos un bot y enviamos mensajes a telegram usándolo
- Agregue soporte de comando y filtros de mensajes al bot
- CĂłmo agregar soporte de teclado a su bot
- Construyendo un diálogo lógico y consistente con el bot
- GestiĂłn de derechos de usuario de bot
Contenido
Si está interesado en el análisis de datos, puede que le interesen mis canales de telegram y youtube . La mayor parte del contenido está dedicado al lenguaje R.
- ¿Qué tipos de teclados admite el bot de telegram?
- Responder teclado
- Inline
3.1. InLine
3.2. ,
3.3. , - habr.com
telegram.bot :
- Reply — , , . , , .
- Inline — . , , , . CallbackQueryHandler.
, sendMessage(), reply_markup.
.
Reply
, .
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) telegram.bot. ReplyKeyboardMarkup(), , KeyboardButton().
ReplyKeyboardMarkup() , ? , , , .. .
resize_keyboard , one_time_keyboard .
, 3 :
- ID — ID
- —
- —
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(), ' ' , BotFather ( ).
/start, .. .

4 :
- start —
- chat_id —
- my_name —
- my_username —
MessageFilters 3 , :
- chat_id —
" ID" - name —
" " - username —
" "
4 , .
#
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)
start() ReplyKeyboardMarkup().
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton(" ID")),
list(KeyboardButton(" ")),
list(KeyboardButton(" "))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
, , . .. , , :
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton(" ID"),
KeyboardButton(" "),
KeyboardButton(" ")
)
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)

sendMessage(), reply_markup.
bot$sendMessage(update$message$chat_id,
text = ' ',
reply_markup = RKM)
Inline
, Inline . .
, Inline .
Inline answerCallbackQuery(), telegram, Inline .
Inline , CallbackQueryHandler().
Inline telegram.bot.
# 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) Inline InlineKeyboardMarkup(), , Reply . InlineKeyboardMarkup() , Inline , InlineKeyboardButton().
Inline - callback_data, - HTML , url.
, Inline , .
Inline .
InLine
covid-19. /test, , .
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(), ' ' , BotFather ( ).
:

:
- test — Inline
- answer_cb — .
, callback_data, . update$callback_query$data, answer_cb.
Inline , answer_cb : CallbackQueryHandler(answer_cb). Inline . CallbackQueryHandler :
callback—pattern— ,callback_data.
pattern :
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(), ' ' , BotFather ( ).
2 , .. , , pattern, :
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no <- CallbackQueryHandler(answer_cb_no, pattern = 'no')
answer_cb bot$answerCallbackQuery(callback_query_id = update$callback_query$id), , inline .
,
, .
. /start , "". Inline , , . , .
:
httr— HTTP , API. API openweathermap.org.stringr— , .
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(), ' ' , BotFather ( ).
:

:

3 , :
- start —
- weather — Inline
- answer_cb — , API , .
start /start, CommandHandler('start', start).
weather :
#
##
MessageFilters$weather <- BaseFilter(function(message) {
#
message$text == ""
}
)
: MessageHandler(weather, filters = MessageFilters$weather).
, answer_cb Inline , : CallbackQueryHandler(answer_cb).
answer_cb, city: city <- update$callback_query$data. API , , answerCallbackQuery , , , Inline .
, - habr.com.
, , Inline .
, /start. 6 , , 5 .
, , habR, R.
habR github, devtools. .
install.packages('devtools')
devtools::install_github('selesnow/habR')
:
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(), ' ' , BotFather ( ).
:

, 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)
}
habr_hub_posts(), habR. , , 20 . head() 5 , .
#
posts <- head(habr_hub_posts(hub, 1), 5)
, Inline lapply().
#
keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))
#
IKM <- InlineKeyboardMarkup(
inline_keyboard = keys
)
posts$title[x], url : url = posts$link[x].
, , .
, , , . .