This is the third article in the series "Writing a telegram bot in the R language". In previous publications, we learned how to create a telegram bot, send messages through it, added commands and message filters to the bot. Therefore, before starting to read this article, I highly recommend that you familiarize yourself with the previous ones , because here I will not stop on the bases of bot building described earlier.
In this article, we will improve the usability of our bot by adding a keyboard, which will make the bot interface intuitive and easy to use.
All articles from the series "Writing a telegram bot in the R language"
- We create a bot and send messages to telegram using it
- Add command support and message filters to the bot
- How to add keyboard support to your bot
- Building a consistent, logical dialogue with the bot
- Bot user rights management
Content
If you are interested in data analysis, you may be interested in my telegram and youtube channels. Most of the content of which is devoted to the R language.
- What types of keyboards does the telegram bot support?
- Reply keyboard
- 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]
.
, , .
, , , . .