用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

這是「用 R 寫電報機器人」系列的第三篇文章。 在先前的出版物中,我們學習如何創建電報機器人、透過它發送訊息、為機器人添加命令和訊息過濾器。 因此,在您開始閱讀本文之前,我強烈建議您閱讀 以前的, 因為這裡我將不再詳述先前描述的機器人建構的基礎知識。

在本文中,我們將透過添加鍵盤來提高機器人的可用性,這將使機器人介面直觀且易於使用。

用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

「用 R 寫電報機器人」系列的所有文章

  1. 我們創建一個機器人並用它來發送電報訊息
  2. 為機器人添加命令支援和訊息過濾器
  3. 如何為機器人添加鍵盤支持

Содержание

如果您對數據分析感興趣,您可能會對我的文章感興趣 電報 и YouTube的 渠道。 大部分內容專門介紹 R 語言。

  1. 電報機器人支援哪些類型的鍵盤?
  2. 回覆鍵盤
  3. 內嵌鍵盤
    3.1. 支援內聯按鈕的簡單機器人範例
    3.2. 報告所選城市當前天氣的機器人範例
    3.3. 顯示最新文章列表的機器人範例,其中包含來自 habr.com 的指定中心的鏈接
  4. 結論

電報機器人支援哪些類型的鍵盤?

在撰寫本文時 telegram.bot 允許您建立兩種類型的鍵盤:

  • 回覆 - 主要的常規鍵盤,位於訊息文字輸入面板下方。 這樣的鍵盤只是向機器人發送文本訊息,並且作為文本,它將發送寫在按鈕本身上的文本。
  • 內嵌 - 與特定機器人訊息關聯的鍵盤。 該鍵盤發送與按下的按鈕相關聯的機器人數據;該數據可能與按鈕本身上寫的文字不同。 而這樣的按鈕是透過處理 回呼查詢處理程序.

為了讓機器人打開鍵盤,需要在透過該方法發送訊息時 sendMessage(),將先前建立的鍵盤作為參數傳遞 reply_markup.

下面我們將看幾個例子。

回覆鍵盤

正如我上面所寫,這是主要的機器人控制鍵盤。

來自官方幫助的創建回复鍵盤的示例

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)

以上是來自包官方幫助的範例 telegram.bot。 若要建立鍵盤,請使用該函數 ReplyKeyboardMarkup(),它又取得由該函數建立的按鈕列表的列表 KeyboardButton().

為什麼在 ReplyKeyboardMarkup() 您是否需要傳遞的不僅僅是一個列表,而是一個列表的列表? 事實上,您傳遞了主列表,並在其中定義了單獨列表中的每一行按鈕,因為您可以將多個按鈕放在一行中。

爭論 resize_keyboard 讓您自動選擇鍵盤按鈕的最佳大小,以及參數 one_time_keyboard 允許您在每次按下按鈕後隱藏鍵盤。

讓我們寫一個簡單的機器人,它有 3 個按鈕:

  • 聊天 ID - 請求與機器人對話的聊天 ID
  • 我的名字 - 請求你的名字
  • 我的登入 - 在電報中請求您的用戶名

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

將“YOUR BOT TOKEN”替換為您在創建機器人時收到的真實令牌後,運行上面的程式碼範例 殭屍之父 (我談到了創建一個機器人 第一篇文章).

啟動後,給機器人一個命令 /start, 因為這正是我們定義的啟動鍵盤。

用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

如果目前您很難透過建立方法、過濾器和處理程序來解析給定的程式碼範例,那麼您應該回到上一個 文章,其中我詳細描述了這一切。

我們創建了 4 個方法:

  • 開始 — 啟動鍵盤
  • chat_id — 請求聊天 ID
  • my_name — 要求您的名字
  • my_username — 請求您登入

反對 訊息過濾器 根據文字新增了 3 個訊息過濾器:

  • chat_id — 帶有文字的訊息 "Чат ID"
  • name - 帶有文字的訊息 "Моё имя"
  • 使用者名稱 - 帶有文字的訊息 "Мой логин"

