Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Il s'agit du troisième article de la série « Écrire un robot télégramme en R ». Dans des publications précédentes, nous avons appris à créer un robot télégramme, à envoyer des messages via celui-ci, à ajouter des commandes et des filtres de messages au robot. Par conséquent, avant de commencer à lire cet article, je vous recommande fortement de lire précédent, parce que Ici, je ne m'attarderai plus sur les bases décrites précédemment de la création de bots.

Dans cet article, nous allons améliorer la convivialité de notre bot en ajoutant un clavier, ce qui rendra l'interface du bot intuitive et facile à utiliser.

Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Tous les articles de la série « Écrire un bot télégramme en R »

  1. Nous créons un bot et l'utilisons pour envoyer des messages par télégramme
  2. Ajouter la prise en charge des commandes et des filtres de messages au bot
  3. Comment ajouter la prise en charge du clavier à un bot

Teneur

Si vous êtes intéressé par l'analyse des données, vous pourriez être intéressé par mon télégramme и Youtube canaux. La plupart du contenu est dédié au langage R.

  1. Quels types de claviers le robot Telegram prend-il en charge ?
  2. Clavier de réponse
  3. Clavier en ligne
    3.1. Un exemple de bot simple prenant en charge les boutons InLine
    3.2. Un exemple de bot qui rapporte la météo actuelle pour une ville sélectionnée
    3.3. Un exemple de bot qui affiche une liste des derniers articles avec des liens vers le Hub spécifié depuis habr.com
  4. Conclusion

Quels types de claviers le robot Telegram prend-il en charge ?

Au moment de la rédaction telegram.bot permet de créer deux types de claviers :

  • Répondre : le clavier principal normal, situé sous le panneau de saisie du texte du message. Un tel clavier envoie simplement un message texte au bot, et comme texte, il enverra le texte écrit sur le bouton lui-même.
  • Inline - Clavier associé à un message de bot spécifique. Ce clavier envoie les données du bot associées au bouton enfoncé ; ces données peuvent différer du texte écrit sur le bouton lui-même. Et ces boutons sont traités via Gestionnaire de requêtes de rappel.

Pour que le bot ouvre le clavier, cela est nécessaire lors de l'envoi d'un message via la méthode sendMessage(), passez le clavier créé précédemment en argument reply_markup.

Ci-dessous, nous examinerons plusieurs exemples.

Clavier de réponse

Comme je l'ai écrit ci-dessus, il s'agit du clavier principal de contrôle du robot.

Un exemple de création d'un clavier de réponse à partir de l'aide officielle

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)

Ce qui précède est un exemple tiré de l'aide officielle du package telegram.bot. Pour créer un clavier, utilisez la fonction ReplyKeyboardMarkup(), qui à son tour prend une liste de listes de boutons créés par la fonction KeyboardButton().

Pourquoi ReplyKeyboardMarkup() Avez-vous besoin de transmettre non seulement une liste, mais une liste de listes ? Le fait est que vous passez la liste principale et que vous y définissez chaque rangée de boutons dans des listes séparées, car Vous pouvez placer plusieurs boutons sur une seule rangée.

Argument resize_keyboard vous permet de sélectionner automatiquement la taille optimale des boutons du clavier et l'argument one_time_keyboard vous permet de masquer le clavier après chaque pression sur un bouton.

Écrivons un bot simple qui aura 3 boutons :

  • ID de chat - Demander l'ID de chat du dialogue avec le bot
  • Mon nom - Demandez votre nom
  • Mon identifiant - Demandez votre nom d'utilisateur par télégramme

Code 1 : bot simple avec clavier de réponse

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

Exécutez l'exemple de code ci-dessus, après avoir remplacé « VOTRE JETON DE BOT » par le vrai jeton que vous avez reçu lors de la création du bot via BotFather (J'ai parlé de créer un bot dans premier article).

Après le lancement, donnez une commande au bot /start, parce que C'est exactement ce que nous avons défini pour lancer le clavier.

Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Si pour le moment il vous est difficile d'analyser l'exemple de code donné, avec la création de méthodes, de filtres et de gestionnaires, alors vous devriez revenir au précédent article, dans lequel j'ai décrit tout cela en détail.

Nous avons créé 4 méthodes :

  • start — Lance le clavier
  • chat_id — Demander un identifiant de chat
  • my_name — Demandez votre nom
  • my_username — Demandez votre connexion

Pour s'opposer Filtres de messages ajout de 3 filtres de messages en fonction de leur texte :

  • chat_id — Messages avec texte "Чат ID"
  • nom — Messages avec texte "Моё имя"
  • nom d'utilisateur — Messages avec texte "Мой логин"

Et nous avons créé 4 gestionnaires qui, sur la base de commandes et de filtres donnés, exécuteront les méthodes spécifiées.

# создаём обработчики
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)

Le clavier lui-même est créé dans la méthode start() l'équipe ReplyKeyboardMarkup().

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

