用 R 編寫電報機器人(第 2 部分):為機器人添加命令支援和訊息過濾器

В 以前的出版物 我們弄清楚如何創建一個機器人,初始化了該類別的一個實例 Bot 並熟悉了使用它發送訊息的方法。

在這篇文章中我將繼續這個主題,所以我建議在閱讀完之後才開始閱讀這篇文章 第一部分.

這次我們將弄清楚如何恢復我們的機器人並為其添加命令支持,並熟悉該類 Updater.

在本文中,我們將編寫幾個簡單的機器人,後者將根據給定的日期和國家代碼,根據生產日曆確定給定國家的一天是週末還是工作日。 但是,和以前一樣,本文的目的是讓您熟悉包接口 telegram.bot 來解決你自己的問題。

用 R 編寫電報機器人(第 2 部分):為機器人添加命令支援和訊息過濾器

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

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

Содержание

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

  1. 更新程式類
  2. 處理程序 - 處理程序
  3. 將第一個命令加入機器人,命令處理程序
  4. 文字訊息處理器和過濾器
  5. 新增帶參數的命令
  6. 在後台運行機器人
  7. 結論

更新程式類

Updater 是一個可以讓您更輕鬆地開發電報機器人的類,並在幕後使用該類 Dispetcher。 課堂作業 Updater 是接收來自機器人的更新(在上一篇文章中我們使用了用於此目的的方法 getUpdates()),並將它們進一步轉移到 Dispetcher.

反過來 Dispetcher 包含您所建立的處理程序,即類別物件 Handler.

處理程序 - 處理程序

使用處理程序新增至 Dispetcher 機器人對各種事件的反應。 在撰寫本文時 telegram.bot 新增了以下類型的處理程序:

  • MessageHandler — 訊息處理程序
  • CommandHandler - 命令處理程序
  • CallbackQueryHandler - 從 Inline 發送的鍵盤的資料處理程序
  • ErrorHandler - 向機器人請求更新時的錯誤處理程序

將第一個命令加入機器人,命令處理程序

如果您以前從未使用過機器人並且不知道命令是什麼,則必須使用正斜杠向機器人發送命令 / 作為前綴。

我們將從簡單的命令開始,即讓我們教我們的機器人按照指令打招呼 /hi.

代碼 1:教機器人打招呼

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# Пишем метод для приветсвия
say_hello <- function(bot, update) {

  # Имя пользователя с которым надо поздароваться
  user_name <- update$message$from$first_name

  # Отправка приветственного сообщения
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Моё почтение, ", user_name, "!"), 
                  parse_mode = "Markdown")

}

# создаём обработчик 
hi_hendler <- CommandHandler('hi', say_hello)

# добаляем обработчик в диспетчер
updater <- updater + hi_hendler

# запускаем бота
updater$start_polling()

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

方法 start_polling()Updater,在程式碼末尾使用,啟動從機器人請求和處理更新的無限循環。

現在讓我們打開 Telegram 並將第一個命令寫入我們的機器人 /hi.

用 R 編寫電報機器人(第 2 部分):為機器人添加命令支援和訊息過濾器

現在我們的機器人理解了這個命令 /hi,並且知道如何向我們打招呼。

概要地,建構這樣一個簡單的機器人的過程可以描述如下。

