U razjasnili smo kako stvoriti bota, inicijalizirali instancu klase Bot i upoznali se s metodama slanja poruka uz njegovu pomoć.
U ovom članku nastavljam ovu temu, stoga preporučujem da krenete s čitanjem ovog članka tek nakon što pročitate .
Ovaj put ćemo razjasniti kako oživjeti našeg bota i dodati mu podršku za naredbe, a također ćemo se upoznati s klasom Updater.
U okviru članka napisat ćemo nekoliko jednostavnih botova, a posljednji će na temelju zadanog datuma i koda zemlje odrediti je li dan u toj zemlji vikend ili radni dan prema radnom kalendaru. No, kao i prije, cilj članka je upoznati vas s sučeljem paketa telegram.bot za rješavanje vaših vlastitih zadataka.

Sve članke iz serije "Pišemo telegram bota na jeziku R"
Sadržaj
Ako vas zanima analitika podataka, možda će vas zanimati moji i kanali. Velik dio sadržaja je posvećen jeziku R.
Klasa Updater
Updater — to je klasa koja vam pojednostavljuje razvoj telegram bota, i koristi ispod haube klasu Dispetcher. Svrha klase Updater je da dobije ažuriranja od bota (u prethodnom članku koristili smo za tu svrhu metodu getUpdates()), i proslijedi ih dalje u Dispetcher.
U svom redu Dispetcher sadrži vaše stvorene obrtnike, tj. objekte klase Handler.
Handlers — obrtnici
Uz pomoć obrtnika dodajete u Dispetcher reakcije bota na razne događaje. U trenutku pisanja članka dodani su sljedeći tipovi obrtnika: telegram.bot MessageHandler — Obrtnik poruka
- CommandHandler — Obrtnik naredbi
- CallbackQueryHandler — Obrtnik podataka poslanih iz Inline tipkovnica
- ErrorHandler — Obrtnik grešaka prilikom zahtjeva za ažuriranja od bota
- Ako nikada prije niste koristili botove i niste upoznati s tim što je naredba, naredbe botu trebate slati pomoću direktnog kosa crta
Dodajemo prvu naredbu botu, obrtnik naredbi
kao prefiksa. / Započnimo s jednostavnim naredbama, tj. naučimo našeg bota da se pozdravlja na naredbu
Počnimo s jednostavnim naredbama, tj. naučit ćemo našeg bota kako da pozdravi na naredbu. /hi.
Kod 1: Učimo bota da se pozdravlja
library(telegram.bot)
# kreiramo instancu klase Updater
updater <- Updater('TOKEN VAŠEG BOTA')
# Definišemo metodu za pozdravljanje
say_hello <- function(bot, update) {
# Ime korisnika sa kojim treba pozdraviti
user_name <- update$message$from$first_name
# Slanje pozdravne poruke
bot$sendMessage(update$message$chat_id,
text = paste0("Moje poštovanje, ", user_name, "!"),
parse_mode = "Markdown")
}
# kreiramo handler
hi_handler <- CommandHandler('hi', say_hello)
# dodajemo handler u dispatcher
updater <- updater + hi_handler
# pokrećemo bota
updater$start_polling()Pokrenite gornji primjer koda, prethodno zamenjujući ‘TOKEN VAŠEG BOTA’ pravim tokenom koji ste dobili prilikom kreiranja bota preko BotFather (o kreiranju bota govorio sam u ).
Metoda start_polling() klase Updater, koji se koristi na kraju koda, pokreće beskonačni ciklus zahteva i obrade ažuriranja od bota.
Sada otvorite Telegram i napišite našem botu prvu komandu /hi.

Sada naš bot razume komandu /hi, i zna kako da se pozdravi s nama.
Shema procesa izrade ovakvog jednostavnog bota može se prikazati na sledeći način.

