Telegramos roboto rašymas R (2 dalis): Komandų palaikymo ir pranešimų filtrų pridėjimas prie roboto

В ankstesnis leidinys sugalvojome, kaip sukurti robotą, inicijavome klasės egzempliorių Bot ir susipažino su pranešimų siuntimo būdais naudojant jį.

Šiame straipsnyje tęsiu šią temą, todėl rekomenduoju pradėti skaityti šį straipsnį tik perskaičius pirmoji dalis.

Šį kartą išsiaiškinsime, kaip atgaivinti savo robotą ir pridėti prie jo komandų palaikymą, taip pat susipažinsime su klase Updater.

Straipsnio eigoje parašysime keletą paprastų botų, pastarieji pagal nurodytą datą ir šalies kodą nustatys, ar diena tam tikroje šalyje yra savaitgalis ar darbo diena pagal gamybos kalendorių. Tačiau, kaip ir anksčiau, straipsnio tikslas yra supažindinti jus su paketo sąsaja telegram.bot išspręsti savo problemas.

Telegramos roboto rašymas R (2 dalis): Komandų palaikymo ir pranešimų filtrų pridėjimas prie roboto

Visi straipsniai iš serijos „Telegramos roboto rašymas R“

  1. Mes sukuriame robotą ir naudojame jį žinutėms telegramoje siųsti
  2. Pridėkite komandų palaikymą ir pranešimų filtrus prie roboto

Turinys

Jei jus domina duomenų analizė, galbūt jus domina mano telegrama и "YouTube" kanalai. Didžioji dalis turinio skirta R kalbai.

  1. Atnaujintojų klasė
  2. Handleriai – tvarkytojai
  3. Pridėkite pirmąją komandą prie roboto, komandų tvarkyklės
  4. Teksto pranešimų procesorius ir filtrai
  5. Komandų pridėjimas su parametrais
  6. Paleiskite robotą fone
  7. išvada

Atnaujintojų klasė

Updater yra klasė, kuri padeda lengviau sukurti telegramų robotą ir naudoja klasę po gaubtu Dispetcher. Klasės užduotis Updater yra gauti atnaujinimus iš roboto (ankstesniame straipsnyje mes naudojome šį metodą getUpdates()) ir perkelkite juos toliau į Dispetcher.

Savo ruožtu Dispetcher yra jūsų sukurtos tvarkyklės, t.y. klasės objektai Handler.

Handleriai – tvarkytojai

Su tvarkytuvais, kuriuos pridedate Dispetcher botų reakcija į įvairius įvykius. Šio straipsnio rašymo metu telegram.bot Pridėta šių tipų tvarkyklių:

  • MessageHandler – pranešimų tvarkytojas
  • CommandHandler – komandų tvarkytojas
  • CallbackQueryHandler – duomenų tvarkytojas klaviatūroms, siunčiamoms iš Inline
  • ErrorHandler – klaidų tvarkytojas, kai prašoma atnaujinti robotą

Pridėkite pirmąją komandą prie roboto, komandų tvarkyklės

Jei niekada anksčiau nenaudojote robotų ir nežinote, kas yra komanda, tada komandos į robotą turi būti siunčiamos naudojant pasvirąjį brūkšnį / kaip priešdėlis.

Pradėsime nuo paprastų komandų, t.y. išmokykime savo robotą pasisveikinti pagal komandą /hi.

1 kodas: mokykite robotą pasisveikinti

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

Vykdykite aukščiau pateiktą kodo pavyzdį, pakeitę „YOUR BOTO TOKEN“ tikruoju prieigos raktu, kurį gavote kurdami robotą per „BotFather“ (Aš kalbėjau apie roboto kūrimą pirmasis straipsnis).

metodas start_polling() klasė Updater, kuris naudojamas kodo pabaigoje, pradeda begalinį atnaujinimų užklausų ir apdorojimo procesą iš roboto.

Dabar atidarykime „Telegram“ ir parašykite pirmąją komandą mūsų robotui /hi.

Telegramos roboto rašymas R (2 dalis): Komandų palaikymo ir pranešimų filtrų pridėjimas prie roboto