我們創建了 4 個處理程序,它們根據給定的命令和過濾器執行指定的方法。

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

鍵盤本身是在方法內部創建的 start() 團隊 ReplyKeyboardMarkup().

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

在我們的例子中,我們將所有按鈕放在一起,但我們可以透過更改按鈕清單的清單將它們排列在一行中。 因為鍵盤內的一行是透過嵌套的按鈕清單建立的,然後為了在一行中顯示我們的按鈕,我們需要重寫建構鍵盤的部分程式碼,如下所示:

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

用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

鍵盤傳送到聊天使用方法 sendMessage(),在論證中 reply_markup.

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

內嵌鍵盤

正如我上面所寫,內聯鍵盤與特定訊息相關聯。 它比主鍵盤更難使用。

最初,您需要為機器人新增一個方法來呼叫內聯鍵盤。

要響應內聯按鈕點擊,您也可以使用機器人方法 answerCallbackQuery(),它可以在電報介面中向按下 Inline 按鈕的使用者顯示通知。

從內聯按鈕發送的資料不是文本,因此要處理它,您需要使用以下命令創建一個特殊的處理程序 CallbackQueryHandler().

構建內聯鍵盤的程式碼在包的官方幫助中給出 telegram.bot.

來自官方幫助的構建內聯鍵盤的代碼

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

您需要使用以下命令建立內聯鍵盤 InlineKeyboardMarkup(),與回覆鍵盤原理相同。 在 InlineKeyboardMarkup() 有必要傳遞內聯按鈕列表的列表,每個單獨的按鈕都是由該函數創建的 InlineKeyboardButton().

內聯按鈕可以使用參數將一些資料傳遞給機器人 callback_data,或開啟使用參數指定的任何 HTML 頁面 url.

結果將是一個列表,其中每個元素也是需要組合成一行的內聯按鈕列表。

接下來我們將看幾個帶有內聯按鈕的機器人範例。

支援內聯按鈕的簡單機器人範例

首先,我們將編寫一個用於 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()

將“YOUR BOT TOKEN”替換為您在創建機器人時收到的真實令牌後,運行上面的程式碼範例 殭屍之父 (我談到了創建一個機器人 第一篇文章).

其結果是:
用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

我們創建了兩種方法:

  • test — 發送至聊天 內嵌鍵盤
  • 答案_cb — 處理從鍵盤傳送的資料。

從每個按鈕發送的資料在參數中指定 callback_data,創建按鈕時。 您可以使用以下結構接收從按鈕發送的數據 update$callback_query$data,在方法內部 答案_cb.

為了讓機器人對內聯鍵盤做出反應,方法 答案_cb 由特殊處理程序處理: CallbackQueryHandler(answer_cb)。 點擊“內聯”按鈕時將運行指定的方法。 處理程式 回呼查詢處理程序 有兩個參數:

  • callback — 需要運行的方法
  • pattern — 使用參數按綁定到按鈕的資料進行過濾 callback_data.

因此,使用論證 pattern 我們可以寫一個單獨的方法來按下每個按鈕:

代碼 3:每個內聯按鈕的單獨方法

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

將“YOUR BOT TOKEN”替換為您在創建機器人時收到的真實令牌後,運行上面的程式碼範例 殭屍之父 (我談到了創建一個機器人 第一篇文章).

現在我們已經編寫了 2 個單獨的方法,即一種方法,每次按下按鈕,並使用參數 pattern,在創建它們的處理程序時:

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

方法程式碼結束 答案_cb 團隊 bot$answerCallbackQuery(callback_query_id = update$callback_query$id),它告訴機器人已收到來自內聯鍵盤的數據。

報告所選城市當前天氣的機器人範例

讓我們嘗試編寫一個請求天氣資料的機器人。

其工作邏輯如下。 最初由團隊 /start 你呼叫主鍵盤,它只有一個「天氣」按鈕。 透過點擊此按鈕,您將收到一條帶有內嵌鍵盤的訊息,以選擇您想要了解當前天氣的城市。 選擇其中一個城市並獲取當前天氣。

