Pisanje bota za telegram u R (2. dio): Dodavanje podrške za naredbe i filtera poruka botu

В prethodna objava shvatili smo kako stvoriti bota, inicijalizirali smo instancu klase Bot te se upoznao s metodama slanja poruka pomoću njega.

U ovom članku nastavljam ovu temu, pa preporučujem da počnete čitati ovaj članak tek nakon čitanja prvi dio.

Ovaj put ćemo smisliti kako oživjeti našeg bota i dodati mu podršku za naredbe, a također ćemo se upoznati s klasom Updater.

Tijekom članka napisat ćemo nekoliko jednostavnih robota, koji će na temelju zadanog datuma i šifre zemlje odrediti je li dan u određenoj zemlji vikend ili radni dan prema proizvodnom kalendaru. No, kao i prije, svrha članka je upoznati vas sa sučeljem paketa telegram.bot za rješavanje vlastitih problema.

Pisanje bota za telegram u R (2. dio): Dodavanje podrške za naredbe i filtera poruka botu

Svi članci iz serije “Pisanje telegram bota u R”

  1. Kreiramo bota i koristimo ga za slanje poruka u telegramu
  2. Dodajte podršku za naredbe i filtre poruka botu

sadržaj

Ako vas zanima analiza podataka, možda će vas zanimati moja telegram и youtube kanala. Većina sadržaja posvećena je jeziku R.

  1. Razred ažuriranja
  2. Handleri – rukovatelji
  3. Dodajte prvu naredbu botu, rukovatelj naredbama
  4. Procesor i filtri tekstualnih poruka
  5. Dodavanje naredbi s parametrima
  6. Pokrenite bot u pozadini
  7. Zaključak

Razred ažuriranja

Updater je klasa koja vam olakšava razvoj telegram bota i koristi klasu ispod haube Dispetcher. Zadatak razreda Updater je primanje ažuriranja od bota (u prethodnom smo članku koristili metodu za ovu svrhu getUpdates()), te ih prenijeti dalje na Dispetcher.

Za uzvrat Dispetcher sadrži rukovatelje koje ste izradili, tj. objekti klase Handler.

Handleri – rukovatelji

S rukovateljima kojima dodajete Dispetcher reakcije botova na razne događaje. U vrijeme pisanja ovog članka u telegram.bot Dodane su sljedeće vrste rukovatelja:

  • MessageHandler — Rukovatelj porukama
  • CommandHandler — Rukovatelj naredbama
  • CallbackQueryHandler — Rukovatelj podacima za tipkovnice poslane s Inline
  • ErrorHandler — Rukovatelj pogreškama prilikom traženja ažuriranja od bota

Dodajte prvu naredbu botu, rukovatelj naredbama

Ako nikada prije niste koristili botove i ne znate što je naredba, tada se naredbe botu moraju poslati koristeći kosu crtu / kao prefiks.

Počet ćemo s jednostavnim naredbama, tj. naučimo našeg bota da pozdravi na naredbu /hi.

Kod 1: Učenje bota da 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()

Pokrenite gornji primjer koda, nakon što ste zamijenili 'VAŠ BOT TOKEN' pravim tokenom koji ste primili prilikom stvaranja bota putem BotOtac (Razgovarao sam o stvaranju bota u prvi članak).

način start_polling() razred Updater, koji se koristi na kraju koda, pokreće beskrajnu petlju traženja i obrade ažuriranja od bota.

Sada otvorimo Telegram i napišemo prvu naredbu našem botu /hi.

Pisanje bota za telegram u R (2. dio): Dodavanje podrške za naredbe i filtera poruka botu

Sada naš bot razumije naredbu /hi, i zna nas pozdraviti.

Shematski, proces izgradnje tako jednostavnog bota može se prikazati na sljedeći način.