Dabar mūsų robotas supranta komandą /hi, ir žino, kaip mus pasveikinti.

Schematiškai tokio paprasto roboto kūrimo procesą galima pavaizduoti taip.

Telegramos roboto rašymas R (2 dalis): Komandų palaikymo ir pranešimų filtrų pridėjimas prie roboto

  1. Sukurkite klasės egzempliorių Updater;
  2. Kuriame metodus, t.y. funkcijas, kurias atliks mūsų robotas. Kodo pavyzdyje tai yra funkcija say_hello(). Funkcijos, kurias naudosite kaip robotų metodus, turi turėti du būtinus argumentus – snukis и atnaujinimasir vienas neprivalomas – argumentuoja. Argumentas snukis, tai yra jūsų robotas, kurio pagalba galite atsakyti į žinutes, siųsti žinutes ar naudoti bet kokius kitus robotui prieinamus metodus. Argumentas atnaujinimas būtent tai robotas gavo iš vartotojo, iš tikrųjų tai, ką mes gavome pirmame straipsnyje naudodami metodą getUpdates(). Argumentas argumentuoja leidžia apdoroti papildomus vartotojo siunčiamus duomenis kartu su komanda, prie šios temos grįšime kiek vėliau;
  3. Kuriame tvarkykles, t.y. Kai kuriuos vartotojo veiksmus susiejame su metodais, sukurtais atliekant ankstesnį veiksmą. Iš esmės tvarkytojas yra trigeris, įvykis, kuris iškviečia kokią nors roboto funkciją. Mūsų pavyzdyje toks trigeris siunčia komandą /hi, ir jį įgyvendina komanda hi_hendler <- CommandHandler('hi', say_hello). Pirmasis funkcijos argumentas CommandHandler() leidžia nurodyti komandą, mūsų atveju hi, į kurį robotas atsakys. Antrasis argumentas leidžia nurodyti boto metodą, mes vadinsime metodą say_hello, kuris bus vykdomas, jei vartotojas iškvietė pirmame argumente nurodytą komandą;
  4. Tada sukurtą tvarkyklę įtraukiame į mūsų klasės egzemplioriaus dispečerį Updater. Galite pridėti tvarkykles keliais būdais; aukščiau esančiame pavyzdyje naudojau paprasčiausią, naudodamas ženklą +Ty updater <- updater + hi_hendler. Tą patį galima padaryti naudojant metodą add_handler(), kuris priklauso klasei Dispatcher, šį metodą galite rasti taip: updater$dispatcher$add_handler();
  5. Paleiskite robotą naudodami komandą start_polling().

Teksto pranešimų procesorius ir filtrai

Mes sugalvojome, kaip siųsti komandas robotui, tačiau kartais mums reikia, kad robotas reaguotų ne tik į komandas, bet ir į kai kuriuos įprastus tekstinius pranešimus. Norėdami tai padaryti, turite naudoti pranešimų tvarkykles − Message Handler.

Normalus Message Handler atsakys į absoliučiai visus gaunamus pranešimus. Todėl pranešimų tvarkyklės dažnai naudojamos kartu su filtrais. Išmokykime botą pasisveikinti ne tik pagal komandą /hi, bet ir kaskart, kai robotui atsiųstame pranešime pasirodo vienas iš šių žodžių: hello, hello, salute, hai, bonjour.

Kol kas naujų metodų nerašysime, nes... Jau turime metodą, kuriuo robotas mus sveikina. Viskas, ką turime padaryti, tai sukurti reikiamą filtrą ir pranešimų tvarkyklę.

2 kodas: pridėkite teksto pranešimų tvarkyklę ir filtrą

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

Vykdykite aukščiau pateiktą kodo pavyzdį, pakeitę „YOUR BOTO TOKEN“ tikruoju prieigos raktu, kurį gavote kurdami robotą per „BotFather“ (Aš kalbėjau apie roboto kūrimą pirmasis straipsnis).

Dabar pabandykime nusiųsti robotui keletą pranešimų, kuriuose yra anksčiau išvardyti sveikinimo žodžiai:
Telegramos roboto rašymas R (2 dalis): Komandų palaikymo ir pranešimų filtrų pridėjimas prie roboto

