Pisanje bota za telegram v R (2. del): dodajanje podpore za ukaze in filtrov sporočil botu

В prejšnja objava ugotovili smo, kako ustvariti bota, inicializirali primerek razreda Bot in se seznanili z načini pošiljanja sporočil z njegovo uporabo.

V tem članku nadaljujem to temo, zato priporočam, da začnete brati ta članek šele po branju 1. del.

Tokrat bomo ugotovili, kako oživiti našega bota in mu dodati podporo za ukaze ter se seznaniti z razredom Updater.

Med potekom članka bomo napisali več preprostih botov, slednji bodo na podlagi podanega datuma in kode države določili, ali je dan v določeni državi vikend ali delovni dan glede na proizvodni koledar. Toda, kot prej, je namen članka seznaniti se z vmesnikom paketa telegram.bot za reševanje lastnih težav.

Pisanje bota za telegram v R (2. del): dodajanje podpore za ukaze in filtrov sporočil botu

Vsi članki iz serije “Pisanje telegram bota v R”

  1. Ustvarimo bota in ga uporabimo za pošiljanje sporočil v telegramu
  2. Botu dodajte podporo za ukaze in filtre sporočil

Vsebina

Če vas zanima analiza podatkov, vas bo morda zanimal moj telegram и youtube kanalov. Večina vsebine je posvečena jeziku R.

  1. Razred posodobitve
  2. Handlerji - handlerji
  3. Dodajte prvi ukaz botu, upravljalnik ukazov
  4. Procesor besedilnih sporočil in filtri
  5. Dodajanje ukazov s parametri
  6. Zaženite bota v ozadju
  7. Zaključek

Razred posodobitve

Updater je razred, ki vam olajša razvoj telegramskega bota in uporablja razred pod pokrovom Dispetcher. Naloga razreda Updater je prejemanje posodobitev od bota (v prejšnjem članku smo za ta namen uporabili metodo getUpdates()), in jih prenesite naprej v Dispetcher.

Po drugi strani pa Dispetcher vsebuje upravljalnike, ki ste jih ustvarili, tj. predmeti razreda Handler.

Handlerji - handlerji

Z obdelovalci, ki jih dodate Dispetcher reakcije botov na različne dogodke. V času pisanja tega članka v telegram.bot Dodani so bili naslednji tipi upravljavcev:

  • MessageHandler — Upravljavec sporočil
  • CommandHandler — Upravljavec ukazov
  • CallbackQueryHandler — Upravljavec podatkov za tipkovnice, poslane iz Inline
  • ErrorHandler — Obravnavalnik napak pri zahtevanju posodobitev od bota

Dodajte prvi ukaz botu, upravljalnik ukazov

Če še nikoli niste uporabljali botov in ne veste, kaj je ukaz, morate ukaze botu poslati s poševnico / kot predpono.

Začeli bomo s preprostimi ukazi, tj. naučimo našega bota, da pozdravi na ukaz /hi.

Koda 1: Učenje bota, da se pozdravi

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

Zaženite zgornji primer kode, potem ko ste zamenjali 'YOUR BOT TOKEN' s pravim žetonom, ki ste ga prejeli pri ustvarjanju bota prek BotOče (O ustvarjanju bota sem govoril v prvi članek).

Metoda start_polling() Razred Updater, ki se uporablja na koncu kode, začne neskončno zanko zahtevanja in obdelave posodobitev od bota.

Zdaj pa odprimo Telegram in napišimo prvi ukaz našemu botu /hi.

Pisanje bota za telegram v R (2. del): dodajanje podpore za ukaze in filtrov sporočil botu

Zdaj naš bot razume ukaz /hi, in ve, kako nas pozdraviti.

Shematično lahko postopek gradnje tako preprostega bota prikažemo na naslednji način.