Dans notre cas, nous avons placé tous les boutons les uns sous les autres, mais nous pouvons les disposer sur une seule ligne en modifiant la liste des listes de boutons. Parce que une ligne à l'intérieur du clavier est créée via une liste imbriquée de boutons, puis afin d'afficher nos boutons sur une seule ligne, nous devons réécrire une partie du code pour construire le clavier comme ceci :

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

Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Le clavier est envoyé au chat en utilisant la méthode sendMessage(), dans l'argumentation reply_markup.

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

Clavier en ligne

Comme je l'ai écrit ci-dessus, le clavier en ligne est lié à un message spécifique. Il est un peu plus difficile à utiliser que le clavier principal.

Initialement, vous devez ajouter une méthode au bot pour appeler le clavier en ligne.

Pour répondre à un clic sur un bouton en ligne, vous pouvez également utiliser la méthode bot answerCallbackQuery(), qui peut afficher une notification dans l'interface de télégramme à l'utilisateur qui appuie sur le bouton Inline.

Les données envoyées depuis le bouton Inline ne sont pas du texte, donc pour les traiter, vous devez créer un gestionnaire spécial à l'aide de la commande CallbackQueryHandler().

Le code pour construire un clavier Inline qui est donné dans l'aide officielle du package telegram.bot.

Code pour créer un clavier en ligne à partir de l'aide officielle

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

Vous devez créer un clavier en ligne à l'aide de la commande InlineKeyboardMarkup(), sur le même principe que le clavier Réponse. DANS InlineKeyboardMarkup() il est nécessaire de passer une liste de listes de boutons Inline, chaque bouton individuel est créé par la fonction InlineKeyboardButton().

Un bouton en ligne peut soit transmettre des données au bot à l'aide d'un argument callback_data, ou ouvrez n'importe quelle page HTML spécifiée à l'aide de l'argument url.

Le résultat sera une liste dans laquelle chaque élément est également une liste de boutons en ligne qui doivent être combinés en une seule ligne.

Nous examinerons ensuite plusieurs exemples de robots dotés de boutons Inline.

Un exemple de bot simple prenant en charge les boutons InLine

Tout d’abord, nous allons écrire un bot pour des tests express pour covid-19. Par commande /test, il vous enverra un clavier avec deux boutons, en fonction du bouton enfoncé il vous enverra un message avec les résultats de vos tests.

Code 2 : Le bot le plus simple avec un clavier en ligne

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

Exécutez l'exemple de code ci-dessus, après avoir remplacé « VOTRE JETON DE BOT » par le vrai jeton que vous avez reçu lors de la création du bot via BotFather (J'ai parlé de créer un bot dans premier article).

Résultat:
Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Nous avons créé deux méthodes :

  • tester — Pour envoyer au chat Clavier en ligne
  • réponse_cb — Pour traiter les données envoyées depuis le clavier.

Les données qui seront envoyées depuis chaque bouton sont spécifiées dans l'argument callback_data, lors de la création d'un bouton. Vous pouvez recevoir les données envoyées depuis le bouton en utilisant la construction update$callback_query$data, à l'intérieur de la méthode réponse_cb.

Pour que le bot réagisse au clavier Inline, méthode réponse_cb traité par un gestionnaire spécial : CallbackQueryHandler(answer_cb). Qui exécute la méthode spécifiée lorsque vous cliquez sur le bouton Inline. Gestionnaire Gestionnaire de requêtes de rappel prend deux arguments :

  • callback — La méthode à exécuter
  • pattern — Filtrer par données liées au bouton à l'aide d'un argument callback_data.

En conséquence, en utilisant l’argument pattern Nous pouvons écrire une méthode distincte pour appuyer sur chaque bouton :

Code 3 : méthodes distinctes pour chaque bouton en ligne

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

Exécutez l'exemple de code ci-dessus, après avoir remplacé « VOTRE JETON DE BOT » par le vrai jeton que vous avez reçu lors de la création du bot via BotFather (J'ai parlé de créer un bot dans premier article).

Nous avons maintenant écrit 2 méthodes distinctes, à savoir une méthode, pour chaque pression sur un bouton, et utilisé l'argument pattern, lors de la création de leurs gestionnaires :

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

Le code de la méthode se termine réponse_cb l'équipe bot$answerCallbackQuery(callback_query_id = update$callback_query$id), qui indique au bot que les données du clavier en ligne ont été reçues.

Un exemple de bot qui rapporte la météo actuelle pour une ville sélectionnée

Essayons d'écrire un bot qui demande des données météorologiques.

La logique de son travail sera la suivante. Initialement par l'équipe /start vous appelez le clavier principal, qui n'a qu'un seul bouton « Météo ». En cliquant sur ce bouton, vous recevrez un message avec le clavier Inline pour sélectionner la ville pour laquelle vous souhaitez connaître la météo actuelle. Sélectionnez l'une des villes et obtenez la météo actuelle.