Pisanje bota za telegram u R (2. dio): Dodavanje podrške za naredbe i filtera poruka botu

  1. Stvorite instancu klase Updater;
  2. Mi stvaramo metode, tj. funkcije koje će naš bot obavljati. U primjeru koda ovo je funkcija say_hello(). Funkcije koje ćete koristiti kao bot metode moraju imati dva potrebna argumenta - bot и ažuriranje, i jedan izborni - argumenata. Argument bot, ovo je vaš bot, uz njegovu pomoć možete odgovarati na poruke, slati poruke ili koristiti bilo koje druge metode dostupne botu. Argument ažuriranje to je ono što je bot dobio od korisnika, zapravo ono što smo mi dobili u prvom članku korištenjem metode getUpdates(). Argument argumenata omogućuje vam obradu dodatnih podataka koje je korisnik poslao zajedno s naredbom, vratit ćemo se na ovu temu malo kasnije;
  3. Kreiramo rukovatelje, tj. Neke radnje korisnika povezujemo s metodama stvorenim u prethodnom koraku. U biti, rukovatelj je okidač, događaj koji poziva neku funkciju bota. U našem primjeru takav okidač je slanje naredbe /hi, a provodi ga tim hi_hendler <- CommandHandler('hi', say_hello). Prvi argument funkcije CommandHandler() omogućuje vam da odredite naredbu, u našem slučaju hi, na što će bot odgovoriti. Drugi argument vam omogućuje da odredite metodu bota, koju ćemo nazvati say_hello, koji će se izvršiti ako korisnik pozove naredbu navedenu u prvom argumentu;
  4. Zatim dodajemo kreirani rukovatelj u dispečer naše instance klase Updater. Rukovatelje možete dodati na nekoliko načina; u gornjem primjeru koristio sam najjednostavniji, pomoću znaka +, tj updater <- updater + hi_hendler. Isto se može učiniti pomoću metode add_handler(), koji pripada klasi Dispatcher, ovu metodu možete pronaći ovako: updater$dispatcher$add_handler();
  5. Pokrenite bot pomoću naredbe start_polling().

Procesor i filtri tekstualnih poruka

Shvatili smo kako slati naredbe botu, ali ponekad nam je potrebno da bot odgovara ne samo na naredbe, već i na neke obične tekstualne poruke. Da biste to učinili morate koristiti rukovatelje porukama − MessageHandler.

Normalan MessageHandler će odgovoriti na apsolutno sve dolazne poruke. Stoga se rukovatelji porukama često koriste zajedno s filtrima. Naučimo bota da pozdravi ne samo na naredbu /hi, ali i kad god se jedna od sljedećih riječi pojavi u poruci poslanoj botu: hello, hello, salute, hai, bonjour.

Za sada nećemo pisati nove metode, jer... Već imamo metodu kojom nas bot pozdravlja. Sve što trebamo učiniti je stvoriti potrebni filter i rukovatelj porukama.

Kôd 2: Dodajte rukovatelj tekstualnim porukama i filtar

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

Pokrenite gornji primjer koda, nakon što ste zamijenili 'VAŠ BOT TOKEN' pravim tokenom koji ste primili prilikom stvaranja bota putem BotOtac (Razgovarao sam o stvaranju bota u prvi članak).

Pokušajmo sada botu poslati nekoliko poruka koje sadrže ranije navedene pozdravne riječi:
Pisanje bota za telegram u R (2. dio): Dodavanje podrške za naredbe i filtera poruka botu

Dakle, prije svega, naučili smo bota ne samo pozdraviti, već i odgovoriti na pozdrav. To smo učinili koristeći argument reply_to_message_id, koji je dostupan u metodi sendMessage(), u koju trebate prenijeti id poruke na koju želite odgovoriti. ID poruke možete dobiti ovako: update$message$message_id.

Ali glavna stvar koju smo učinili jest dodavanje filtra botu pomoću funkcije BaseFilter():

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

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

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

)

Kao što ste možda primijetili, objektu je potrebno dodati filtere MessageFilters, koji u početku već sadrži mali skup gotovih filtara. U našem primjeru, na objekt MessageFilters dodali smo element hi, ovo je novi filter.

U funkciji BaseFilter() morate proći funkciju filtera. U biti, filtar je samo funkcija koja prima instancu poruke i vraća je TRUE ili FALSE. U našem primjeru napisali smo jednostavnu funkciju koja, koristeći osnovnu funkciju grepl() provjerava tekst poruke i odgovara li regularnom izrazu привет|здравствуй|салют|хай|бонжур vraća TRUE.

Zatim stvaramo rukovatelj porukama hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). Prvi argument funkcije MessageHandler() je metoda koja će pozvati rukovatelj, a drugi argument je filtar pomoću kojeg će biti pozvana. U našem slučaju, ovo je filtar koji smo izradili MessageFilters$hi.

Pa, na kraju, otpremniku dodajemo kreirani rukovatelj hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Kao što sam gore napisao, u paketu telegram.bot i prigovarati MessageFilters Već postoji skup ugrađenih filtara koje možete koristiti:

  • sve — Sve poruke
  • tekst — SMS poruke
  • naredba — Naredbe, tj. poruke koje počinju s /
  • odgovor — Poruke koje su odgovor na drugu poruku
  • audio — Poruke koje sadrže audio datoteku
  • dokument — Poruke s poslanim dokumentom
  • foto - Poruke s poslanim slikama
  • naljepnica — Poruke s poslanom naljepnicom
  • video — Poruke s videom
  • glas - Glasovne poruke
  • kontakt — Poruke koje sadrže sadržaj telegrama korisnika
  • lokacija — Poruke s geolokacijom
  • mjesto — Proslijeđene poruke
  • igra — Igre

