Píšeme telegramového bota v jazyce R (díl 2): Přidání podpory příkazů a filtrů zpráv

V předchozí publikace probrali jsme, jak vytvořit bota, inicializovali instanci třídy Bot a seznámili se s metodami, jak posílat zprávy pomocí něj.

V tomto článku pokračuji k tomuto tématu, proto doporučuji začít číst tento článek až po přečtení první části.

Tentokrát se podíváme, jak oživit našeho bota a přidat mu podporu příkazů, a také se seznámíme s třídou Updater.

V průběhu článku napíšeme několik jednoduchých botů, poslední z nich bude podle daného data a kódu země určovat, zda je den v této zemi pracovním dnem nebo dnem volna podle pracovního kalendáře. Ale, jak bylo dříve cílem článku, je seznámit vás s rozhraním balíčku telegram.bot pro řešení vašich vlastních úkolů.

Píšeme telegramového bota v jazyce R (díl 2): Přidání podpory příkazů a filtrů zpráv

Všechny články ze série "Píšeme telegramového bota v jazyce R"

  1. Vytváříme bota a pomocí něj posíláme zprávy na telegram
  2. Přidáváme botovi podporu příkazů a filtry zpráv

Obsah

Pokud se zajímáte o analýzu dat, možná vás zaujmou mé telegram a youtube kanály. Většina obsahu je věnována jazyku R.

  1. Třída Updater
  2. Handlers — zpracovatelé
  3. Přidáváme první příkaz bota, zpracovatel příkazů
  4. Zpracovatel textových zpráv a filtry
  5. Přidání příkazů s parametry
  6. Spouštíme bota na pozadí
  7. Závěr

Třída Updater

Updater — to je třída, která usnadňuje vývoj telegram bota, a pod kapotou používá třídu Dispatcher. Účelem třídy Updater je získat aktualizace od bota (v předchozím článku jsme k tomuto účelu použili metodu getUpdates()), a předat je dále do Dispatcher.

Na oplátku Dispatcher obsahuje vámi vytvořené zpracovatele, tj. objekty třídy Handler.

Handlers — zpracovatelé

Pomocí zpracovatelů přidáváte do Dispatcher reakce bota na různé události. V době psaní článku byly přidány následující typy zpracovatelů: telegram.bot MessageHandler — Zpracovatel zpráv

  • CommandHandler — Zpracovatel příkazů
  • CallbackQueryHandler — Zpracovatel dat posílaných z inline klávesnic
  • ErrorHandler — Zpracovatel chyb při dotazování na aktualizace od bota
  • Pokud jste nikdy předtím nepoužívali boty a nevíte, co je příkaz, musíte botovi posílat příkazy pomocí přímého lomítka

Přidáváme první příkaz bota, zpracovatel příkazů

jako prefix. / Začneme s jednoduchými příkazy, tj. naučíme našeho bota zdravit na příkaz

Kód 1: Učíme bota zdravit /hi.

Kód 1: Učíme bota pozdravit

library(telegram.bot)

# vytváříme instanci třídy Updater
updater <- Updater('VAŠE BOT TOKEN')

# Píšeme metodu pro pozdrav
say_hello <- function(bot, update) {

  # Uživatelské jméno, se kterým se máme pozdravit
  user_name <- update$message$from$first_name

  # Odeslání pozdravné zprávy
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("S pozdravem, ", user_name, "!"), 
                  parse_mode = "Markdown")

}

# vytváříme zpracovatele
hi_hendler <- CommandHandler('hi', say_hello)

# přidáváme zpracovatele do správce
updater <- updater + hi_hendler

# spouštíme bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Metoda start_polling() třídy Updater, který se používá na konci kódu, spouští nekonečnou smyčku dotazování a zpracování aktualizací od bota.

Nyní otevřeme Telegram a napíšeme našemu botu první příkaz /hi.

Píšeme telegramového bota v jazyce R (díl 2): Přidání podpory příkazů a filtrů zpráv

Nyní náš bot rozumí příkazu /hi, a umí se s námi zdravit.

Schématicky lze proces budování takového nejjednoduššího bota znázornit následovně.

