שרייבן אַ טעלעגראַם באָט אין ר (טייל 3): ווי צו לייגן קלאַוויאַטור שטיצן צו אַ באָט
דאָס איז דער דריטער אַרטיקל אין דער סעריע "שרייבן אַ טעלעגראַם באָט אין ר". אין פריערדיקע אויסגאבעס, מיר געלערנט ווי צו שאַפֿן אַ טעלעגראַם באָט, שיקן אַרטיקלען דורך אים, צוגעלייגט קאַמאַנדז און אָנזאָג פילטערס צו די באָט. דעריבער, איידער איר אָנהייבן לייענען דעם אַרטיקל, איך העכסט רעקאָמענדירן איר לייענען פֿריִערדיקע, т.к. тут я уже не буду останавливать на описанных ранее основах ботостроения.
אין דעם אַרטיקל, מיר וועלן פֿאַרבעסערן די וסאַביליטי פון אונדזער באָט דורך אַדינג אַ קלאַוויאַטור, וואָס וועט מאַכן די באָט צובינד ינטואַטיוו און גרינג צו נוצן.
אויב איר זענט אינטערעסירט אין דאַטן אַנאַליסיס, איר קען זיין אינטערעסירט אין מיין telegram и יאָוטובע טשאַנאַלז. רובֿ פון די אינהאַלט איז דעדאַקייטאַד צו די R שפּראַך.
וואָס טייפּס פון קיבאָרדז שטיצט די טעלעגראַם באָט?
אין דער צייט פון דעם שרייבן telegram.bot אַלאַוז איר צו שאַפֿן צוויי טייפּס פון קיבאָרדז:
ענטפער - די הויפּט, רעגולער קלאַוויאַטור, וואָס איז ליגן אונטער די אָנזאָג טעקסט אַרייַנשרייַב טאַפליע. אַזאַ אַ קלאַוויאַטור שיקט פשוט אַ טעקסט אָנזאָג צו די באָט, און ווי דער טעקסט וועט עס שיקן די טעקסט וואָס איז געשריבן אויף די קנעפּל זיך.
ינלינע - קלאַוויאַטור פֿאַרבונדן מיט אַ ספּעציפיש באָט אָנזאָג. די קלאַוויאַטור סענדז די באָט דאַטן פֿאַרבונדן מיט דעם קנעפּל געדריקט; די דאַטן קען זיין אַנדערש פון די טעקסט געשריבן אויף די קנעפּל זיך. און אַזאַ קנעפּלעך זענען פּראַסעסט דורך CallbackQueryHandler.
Для того, что бы бот открыл клавиатуру необходимо при отправке сообщения через метод sendMessage(), פאָרן די פריער באשאפן קלאַוויאַטור ווי אַן אַרגומענט reply_markup.
ונטער מיר וועלן קוקן אין עטלעכע ביישפילן.
ענטפער קלאַוויאַטור
Как я уже писал выше, это основная клавиатура управления ботом.
Пример создания Reply клавиатуры из официальной справки
Выше приведён пример из официальной справки пакета telegram.bot. צו שאַפֿן אַ קלאַוויאַטור, נוצן די פֿונקציע ReplyKeyboardMarkup(), которая в свою очередь принимает список списков кнопок, которые создаются функцией KeyboardButton().
פארוואס אין ReplyKeyboardMarkup() צי איר דאַרפֿן צו פאָרן נישט בלויז אַ רשימה, אָבער אַ רשימה פון רשימות? די פונט איז אַז איר פאָרן די הויפּט רשימה, און אין עס איר דעפינירן יעדער רודערן פון קנעפּלעך אין באַזונדער רשימות, ווייַל איר קענען שטעלן עטלעכע קנעפּלעך אין איין רודערן.
אַרגומענט resize_keyboard позволяет автоматически подбирать оптимальный размер кнопок клавиатуры, а аргумент one_time_keyboard позволяет скрывать клавиатуру после каждого нажатия на кнопку.
Давайте напишем простейшего бота, у которого будет 3 кнопки:
שמועסן שייַן - בעטן שמועס שייַן פון דיאַלאָג מיט באָט
מייַן נאָמען - בעטן דיין נאָמען
מיין לאָגין - בעטן דיין נאמען אין טעלעגראַם
קאָד 1: פּשוט באָט מיט ענטפער קלאַוויאַטור
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()
נאָך לאָנטשינג, געבן די באָט אַ באַפֿעל /start, т.к. именно её мы определили для запуска клавиатуры.
אויב אין דעם מאָמענט עס איז שווער פֿאַר איר צו פּאַרס די געגעבן קאָד בייַשפּיל, מיט די שאַפונג פון מעטהאָדס, פילטערס און האַנדלערס, איר זאָל צוריקקומען צו די פריערדיקע. אַרטיקל, אי ן װעלכ ן אי ך הא ב דא ס אל ץ באשריבן .
אין אונדזער פאַל, מיר שטעלן אַלע די קנעפּלעך אונטער יעדער אנדערע, אָבער מיר קענען צולייגן זיי אין איין רודערן דורך מאַכן ענדערונגען אין דער רשימה פון קנעפּל רשימות. ווייַל איין רודערן אין די קלאַוויאַטור איז באשאפן דורך אַ נעסטעד רשימה פון קנעפּלעך, און אין סדר צו ווייַזן אונדזער קנעפּלעך אין איין רודערן, מיר דאַרפֿן צו רירייט טייל פון די קאָד פֿאַר קאַנסטראַקטינג די קלאַוויאַטור ווי דאָס:
די קלאַוויאַטור איז געשיקט צו די שמועסן מיט דעם אופֿן sendMessage(), אין די אַרגומענט reply_markup.
bot$sendMessage(update$message$chat_id,
text = 'Выберите команду',
reply_markup = RKM)
ינלינע קלאַוויאַטור
ווי איך געשריבן אויבן, די ינלינע קלאַוויאַטור איז טייד צו אַ ספּעציפיש אָנזאָג. עס איז עפּעס מער שווער צו אַרבעטן מיט די הויפּט קלאַוויאַטור.
Изначально вам необходимо добавить боту метод, для вызова Inline клавиатуры.
Для ответа на нажатие Inline кнопки также можно использовать метод бота answerCallbackQuery(), который может вывести уведомление в интерфейсе telegram, пользователю нажавшему Inline кнопку.
די דאַטן געשיקט פֿון די ינלינע קנעפּל זענען נישט טעקסט, אַזוי צו פּראָצעס עס איר דאַרפֿן צו שאַפֿן אַ ספּעציעל האַנדלער מיט דעם באַפֿעל CallbackQueryHandler().
Код построения Inline клавиатуры который приводится в официальной справке пакета telegram.bot.
Код построения Inline клавиатуры из официальной справки
Строить Inline клавиатуру необходимо с помощью команды InlineKeyboardMarkup(), по такому же принципу, как и Reply клавиатуру. В InlineKeyboardMarkup() עס איז נייטיק צו פאָרן אַ רשימה פון רשימות פון ינלינע קנעפּלעך, יעדער יחיד קנעפּל איז באשאפן דורך די פונקציע InlineKeyboardButton().
Inline кнопка может либо передавать боту какие-то данные с помощью аргумента callback_data, либо открывать какую-либо HTML страницу, заданную с помощью аргумента url.
דער רעזולטאַט וועט זיין אַ רשימה אין וואָס יעדער עלעמענט איז אויך אַ רשימה פון ינלינע קנעפּלעך וואָס דאַרפֿן צו זיין קאַמביינד אין איין רודערן.
Далее мы рассмотрим несколько примеров ботов с Inline кнопками.
Пример простейшего бота с поддержкой InLine кнопок
Для начала мы напишем бота для экспресс тестирования на covid-19. По команде /test, он будет отправлять вам клавиатуру с двумя кнопками, в зависимости от нажатой кнопки он будет присылать вам сообщение с результатами вашего тестирования.
קאָד 2: די סימפּלאַסט באָט מיט אַן ינלינע קלאַוויאַטור
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()
answer_cb - צו פּראָצעס דאַטן געשיקט פֿון די קלאַוויאַטור.
Данные, которые будут отправлены с каждой кнопки задаются в аргументе callback_data, при создании кнопки. Получить отправленные с кнопки данные можно с помощью конструкции update$callback_query$data, ין דער אופֿן answer_cb.
Что бы бот реагировал на Inline клавиатуру, метод answer_cb פּראַסעסט דורך אַ ספּעציעל האַנדלער: CallbackQueryHandler(answer_cb). Который запускает указанный метод по нажатию Inline кнопки. Обработчик CallbackQueryHandler נעמט צוויי טענות:
callback — דער מעטאד וואס דארף לויפן
pattern — Фильтр по данным, которые привязаны к кнопке с помощью аргумента callback_data.
אַקקאָרדינגלי, ניצן די אַרגומענט pattern мы можем под нажатие каждой кнопки написать отдельный метод:
מעטאָד קאָד ענדס answer_cb מאַנשאַפֿט bot$answerCallbackQuery(callback_query_id = update$callback_query$id), которая сообщает боту, что данные с inline клавиатуры получены.
Пример бота, который сообщает текущую погоду по выбранному городу
Давайте попробуем написать бота, который запрашивает данные о погоде.
Логика его работы будет следующая. Изначально командой /start איר רופן אַרויף די הויפּט קלאַוויאַטור, וואָס האט בלויז איין "וועטער" קנעפּל. דורך געבן אַ קליק אויף דעם קנעפּל איר וועט באַקומען אַ אָנזאָג מיט די ינלינע קלאַוויאַטור צו אויסקלייַבן די שטאָט פֿאַר וואָס איר ווילן צו געפֿינען די קראַנט וועטער. אויסקלייַבן איינער פון די שטעט און באַקומען די קראַנט וועטער.
В этом примере кода мы будем использовать несколько дополнительных пакетов:
httr - אַ פּעקל פֿאַר ארבעטן מיט הטטפּ ריקוועס, אויף דער באזע פון וואָס אַרבעט מיט קיין אַפּי איז געבויט. אין אונדזער פאַל, מיר וועלן נוצן די פריי API openweathermap.org.
stringr - אַ פּעקל פֿאַר ארבעטן מיט טעקסט, אין אונדזער פאַל, מיר וועלן נוצן עס צו דזשענערייט אַ אָנזאָג וועגן די וועטער אין די אויסגעקליבן שטאָט.
Код 4: Бот, который сообщает текущую погоду по выбранному городу
און אין די סוף, אונדזער הויפּט שיטה answer_cb реагирует на нажатие Inline кнопок, что реализовано специальным обработчиком: CallbackQueryHandler(answer_cb).
אין אַ שיטה answer_cb, мы считываем отправленные с клавиатуры данные и записываем их в переменную city: city <- update$callback_query$data. После чего запрашиваем из API данные о погоде, формируем и отправляем сообщение, и в конце концов используем метод answerCallbackQuery для того, что бы сообщить боту, о том, что мы обработали нажатие Inline кнопки.
א ביישפּיל פון אַ באָט וואָס דיספּלייז אַ רשימה פון די לעצטע אַרטיקלען מיט לינקס צו די ספּעסיפיעד הוב פֿון www.habr.com.
Данного бота я привожу для того, что бы показать вам, как вывести Inline кнопки которые ведут на веб страницы.
Логика данного бота схожа с предыдущим, изначально мы запускаем основную клавиатуру командой /start. דערנאָך, דער באָט גיט אונדז אַ רשימה פון 6 כאַבז צו קלייַבן פון, מיר אויסקלייַבן די כאַב וואָס מיר זענען אינטערעסירט אין, און באַקומען די 5 מערסט פריש אויסגאבעס פון די אויסגעקליבן כאַב.
ווי איר פֿאַרשטיין, אין דעם פאַל מיר דאַרפֿן צו באַקומען אַ רשימה פון אַרטיקלען, און פֿאַר דעם מיר וועלן נוצן אַ ספּעציעל פּעקל habR, который позволяет запрашивать из хабры статьи и некоторую статистику по ним в R.
ינסטאַלירן פּעקל habR можно только из github, для чего вам понадобится дополнительный пакет devtools. צו ינסטאַלירן, נוצן די קאָד אונטן.
Список статей из указанного Хаба мы получаем командой habr_hub_posts(), פון די פּעקל habR. גלײכצײטי ק װײז ן מי ר אוי ף דע ר גאנצע ר צײט , א ז מי ר דארפ ן ניש ט קײ ן ארטיקל־רשימה , נא ר נא ר דע ר ערשטע ר בלאט , אוי ף װעלכ ן ע ם געפינע ן זי ך 20 ארטיקלען . פון די ריזאַלטינג טיש ניצן די באַפֿעל head() оставляем только 5 самых верхних, которые и являются самыми свежими статьями.
די לאָגיק איז זייער ענלעך צו די פריערדיקע באָט, אָבער אין דעם פאַל, מיר דזשענערייט אַן ינלינע קלאַוויאַטור מיט אַ רשימה פון אַרטיקלען דינאַמיקאַללי ניצן די פונקציע lapply().