Ako želite kombinirati neke filtre u jedan rukovatelj, samo upotrijebite znak | - kao logično ILI, i potpišite & kao logično И. Na primjer, ako želite da bot pozove istu metodu kada primi video, sliku ili dokument, upotrijebite sljedeći primjer za stvaranje rukovatelja porukama:

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

Dodavanje naredbi s parametrima

Već znamo što su naredbe, kako ih kreirati i kako natjerati bota da izvrši željenu naredbu. Ali u nekim slučajevima, osim naziva naredbe, moramo proslijediti neke podatke da bismo je izvršili.

Ispod je primjer bota koji vam, zadani datum i državu, vraća vrstu dana iz proizvodnog kalendara.

Bot u nastavku koristi API proizvodnog kalendara isdayoff.ru.

Kod 3: Bot koji izvještava po datumu i zemlji

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

Pokrenite gornji primjer koda, nakon što ste zamijenili 'VAŠ BOT TOKEN' pravim tokenom koji ste primili prilikom stvaranja bota putem BotOtac (Razgovarao sam o stvaranju bota u prvi članak).

Napravili smo bota koji u svom arsenalu ima samo jednu metodu check_date, ova se metoda poziva istoimenom naredbom.

No, osim naziva naredbe, ova metoda zahtijeva da unesete dva parametra, pozivni broj zemlje i datum. Zatim bot provjerava je li određeni dan u navedenoj zemlji vikend, skraćeni dan ili radni dan prema službenom proizvodnom kalendaru.

Kako bi metoda koju kreiramo prihvatila dodatne parametre uz naredbu, koristite argument pass_args = TRUE u funkciji CommandHandler(), a prilikom kreiranja metode, pored potrebnih argumenata bot, ažuriranje stvorite izbornu - argumenata. Ovako kreirana metoda će prihvatiti parametre koje proslijedite botu nakon naziva naredbe. Parametri moraju biti odvojeni razmakom; bit će poslani metodi kao tekstualni vektor.

Pokrenimo i testirajmo našeg bota.

Pisanje bota za telegram u R (2. dio): Dodavanje podrške za naredbe i filtera poruka botu

Pokrenite bot u pozadini

Posljednji korak koji moramo dovršiti je pokretanje bota u pozadini.

Da biste to učinili, slijedite algoritam opisan u nastavku:

  1. Spremite kod bota u datoteku s ekstenzijom R. Kada radite u RStudiu, to se radi kroz izbornik file, tim Spremi kao.
  2. Put do mape bin, koja se pak nalazi u mapi u kojoj ste instalirali jezik R, dodajte u varijablu Path, upute ovdje.
  3. Napravite običnu tekstualnu datoteku u koju upišite 1 redak: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R, Umjesto C:UsersAlseyDocumentsmy_bot.R napišite put do svoje bot skripte. Pritom je važno da usput nema ćiriličnih znakova i razmaka jer to može uzrokovati probleme prilikom pokretanja bota. Spremite ga i zamijenite njegovo proširenje s txt na šišmiš.
  4. Otvorite Windows Task Scheduler, postoji mnogo načina za to, na primjer, otvorite bilo koju mapu i unesite adresu %windir%system32taskschd.msc /s. Mogu se pronaći i druge metode pokretanja ovdje.
  5. U gornjem desnom izborniku planera kliknite "Stvori zadatak...".
  6. Na kartici "Općenito" dajte svom zadatku prilagođeni naziv i prebacite prekidač u stanje "Pokreni za sve korisnike".
  7. Idite na karticu "Radnje", kliknite "Stvori". U polju "Program ili skripta" kliknite "Pregledaj", pronađite onaj koji je stvoren u drugom koraku šišmiš datoteku i kliknite OK.
  8. Kliknite OK i, ako je potrebno, unesite lozinku za svoj račun operativnog sustava.
  9. Pronađite stvoreni zadatak u planeru, odaberite ga i kliknite gumb "Pokreni" u donjem desnom kutu.

Naš bot radi u pozadini i radit će sve dok ne zaustavite zadatak ili isključite računalo ili poslužitelj na kojem je pokrenut.

Zaključak

U ovom smo članku shvatili kako napisati potpunog bota koji ne samo da može slati poruke, već i odgovarati na dolazne poruke i naredbe. Stečeno znanje već je dovoljno za rješavanje većine vaših problema.

Sljedeći članak će govoriti o tome kako dodati tipkovnicu botu za praktičniji rad.

Pretplatite se na moju telegram и youtube kanali.

Izvor: www.habr.com

Dodajte komentar