Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

To już trzeci artykuł z serii „Pisanie bota telegramowego w R”. W poprzednich publikacjach dowiedzieliśmy się jak stworzyć bota telegramowego, wysyłać za jego pośrednictwem wiadomości, dodawać do bota polecenia i filtry wiadomości. Dlatego zanim zaczniesz czytać ten artykuł, gorąco polecam go przeczytać poprzedni, ponieważ Nie będę już rozwodzić się nad wcześniej opisanymi podstawami budowania botów.

W tym artykule poprawimy użyteczność naszego bota, dodając klawiaturę, dzięki której interfejs bota będzie intuicyjny i łatwy w użyciu.

Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Wszystkie artykuły z serii „Pisanie bota telegramowego w R”

  1. Tworzymy bota i używamy go do wysyłania wiadomości w telegramie
  2. Dodaj obsługę poleceń i filtry wiadomości do bota
  3. Jak dodać obsługę klawiatury do bota

Zawartość

Jeśli interesuje Cię analiza danych, być może zainteresuje Cię mój telegram и youtube kanały. Większość treści jest poświęcona językowi R.

  1. Jakie typy klawiatur obsługuje bot telegramu?
  2. Klawiatura odpowiedzi
  3. Klawiatura wbudowana
    3.1. Przykład prostego bota z obsługą przycisków InLine
    3.2. Przykład bota raportującego aktualną pogodę dla wybranego miasta
    3.3. Przykład bota wyświetlającego listę najnowszych artykułów z linkami do określonego Huba z habr.com
  4. wniosek

Jakie typy klawiatur obsługuje bot telegramu?

W momencie pisania tego tekstu telegram.bot umożliwia utworzenie dwóch typów klawiatur:

  • Odpowiedź - główna, zwykła klawiatura, która znajduje się pod panelem wprowadzania tekstu wiadomości. Taka klawiatura po prostu wysyła do bota wiadomość tekstową, a jako tekst wyśle ​​​​tekst, który jest zapisany na samym przycisku.
  • Inline — klawiatura powiązana z konkretną wiadomością od bota. Ta klawiatura wysyła do bota dane powiązane z naciśniętym przyciskiem; dane te mogą różnić się od tekstu zapisanego na samym przycisku. I takie przyciski są przetwarzane Funkcja obsługi zapytań zwrotnych.

Aby bot otworzył klawiaturę, jest to konieczne podczas wysyłania wiadomości tą metodą sendMessage(), podaj wcześniej utworzoną klawiaturę jako argument reply_markup.

Poniżej przyjrzymy się kilku przykładom.

Klawiatura odpowiedzi

Jak pisałem powyżej jest to główna klawiatura sterująca botem.

Przykład tworzenia klawiatury odpowiedzi z oficjalnej pomocy

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)

Powyższy przykład pochodzi z oficjalnej pomocy pakietu telegram.bot. Aby utworzyć klawiaturę, użyj funkcji ReplyKeyboardMarkup(), co z kolei pobiera listę list przycisków tworzonych przez funkcję KeyboardButton().

Dlaczego w ReplyKeyboardMarkup() Czy musisz przekazać nie tylko listę, ale listę list? Faktem jest, że przekazujesz listę główną, a na niej definiujesz każdy rząd przycisków na osobnych listach, ponieważ Możesz umieścić kilka przycisków w jednym rzędzie.

argument resize_keyboard pozwala automatycznie wybrać optymalny rozmiar przycisków klawiatury i argumentu one_time_keyboard pozwala ukryć klawiaturę po każdym naciśnięciu przycisku.

Napiszmy prostego bota, który będzie miał 3 przyciski:

  • Identyfikator czatu — żądanie identyfikatora czatu dialogu z botem
  • Moje imię — poproś o podanie imienia
  • Mój login — poproś o nazwę użytkownika w telegramie

Kod 1: Prosty bot z klawiaturą odpowiedzi

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()

Uruchom powyższy przykładowy kod, po zastąpieniu „TWOJEGO ŻETONA BOTA” prawdziwym tokenem, który otrzymałeś podczas tworzenia bota poprzez Ojciec Bota (Mówiłem o stworzeniu bota w Pierwszy artykuł).