用 R 編寫電報機器人(第 2 部分):為機器人添加命令支援和訊息過濾器

  1. 建立類別的實例 Updater;
  2. 我們創建方法,即我們的機器人將執行的功能。 在程式碼範例中,這是一個函數 say_hello()。 您將用作機器人方法的函數必須有兩個必需參數 - BOT и 更新,以及一個可選的 - 參數。 爭論 BOT,這是您的機器人,在它的幫助下您可以回覆訊息、發送訊息或使用機器人可用的任何其他方法。 爭論 更新 這是機器人從用戶那裡收到的內容,事實上,我們在第一篇文章中使用該方法收到的內容 getUpdates()。 爭論 參數 允許您處理用戶隨命令發送的附加數據,我們稍後將回到這個主題;
  3. 我們創建處理程序,即我們將一些使用者操作與上一步中建立的方法關聯起來。 本質上,處理程序是一個觸發器,一個呼叫某些機器人函數的事件。 在我們的範例中,此類觸發器正在發送命令 /hi,並由團隊實施 hi_hendler <- CommandHandler('hi', say_hello)。 第一個函數參數 CommandHandler() 允許您指定一個命令,在我們的例子中 hi,機器人將對此做出回應。 第二個參數可讓您指定機器人方法,我們將呼叫該方法 say_hello,如果使用者呼叫第一個參數中指定的命令,則會執行該命令;
  4. 接下來,我們將建立的處理程序新增到類別實例的調度程序中 Updater。 您可以透過多種方式添加處理程序;在上面的範例中,我使用了最簡單的一種,使用符號 +updater <- updater + hi_hendler。 使用該方法也可以完成相同的操作 add_handler(),屬於該類 Dispatcher,你可以這樣找到這個方法: updater$dispatcher$add_handler();
  5. 使用命令啟動機器人 start_polling().

文字訊息處理器和過濾器

我們弄清楚瞭如何向機器人發送命令,但有時我們需要機器人不僅響應命令,還需要回應一些常規簡訊。 為此,您需要使用訊息處理程序 - 消息處理程序.

正常 消息處理程序 將回應絕對所有傳入訊息。 因此,訊息處理程序經常與過濾器一起使用。 讓我們教機器人不只照著指令打招呼 /hi,而且每當發送給機器人的訊息中出現以下單字之一時:你好、你好、致敬、海伊、你好。

現在我們不會寫任何新方法,因為...... 我們已經有了機器人向我們打招呼的方法。 我們需要做的就是建立所需的過濾器和訊息處理程序。

代碼 2:新增簡訊處理程序和過濾器

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('ТОКЕН ВАШЕГО БОТА')

# Пишем метод для приветсвия
## команда приветвия
say_hello <- function(bot, update) {

  # Имя пользователя с которым надо поздароваться
  user_name <- update$message$from$first_name

  # Отправляем приветсвенное сообщение
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Моё почтение, ", user_name, "!"),
                  parse_mode = "Markdown",
                  reply_to_message_id = update$message$message_id)

}

# создаём фильтры
MessageFilters$hi <- BaseFilter(function(message) {

  # проверяем, встречается ли в тексте сообщения слова: привет, здравствуй, салют, хай, бонжур
  grepl(x           = message$text, 
        pattern     = 'привет|здравствуй|салют|хай|бонжур',
        ignore.case = TRUE)
  }
)

# создаём обработчик 
hi_hendler <- CommandHandler('hi', say_hello) # обработчик команды hi
hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)

# добаляем обработчики в диспетчер
updater <- updater + 
             hi_hendler +
             hi_txt_hnd

# запускаем бота
updater$start_polling()

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

現在,我們嘗試向機器人發送幾條包含前面列出的問候語的訊息:
用 R 編寫電報機器人(第 2 部分):為機器人添加命令支援和訊息過濾器

因此,首先,我們教導機器人不僅要打招呼,還要回應問候。 我們使用參數來做到這一點 回覆訊息 ID,在方法中可用 sendMessage(),您需要將要回應的訊息的 id 傳輸到其中。 您可以這樣取得訊息 id: update$message$message_id.

但我們做的主要事情是使用該函數向機器人添加過濾器 BaseFilter():

# создаём фильтры
MessageFilters$hi <- BaseFilter( 

  # анонимная фильтрующая функция
  function(message) {

    # проверяем, встречается ли в тексте сообщения слова приветствия
    grepl(x           = message$text, 
          pattern     = 'привет|здравствуй|салют|хай|бонжур',
          ignore.case = TRUE)
  }

)