- Kreiramo instancu klase
Updater; - Kreiramo metode, tj. funkcije koje će naš bot izvoditi. U primjeru koda to je funkcija
say_hello(). Funkcije koje ćete koristiti kao metode bota moraju imati dva obavezna argumenta — bot i update, i jedan opcioni — args. Argument bot, to je vaš bot, uz njegovu pomoć možete odgovarati na poruke, slati poruke ili koristiti bilo koje druge dostupne metode bota. Argument update to je ono što bot prima od korisnika, u suštini, ono što smo u prvom članku dobijali metodomgetUpdates(). Argument args omogućava vam da obrađujete dodatne podatke koje je korisnik poslao zajedno s komandom, o ovoj temi ćemo se još malo kasnije vratiti; - Kreiramo handler-e, tj. povezujemo određene radnje korisnika s metodama koje smo kreirali na prethodnom koraku. U suštini, handler je okidač, događaj koji poziva neku funkciju bota. U našem primjeru, takav okidač je slanje komande
/hi, i realizuje se komandomhi_handler <- CommandHandler('hi', say_hello). Prvi argument funkcijeCommandHandler()omogućava vam da postavite komandu, u našem slučajuhi, na koju će bot reagovati. Drugi argument omogućava da odredite metodu bota, pozvaćemo metodusay_hello, koji će se izvršiti kada korisnik pozove naredbu navedenu u prvom argumentu; - Zatim dodajemo stvoreni handler u upravitelj naše instance klase
Updater. Dodavanje handlera može se izvršiti na nekoliko načina, u gornjem primjeru koristio sam najjednostavniji, s oznakom+, tj.updater <- updater + hi_handler. Isto se može učiniti putem metodeadd_handler(), koja pripada klasiDispatcher, ovaj metod se može pronaći ovako:updater$dispatcher$add_handler(); - Pokrećemo bota koristeći naredbu
start_polling().
Obrtnik tekstualnih poruka i filtri
Kako smo shvatili kako slati komande boti, ali ponekad bismo željeli da bot reagira ne samo na komande, već i na obične tekstualne poruke. Za to treba koristiti обработчики poruka — MessageHandler.
Obični MessageHandler reagirat će na apsolutno sve dolazne poruke. Stoga se handleri poruka često koriste zajedno s filtrima. Naučimo bota da se pozdravlja ne samo na komandu /hi, već i uvijek kada se u poruci poslanom botu pojavi jedna od sljedećih riječi: zdravo, dobar dan, pozdrav, hej, bonjour.
Dok ne planiramo pisati nove metode, pošto već imamo metodu kojom se bot pozdravlja. Od nas se traži samo da stvorimo potreban filtar i handler poruka.
Kod 2: Dodajemo handler za tekstualne poruke i filtar
library(telegram.bot)
# stvaramo instancu klase Updater
updater <- Updater('TOKEN VAŠEG BOTA')
# Pisanje metode za pozdrav
## naredba pozdrava
say_hello <- function(bot, update) {
# Ime korisnika s kojim treba pozdraviti
user_name <- update$message$from$first_name
# Šaljemo pozdravnu poruku
bot$sendMessage(update$message$chat_id,
text = paste0("Moje poštovanje, ", user_name, "!"),
parse_mode = "Markdown",
reply_to_message_id = update$message$message_id)
}
# stvaramo filtre
MessageFilters$hi <- BaseFilter(function(message) {
# provjeravamo, pojavljuje li se u tekstu poruke riječi: zdravo, dobar dan, pozdrav, hej, bonjour
grepl(x = message$text,
pattern = 'zdravo|dobar dan|pozdrav|hej|bonjour',
ignore.case = TRUE)
}
)
# stvaramo handler
hi_handler <- CommandHandler('hi', say_hello) # handler za naredbu hi
hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)
# dodajemo handlerse u upravitelj
updater <- updater +
hi_handler +
hi_txt_hnd
# pokrećemo bota
updater$start_polling()Pokrenite gornji primjer koda, prethodno zamenjujući ‘TOKEN VAŠEG BOTA’ pravim tokenom koji ste dobili prilikom kreiranja bota preko BotFather (o kreiranju bota govorio sam u ).
Sada ćemo pokušati poslati botu nekoliko poruka koje će sadržavati prethodno navedene riječi pozdrava:

Dakle, prvo smo naučili bota ne samo da se pozdravlja, već i da odgovara na pozdrave. To smo postigli pomoću argumenta reply_to_message_id, koji je dostupan u metodi sendMessage(), u koju je potrebno proslijediti id poruke na koju treba odgovoriti. Id poruke možete dobiti ovako: update$message$message_id.
Ali najvažnije je što smo učinili — dodali smo bota filtar pomoću funkcije BaseFilter():
# создаём фильтры
MessageFilters$hi <- BaseFilter(
# анонимная фильтрующая функция
function(message) {
# проверяем, встречается ли в тексте сообщения слова приветствия
grepl(x = message$text,
pattern = 'привет|здравствуй|салют|хай|бонжур',
ignore.case = TRUE)
}
)Kao što ste mogli primijetiti, filtre treba dodavati u objekt MessageFilters, u kojem već postoji mali skup gotovih filtara. U našem primjeru u objekt MessageFilters dodali smo element hi, to je novi filter.
U funkciju BaseFilter() potrebno je proslijediti funkciju za filtriranje. U suštini, filter — to je jednostavno funkcija koja prima instancu poruke i vraća TRUE ili FALSE. U našem primjeru, napisali smo najjednostavniju funkciju koja pomoću osnovne funkcije grepl() provjerava tekst poruke, i ako odgovara regularnom izrazu pozdrav|zdravo|salut|hej|bonjour vraća TRUE.
Zatim kreiramo handler poruka hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). Prvi argument funkcije MessageHandler() — metoda koja će pozvati handler, a drugi argument — to je filter prema kojem će biti pozvan. U našem slučaju to je stvoreni filter MessageFilters$hi.
I na kraju, dodajemo u dispečer upravo stvoreni handler hi_txt_hnd.
updater <- updater +
hi_handler +
hi_txt_hndKao što sam već ranije spomenuo, u paketu telegram.bot i objektu MessageFilters već postoji skup ugrađenih filtara koje možete koristiti:
- all — Sve poruke
- text — Tekstualne poruke
- command — Komande, tj. poruke koje započinju s
/ - reply — Poruke koje su odgovor na drugu poruku
- audio — Poruke koje sadrže audio datoteku
- document — Poruke s poslanim dokumentom
- photo — Poruke s poslanim slikama
- sticker — Poruke s poslanim naljepnicama
- video — Poruke s videom
- voice — Glasovne poruke
- contact — Poruke koje sadrže kontakt Telegram korisnika
- location — Poruke s geolokacijom
- venue — Proslijeđene poruke
- game — Igre
Ako želite kombinirati neke filtre u jednom handleru, samo koristite znak | — kao logički ILI, i znak & kao logički I. Na primjer, ako želite da bot poziva istu metodu kada primi video, sliku ili dokument, koristite sljedeći primjer kreiranja obradnika poruka:
handler <- MessageHandler(callback,
MessageFilters$video | MessageFilters$photo | MessageFilters$document
)Dodavanje naredbi s parametrima
Već znamo što su komande, kako ih stvoriti i kako natjerati bota da izvrši potrebnu komandu. No, u nekim slučajevima pored naziva komande, potrebno je proslijediti i neke podatke za njeno izvršavanje.
Ispod je primjer bota koji na temelju zadanog datuma i države vraća tip dana iz proizvodnog kalendara.
Donji bot koristi API proizvodnog kalendara .
Kod 3: Bot koji obavještava prema datumu i državi
library(telegram.bot)
# kreiramo instancu klase Updater
updater <- Updater('1165649194:AAFkDqIzQ6Wq5GV0YU7PmEZcv1gmWIFIB_8')
# Pišemo metodu za pozdrav
## komanda pozdrav
check_date <- function(bot, update, args) {
# ulazni podaci
day <- args[1] # datum
country <- args[2] # zemlja
# provjera unesenih parametara
if ( !grepl('\d{4}-\d{2}-\d{2}', day) ) {
# Pošalji prilagođenu tipkovnicu
bot$sendMessage(update$message$chat_id,
text = paste0(day, " - neispravan datum, unesite datum u formatu GGGG-MM-DD"),
parse_mode = "Markdown")
} else {
day <- as.Date(day)
# pretvaramo u format POSIXtl
y <- format(day, "%Y")
m <- format(day, "%m")
d <- format(day, "%d")
}
# zemlja za provjeru
## provjeravamo je li zemlja zadana
## ako nije, postavljamo ru
if ( ! country %in% c('ru', 'ua', 'by', 'kz', 'us') ) {
# Pošalji prilagođenu tipkovnicu
bot$sendMessage(update$message$chat_id,
text = paste0(country, " - neispravan kod zemlje, mogući vrijednosti: ru, by, kz, ua, us. Traženi podaci za Rusiju."),
parse_mode = "Markdown")
country <- 'ru'
}
# zahtjev podataka iz API
# slaganje HTTP zahtjeva
url <- paste0("https://isdayoff.ru/api/getdata?",
"year=", y, "&",
"month=", m, "&",
"day=", d, "&",
"cc=", country, "&",
"pre=1&",
"covid=1")
# dobivamo odgovor
res <- readLines(url)
# interpretacija odgovora
out <- switch(res,
"0" = "Radni dan",
"1" = "Neradni dan",
"2" = "Smanjeni radni dan",
"4" = "covid-19",
"100" = "Greška u datumu",
"101" = "Podaci nisu pronađeni",
"199" = "Greška usluge")
# šaljemo poruku
bot$sendMessage(update$message$chat_id,
text = paste0(day, " - ", out),
parse_mode = "Markdown")
}
# kreiramo handler
date_hendler <- CommandHandler('check_date', check_date, pass_args = TRUE)
# dodajemo handler u dispatcher
updater <- updater + date_hendler
# pokrećemo bota
updater$start_polling()Pokrenite gornji primjer koda, prethodno zamenjujući ‘TOKEN VAŠEG BOTA’ pravim tokenom koji ste dobili prilikom kreiranja bota preko BotFather (o kreiranju bota govorio sam u ).
Stvorili smo bota koji u svom arsenalu ima samo jednu metodu check_date, ova metoda se poziva istom imenom komande.
No, osim imena komande, ova metoda očekuje da unesete dva parametra, kod zemlje i datum. Zatim bot provjerava je li zadan dan u određenoj zemlji slobodan, skraćeni radni dan ili radni dan prema službenom radnom kalendaru.
Kako bi naš stvoreni metod prihvatio dodatne parametre zajedno s komandom, koristite argument pass_args = TRUE u funkciji CommandHandler(), i pri stvaranju metode, osim obaveznih argumenata bot, update stvorite opcionalni — argsMetoda izrađena na ovaj način primat će parametre koje proslijedite botu nakon naziva naredbe. Parametre je potrebno odvojiti razmakom, u metodu će doći kao tekstni vektor.
Pokrenimo i testirajmo našeg bota.