Píšeme telegramového bota v jazyce R (díl 2): Přidání podpory příkazů a filtrů zpráv

  1. Vytváříme instanci třídy Updater;
  2. Vytváříme metody, tedy funkce, které náš bot bude vykonávat. V příkladu kódu to je funkce say_hello(). Funkce, které budete používat jako metody bota, musí mít dva povinné argumenty — bot a update, a jeden volitelný — args. Argument bot, to je váš bot, s jehož pomocí můžete odpovídat na zprávy, posílat zprávy nebo používat jakékoli jiné dostupné metody bota. Argument update je to, co bot obdržel od uživatele, v podstatě to, co jsme v prvním článku získávali metodou getUpdates(). Argument args umožňuje vám zpracovávat dodatečná data odeslaná uživatelem spolu s příkazem, k této tématice se ještě vrátíme trochu později;
  3. Vytváříme zpracovatele, tedy propojujeme nějaké akce uživatele s vytvořenými v předchozím kroku metodami. V podstatě je zpracovatel trenér, událost, která vyvolává nějakou funkci bota. V našem příkladě je takovým trenérem odeslání příkazu /hi, a realizuje se příkazem hi_hendler <- CommandHandler('hi', say_hello). První argument funkce CommandHandler() vám umožňuje nastavit příkaz, v našem případě hi, na který bude bot reagovat. Druhý argument umožňuje určit metodu bota, budeme volat metodu say_hello, který se provede, pokud uživatel vyvolá příkaz uvedený v prvním argumentu;
  4. Poté přidáme vytvořený zpracovatel do správce naší instance třídy Updater. Zpracovatele je možné přidávat několika způsoby, v uvedeném příkladu jsem použil nejjednodušší pomocí znaku +, tj. updater <- updater + hi_hendler. Totéž lze udělat pomocí metody add_handler(), která patří do třídy Dispatcher, tento метод можно найти так: updater$dispatcher$add_handler();
  5. Spouštíme bota pomocí příkazu start_polling().

Zpracovatel textových zpráv a filtry

Jak jsme si vysvětlili, jak posílat bota příkazy, ale někdy potřebujeme, aby bot reagoval nejen na příkazy, ale i na nějaké běžné textové zprávy. K tomu je nutné použít zpracovatele zpráv — MessageHandler.

Běžný MessageHandler bude reagovat na všechny příchozí zprávy. Proto se zpracovatelé zpráv často používají spolu s filtry. Naučme bota zdravit nejen na příkaz /hi, ale také vždy, když se ve zprávě zaslané botovi nachází jedno z následujících slov: ahoj, zdravím, pozdrav, čau, bonjour.

Prozatím nebudeme psát žádné nové metody, protože už máme metodu, se kterou nás bot zdraví. Od nás jen vyžaduje vytvoření potřebného filtru a zpracovatele zpráv.

Kód 2: Přidáváme zpracovatele textových zpráv a filtr

library(telegram.bot)

# vytváříme instanci třídy Updater
updater <- Updater('TOKEN VAŠEHO BOTA')

# Píšeme metodu pro pozdrav
## příkaz pro pozdrav
say_hello <- function(bot, update) {

  # Jméno uživatele, kterého se má pozdravit
  user_name <- update$message$from$first_name

  # Posíláme pozdravnou zprávu
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("S úctou, ", user_name, "!"),
                  parse_mode = "Markdown",
                  reply_to_message_id = update$message$message_id)

}

# vytváříme filtry
MessageFilters$hi <- BaseFilter(function(message) {

  # kontrolujeme, zda se ve zprávě nacházejí slova: ahoj, zdravím, pozdrav, čau, bonjour
  grepl(x = message$text, 
        pattern = 'ahoj|zdravím|pozdrav|čau|bonjour',
        ignore.case = TRUE)
  }
)

# vytváříme zpracovatele 
hi_hendler <- CommandHandler('hi', say_hello) # zpracovatel příkazu hi
hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)

# přidáme zpracovatele do správce
updater <- updater + 
             hi_hendler +
             hi_txt_hnd

# spouštíme bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Teď se pokusíme poslat botovi několik zpráv, které budou obsahovat dříve zmíněná slova pozdravu:
Píšeme telegramového bota v jazyce R (díl 2): Přidání podpory příkazů a filtrů zpráv

Takže nejprve jsme naučili bota nejen zdravit, ale také odpovídat na pozdrav. Udělali jsme to pomocí argumentu reply_to_message_id, který je dostupný v metodě sendMessage(), do které je třeba předat id zprávy, na kterou má být odpovězeno. Id zprávy lze získat takto: update$message$message_id.