您可能已經注意到,需要將篩選器新增至物件中 訊息過濾器,它最初已經包含一小組現成的過濾器。 在我們的例子中,對於對象 訊息過濾器 我們加入了一個元素 hi,這是一個新的過濾器。

在功能 BaseFilter() 你需要透過過濾功能。 本質上,過濾器只是一個接收訊息實例並傳回的函數 TRUE。 在我們的範例中,我們編寫了一個簡單的函數,使用基本函數 grepl() 檢查訊息文字以及它是否與正規表示式匹配 привет|здравствуй|салют|хай|бонжур 回報 TRUE.

接下來我們建立一個訊息​​處理程序 hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)。 第一個函數參數 MessageHandler() 是將呼叫處理程序的方法,第二個參數是呼叫它的過濾器。 在我們的例子中,這是我們創建的過濾器 MessageFilters$hi.

好吧,最後,我們將創建的處理程序添加到調度程序中 hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

正如我上面寫的,在包中 telegram.bot 和對象 訊息過濾器 您已經可以使用一組內建濾鏡:

  • 全部 — 所有訊息
  • 文字 — 簡訊
  • 命令——命令,即以以下內容開頭的訊息 /
  • 回覆 — 回覆另一則訊息的訊息
  • 音訊 - 包含音訊檔案的訊息
  • document — 帶有已傳送文件的訊息
  • 照片 - 帶有已發送圖像的訊息
  • 貼紙 — 已發送貼紙的訊息
  • 影片 — 有影片的訊息
  • 語音 - 語音訊息
  • contact-包含用戶電報內容的訊息
  • location-帶有地理位置的訊息
  • 地點——轉發的訊息
  • 遊戲 — 遊戲

如果您想在一個處理程序中組合一些過濾器,只需使用符號 | - 作為一個邏輯 OR,並簽名 & 合乎邏輯的 И。 例如,如果您希望機器人在接收影片、影像或文件時呼叫相同的方法,請使用下列範例建立訊息處理程序:

handler <- MessageHandler(callback, 
  MessageFilters$video | MessageFilters$photo | MessageFilters$document
)

新增帶參數的命令

我們已經知道命令是什麼、如何創建它們以及如何強制機器人執行所需的命令。 但在某些情況下,除了命令名稱之外,我們還需要傳遞一些資料來執行它。

下面是一個機器人範例,在給定給定日期和國家/地區的情況下,機器人會從生產日曆中傳回日期類型。

下面的機器人使用生產日曆 API isdayoff.ru.

代碼 3:按日期和國家報告的機器人

library(telegram.bot)

# создаём экземпляр класса Updater
updater <- Updater('1165649194:AAFkDqIzQ6Wq5GV0YU7PmEZcv1gmWIFIB_8')

# Пишем метод для приветсвия
## команда приветвия
check_date <- function(bot, update, args) {

  # входящие данные
  day     <- args[1]  # дата
  country <- args[2]  # страна

  # проверка введённых параметров
  if ( !grepl('\d{4}-\d{2}-\d{2}', day) ) {

    # Send Custom Keyboard
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(day, " - некорреткная дата, введите дату в формате ГГГГ-ММ-ДД"),
                    parse_mode = "Markdown")

  } else {
    day <- as.Date(day)
    # переводим в формат POSIXtl
    y <- format(day, "%Y")
    m <- format(day, "%m")
    d <- format(day, "%d")

  }

  # страна для проверки
  ## проверяем задана ли страна
  ## если не задана устанавливаем ru
  if ( ! country %in% c('ru', 'ua', 'by', 'kz', 'us') ) {

    # Send Custom Keyboard
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(country, " - некорретктный код страны, возможнные значения: ru, by, kz, ua, us. Запрошены данные по России."),
                    parse_mode = "Markdown")

    country <- 'ru'

  }

  # запрос данных из API
  # компоновка HTTP запроса
  url <- paste0("https://isdayoff.ru/api/getdata?",
                "year=",  y, "&",
                "month=", m, "&",
                "day=",   d, "&",
                "cc=",    country, "&",
                "pre=1&",
                "covid=1")

  # получаем ответ
  res <- readLines(url)

  # интрепретация ответа
  out <- switch(res, 
                "0"   = "Рабочий день",
                "1"   = "Нерабочий день",
                "2"   = "Сокращённый рабочий день",
                "4"   = "covid-19",
                "100" = "Ошибка в дате",
                "101" = "Данные не найдены",
                "199" = "Ошибка сервиса")

  # отправляем сообщение
  bot$sendMessage(update$message$chat_id, 
                  text = paste0(day, " - ", out),
                  parse_mode = "Markdown")

}

