用 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 为了通知机器人我们处理了“内联”按钮的点击。

显示最新文章列表的机器人示例,其中包含指向指定中心的链接 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].

接下来,我们创建一个过滤器、处理程序并启动我们的机器人。

结论

现在,您编写的机器人将使用起来更加方便,因为它们将通过键盘进行控制,而不是通过输入命令。 至少,当通过智能手机与机器人交互时,键盘将显着简化使用过程。

在下一篇文章中,我们将了解如何与机器人建立逻辑对话并使用数据库。

来源: habr.com

添加评论