Taigi, visų pirma, išmokėme botą ne tik pasisveikinti, bet ir atsakyti į pasisveikinimą. Mes tai padarėme naudodami argumentą reply_to_message_id, kuris yra prieinamas metodu sendMessage(), į kurį reikia perkelti pranešimo, į kurį norite atsakyti, ID. Pranešimo ID galite gauti taip: update$message$message_id.

Tačiau pagrindinis dalykas, kurį padarėme, buvo pridėti filtrą prie roboto naudojant funkciją BaseFilter():

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

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

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

)

Kaip tikriausiai pastebėjote, prie objekto reikia pridėti filtrų Pranešimų filtrai, kuriame iš pradžių jau yra nedidelis paruoštų filtrų rinkinys. Mūsų pavyzdyje į objektą Pranešimų filtrai pridėjome elementą hi, tai naujas filtras.

Funkcijoje BaseFilter() turite išlaikyti filtro funkciją. Iš esmės filtras yra tik funkcija, kuri gauna pranešimo egzempliorių ir grąžina TIKROJI arba FALSE. Savo pavyzdyje mes parašėme paprastą funkciją, kuri, naudojant pagrindinę funkciją grepl() patikrina pranešimo tekstą ir ar jis atitinka reguliarųjį posakį привет|здравствуй|салют|хай|бонжур grįžta TIKROJI.

Toliau sukuriame pranešimų tvarkyklę hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). Pirmasis funkcijos argumentas MessageHandler() yra metodas, kuris iškvies tvarkyklę, o antrasis argumentas yra filtras, kuriuo jis bus iškviestas. Mūsų atveju tai yra mūsų sukurtas filtras MessageFilters$hi.

Na, o pabaigoje mes pridedame prie dispečerio sukurtą tvarkyklę hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Kaip rašiau aukščiau, pakuotėje telegram.bot ir objektas Pranešimų filtrai Jau yra integruotų filtrų rinkinys, kurį galite naudoti:

  • visi — visi pranešimai
  • text — teksto žinutės
  • komanda – Komandos, t.y. žinutes, kurios prasideda /
  • atsakyti — žinutės, kurios yra atsakymas į kitą žinutę
  • garsas – pranešimai, kuriuose yra garso failas
  • dokumentas — pranešimai su išsiųstu dokumentu
  • nuotrauka – žinutės su išsiųstais vaizdais
  • lipdukas – žinutės su išsiųstu lipduku
  • vaizdo įrašas — žinutės su vaizdo įrašu
  • balsas – balso žinutės
  • kontaktas – pranešimai, kuriuose yra vartotojo telegramos turinys
  • vieta – pranešimai su geografine vieta
  • vieta – persiųsti pranešimai
  • žaidimas – žaidimai

Jei norite sujungti kai kuriuos filtrus vienoje tvarkyklėje, tiesiog naudokite ženklą | - kaip logiška ARBA, ir pasirašykite & kaip logiška И. Pavyzdžiui, jei norite, kad robotas iškviestų tą patį metodą, kai gauna vaizdo įrašą, vaizdą ar dokumentą, naudokite šį pavyzdį, kad sukurtumėte pranešimų tvarkyklę:

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

Komandų pridėjimas su parametrais

Jau žinome, kas yra komandos, kaip jas sukurti ir kaip priversti botą vykdyti norimą komandą. Tačiau kai kuriais atvejais, be komandos pavadinimo, norint ją vykdyti, turime perduoti kai kuriuos duomenis.

Žemiau pateikiamas roboto, kuris, atsižvelgiant į nurodytą datą ir šalį, grąžina dienos tipą iš gamybos kalendoriaus, pavyzdys.

Toliau pateiktame robote naudojama gamybos kalendoriaus API isdayoff.ru.

3 kodas: robotas, teikiantis ataskaitas pagal datą ir šalį

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