Po uruchomieniu wydaj botowi polecenie /start, ponieważ Dokładnie to zdefiniowaliśmy, aby uruchomić klawiaturę.

Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Jeśli w tej chwili trudno Ci przeanalizować podany przykładowy kod, wraz z utworzeniem metod, filtrów i handlerów, to powinieneś wrócić do poprzedniego Artykuł, w którym wszystko to szczegółowo opisałem.

Stworzyliśmy 4 metody:

  • start — Uruchom klawiaturę
  • chat_id — Poproś o identyfikator czatu
  • my_name — Poproś o podanie imienia
  • my_username — Poproś o login

Sprzeciwiać się Filtry wiadomości dodano 3 filtry wiadomości na podstawie ich tekstu:

  • chat_id — Wiadomości z tekstem "Чат ID"
  • nazwa — Wiadomości z tekstem "Моё имя"
  • nazwa użytkownika — Wiadomości z tekstem "Мой логин"

Stworzyliśmy 4 procedury obsługi, które na podstawie podanych poleceń i filtrów wykonają 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() według zespołu ReplyKeyboardMarkup().

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(KeyboardButton("Чат ID")),
      list(KeyboardButton("Моё имя")),
      list(KeyboardButton("Мой логин"))
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

W naszym przypadku wszystkie przyciski umieściliśmy pod sobą, ale możemy je ułożyć w jednym rzędzie dokonując zmian na liście list przycisków. Ponieważ jeden wiersz wewnątrz klawiatury tworzony jest poprzez zagnieżdżoną listę przycisków, wówczas aby wyświetlić nasze przyciski w jednym rzędzie musimy przepisać część kodu budującego klawiaturę w następujący sposób:

RKM <- ReplyKeyboardMarkup(
    keyboard = list(
      list(
          KeyboardButton("Чат ID"),
          KeyboardButton("Моё имя"),
          KeyboardButton("Мой логин")
     )
    ),
    resize_keyboard = FALSE,
    one_time_keyboard = TRUE
)

Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Klawiatura jest wysyłana do czatu za pomocą metody sendMessage(), w argumentacji reply_markup.

  bot$sendMessage(update$message$chat_id,
                  text = 'Выберите команду', 
                  reply_markup = RKM)

Klawiatura wbudowana

Jak pisałem powyżej, klawiatura Inline jest powiązana z konkretnym komunikatem. Praca z nią jest nieco trudniejsza niż z klawiaturą główną.

Początkowo musisz dodać do bota metodę wywoływania klawiatury Inline.

Aby odpowiedzieć na kliknięcie przycisku Inline, możesz także skorzystać z metody bota answerCallbackQuery(), który może wyświetlić powiadomienie w interfejsie telegramu użytkownikowi, który naciśnie przycisk Inline.

Dane wysyłane z przycisku Inline nie są tekstem, dlatego aby je przetworzyć należy za pomocą polecenia utworzyć specjalny moduł obsługi CallbackQueryHandler().

Kod do zbudowania klawiatury Inline podany w oficjalnej pomocy pakietu telegram.bot.

Kod do zbudowania klawiatury Inline z oficjalnej pomocy

# 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)

Musisz zbudować klawiaturę Inline za pomocą polecenia InlineKeyboardMarkup(), na tej samej zasadzie co klawiatura Odpowiedz. W InlineKeyboardMarkup() konieczne jest przekazanie listy list przycisków Inline, każdy indywidualny przycisk jest tworzony przez funkcję InlineKeyboardButton().

Przycisk wbudowany może przekazać botowi pewne dane za pomocą argumentu callback_datalub otwórz dowolną stronę HTML określoną za pomocą argumentu url.

Rezultatem będzie lista, w której każdy element jest jednocześnie listą przycisków Inline, które należy połączyć w jeden wiersz.

Następnie przyjrzymy się kilku przykładom botów z przyciskami Inline.

Przykład prostego bota z obsługą przycisków InLine

Na początek napiszemy bota do ekspresowych testów na covid-19. Na polecenie /test, wyśle ​​​​Ci klawiaturę z dwoma przyciskami, w zależności od naciśniętego przycisku wyśle ​​​​Ci wiadomość z wynikami testu.