在此程式碼範例中,我們將使用幾個附加套件:

  • httr — 一個用於處理 HTTP 請求的套件,在此基礎上建立了任何 API 的工作。 在我們的例子中,我們將使用免費的 API openweathermap.org.
  • stringr — 一個用於處理文字的包,在我們的例子中,我們將使用它來產生有關所選城市天氣的訊息。

代碼 4​​:報告所選城市當前天氣的機器人

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

將“YOUR BOT TOKEN”替換為您在創建機器人時收到的真實令牌後,運行上面的程式碼範例 殭屍之父 (我談到了創建一個機器人 第一篇文章).

結果,我們的機器人將像這樣工作:
用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

從原理上講,這個機器人可以這樣描述:
用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

我們在天氣機器人中創建了 3 種可用方法:

  • 開始 — 啟動主機器人鍵盤
  • 天氣 — 啟動內嵌鍵盤選擇城市
  • 答案_cb — 從 API 請求給定城市的天氣並將其發送到聊天的主要方法。

方法 開始 我們用命令啟動它 /start,由處理程序實現 CommandHandler('start', start).

運行方法 天氣 我們創建了一個同名的過濾器:

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

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

}
)

我們使用以下訊息處理程序呼叫此方法: MessageHandler(weather, filters = MessageFilters$weather).

最後,我們的主要方法 答案_cb 對按下內聯按鈕做出反應,這是由特殊處理程序實現的: CallbackQueryHandler(answer_cb).

在方法內部 答案_cb,我們讀取從鍵盤發送的資料並將其寫入變量 city: city <- update$callback_query$data。 然後我們向API請求天氣數據,產生並發送訊息,最後使用該方法 answerCallbackQuery 為了通知機器人我們處理了「內聯」按鈕的點擊。

顯示最新文章列表的機器人範例,其中包含指向指定中心的鏈接 www.habr.com.

我展示這個機器人是為了向您展示如何顯示通往網頁的內嵌按鈕。

機器人的邏輯與前一個類似;最初我們使用以下命令啟動主鍵盤 /start。 接下來,機器人為我們提供了 6 個中心的清單供我們選擇,我們選擇我們感興趣的中心,並從所選中心接收 5 個最新出版物。

如您所知,在這種情況下我們需要獲取文章列表,為此我們將使用一個特殊的包 habR,它允許您請求 Habra 的文章以及 R 中的一些統計數據。

安裝包 habR 只能從 github 獲取,為此你需要一個額外的包 devtools。 要安裝,請使用下面的程式碼。

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

現在讓我們來看看建立上述機器人的程式碼:

代碼 5:顯示所選中心上最新文章清單的機器人

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

將“YOUR BOT TOKEN”替換為您在創建機器人時收到的真實令牌後,運行上面的程式碼範例 殭屍之父 (我談到了創建一個機器人 第一篇文章).

結果,我們會得到這樣的結果:
用 R 編寫電報機器人(第 3 部分):如何為機器人添加鍵盤支援

我們對方法中可供選擇的集線器清單進行了硬編碼 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)
}

我們使用以下命令從指定 Hub 取得文章列表 habr_hub_posts(),從包包中 habR。 同時,我們指出,我們不需要整個時間的文章列表,而只需要第 20 篇文章所在的頁面。 使用命令從結果表中 head() 我們只留下前 5 篇文章,它們是最新的文章。

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

邏輯與之前的機器人非常相似,但在這種情況下,我們使用該函數動態生成一個帶有文章列表的內聯鍵盤 lapply().

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

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

我們將文章標題插入按鈕文字中 posts$title[x],並且在論證中 url 文章連結: url = posts$link[x].

接下來,我們創建一個過濾器、處理程序並啟動我們的機器人。

結論

現在,您編寫的機器人將使用起來更加方便,因為它們將透過鍵盤控制,而不是透過輸入命令來控制。 至少,當透過智慧型手機與機器人互動時,鍵盤將顯著簡化使用過程。

在下一篇文章中,我們將了解如何與機器人建立邏輯對話並使用資料庫。

來源: www.habr.com

添加評論