Vykdykite aukščiau pateiktą kodo pavyzdį, pakeitę „YOUR BOTO TOKEN“ tikruoju prieigos raktu, kurį gavote kurdami robotą per „BotFather“ (Aš kalbėjau apie roboto kūrimą pirmasis straipsnis).

Sukūrėme robotą, kurio arsenale yra tik vienas metodas check_date, šis metodas vadinamas to paties pavadinimo komanda.

Tačiau, be komandos pavadinimo, šis metodas reikalauja įvesti du parametrus – šalies kodą ir datą. Tada robotas patikrina, ar tam tikra diena nurodytoje šalyje yra savaitgalis, sutrumpinta diena ar darbo diena pagal oficialų gamybos kalendorių.

Kad mūsų sukurtas metodas priimtų papildomus parametrus kartu su komanda, naudokite argumentą pass_args = TRUE funkcijoje CommandHandler(), o kurdami metodą, be reikalingų argumentų snukis, atnaujinimas sukurti neprivalomą - argumentuoja. Tokiu būdu sukurtas metodas priims parametrus, kuriuos perduodate robotui po komandos pavadinimo. Parametrai turi būti atskirti tarpu, jie bus siunčiami metodui kaip teksto vektorius.

Paleiskime ir išbandykime savo robotą.

Telegramos roboto rašymas R (2 dalis): Komandų palaikymo ir pranešimų filtrų pridėjimas prie roboto

Paleiskite robotą fone

Paskutinis veiksmas, kurį turime atlikti, yra paleisti robotą fone.

Norėdami tai padaryti, vadovaukitės toliau aprašytu algoritmu:

  1. Išsaugokite boto kodą faile su plėtiniu R. Dirbant RStudio, tai daroma per meniu filė, komanda Išsaugoti kaip.
  2. Pridėkite kelią į aplanką bin, kuris savo ruožtu yra aplanke, kuriame įdiegėte R kalbą, prie kintamojo Path, instrukcijas čia.
  3. Sukurkite įprastą tekstinį failą, kuriame parašykite 1 eilutę: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. Vietoj C:UsersAlseyDocumentsmy_bot.R parašykite kelią į savo roboto scenarijų. Kartu svarbu, kad pakeliui nebūtų kirilicos simbolių ar tarpų, nes tai gali sukelti problemų paleidžiant robotą. Išsaugokite jį ir pakeiskite jo plėtinį į txt apie bat.
  4. Atidarykite „Windows Task Scheduler“, yra daug būdų tai padaryti, pavyzdžiui, atidarykite bet kurį aplanką ir įveskite adresą %windir%system32taskschd.msc /s. Galima rasti kitų paleidimo būdų čia.
  5. Viršutiniame dešiniajame planuotojo meniu spustelėkite „Sukurti užduotį...“.
  6. Skirtuke „Bendra“ suteikite užduočiai priskirtą pavadinimą ir perjunkite jungiklį į būseną „Vykdyti visiems vartotojams“.
  7. Eikite į skirtuką „Veiksmai“, spustelėkite „Sukurti“. Lauke „Programa arba scenarijus“ spustelėkite „Naršyti“, raskite sukurtą antrame veiksme bat failą ir spustelėkite Gerai.
  8. Spustelėkite Gerai ir, jei reikia, įveskite operacinės sistemos paskyros slaptažodį.
  9. Planuoklyje suraskite sukurtą užduotį, pasirinkite ją ir apatiniame dešiniajame kampe spustelėkite mygtuką „Vykdyti“.

Mūsų robotas veikia fone ir veiks tol, kol sustabdysite užduotį arba išjungsite kompiuterį ar serverį, kuriame jis buvo paleistas.

išvada

Šiame straipsnyje mes išsiaiškinome, kaip parašyti visavertį robotą, galintį ne tik siųsti pranešimus, bet ir reaguoti į gaunamus pranešimus bei komandas. Įgytų žinių jau pakanka daugumai jūsų problemų išspręsti.

Kitame straipsnyje bus kalbama apie tai, kaip prie roboto pridėti klaviatūrą, kad būtų patogiau dirbti.

Prenumeruokite mano telegrama и "YouTube" kanalai.

Šaltinis: www.habr.com

Добавить комментарий