Pisanje bota za telegram v R (2. del): dodajanje podpore za ukaze in filtrov sporočil botu

  1. Ustvarite primerek razreda Updater;
  2. Ustvarjamo metode, t.j. funkcije, ki jih bo opravljal naš bot. V primeru kode je to funkcija say_hello(). Funkcije, ki jih boste uporabili kot metode botov, morajo imeti dva zahtevana argumenta - bot и posodobitevin ena neobvezna - rogove. Prepir bot, to je vaš bot, z njegovo pomočjo lahko odgovarjate na sporočila, pošiljate sporočila ali uporabljate druge metode, ki so na voljo botu. Prepir posodobitev to je bot prejel od uporabnika, pravzaprav tisto, kar smo prejeli v prvem članku z uporabo metode getUpdates(). Prepir rogove omogoča obdelavo dodatnih podatkov, ki jih uporabnik pošlje skupaj z ukazom, k tej temi se bomo vrnili malo kasneje;
  3. Izdelujemo handlerje, t.j. Nekatera uporabniška dejanja povežemo z metodami, ustvarjenimi v prejšnjem koraku. V bistvu je upravljalnik sprožilec, dogodek, ki pokliče neko funkcijo bota. V našem primeru je tak sprožilec pošiljanje ukaza /hi, izvaja pa ga ekipa hi_hendler <- CommandHandler('hi', say_hello). Prvi argument funkcije CommandHandler() vam omogoča, da določite ukaz, v našem primeru hi, na kar se bo bot odzval. Drugi argument vam omogoča, da določite metodo bota, ki jo bomo poklicali say_hello, ki se bo izvršil, če je uporabnik poklical ukaz, naveden v prvem argumentu;
  4. Nato dodamo ustvarjeni upravljalnik v dispečer primerka našega razreda Updater. Handlerje lahko dodajate na več načinov, v zgornjem primeru sem uporabil najpreprostejšega, z uporabo znaka +, tj. updater <- updater + hi_hendler. Enako je mogoče storiti z uporabo metode add_handler(), ki spada v razred Dispatcher, lahko to metodo najdete takole: updater$dispatcher$add_handler();
  5. Zaženite bota z ukazom start_polling().

Procesor besedilnih sporočil in filtri

Ugotovili smo, kako poslati ukaze botu, vendar včasih potrebujemo, da se bot odzove ne samo na ukaze, ampak tudi na nekatera običajna besedilna sporočila. Če želite to narediti, morate uporabiti upravljalnike sporočil − MessageHandler.

Normalno MessageHandler bo odgovoril na absolutno vsa dohodna sporočila. Zato se obdelovalniki sporočil pogosto uporabljajo skupaj s filtri. Naučimo bota, da pozdravi ne le na ukaz /hi, pa tudi kadar koli se v sporočilu, poslanem botu, pojavi ena od naslednjih besed: hello, hello, salute, hai, bonjour.

Zaenkrat ne bomo pisali novih metod, ker... Metodo, s katero nas bot pozdravi, že imamo. Vse, kar moramo storiti, je ustvariti zahtevani filter in upravljalnik sporočil.

Koda 2: dodajte urejevalnik besedilnih sporočil in filter

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

Zaženite zgornji primer kode, potem ko ste zamenjali 'YOUR BOT TOKEN' s pravim žetonom, ki ste ga prejeli pri ustvarjanju bota prek BotOče (O ustvarjanju bota sem govoril v prvi članek).

Zdaj pa poskusimo botu poslati več sporočil, ki vsebujejo prej navedene pozdravne besede:
Pisanje bota za telegram v R (2. del): dodajanje podpore za ukaze in filtrov sporočil botu

Torej, najprej smo bota naučili ne samo pozdraviti, ampak tudi odgovoriti na pozdrav. To smo storili z uporabo argumenta reply_to_message_id, ki je na voljo v metodi sendMessage(), v katerega morate prenesti ID sporočila, na katerega želite odgovoriti. ID sporočila lahko dobite takole: update$message$message_id.

Toda glavna stvar, ki smo jo naredili, je bila dodajanje filtra botu s funkcijo BaseFilter():

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

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

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

)

Kot ste morda opazili, je treba objektu dodati filtre MessageFilters, ki na začetku že vsebuje majhen nabor že pripravljenih filtrov. V našem primeru na predmet MessageFilters smo dodali element hi, to je nov filter.

V funkciji BaseFilter() prenesti morate funkcijo filtra. V bistvu je filter le funkcija, ki prejme primerek sporočila in ga vrne TRUE ali FALSE. V našem primeru smo napisali preprosto funkcijo, ki z uporabo osnovne funkcije grepl() preveri besedilo sporočila in ali se ujema z regularnim izrazom привет|здравствуй|салют|хай|бонжур vrne TRUE.

Nato ustvarimo upravljalnik sporočil hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). Prvi argument funkcije MessageHandler() je metoda, ki bo poklicala obravnavo, drugi argument pa je filter, s katerim bo poklicana. V našem primeru je to filter, ki smo ga ustvarili MessageFilters$hi.

No, na koncu dodamo dispečerju ustvarjeni upravljalnik hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Kot sem napisal zgoraj, v paketu telegram.bot in ugovarjati MessageFilters Obstaja že niz vgrajenih filtrov, ki jih lahko uporabite:

  • vse — Vsa sporočila
  • besedilo — Besedilna sporočila
  • ukaz — Ukazi, tj. sporočila, ki se začnejo z /
  • odgovor — Sporočila, ki so odgovor na drugo sporočilo
  • zvok — Sporočila, ki vsebujejo zvočno datoteko
  • dokument — Sporočila s poslanim dokumentom
  • fotografija - Sporočila s poslanimi slikami
  • nalepka — Sporočila s poslano nalepko
  • video — Sporočila z videom
  • glas – glasovna sporočila
  • kontakt — Sporočila, ki vsebujejo uporabnikovo vsebino telegrama
  • lokacija — Sporočila z geolokacijo
  • prizorišče — Posredovana sporočila
  • igra — Igre