Ale hlavní, co jsme udělali — přidali jsme bota filtr pomocí funkce BaseFilter():

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

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

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

)

Jak jste si mohli všimnout, filtry je třeba přidávat do objektu MessageFilters, který už v sobě má malou sadu připravených filtrů. V našem příkladu jsme do objektu MessageFilters přidali prvek hi, což je nový filtr.

Do funkce BaseFilter() musíte předat filtrační funkci. V podstatě filtr — je to prostě funkce, která přijímá instanci zprávy a vrací TRUE nebo FALSE. V našem příkladu jsme napsali nejjednodušší funkci, která pomocí základní funkce grepl() kontroluje text zprávy, a pokud odpovídá regulárnímu výrazu ahoj|zdravstvuj|salu|čau|bonjour vrací TRUE.

Dále vytváříme zpracovatele zpráv hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). První argument funkce MessageHandler() — metoda, která vyvolá zpracovatele, a druhý argument — je filtr, podle kterého bude vyvolán. V našem případě to je filtr, který jsme vytvořili MessageFilters$hi.

A nakonec, přidáváme do správce právě vytvořený zpracovatel hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Jak jsem již psal výše, v balíčku telegram.bot a objektu MessageFilters už jsou k dispozici sady vestavěných filtrů, které můžete použít:

  • all — Všechny zprávy
  • text — Textové zprávy
  • command — Příkazy, t.j. zprávy, které začínají na /
  • reply — Zprávy, které jsou odpovědí na jinou zprávu
  • audio — Zprávy, které obsahují audio soubor
  • document — Zprávy s odeslaným dokumentem
  • photo — Zprávy s odeslanými obrázky
  • sticker — Zprávy s odeslaným nálepkou
  • video — Zprávy s videem
  • voice — Hlasové zprávy
  • contact — Zprávy, které obsahují kontakt uživatele Telegramu
  • location — Zprávy s geografickou polohou
  • venue — Přeposílané zprávy
  • game — Hry

Pokud chcete kombinovat některé filtry v jednom zpracovateli, jednoduše použijte znak | — jako logický NEBO, a znak && jako logické A. Například, pokud chcete, aby bot volal stejnou metodu, když obdrží video, obrázek nebo dokument, použijte následující příklad vytvoření zpracovatele zpráv:

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

Přidání příkazů s parametry

Už víme, co jsou příkazy, jak je vytvářet a jak přimět bota vykonat potřebný příkaz. V některých případech však kromě názvu příkazu musíme předat některá data pro jeho vykonání.

Níže je příklad bota, který na základě zadaného data a země vrací typ dne z výrobního kalendáře.

Níže uvedený bot používá API výrobního kalendáře isdayoff.ru.

Kód 3: Bot, který oznamuje podle data a země

library(telegram.bot)

# Vytvoření instance třídy Updater
updater <- Updater('1165649194:AAFkDqIzQ6Wq5GV0YU7PmEZcv1gmWIFIB_8')

# Napíšeme metodu pro uvítání
## příkaz uvítání
check_date <- function(bot, update, args) {

  # příchozí data
  day <- args[1]  # datum
  country <- args[2]  # země

  # kontrola zadaných parametrů
  if ( !grepl('\d{4}-\d{2}-\d{2}', day) ) {

    # Odeslat vlastní klávesnici
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(day, " - neplatné datum, zadejte datum ve formátu RRRR-MM-DD"),
                    parse_mode = "Markdown")

  } else {
    day <- as.Date(day)
    # převedeme na formát POSIXtl
    y <- format(day, "%Y")
    m <- format(day, "%m")
    d <- format(day, "%d")

  }

  # země pro kontrolu
  ## kontrolujeme, zda byla zadaná země
  ## pokud není zadána, nastavíme ru
  if ( ! country %in% c('ru', 'ua', 'by', 'kz', 'us') ) {

    # Odeslat vlastní klávesnici
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(country, " - neplatný kód země, možné hodnoty: ru, by, kz, ua, us. Požadována data pro Rusko."),
                    parse_mode = "Markdown")

    country <- 'ru'

  }

  # dotaz na data z API
  # sestavení HTTP dotazu
  url <- paste0("https://isdayoff.ru/api/getdata?",
                "year=",  y, "&",
                "month=", m, "&",
                "day=",   d, "&",
                "cc=",    country, "&",
                "pre=1&",
                "covid=1")

  # získání odpovědi
  res <- readLines(url)

  # interpretace odpovědi
  out <- switch(res, 
                "0"   = "Pracovní den",
                "1"   = "Nevyplněný den",
                "2"   = "Zkrácený pracovní den",
                "4"   = "covid-19",
                "100" = "Chyba v datu",
                "101" = "Data nebyla nalezena",
                "199" = "Chyba služby")

  # odeslat zprávu
  bot$sendMessage(update$message$chat_id, 
                  text = paste0(day, " - ", out),
                  parse_mode = "Markdown")

}