Dans cet exemple de code, nous utiliserons plusieurs packages supplémentaires :

  • httr — un package pour travailler avec des requêtes HTTP, sur la base duquel le travail avec n'importe quelle API est construit. Dans notre cas nous utiliserons l'API gratuite openweathermap.org.
  • stringr — un package pour travailler avec du texte, dans notre cas nous l'utiliserons pour générer un message sur la météo dans la ville sélectionnée.

Code 4 : Un bot qui rapporte la météo actuelle pour la ville sélectionnée

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

Exécutez l'exemple de code ci-dessus, après avoir remplacé « VOTRE JETON DE BOT » par le vrai jeton que vous avez reçu lors de la création du bot via BotFather (J'ai parlé de créer un bot dans premier article).

En conséquence, notre bot fonctionnera à peu près comme ceci :
Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Schématiquement, ce bot peut être représenté comme ceci :
Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Nous avons créé 3 méthodes disponibles dans notre bot météo :

  • Commencer — Lancez le clavier principal du bot
  • météo — Lancez le clavier en ligne pour sélectionner une ville
  • réponse_cb — La méthode principale qui demande la météo à l'API pour une ville donnée et l'envoie au chat.

méthode Commencer on le lance avec la commande /start, qui est implémenté par le gestionnaire CommandHandler('start', start).

Pour exécuter une méthode météo nous avons créé un filtre du même nom :

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

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

}
)

Et nous appelons cette méthode avec le gestionnaire de messages suivant : MessageHandler(weather, filters = MessageFilters$weather).

Et au final, notre méthode principale réponse_cb réagit à l'appui sur les boutons Inline, qui est implémenté par un gestionnaire spécial : CallbackQueryHandler(answer_cb).

À l'intérieur d'une méthode réponse_cb, nous lisons les données envoyées depuis le clavier et les écrivons dans une variable city: city <- update$callback_query$data. Ensuite, nous demandons des données météorologiques à l'API, générons et envoyons un message, et enfin utilisons la méthode answerCallbackQuery afin d'informer le bot que nous avons traité le clic sur le bouton Inline.

Un exemple de bot qui affiche une liste des derniers articles avec des liens vers le Hub spécifié à partir de habr.com.

Je présente ce bot pour vous montrer comment afficher les boutons en ligne qui mènent à des pages Web.

La logique de ce bot est similaire au précédent ; dans un premier temps on lance le clavier principal avec la commande /start. Ensuite, le bot nous propose une liste de 6 hubs parmi lesquels choisir, nous sélectionnons le hub qui nous intéresse et recevons les 5 publications les plus récentes du Hub sélectionné.

Comme vous le comprenez, dans ce cas, nous devons obtenir une liste d'articles et pour cela, nous utiliserons un package spécial. habR, qui vous permet de demander des articles à Habra et quelques statistiques à leur sujet dans R.

Installer le paquet habR uniquement possible depuis github, pour lequel vous aurez besoin d'un package supplémentaire devtools. Pour installer, utilisez le code ci-dessous.

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

Examinons maintenant le code de construction du bot décrit ci-dessus :

Code 5 : Un bot qui affiche une liste des articles les plus récents sur le Hub sélectionné

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

Exécutez l'exemple de code ci-dessus, après avoir remplacé « VOTRE JETON DE BOT » par le vrai jeton que vous avez reçu lors de la création du bot via BotFather (J'ai parlé de créer un bot dans premier article).

En conséquence, nous obtiendrons ce résultat :
Écrire un bot de télégramme dans R (partie 3) : comment ajouter la prise en charge du clavier à un bot

Nous avons codé en dur la liste des Hubs disponibles pour la sélection dans la méthode 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)
}

Nous obtenons une liste d'articles du Hub spécifié avec la commande habr_hub_posts(), du paquet habR. Dans le même temps, nous soulignons que nous n'avons pas besoin d'une liste d'articles pour tout le temps, mais seulement de la première page sur laquelle se trouvent 20 articles. À partir du tableau résultant à l'aide de la commande head() Nous ne laissons que le top 5, qui sont les articles les plus récents.

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

La logique est très similaire au bot précédent, mais dans ce cas nous générons dynamiquement un clavier Inline avec une liste d'articles en utilisant la fonction lapply().

  # формируем список кнопок
  keys <- lapply(1:5, function(x) list(InlineKeyboardButton(posts$title[x], url = posts$link[x])))

  # формируем клавиатуру
  IKM <- InlineKeyboardMarkup(
    inline_keyboard =  keys 
    )

Nous insérons le titre de l'article dans le texte du bouton posts$title[x], et dans l'argumentation url lien vers l'article : url = posts$link[x].

Ensuite, nous créons un filtre, des gestionnaires et lançons notre bot.

Conclusion

Désormais, les robots que vous écrivez seront beaucoup plus pratiques à utiliser, car ils seront contrôlés à partir du clavier plutôt qu'en saisissant des commandes. Au minimum, lors de l'interaction avec un bot via un smartphone, le clavier simplifiera considérablement le processus d'utilisation de celui-ci.

Dans le prochain article, nous verrons comment construire un dialogue logique avec un bot et travailler avec des bases de données.

Source: habr.com

Ajouter un commentaire