Če želite združiti nekaj filtrov v enem upravljalniku, samo uporabite znak | - kot logično ALI, in se podpišite & kot logično И. Na primer, če želite, da bot pokliče isto metodo, ko prejme videoposnetek, sliko ali dokument, uporabite naslednji primer za ustvarjanje upravljalnika sporočil:

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

Dodajanje ukazov s parametri

Že vemo, kaj so ukazi, kako jih ustvariti in kako prisiliti bota, da izvede želeni ukaz. Toda v nekaterih primerih moramo poleg imena ukaza posredovati še nekaj podatkov za njegovo izvedbo.

Spodaj je primer bota, ki vam glede na dani datum in državo vrne vrsto dneva iz produkcijskega koledarja.

Spodnji bot uporablja API za produkcijski koledar isdayoff.ru.

Koda 3: Bot, ki poroča po datumu in državi

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

Zaženite zgornji primer kode, potem ko ste zamenjali 'YOUR BOT TOKEN' s pravim žetonom, ki ste ga prejeli pri ustvarjanju bota prek BotOče (O ustvarjanju bota sem govoril v prvi članek).

Ustvarili smo bota, ki ima v svojem arzenalu samo eno metodo check_date, to metodo pokliče ukaz z istim imenom.

Toda ta metoda poleg imena ukaza zahteva, da vnesete dva parametra, kodo države in datum. Nato bot preveri, ali je določen dan v navedeni državi vikend, skrajšani dan ali delovni dan glede na uradni proizvodni koledar.

Če želite, da metoda, ki jo ustvarimo, sprejme dodatne parametre skupaj z ukazom, uporabite argument pass_args = TRUE v funkciji CommandHandler(), in pri ustvarjanju metode poleg zahtevanih argumentov bot, posodobitev ustvari izbirnega - rogove. Tako ustvarjena metoda bo sprejela parametre, ki jih posredujete botu po imenu ukaza. Parametri morajo biti ločeni s presledkom; metodi bodo poslani kot besedilni vektor.

Zaženimo in preizkusimo našega bota.

Pisanje bota za telegram v R (2. del): dodajanje podpore za ukaze in filtrov sporočil botu

Zaženite bota v ozadju

Zadnji korak, ki ga moramo opraviti, je zagon bota v ozadju.

Če želite to narediti, sledite spodaj opisanemu algoritmu:

  1. Kodo bota shranite v datoteko s pripono R. Pri delu v RStudio to storite prek menija file, ekipa Shrani kot.
  2. Dodajte pot do mape bin, ki se nahaja v mapi, v kateri ste namestili jezik R, v spremenljivko Pot, navodila tukaj.
  3. Ustvarite običajno besedilno datoteko, v katero zapišite 1 vrstico: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. Namesto C:UporabnikiAlseyDocumentsmy_bot.R napišite pot do skripta svojega bota. Ob tem je pomembno, da na poti ni ciriličnih znakov in presledkov, saj to lahko povzroči težave pri zagonu bota. Shranite ga in zamenjajte njegovo razširitev z txt o bat.
  4. Odprite Windows Task Scheduler, obstaja veliko načinov za to, na primer odprite katero koli mapo in vnesite naslov %windir%system32taskschd.msc /s. Najdete lahko druge načine zagona tukaj.
  5. V zgornjem desnem meniju razporejevalnika kliknite »Ustvari opravilo ...«.
  6. Na zavihku »Splošno« dajte svoji nalogi ime po meri in preklopite stikalo v stanje »Zaženi za vse uporabnike«.
  7. Pojdite na zavihek »Dejanja«, kliknite »Ustvari«. V polju "Program ali skript" kliknite "Prebrskaj", poiščite tistega, ki je bil ustvarjen v drugem koraku bat datoteko in kliknite V redu.
  8. Kliknite V redu in po potrebi vnesite geslo za svoj račun operacijskega sistema.
  9. Poiščite ustvarjeno nalogo v razporejevalniku, jo izberite in v spodnjem desnem kotu kliknite gumb »Zaženi«.

Naš bot deluje v ozadju in bo deloval, dokler ne ustavite opravila ali izklopite računalnika ali strežnika, na katerem je bil zagnan.

Zaključek

V tem članku smo ugotovili, kako napisati polnopravnega bota, ki ne more samo pošiljati sporočil, temveč tudi odgovarjati na dohodna sporočila in ukaze. Pridobljeno znanje je že dovolj za rešitev večine vaših težav.

Naslednji članek bo govoril o tem, kako dodati tipkovnico botu za bolj priročno delo.

Naročite se na moje telegram и youtube kanalov.

Vir: www.habr.com

Dodaj komentar