# vytvoření zpracovatele
date_hendler <- CommandHandler('check_date', check_date, pass_args = TRUE)

# přidání zpracovatele do správce
updater <- updater + date_hendler

# spuštění bota
updater$start_polling()

Spusťte výše uvedený příklad kódu, než nahradíte 'VAŠE BOT TOKEN' skutečným tokenem, který jste získali při vytváření bota přes BotFather (o vytváření bota jsem mluvil v v prvním článku).

Vytvořili jsme bota, který má ve své nabídce pouze jednu metodu check_date, tato metoda je volána příkazem se stejným názvem.

Ale kromě názvu příkazu tato metoda očekává, že od vás zadáte dva parametry, kód země a datum. Následně bot zkontroluje, zda je zadaný den ve stanovené zemi víkend, zkrácený pracovní den nebo pracovní den podle oficiálního pracovního kalendáře.

Aby vytvořená metoda přijímala další parametry spolu s příkazem, použijte argument pass_args = TRUE ve funkci CommandHandler(), a při vytváření metody, kromě povinných argumentů bot, update vytvořte volitelný — argsVytvořená metoda bude přijímat parametry, které předáváte botovi po názvu příkazu. Parametry je nutné mezi sebou oddělit mezerou, do metody přijdou jako textový vektor.

Pojďme spustit a otestovat našeho bota.

Píšeme telegramového bota v jazyce R (díl 2): Přidání podpory příkazů a filtrů zpráv

Spouštíme bota na pozadí

Posledním krokem, který nám zbývá udělat, je spustit bota na pozadí.

K tomu následujte níže uvedený postup:

  1. Uložte kód bota do souboru s příponou R. Při práci v RStudio se to dělá přes menu Soubor, příkazem Uložit jako….
  2. Přidejte cestu k složce bin, která je zase umístěna ve složce, do které jste nainstalovali jazyk R do proměnné Path, instrukce tady.
  3. Vytvořte obyčejný textový soubor, do kterého napište jeden řádek: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. Místo C:UsersAlseyDocumentsmy_bot.R napište cestu k vašemu skriptu bota. Přitom je důležité, aby v cestě nebyla cyrilice a mezery, protože to může způsobit problémy při spuštění bota. Uložte ho a změňte jeho příponu na txt na bat.
  4. Otevřete Plánovač úloh systému Windows, existuje mnoho způsobů, jak to udělat, například otevřete jakoukoliv složku a do adresy zadejte %windir%system32taskschd.msc /s. Další způsoby spuštění můžete najít tady.
  5. V pravém horním menu Plánovače klikněte na "Vytvořit úkol…".
  6. Na kartě "Obecné" zadejte libovolné jméno vašeho úkolu a přepínač přepněte do stavu "Spouštět pro všechny uživatele".
  7. Přejděte na kartu "Akce", klikněte na "Vytvořit". V poli "Program nebo skript" klikněte na "Procházet", najděte vytvořený soubor z druhého kroku bat , a klikněte na OK.
  8. Klikneme na OK, pokud je to nutné, zadejte heslo k vašemu účtu operačního systému.
  9. Najděte v Plánovači vytvořený úkol, vyberte ho a v pravém dolním rohu klikněte na tlačítko "Spustit".

Náš bot je spuštěn na pozadí a bude fungovat, dokud nezastavíte úkol nebo nevypnete svůj počítač nebo server, na kterém byl spuštěn.

Závěr

V tomto článku jsme se naučili, jak napsat plnohodnotného bota, který umí nejen posílat zprávy, ale také reagovat na příchozí zprávy a příkazy. Získané znalosti jsou již dostatečné pro řešení většiny vašich úkolů.

V dalším článku se budeme zabývat tím, jak přidat botovi klávesnici pro pohodlnější práci.

Přihlaste se k mému telegram a youtube kanálu.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster