ProHoster > Blog > İdarə > R-də teleqram botunun yazılması (3-cü hissə): Bota klaviatura dəstəyini necə əlavə etmək olar
R-də teleqram botunun yazılması (3-cü hissə): Bota klaviatura dəstəyini necə əlavə etmək olar
Bu, “R-də teleqram botunun yazılması” seriyasındakı üçüncü məqalədir. Əvvəlki nəşrlərdə biz teleqram botunu necə yaratmağı, onun vasitəsilə mesaj göndərməyi öyrəndik, bota əmrlər və mesaj filtrləri əlavə etdik. Buna görə də, bu məqaləni oxumağa başlamazdan əvvəl oxumağı çox tövsiyə edirəm əvvəlki, çünki Burada daha əvvəl bot qurulmasının əsasları üzərində dayanmayacağam.
Bu yazıda biz bot interfeysini intuitiv və istifadəsi asan edəcək klaviatura əlavə etməklə botumuzun istifadə imkanlarını artıracağıq.
“R-də teleqram botunun yazılması” seriyasından bütün məqalələr
Telegram botu hansı klaviatura növlərini dəstəkləyir?
Bu yazı zamanı telegram.bot iki növ klaviatura yaratmağa imkan verir:
Cavab vermək - Mesaj mətni daxiletmə panelinin altında yerləşən əsas, adi klaviatura. Belə klaviatura sadəcə olaraq bota mətn mesajı göndərir və mətn olaraq düymənin özündə yazılmış mətni göndərir.
Inline - Müəyyən bir bot mesajı ilə əlaqəli klaviatura. Bu klaviatura basılan düymə ilə əlaqəli bot məlumatlarını göndərir; bu məlumatlar düymənin özündə yazılmış mətndən fərqli ola bilər. Və bu cür düymələr vasitəsilə işlənir CallbackQueryHandler.
Botun klaviaturanı açması üçün bu üsulla mesaj göndərərkən lazımdır sendMessage(), əvvəllər yaradılmış klaviaturanı arqument kimi ötürün reply_markup.
Aşağıda bir neçə nümunəyə baxacağıq.
Cavab klaviaturası
Yuxarıda yazdığım kimi, bu, əsas bot idarəetmə klaviaturasıdır.
Rəsmi yardımdan Cavab klaviaturasının yaradılması nümunəsi
Yuxarıda göstərilənlər paketin rəsmi yardımından bir nümunədir telegram.bot. Klaviatura yaratmaq üçün funksiyadan istifadə edin ReplyKeyboardMarkup(), bu da öz növbəsində funksiya tərəfindən yaradılan düymələrin siyahısını götürür KeyboardButton().
Niyə içindədir ReplyKeyboardMarkup() Sadəcə siyahı deyil, siyahıların siyahısını keçmək lazımdırmı? Məsələ burasındadır ki, siz əsas siyahıdan keçirsiniz və orada hər bir düymə sırasını ayrı-ayrı siyahılarda müəyyənləşdirirsiniz, çünki Bir sıra bir neçə düyməni yerləşdirə bilərsiniz.
arqument resize_keyboard klaviatura düymələrinin optimal ölçüsünü və arqumenti avtomatik seçməyə imkan verir one_time_keyboard hər düyməni basdıqdan sonra klaviaturanı gizlətməyə imkan verir.
3 düymədən ibarət sadə bir bot yazaq:
Chat ID - Bot ilə dialoqun chat ID-sini tələb edin
Mənim adım - Adınızı tələb edin
Girişim - İstifadəçi adınızı telegramda tələb edin
Kod 1: Cavab klaviaturası ilə sadə bot
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()
'SİZİN BOT TOKEN'i vasitəsilə botu yaradarkən aldığınız real işarə ilə əvəz etdikdən sonra yuxarıdakı kod nümunəsini işlədin. BotAta (Mən bir bot yaratmaq haqqında danışdım ilk məqalə).
Başladıqdan sonra bota əmr verin /start, çünki Klaviaturanı işə salmaq üçün təyin etdiyimiz şey budur.
Əgər hazırda metodlar, filtrlər və işləyicilərin yaradılması ilə verilmiş kod nümunəsini təhlil etmək sizin üçün çətindirsə, onda siz əvvəlkinə qayıtmalısınız. məqalə, bütün bunları ətraflı təsvir etdiyim.
4 üsul yaratdıq:
start — klaviaturanı işə salın
chat_id — Söhbət ID-sini tələb edin
my_name — Adınızı tələb edin
my_username — Girişinizi tələb edin
Etiraz etmək Mesaj Filtrləri mətninə əsasən 3 mesaj filtri əlavə etdi:
chat_id — Mətni olan mesajlar "Чат ID"
ad — mətnli mesajlar "Моё имя"
istifadəçi adı — Mətni olan mesajlar "Мой логин"
Və biz verilmiş əmrlər və filtrlər əsasında göstərilən metodları yerinə yetirəcək 4 işləyici yaratdıq.
Bizim vəziyyətimizdə biz bütün düymələri bir-birinin altına yerləşdirmişik, lakin düymə siyahılarının siyahısına dəyişiklik etməklə onları bir sıra təşkil edə bilərik. Çünki klaviatura daxilində bir sıra düymələrin iç-içə siyahısı vasitəsilə yaradılır, sonra düymələrimizi bir cərgədə göstərmək üçün klaviaturanı qurmaq üçün kodun bir hissəsini belə yenidən yazmalıyıq:
Metoddan istifadə edərək klaviatura söhbətə göndərilir sendMessage(), mübahisədə reply_markup.
bot$sendMessage(update$message$chat_id,
text = 'Выберите команду',
reply_markup = RKM)
Daxili klaviatura
Yuxarıda yazdığım kimi, Inline klaviaturası müəyyən bir mesaja bağlıdır. Onunla işləmək əsas klaviatura ilə müqayisədə bir qədər çətindir.
Əvvəlcə Inline klaviaturasına zəng etmək üçün bota bir üsul əlavə etməlisiniz.
Daxili düyməyə klikləməyə cavab vermək üçün siz bot metodundan da istifadə edə bilərsiniz answerCallbackQuery(), bu da Inline düyməsini basan istifadəçiyə teleqram interfeysində bildiriş göstərə bilər.
Inline düyməsindən göndərilən məlumatlar mətn deyil, ona görə də onu emal etmək üçün əmrdən istifadə edərək xüsusi işləyici yaratmaq lazımdır CallbackQueryHandler().
Paketin rəsmi yardımında verilmiş Inline klaviaturasının qurulması kodu telegram.bot.
Komandanı istifadə edərək, Inline klaviatura qurmalısınız InlineKeyboardMarkup(), Cavab klaviaturası ilə eyni prinsipdə. IN InlineKeyboardMarkup() Daxili düymələrin siyahılarının siyahısını keçmək lazımdır, hər bir fərdi düymə funksiya tərəfindən yaradılır InlineKeyboardButton().
Daxili düymə ya arqumentdən istifadə edərək bəzi məlumatları bota ötürə bilər callback_data, və ya arqumentdən istifadə edərək göstərilən hər hansı HTML səhifəsini açın url.
Nəticə, hər bir elementin eyni zamanda bir sıraya birləşdirilməli olan Inline düymələrinin siyahısı olduğu bir siyahı olacaq.
Sonra biz Inline düymələri olan bir neçə bot nümunəsinə baxacağıq.
InLine düymələrini dəstəkləyən sadə botun nümunəsi
Əvvəlcə covid-19 üçün ekspress test üçün bir bot yazacağıq. Əmrlə /test, o, sizə iki düyməli klaviatura göndərəcək, basılan düymədən asılı olaraq testinizin nəticələri ilə sizə mesaj göndərəcək.
Kod 2: Daxili klaviatura ilə ən sadə bot
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()
'SİZİN BOT TOKEN'i vasitəsilə botu yaradarkən aldığınız real işarə ilə əvəz etdikdən sonra yuxarıdakı kod nümunəsini işlədin. BotAta (Mən bir bot yaratmaq haqqında danışdım ilk məqalə).
Nəticə:
İki üsul yaratdıq:
sınaq — Söhbətə göndərmək üçün Inline klaviatura
cavab_cb — Klaviaturadan göndərilən məlumatları emal etmək üçün.
Hər bir düymədən göndəriləcək məlumatlar arqumentdə göstərilir callback_data, düymə yaratarkən. Quruluşdan istifadə edərək düymədən göndərilən məlumatları qəbul edə bilərsiniz update$callback_query$data, metod daxilində cavab_cb.
Botun Inline klaviaturasına reaksiya verməsi üçün metod cavab_cb xüsusi işləyici tərəfindən işlənir: CallbackQueryHandler(answer_cb). Hansı ki, Inline düyməsi kliklədikdə göstərilən metodu işlədir. İşləyən CallbackQueryHandler iki arqument götürür:
callback - İstifadə edilməli olan üsul
pattern — Arqumentdən istifadə edərək düyməyə bağlı olan məlumatlara görə süzün callback_data.
Müvafiq olaraq, arqumentdən istifadə edərək pattern Hər düyməni basmaq üçün ayrıca üsul yaza bilərik:
Kod 3: Hər Inline düyməsi üçün ayrı üsullar
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()
'SİZİN BOT TOKEN'i vasitəsilə botu yaradarkən aldığınız real işarə ilə əvəz etdikdən sonra yuxarıdakı kod nümunəsini işlədin. BotAta (Mən bir bot yaratmaq haqqında danışdım ilk məqalə).
İndi biz 2 ayrı üsul yazdıq, yəni. bir üsul, hər düyməni basın və arqumentdən istifadə edin pattern, işləyicilərini yaratarkən:
Metod kodu bitir cavab_cb komanda bot$answerCallbackQuery(callback_query_id = update$callback_query$id), bu, bota daxili klaviaturadan məlumatların qəbul edildiyini bildirir.
Seçilmiş şəhər üçün cari hava haqqında məlumat verən bot nümunəsi
Gəlin hava məlumatlarını tələb edən bir bot yazmağa çalışaq.
Onun işinin məntiqi aşağıdakı kimi olacaq. Əvvəlcə komanda tərəfindən /start yalnız bir “Hava” düyməsi olan əsas klaviaturanı çağırırsınız. Bu düyməni klikləməklə, cari hava vəziyyətini öyrənmək istədiyiniz şəhəri seçmək üçün Inline klaviaturası ilə mesaj alacaqsınız. Şəhərlərdən birini seçin və cari havanı əldə edin.
Bu kod nümunəsində biz bir neçə əlavə paketdən istifadə edəcəyik:
httr — HTTP sorğuları ilə işləmək üçün paket, onun əsasında istənilən API ilə iş qurulur. Bizim vəziyyətimizdə pulsuz API istifadə edəcəyik openweathermap.org.
stringr — mətnlə işləmək üçün paket, bizim vəziyyətimizdə ondan seçilmiş şəhərdə hava haqqında mesaj yaratmaq üçün istifadə edəcəyik.
Kod 4: Seçilmiş şəhər üçün cari hava haqqında məlumat verən bot
'SİZİN BOT TOKEN'i vasitəsilə botu yaradarkən aldığınız real işarə ilə əvəz etdikdən sonra yuxarıdakı kod nümunəsini işlədin. BotAta (Mən bir bot yaratmaq haqqında danışdım ilk məqalə).
Nəticədə, botumuz belə işləyəcək:
Sxematik olaraq bu botu belə təsvir etmək olar:
Hava botumuzda mövcud olan 3 üsul yaratdıq:
Başlamaq — Əsas bot klaviaturasını işə salın
hava — Şəhər seçmək üçün Inline klaviaturasını işə salın
cavab_cb — Müəyyən bir şəhər üçün API-dən hava tələb edən və onu söhbətə göndərən əsas üsul.
üsul Başlamaq əmri ilə işə salırıq /start, işləyici tərəfindən həyata keçirilir CommandHandler('start', start).
Bir metodu işə salmaq üçün hava eyni adlı filtr yaratdıq:
# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {
# проверяем текст сообщения
message$text == "Погода"
}
)
Və biz bu metodu aşağıdakı mesaj işləyicisi ilə çağırırıq: MessageHandler(weather, filters = MessageFilters$weather).
Və sonda əsas metodumuz cavab_cb xüsusi işləyici tərəfindən həyata keçirilən Inline düymələrinə basmağa reaksiya verir: CallbackQueryHandler(answer_cb).
Bir üsul daxilində cavab_cb, biz klaviaturadan göndərilən məlumatları oxuyuruq və dəyişənə yazırıq city: city <- update$callback_query$data. Sonra API-dən hava məlumatlarını tələb edirik, mesaj yaradır və göndəririk və nəhayət metoddan istifadə edirik answerCallbackQuery Inline düyməsinə kliklədiyimizi bota bildirmək üçün.
Göstərilən Hub-a keçidləri olan ən son məqalələrin siyahısını göstərən bot nümunəsi www.habr.com.
Bu botu sizə veb səhifələrə aparan Inline düymələrini necə göstərəcəyinizi göstərmək üçün təqdim edirəm.
Bu botun məntiqi əvvəlkinə bənzəyir, əvvəlcə komanda ilə əsas klaviaturanı işə salırıq /start. Sonra, bot bizə seçmək üçün 6 mərkəzin siyahısını verir, biz maraqlandığımız mərkəzi seçirik və seçilmiş Hubdan ən son 5 nəşri alırıq.
Anladığınız kimi, bu halda məqalələrin siyahısını əldə etməliyik və bunun üçün xüsusi paketdən istifadə edəcəyik habR, bu sizə Habra-dan məqalələr və R-də bəzi statistik məlumatlar tələb etməyə imkan verir.
Paketi quraşdırın habR yalnız github-dan mümkündür, bunun üçün əlavə paketə ehtiyacınız olacaq devtools. Quraşdırmaq üçün aşağıdakı kodu istifadə edin.
İndi yuxarıda təsvir edilən botun qurulması koduna baxaq:
Kod 5: Seçilmiş Hub-da ən son məqalələrin siyahısını göstərən bot
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()
'SİZİN BOT TOKEN'i vasitəsilə botu yaradarkən aldığınız real işarə ilə əvəz etdikdən sonra yuxarıdakı kod nümunəsini işlədin. BotAta (Mən bir bot yaratmaq haqqında danışdım ilk məqalə).
Nəticədə bu nəticəni əldə edəcəyik:
Metodda seçim üçün mövcud olan Hubların siyahısını sərt kodlaşdırdıq habs:
Əmri ilə göstərilən Hub-dan məqalələrin siyahısını alırıq habr_hub_posts(), paketdən habR. Eyni zamanda qeyd edirik ki, bizə bütün zaman üçün məqalələrin siyahısı lazım deyil, yalnız 20 məqalənin yerləşdiyi birinci səhifə lazımdır. Komandadan istifadə edərək nəticə cədvəlindən head() Biz yalnız ən son məqalələr olan ilk 5-i buraxırıq.
Məntiq əvvəlki bota çox bənzəyir, lakin bu halda funksiyadan dinamik şəkildə istifadə edərək məqalələrin siyahısı ilə daxili klaviatura yaradırıq. lapply().
Düymə mətninə məqalənin başlığını daxil edirik posts$title[x], və mübahisədə url məqaləyə keçid: url = posts$link[x].
Sonra filtr, işləyicilər yaradırıq və botu işə salırıq.
Nəticə
İndi yazdığınız botlar əmr daxil etməklə deyil, klaviaturadan idarə olunacağına görə istifadə etmək çox daha rahat olacaq. Ən azı smartfon vasitəsilə botla əlaqə qurarkən klaviatura ondan istifadə prosesini xeyli asanlaşdıracaq.
Növbəti məqalədə biz botla məntiqi dialoq qurmağı və verilənlər bazası ilə işləməyi öyrənəcəyik.