# создаём обработчик 
date_hendler <- CommandHandler('check_date', check_date, pass_args = TRUE)

# добаляем обработчик в диспетчер
updater <- updater + date_hendler

# запускаем бота
updater$start_polling()

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

我們創建了一個機器人,其武器庫中只有一種方法 check_date,該方法由同名命令呼叫。

但是,除了命令名稱之外,此方法還要求您輸入兩個參數:國家/地區代碼和日期。 接下來,機器人根據官方生產日曆檢查指定國家/地區的給定日期是否為週末、縮短日或工作日。

為了使我們創建的方法能夠接受附加參數以及命令,請使用參數 pass_args = TRUE 在功能上 CommandHandler(),並且在創建方法時,除了必需的參數之外 BOT, 更新 建立一個可選的 - 參數。 以這種方式創建的方法將接受您在命令名稱之後傳遞給機器人的參數。 參數必須用空格分隔;它們將作為文字向量傳送到該方法。

讓我們啟動並測試我們的機器人。

用 R 編寫電報機器人(第 2 部分):為機器人添加命令支援和訊息過濾器

在後台運行機器人

我們需要完成的最後一步是在後台啟動機器人。

為此,請遵循下面描述的演算法:

  1. 將機器人程式碼儲存到擴展名為 R 的檔案中。在 RStudio 中工作時,這是透過選單完成的 文件, 團隊 另存為….
  2. 將bin資料夾的路徑加入Path變數中,該資料夾又位於安裝R語言的資料夾中,說明 這裡.
  3. 建立一個常規文字文件,其中寫入 1 行: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R。 代替 C:UsersAlseyDocumentsmy_bot.R 寫入您的機器人腳本的路徑。 同時,重要的是一路上沒有西里爾字符或空格,因為這可能會在運行機器人時導致問題。 保存它,並將其擴展名替換為 TXT蝙蝠.
  4. 打開Windows任務計劃程序,有很多方法可以做到這一點,例如打開任意資料夾並輸入地址 %windir%system32taskschd.msc /s。 其他啟動方式可參見 這裡.
  5. 在調度程式的右上角選單中,按一下「建立任務...」。
  6. 在「常規」標籤上,為您的任務指定自訂名稱,並將開關切換到「為所有使用者執行」狀態。
  7. 轉到“操作”選項卡,按一下“建立”。 在“程式或腳本”一欄,點擊“瀏覽”,找到第二步中建立的 蝙蝠 文件並點擊“確定”。
  8. 按一下“確定”,如有必要,請輸入作業系統帳戶的密碼。
  9. 在調度程序中找到已建立的任務,選擇它並點擊右下角的「運行」按鈕。

我們的機器人在後台運行,並將一直工作,直到您停止任務,或關閉啟動它的電腦或伺服器。

結論

在本文中,我們了解如何編寫一個成熟的機器人,它不僅可以發送訊息,還可以回應傳入的訊息和命令。 所獲得的知識已經足以解決您的大部分問題。

下一篇文章會講如何為機器人添加鍵盤,以方便工作。

訂閱我的 電報 и YouTube的 渠道。

來源: www.habr.com

添加評論