To trzeci artykuł z serii „Tworzymy bota Telegram w języku R”. W poprzednich publikacjach nauczyliśmy się tworzyć bota Telegram, wysyłać przez niego wiadomości, dodawaliśmy komendy i filtry wiadomości. Dlatego przed przystąpieniem do lektury tego artykułu zdecydowanie polecam zapoznać się z , ponieważ tutaj nie będę się zatrzymywać na wcześniej opisanych podstawach budowy bota.
W tym artykule poprawimy użyteczność naszego bota poprzez dodanie klawiatury, która uczyni interfejs bota intuicyjnie zrozumiałym i prostym w użyciu.

Wszystkie artykuły z serii „Tworzymy bota Telegram w języku R”
Spis treści
Jeśli interesujesz się analizą danych, to mogą Cię zainteresować moje i kanały. Większość zawartości poświęcona jest językowi R.
3.1.
3.2.
3.3.
Jakie typy klawiatur wspiera bot Telegram
W momencie pisania artykułu telegram.bot umożliwia Ci stworzenie klawiatur dwóch typów:
- Reply — Podstawowa, normalna klawiatura, która znajduje się pod panelem wprowadzania tekstu wiadomości. Taka klawiatura po prostu wysyła do bota tekstową wiadomość i jako tekst wysyła ten, który jest napisany na samej przycisku.
- Inline — Klawiatura przypisana do konkretnej wiadomości bota. Ta klawiatura przesyła do bota dane związane z naciśniętym przyciskiem, które mogą różnić się od tekstu napisanego na przycisku. Takie przyciski są przetwarzane za pośrednictwem CallbackQueryHandler.
Aby bot otworzył klawiaturę, musisz podczas wysyłania wiadomości przez metodę sendMessage(), przekazać wcześniej utworzoną klawiaturę jako argument reply_markup.
Poniżej omówimy kilka przykładów.
Klawiatura Reply
Jak już wcześniej pisałem, to główna klawiatura sterująca botem.
Przykład tworzenia klawiatury Reply z oficjalnej dokumentacji
bot <- Bot(token = "TOKEN")
chat_id <- "CHAT_ID"
# Tworzenie niestandardowej klawiatury
text <- "Czy te niestandardowe klawiatury nie są fajne?"
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton("Tak, z pewnością!")),
list(KeyboardButton("Nie jestem pewien")),
list(KeyboardButton("Nie..."))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
# Wysyłanie niestandardowej klawiatury
bot$sendMessage(chat_id, text, reply_markup = RKM)Powyżej znajduje się przykład z oficjalnej dokumentacji pakietu telegram.bot. Do tworzenia klawiatury używana jest funkcja ReplyKeyboardMarkup(), która z kolei przyjmuje listę list przycisków, które są tworzone przez funkcję KeyboardButton().
Dlaczego w ReplyKeyboardMarkup() należy przekazywać nie tylko listę, ale listę list? Chodzi o to, że przekazujesz główną listę, a w niej oddzielnymi listami definiujesz każdy rząd przycisków, ponieważ w jednym rzędzie można umieścić kilka przycisków.
Argument resize_keyboard pozwala automatycznie dopasować optymalny rozmiar przycisków klawiatury, a argument one_time_keyboard pozwala ukryć klawiaturę po każdym naciśnięciu przycisku.
Napiszmy prostego bota, który będzie miał 3 przyciski:
- Chat ID — Zapytaj o ID czatu dialogu z botem
- Moje imię — Zapytaj o swoje imię
- Mój login — Zapytaj o swoją nazwę użytkownika w Telegramie
Kod 1: Prosty bot z klawiaturą Reply
library(telegram.bot)
# Tworzymy instancję klasy Updater
updater <- Updater('TWÓJ TOKEN BOTA')
# Tworzymy metody
## metoda do uruchamiania klawiatury
start <- function(bot, update) {
# Tworzymy klawiaturę
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton("ID czatu")),
list(KeyboardButton("Moje imię")),
list(KeyboardButton("Mój login"))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
# Wysyłamy klawiaturę
bot$sendMessage(update$message$chat_id,
text = 'Wybierz komendę',
reply_markup = RKM)
}
## metoda zwracająca ID czatu
chat_id <- function(bot, update) {
bot$sendMessage(update$message$chat_id,
text = paste0("ID czatu tej rozmowy: ", update$message$chat_id),
parse_mode = "Markdown")
}
## metoda zwracająca imię
my_name <- function(bot, update) {
bot$sendMessage(update$message$chat_id,
text = paste0("Nazywasz się ", update$message$from$first_name),
parse_mode = "Markdown")
}
## metoda zwracająca login
my_username <- function(bot, update) {
bot$sendMessage(update$message$chat_id,
text = paste0("Twój login to ", update$message$from$username),
parse_mode = "Markdown")
}
# Tworzymy filtry
## wiadomości z tekstem ID czatu
MessageFilters$chat_id <- BaseFilter(function(message) {
# Sprawdzamy tekst wiadomości
message$text == "ID czatu"
}
)
## wiadomości z tekstem Moje imię
MessageFilters$name <- BaseFilter(function(message) {
# Sprawdzamy tekst wiadomości
message$text == "Moje imię"
}
)
## wiadomości z tekstem Mój login
MessageFilters$username <- BaseFilter(function(message) {
# Sprawdzamy tekst wiadomości
message$text == "Mój login"
)
# Tworzymy obsługiwacze
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)
# Dodajemy obsługiwacze do menedżera
updater <- updater +
h_start +
h_chat_id +
h_name +
h_username
# Uruchamiamy bota
updater$start_polling()Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w ).
Po uruchomieniu, nadaj botowi polecenie /start, ponieważ to właśnie je zdefiniowaliśmy do uruchamiania klawiatury.