Kod 2: Najprostszy bot z klawiaturą Inline

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()

Uruchom powyższy przykładowy kod, po zastąpieniu „TWOJEGO ŻETONA BOTA” prawdziwym tokenem, który otrzymałeś podczas tworzenia bota poprzez Ojciec Bota (Mówiłem o stworzeniu bota w Pierwszy artykuł).

Wynik:
Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Stworzyliśmy dwie metody:

  • test — Aby wysłać do czatu Klawiatura wbudowana
  • odpowiedź_cb — Aby przetwarzać dane przesyłane z klawiatury.

Dane, które zostaną wysłane z każdego przycisku, są określone w argumencie callback_data, podczas tworzenia przycisku. Dane wysyłane z przycisku możesz odbierać za pomocą konstrukcji update$callback_query$data, wewnątrz metody odpowiedź_cb.

Aby bot reagował na klawiaturę Inline, metoda odpowiedź_cb przetwarzane przez specjalnego handlera: CallbackQueryHandler(answer_cb). Który uruchamia określoną metodę po kliknięciu przycisku Inline. Treser Funkcja obsługi zapytań zwrotnych przyjmuje dwa argumenty:

  • callback — Metoda, która ma zostać uruchomiona
  • pattern — Filtruj według danych powiązanych z przyciskiem za pomocą argumentu callback_data.

W związku z tym, używając argumentu pattern Możemy napisać osobną metodę naciskania każdego przycisku:

Kod 3: Oddzielne metody dla każdego przycisku Inline

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()

Uruchom powyższy przykładowy kod, po zastąpieniu „TWOJEGO ŻETONA BOTA” prawdziwym tokenem, który otrzymałeś podczas tworzenia bota poprzez Ojciec Bota (Mówiłem o stworzeniu bota w Pierwszy artykuł).

Teraz napisaliśmy 2 oddzielne metody, tj. jedną metodę na każde naciśnięcie przycisku i użył argumentu pattern, podczas tworzenia ich procedur obsługi:

query_handler_yes <- CallbackQueryHandler(answer_cb_yes, pattern = 'yes')
query_handler_no  <- CallbackQueryHandler(answer_cb_no, pattern = 'no')

Kod metody kończy się odpowiedź_cb według zespołu bot$answerCallbackQuery(callback_query_id = update$callback_query$id), który informuje bota, że ​​odebrane zostały dane z wbudowanej klawiatury.

Przykład bota raportującego aktualną pogodę dla wybranego miasta

Spróbujmy napisać bota żądającego danych o pogodzie.

Logika jego działania będzie następująca. Początkowo przez zespół /start wywołujesz klawiaturę główną, która ma tylko jeden przycisk „Pogoda”. Kliknięcie tego przycisku spowoduje wyświetlenie komunikatu z klawiaturą Inline w celu wybrania miasta, dla którego chcesz sprawdzić aktualną pogodę. Wybierz jedno z miast i poznaj aktualną pogodę.

W tym przykładzie kodu użyjemy kilku dodatkowych pakietów:

  • httr — pakiet do pracy z żądaniami HTTP, na podstawie którego budowana jest praca z dowolnym API. W naszym przypadku skorzystamy z darmowego API openweathermap.org.
  • stringr — pakiet do pracy z tekstem, w naszym przypadku wykorzystamy go do wygenerowania komunikatu o pogodzie w wybranym mieście.

Kod 4: Bot raportujący aktualną pogodę dla wybranego miasta

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()

Uruchom powyższy przykładowy kod, po zastąpieniu „TWOJEGO ŻETONA BOTA” prawdziwym tokenem, który otrzymałeś podczas tworzenia bota poprzez Ojciec Bota (Mówiłem o stworzeniu bota w Pierwszy artykuł).

W rezultacie nasz bot będzie działał mniej więcej tak:
Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Schematycznie tego bota można przedstawić w następujący sposób:
Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Stworzyliśmy 3 metody dostępne w naszym bocie pogodowym:

  • początek — Uruchom główną klawiaturę bota
  • pogoda — Uruchom klawiaturę Inline, aby wybrać miasto
  • odpowiedź_cb — Główna metoda, która żąda pogody z API dla danego miasta i wysyła ją na czat.

metoda początek uruchamiamy go za pomocą polecenia /start, który jest implementowany przez procedurę obsługi CommandHandler('start', start).

Aby uruchomić metodę pogoda stworzyliśmy filtr o tej samej nazwie:

# создаём фильтры
## сообщения с текстом Погода
MessageFilters$weather <- BaseFilter(function(message) {

  # проверяем текст сообщения
  message$text == "Погода"

}
)

I wywołujemy tę metodę z następującą procedurą obsługi komunikatów: MessageHandler(weather, filters = MessageFilters$weather).

I na koniec nasza główna metoda odpowiedź_cb reaguje na wciśnięcie przycisków Inline, co jest realizowane przez specjalny handler: CallbackQueryHandler(answer_cb).

Wewnątrz metody odpowiedź_cb, odczytujemy dane przesłane z klawiatury i zapisujemy je do zmiennej city: city <- update$callback_query$data. Następnie żądamy danych pogodowych z API, generujemy i wysyłamy wiadomość, a na koniec korzystamy z metody answerCallbackQuery w celu poinformowania bota, że ​​przetworzyliśmy kliknięcie przycisku Inline.

Przykład bota wyświetlającego listę najnowszych artykułów z linkami do określonego Huba www.habr.com.

Prezentuję tego bota, aby pokazać Ci, jak wyświetlić przyciski Inline prowadzące do stron internetowych.

Logika tego bota jest podobna do poprzedniego, początkowo uruchamiamy klawiaturę główną za pomocą polecenia /start. Następnie bot podaje nam listę 6 hubów do wyboru, wybieramy hub, który nas interesuje i odbieramy 5 najnowszych publikacji z wybranego Huba.

Jak rozumiesz, w tym przypadku musimy uzyskać listę artykułów i do tego użyjemy specjalnego pakietu habR, który umożliwia żądanie artykułów z Habra i niektórych statystyk na ich temat w R.

Zainstaluj pakiet habR możliwe tylko z githuba, do którego będziesz potrzebować dodatkowego pakietu devtools. Aby zainstalować użyj poniższego kodu.

install.packages('devtools')
devtools::install_github('selesnow/habR')

Przyjrzyjmy się teraz kodowi budowy bota opisanego powyżej:

Kod 5: Bot wyświetlający listę najnowszych artykułów w wybranym Hubie

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()

Uruchom powyższy przykładowy kod, po zastąpieniu „TWOJEGO ŻETONA BOTA” prawdziwym tokenem, który otrzymałeś podczas tworzenia bota poprzez Ojciec Bota (Mówiłem o stworzeniu bota w Pierwszy artykuł).

W rezultacie otrzymamy taki wynik:
Pisanie telegramowego bota w R (część 3): Jak dodać obsługę klawiatury do bota

Zakodowaliśmy na stałe listę koncentratorów dostępnych do wyboru 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)
}

Za pomocą polecenia otrzymujemy listę artykułów z określonego Huba habr_hub_posts(), z pakietu habR. Jednocześnie zwracamy uwagę, że nie potrzebujemy spisu artykułów na cały czas, a jedynie pierwszą stronę, na której znajduje się 20 artykułów. Z wynikowej tabeli za pomocą polecenia head() Zostawiamy tylko 5 najlepszych, czyli najnowsze artykuły.

  # парсим Хабр
  posts <- head(habr_hub_posts(hub, 1), 5)

Logika jest bardzo podobna do poprzedniego bota, jednak w tym przypadku klawiaturę Inline z 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 
    )

Wstawiamy tytuł artykułu do tekstu przycisku posts$title[x]i w argumentacji url link do artykułu: url = posts$link[x].

Następnie tworzymy filtr, handlery i uruchamiamy naszego bota.

wniosek

Teraz obsługa botów, które napiszesz, będzie dużo wygodniejsza, bo sterować nimi będziesz z klawiatury, a nie poprzez wpisywanie poleceń. Przynajmniej podczas interakcji z botem za pośrednictwem smartfona klawiatura znacznie uprości proces jej obsługi.

W kolejnym artykule dowiemy się jak zbudować logiczny dialog z botem i pracować z bazami danych.

Źródło: www.habr.com

Dodaj komentarz