Pokrećemo bota u pozadinskom režimu
Posljednji korak koji nam preostaje je pokrenuti bota u pozadinskom režimu.
Za to slijedite opisani algoritam:
- Spremite kod bota u datoteku s ekstenzijom R. Kada radite u RStudiu, to se radi kroz izbornik Datoteka, naredbom Spremi kao….
- Dodajte put do mape bin, koja se nalazi u mapi u koju ste instalirali R, u varijablu Path, upute .
- Izradite običnu tekstualnu datoteku, u kojoj napišite 1 redak:
R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. Umjesto C:UsersAlseyDocumentsmy_bot.R napišite put do svog bota. Važno je da u putu ne bude ćirilice i razmaka, jer to može uzrokovati probleme pri pokretanju bota. Spremite ga i promijenite ekstenziju iz txt na bat. - Otvorite Planner zadataka Windows, postoji više načina da to učinite, primjerice otvorite bilo koju mapu i u adresnu traku upišite
%windir%system32taskschd.msc /s. Drugi načini pokretanja mogu se naći . - U gornjem desnom izborniku planera kliknite "Izradi zadatak…".
- Na kartici "Općenito" odredite proizvoljno ime vašem zadatku, i prebacite prekidač u stanje "Izvoditi za sve korisnike".
- Idite na karticu "Radnje", kliknite "Izraditi". U polju "Program ili skripta" kliknite "Pregledaj", pronađite datoteku koju ste izradili u drugom koraku bat , i kliknite U redu.
- Kliknite U redu, po potrebi unesite lozinku za svoj korisnički račun operativnog sustava.
- Pronađite u Planneru stvoreni zadatak, označite i u donjem desnom kutu kliknite gumb "Pokreni".
Naš bot je pokrenut u pozadinskom režimu i radit će sve dok ne zaustavite zadatak ili ne isključite svoj PC ili poslužitelj na kojem ste ga pokrenuli.
Zaključak
U ovom članku smo objasnili kako napisati punopravnog bota koji ne samo da može slati poruke, već i reagirati na dolazne poruke i naredbe. Stečeno znanje već je dovoljno za rješavanje većine vaših zadataka.
U sljedećem članku govorit ćemo o tome kako dodati botu tipkovnicu za jednostavnije korištenje.
Pratite me na i kanalima.
Izvor: habr.com