Jeśli w tej chwili masz trudności z zrozumieniem powyższego przykładu kodu, z metodami, filtrami i obsługiwaczami, warto wrócić do wcześniejszej , w której szczegółowo to wszystko opisałem.
Stworzyliśmy 4 metody:
- start — Uruchomienie klawiatury
- chat_id — Zapytanie o identyfikator czatu
- my_name — Zapytanie o swoje imię
- my_username — Zapytanie o swój login
Do obiektu MessageFilters dodaliśmy 3 filtry wiadomości, według ich tekstu:
- chat_id — Wiadomości z tekstem
"ID czatu" - name — Wiadomości z tekstem
"Moje imię" - username — Wiadomości z tekstem
"Mój login"
I stworzono 4 obsługiwaczy, które na podstawie podanych poleceń i filtrów będą wykonywać określone metody.
# создаём обработчики
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)Sama klawiatura jest tworzona wewnątrz metody start() poleceniem ReplyKeyboardMarkup().
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(KeyboardButton("ID czatu")),
list(KeyboardButton("Moje imię")),
list(KeyboardButton("Mój login"))
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)W naszym przypadku wszystkie przyciski umieściliśmy jeden pod drugim, ale możemy je umieścić w jednym rzędzie, wprowadzając zmiany w liście list przycisków. Ponieważ jeden rząd w klawiaturze jest tworzony za pomocą zagnieżdżonej listy przycisków, aby wyświetlić nasze przyciski w jednym rzędzie, należy przekształcić część kodu budującego klawiaturę w ten sposób:
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("ID czatu"),
KeyboardButton("Moje imię"),
KeyboardButton("Mój login")
)
),
resize_keyboard = FALSE,
one_time_keyboard = TRUE
)
Klawiatura jest wysyłana do czatu za pomocą metody sendMessage(), w argumencie reply_markup.
bot$sendMessage(update$message$chat_id,
text = 'Wybierz polecenie',
reply_markup = RKM)Klawiatura Inline
Jak już wspomniałem, klawiatura Inline jest przypisana do konkretnej wiadomości. Praca z nią jest nieco bardziej skomplikowana niż z główną klawiaturą.
Najpierw musisz dodać do bota metodę do wywoływania klawiatury Inline.
Aby odpowiedzieć na naciśnięcie przycisku Inline, możesz również użyć metody bota answerCallbackQuery(), która może wyświetlić powiadomienie w interfejsie telegramu użytkownikowi, który nacisnął przycisk Inline.
Dane wysłane z przycisku Inline nie są tekstem, dlatego aby je przetworzyć, należy stworzyć specjalny obsługiwacz za pomocą polecenia CallbackQueryHandler().
Kod budowy klawiatury Inline jest przedstawiony w oficjalnej dokumentacji pakietu telegram.bot.
Kod budowy klawiatury Inline z oficjalnej dokumentacji
# 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)Budowanie klawiatury Inline należy przeprowadzić za pomocą polecenia InlineKeyboardMarkup(), w podobny sposób jak klawiatury Reply. W InlineKeyboardMarkup() należy przekazać listę, list Inline przycisków, każdy przycisk jest tworzony za pomocą funkcji InlineKeyboardButton().
Przycisk Inline może albo przesyłać botowi jakieś dane za pomocą argumentu callback_data, albo otwierać jakąkolwiek stronę HTML, określoną za pomocą argumentu url.
W rezultacie uzyskamy listę, w której każdy element również jest listą przycisków Inline, które należy połączyć w jeden rząd.
Następnie omówimy kilka przykładów botów z przyciskami inline.
Przykład najprostszej aplikacji bota z wsparciem dla przycisków Inline
Na początek napiszemy bota do szybkiego testowania na covid-19. Na komendę /test, wyśle ci klawiaturę z dwoma przyciskami, a w zależności od naciśniętego przycisku wyśle ci wiadomość z wynikami twojego testu.
Kod 2: Najprostszy bot z klawiaturą inline
library(telegram.bot)
# tworzę instancję klasy Updater
updater <- Updater('TOKEN TWOJEGO BOTA')
# metoda do wysyłania klawiatury inline
test <- function(bot, update) {
# tworzę klawiaturę inline
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton("Tak", callback_data = 'yes'),
InlineKeyboardButton("Nie", callback_data = 'no')
)
)
)
# Wysyłam klawiaturę na czat
bot$sendMessage(update$message$chat_id,
text = "Czy masz koronawirusa?",
reply_markup = IKM)
}
# metoda do przetwarzania naciśnięcia przycisku
answer_cb <- function(bot, update) {
# otrzymane dane z przycisku
data <- update$callback_query$data
# uzyskuję imię użytkownika, który nacisnął przycisk
uname <- update$effective_user()$first_name
# przetwarzanie wyniku
if ( data == 'no' ) {
msg <- paste0(uname, ", gratulacje, twój test na covid-19 jest negatywny.")
} else {
msg <- paste0(uname, ", niestety, twój test na covid-19 jest pozytywny.")
}
# Wysłanie wiadomości
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
# informuję bota, że zapytanie z przycisku zostało przyjęte
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# tworzę obsługiwacze
inline_h <- CommandHandler('test', test)
query_handler <- CallbackQueryHandler(answer_cb)
# dodaję obsługiwacze do menedżera
updater <- updater + inline_h + query_handler
# uruchamiam bota
updater$start_polling()Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w ).
Wynik:

Utworzyliśmy dwie metody:
- test — Do wysyłania klawiatury inline na czat
- answer_cb — Do przetwarzania danych wysyłanych z klawiatury.
Dane, które będą wysyłane z każdego przycisku są ustalane w argumencie callback_data, przy tworzeniu przycisku. Otrzymać wysłane z przycisku dane można za pomocą konstrukcji update$callback_query$data, wewnątrz metody answer_cb.
Aby bot reagował na klawiaturę inline, metoda answer_cb jest przetwarzana przez specjalny obsługiwacz: CallbackQueryHandler(answer_cb). Który uruchamia określoną metodę po naciśnięciu przycisku inline. Obsługiwacz CallbackQueryHandler przyjmuje dwa argumenty:
callback— metoda, którą należy uruchomićwzorzec— filtr według danych, które są przypisane do przycisku za pomocą argumentucallback_data.
Odpowiednio za pomocą argumentu wzorzec możemy napisać oddzielną metodę na każde naciśnięcie przycisku:
Kod 3: Rozdzielamy metody dla każdego przycisku inline
library(telegram.bot)
# tworzymy instancję klasy Updater
updater <- Updater('TOKEN TWOJEGO BOTA')
# metoda do wysyłania InLine klawiatury
test <- function(bot, update) {
# tworzymy InLine klawiaturę
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton("Tak", callback_data = 'yes'),
InlineKeyboardButton("Nie", callback_data = 'no')
)
)
)
# Wysyłamy klawiaturę na czacie
bot$sendMessage(update$message$chat_id,
text = "Czy jesteś chory na koronawirusa?",
reply_markup = IKM)
}
# metoda do obsługi kliknięcia przycisku Tak
answer_cb_yes <- function(bot, update) {
# pobieramy imię użytkownika, który kliknął przycisk
uname <- update$effective_user()$first_name
# przetwarzanie wyniku
msg <- paste0(uname, ", niestety twój test na covid-19 jest pozytywny.")
# Wysłanie wiadomości
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
# informujemy bota, że zapytanie z przycisku zostało przyjęte
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# metoda do obsługi kliknięcia przycisku Nie
answer_cb_no <- function(bot, update) {
# pobieramy imię użytkownika, który kliknął przycisk
uname <- update$effective_user()$first_name
msg <- paste0(uname, ", gratulacje, twój test na covid-19 jest negatywny.")
# Wysłanie wiadomości
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
# informujemy bota, że zapytanie z przycisku zostało przyjęte
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# tworzymy obsługiwacze
inline_h <- CommandHandler('test', test)
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no <- CallbackQueryHandler(answer_cb_no, pattern = 'no')
# dodajemy obsługiwacze do menedżera
updater <- updater +
inline_h +
query_handler_yes +
query_handler_no
# uruchamiamy bota
updater$start_polling()Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w ).
Teraz napisaliśmy 2 oddzielne metody, tj. po jednej metodzie na kliknięcie każdego przycisku oraz użyliśmy argumentu wzorzec, przy tworzeniu ich obsługiwaczy:
query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no <- CallbackQueryHandler(answer_cb_no, pattern = 'no')Kończy się kod metody answer_cb poleceniem bot$answerCallbackQuery(callback_query_id = update$callback_query$id), która informuje bota, że dane z inline klawiatury zostały odebrane.
Przykład bota, który informuje o aktualnej pogodzie dla wybranego miasta
Spróbujmy napisać bota, który pyta o dane dotyczące pogody.
Logika działania będzie następująca. Początkowo komendą /start wywołujesz główną klawiaturę, w której znajduje się tylko jeden przycisk "Pogoda". Po naciśnięciu tego przycisku otrzymujesz wiadomość z InLine klawiaturą, aby wybrać miasto, dla którego chcesz znać aktualną pogodę. Wybierasz jedno z miast i otrzymujesz bieżącą prognozę.
W tym przykładzie kodu użyjemy kilku dodatkowych pakietów:
httr— pakiet do obsługi zapytań HTTP, na którym oparta jest praca z każdym API. W naszym przypadku będziemy korzystać z darmowego API .stringr— pakiet do pracy z tekstem, w naszym przypadku będziemy go używać do tworzenia komunikatu o pogodzie w wybranym mieście.
Kod 4: Bot, który informuje o aktualnej pogodzie w wybranym mieście
library(telegram.bot)
library(httr)
library(stringr)
# Tworzymy instancję klasy Updater
updater <- Updater('TOKEN TWOJEGO BOTA')
# Tworzymy metody
## metoda do uruchomienia głównej klawiatury
start <- function(bot, update) {
# Tworzymy klawiaturę
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("Pogoda")
)
),
resize_keyboard = TRUE,
one_time_keyboard = TRUE
)
# Wysyłamy klawiaturę
bot$sendMessage(update$message$chat_id,
text = 'Wybierz polecenie',
reply_markup = RKM)
}
## Metoda wywołania klawiatury Inline
weather <- function(bot, update) {
IKM <- InlineKeyboardMarkup(
inline_keyboard = list(
list(
InlineKeyboardButton(text = 'Moskwa', callback_data = 'New York,us'),
InlineKeyboardButton(text = 'Sankt Petersburg', callback_data = 'Saint Petersburg'),
InlineKeyboardButton(text = 'Nowy Jork', callback_data = 'New York')
),
list(
InlineKeyboardButton(text = 'Jekaterynburg', callback_data = 'Yekaterinburg,ru'),
InlineKeyboardButton(text = 'Berlin', callback_data = 'Berlin,de'),
InlineKeyboardButton(text = 'Paryż', callback_data = 'Paris,fr')
),
list(
InlineKeyboardButton(text = 'Rzym', callback_data = 'Rome,it'),
InlineKeyboardButton(text = 'Odessa', callback_data = 'Odessa,ua'),
InlineKeyboardButton(text = 'Kijów', callback_data = 'Kyiv,fr')
),
list(
InlineKeyboardButton(text = 'Tokio', callback_data = 'Tokyo'),
InlineKeyboardButton(text = 'Amsterdam', callback_data = 'Amsterdam,nl'),
InlineKeyboardButton(text = 'Waszyngton', callback_data = 'Washington,us')
)
)
)
# Wyślij klawiaturę Inline
bot$sendMessage(chat_id = update$message$chat_id,
text = "Wybierz miasto",
reply_markup = IKM)
}
# Metoda do przesyłania informacji o pogodzie
answer_cb <- function(bot, update) {
# Pobieramy miasto z wiadomości
city <- update$callback_query$data
# Wysyłamy zapytanie
ans <- GET('https://api.openweathermap.org/data/2.5/weather',
query = list(q = city,
lang = 'pl',
units = 'metric',
appid = '4776568ccea136ffe4cda9f1969af340'))
# Parsujemy odpowiedź
result <- content(ans)
# Formujemy wiadomość
msg <- str_glue("{result$name} pogoda:n",
"Aktualna temperatura: {result$main$temp}n",
"Prędkość wiatru: {result$wind$speed}n",
"Opis: {result$weather[[1]]$description}")
# Wysyłamy informację o pogodzie
bot$sendMessage(chat_id = update$from_chat_id(),
text = msg)
bot$answerCallbackQuery(callback_query_id = update$callback_query$id)
}
# Tworzymy filtry
## wiadomości z tekstem Pogoda
MessageFilters$weather <- BaseFilter(function(message) {
# Sprawdzamy tekst wiadomości
message$text == "Pogoda"
}
)
# Tworzymy obsługiwacze
h_start <- CommandHandler('start', start)
h_weather <- MessageHandler(weather, filters = MessageFilters$weather)
h_query_handler <- CallbackQueryHandler(answer_cb)
# Dodajemy obsługiwacze do dispatcher
updater <- updater +
h_start +
h_weather +
h_query_handler
# Uruchamiamy bota
updater$start_polling()Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w ).
W rezultacie nasz bot będzie działał mniej więcej tak:

Schematycznie tego bota można zobaczyć tak:

Stworzyliśmy 3 metody, dostępne w naszym bocie pogodowym:
- start — Uruchomienie głównej klawiatury bota
- weather — Uruchomienie klawiatury inline do wyboru miasta
- answer_cb — Główna metoda, która na podstawie podanego miasta pobiera w API dane o pogodzie i wysyła je na czat.
Metoda start uruchamiamy za pomocą komendy /start, co realizuje handler CommandHandler('start', start).
Aby uruchomić metodę weather stworzono filtr o tej samej nazwie:
# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {
# проверяем текст сообщения
message$text == "Погода"
}
)I wywołujemy tę metodę następnym handlerem wiadomości: MessageHandler(weather, filters = MessageFilters$weather).
I w końcu nasza główna metoda answer_cb reaguje na naciśnięcie przycisków inline, co realizuje specjalny handler: CallbackQueryHandler(answer_cb).
Wewnątrz metody answer_cb, odczytujemy dane wysłane z klawiatury i zapisujemy je w zmiennej city: city <- update$callback_query$data. Po czym pobieramy z API dane o pogodzie, formatujemy i wysyłamy wiadomość, a na koniec używamy metody answerCallbackQuery aby poinformować bota, że przetworzyliśmy naciśnięcie przycisku inline.
Przykład bota, który wyświetla listę najnowszych artykułów z linkami do wskazanego Habu z .
Tego bota podaję, aby pokazać Wam, jak wyświetlić przyciski inline, które prowadzą do stron internetowych.
Logika tego bota jest podobna do poprzedniego, najpierw uruchamiamy główną klawiaturę komendą /start. Następnie bot daje nam do wyboru listę 6 hubów, wybieramy interesujący nas hub i otrzymujemy 5 najnowszych publikacji z wybranego Habu.
Jak rozumiecie, w tym przypadku musimy uzyskać listę artykułów, i w tym celu będziemy używać specjalnego pakietu habR, który pozwala na pobieranie artykułów z Habr i pewnych statystyk na ich temat w R.
Zainstalować pakiet habR można tylko z github, do czego potrzebny będzie dodatkowy pakiet devtools. Do instalacji użyj poniższego kodu.
install.packages('devtools')
devtools::install_github('selesnow/habR')Teraz przyjrzyjmy się kodowi opisującemu powyższego bota:
Kod 5: Bot, który wyświetla listę najnowszych artykułów z wybranego Habu
library(telegram.bot)
library(habR)
# Tworzymy instancję klasy Updater
updater <- Updater('TOKEN TWOJEGO BOTA')
# Tworzymy metody
## metoda do uruchomienia głównej klawiatury
start <- function(bot, update) {
# Tworzymy klawiaturę
RKM <- ReplyKeyboardMarkup(
keyboard = list(
list(
KeyboardButton("Lista artykułów")
)
),
resize_keyboard = TRUE,
one_time_keyboard = TRUE
)
# Wysyłamy klawiaturę
bot$sendMessage(update$message$chat_id,
text = 'Wybierz polecenie',
reply_markup = RKM)
}
## Metoda wywołania klawiatury Inline
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 = 'Wizualizacja danych', callback_data = 'data_visualization')
)
)
)
# Wysyłamy klawiaturę Inline
bot$sendMessage(chat_id = update$message$chat_id,
text = "Wybierz Hub",
reply_markup = IKM)
}
# metoda do przekazywania prognozy pogody
answer_cb <- function(bot, update) {
# Pobieramy z wiadomości hub
hub <- update$callback_query$data
# Wiadomość informująca, że dane z przycisku zostały odebrane
bot$answerCallbackQuery(callback_query_id = update$callback_query$id,
text = 'Proszę czekać kilka minut, przetwarzam zapytanie')
# Wiadomość informująca, że należy poczekać, aż bot uzyska dane
mid <- bot$sendMessage(chat_id = update$from_chat_id(),
text = "Proszę czekać kilka minut, podczas gdy zbieram dane o wybranym Hubie")
# Parsowanie Habr
posts <- head(habr_hub_posts(hub, 1), 5)
# Usuwamy wiadomość informującą, że należy czekać
bot$deleteMessage(update$from_chat_id(), mid$message_id)
# Tworzymy listę przycisków
keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))
# Tworzymy klawiaturę
IKM <- InlineKeyboardMarkup(
inline_keyboard = keys
)
# Wysyłamy informacje o pogodzie
bot$sendMessage(chat_id = update$from_chat_id(),
text = paste0("5 najnowszych artykułów z Habu ", hub),
reply_markup = IKM)
}
# Tworzymy filtry
## wiadomości z tekstem Pogoda
MessageFilters$hubs <- BaseFilter(function(message) {
# Sprawdzamy tekst wiadomości
message$text == "Lista artykułów"
}
)
# Tworzymy obsługiwacze
h_start <- CommandHandler('start', start)
h_hubs <- MessageHandler(habs, filters = MessageFilters$hubs)
h_query_handler <- CallbackQueryHandler(answer_cb)
# Dodajemy obsługiwacze do menedżera
updater <- updater +
h_start +
h_hubs +
h_query_handler
# Uruchamiamy bota
updater$start_polling()Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w ).
W rezultacie uzyskamy taki efekt:

Listę dostępnych do wyboru Hublów wprowadziliśmy na sztywno w metodzie 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)
}Listę artykułów z podanego Hublu otrzymujemy za pomocą komendy habr_hub_posts(), z pakietu habR. Przy tym wskazujemy, że nie potrzebujemy listy artykułów za cały czas, a jedynie pierwszej strony, na której znajduje się 20 artykułów. Z uzyskanej tabeli za pomocą komendy head() zostawiamy tylko 5 najwyższych, które są najnowszymi artykułami.
# парсим Хабр
posts <- head(habr_hub_posts(hub, 1), 5)Logika jest bardzo podobna do poprzedniego bota, ale w tym przypadku inline klawiaturę ze listą artykułów generujemy dynamicznie za pomocą funkcji lapply().
# формируем список кнопок
keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))
# формируем клавиатуру
IKM <- InlineKeyboardMarkup(
inline_keyboard = keys
)Do tekstu przycisku podstawiamy tytuł artykułu posts$title[x], a w argument url link do artykułu: url = posts$link[x].
Następnie tworzymy filtr, obsługiwacze i uruchamiamy naszego bota.
Podsumowanie
Teraz napisane przez Ciebie boty będą znacznie wygodniejsze w użytkowaniu, ponieważ zarządzanie nimi odbywać się będzie za pomocą klawiatury, a nie poprzez wprowadzanie komend. Przynajmniej przy interakcji z botem za pomocą smartfona klawiatura znacznie uprości proces użytkowania.
W następnym artykule rozwiążemy, jak budować logiczny dialog z botem i pracować z bazami danych.
Źródło: habr.com
