Pisanie bota telegramowego w języku R (część 2): Dodajemy do bota wsparcie dla komend i filtry wiadomości

W poprzedniej publikacji Zrozumieliśmy, jak stworzyć bota, zainicjowaliśmy instancję klasy Bot i zapoznaliśmy się z metodami wysyłania wiadomości za jego pomocą.

W tym artykule kontynuuję ten temat, dlatego zalecam rozpoczęcie lektury dopiero po przeczytaniu pierwszej części.

Tym razem dowiemy się, jak ożywić naszego bota i dodamy mu wsparcie dla komend, a także zapoznamy się z klasą Updater.

W trakcie artykułu napiszemy kilka prostych botów, z których ostatni będzie określał, czy dany dzień w danym kraju jest dniem wolnym czy roboczym zgodnie z kalendarzem roboczym, na podstawie podanej daty i kodu kraju. Jednakże, jak w poprzednich artykułach, celem tego tekstu jest zapoznanie was z interfejsem pakietu telegram.bot do rozwiązania waszych własnych zadań.

Pisanie bota telegramowego w języku R (część 2): Dodajemy do bota wsparcie dla komend i filtry wiadomości

Wszystkie artykuły z serii „Tworzymy bota Telegram w języku R”

  1. Tworzymy bota i wysyłamy z jego pomocą wiadomości w Telegramie
  2. Dodajemy wsparcie dla komend i filtry wiadomości

Spis treści

Jeśli interesujesz się analizą danych, to mogą Cię zainteresować moje telegram i youtube kanały. Większość zawartości poświęcona jest językowi R.

  1. Klasa Updater
  2. Handlery — obsługiwacze
  3. Dodajemy pierwszą komendę do bota, obsługiwacz komend
  4. Obsługiwacz wiadomości tekstowych i filtry
  5. Dodawanie komend z parametrami
  6. Uruchamiamy bota w tle
  7. Podsumowanie

Klasa Updater

Updater — to klasa, która ułatwia tworzenie bota telegramowego, i pod spodem wykorzystuje klasę Dispatcher. Przeznaczenie klasy Updater polega na odbieraniu aktualizacji od bota (w poprzednim artykule używaliśmy do tego celu metody getUpdates()), i przesyłaniu ich dalej do Dispatcher.

Z kolei Dispatcher zawiera stworzone przez was obsługiwacze, tzn. obiekty klasy Handler.

Handlery — obsługiwacze

Za pomocą obsługiwaczy dodajecie do Dispatcher reakcje bota na różne zdarzenia. W momencie pisania artykułu w telegram.bot dodano następujące typy obsługiwaczy:

  • MessageHandler — Obsługiwacz wiadomości
  • CommandHandler — Obsługiwacz komend
  • CallbackQueryHandler — Obsługiwacz danych wysyłanych z przycisków Inline
  • ErrorHandler — Obsługiwacz błędów podczas zapytań o aktualizacje od bota

Dodajemy pierwszą komendę do bota, obsługiwacz komend

Jeśli nigdy wcześniej nie korzystaliście z botów i nie wiecie, co to jest komenda, to komendy do bota należy wysyłać za pomocą bezpośredniego ukośnika / jako prefiksu.

Zacznijmy od prostych komend, tzn. nauczmy naszego bota witać się na komendę /hi.

Kod 1: Uczymy bota witać się

library(telegram.bot)

# tworzymy instancję klasy Updater
updater <- Updater('TOKEN TWOJEGO BOTA')

# Piszemy metodę do powitania
say_hello <- function(bot, update) {

  # Imię użytkownika, z którym trzeba się przywitać
  user_name <- update$message$from$first_name

  # Wysyłanie wiadomości powitalnej
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Witam, ", user_name, "!"), 
                  parse_mode = "Markdown")

}

# tworzymy handler
hi_handler <- CommandHandler('hi', say_hello)

# dodajemy handler do dispatcher
updater <- updater + hi_handler

# uruchamiamy bota
updater$start_polling()

Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w pierwszym artykule).

Metoda start_polling() klasy Updater, który używany jest na końcu kodu, uruchamia nieskończoną pętlę zapytań i przetwarzania aktualizacji od bota.

Teraz otwórzmy Telegram i wyślijmy naszemu botowi pierwszą komendę /hi.

Pisanie bota telegramowego w języku R (część 2): Dodajemy do bota wsparcie dla komend i filtry wiadomości

Teraz nasz bot rozumie komendę /hi, i potrafi się z nami witać.

Schematycznie proces budowy takiego prostego bota można zobrazować w następujący sposób.

Pisanie bota telegramowego w języku R (część 2): Dodajemy do bota wsparcie dla komend i filtry wiadomości

  1. Tworzymy instancję klasy Updater;
  2. Tworzymy metody, czyli funkcje, które będzie wykonywał nasz bot. W przykładowym kodzie jest to funkcja say_hello(). Funkcje, które będą używane jako metody bota, muszą mieć dwa obowiązkowe argumenty — bot i update, i jeden opcjonalny — args. Argument bot, to jest twój bot, za pomocą którego możesz odpowiadać na wiadomości, wysyłać wiadomości lub korzystać z innych dostępnych metod bota. Argument update to to, co bot otrzymał od użytkownika, w zasadzie to, co w pierwszym artykule otrzymywaliśmy metodą getUpdates(). Argument args pozwala ci przetwarzać dodatkowe dane wysłane przez użytkownika wraz z komendą, do tej tematyki wrócimy jeszcze trochę później;
  3. Tworzymy handler, czyli łączymy jakieś działania użytkownika z utworzonymi metodami z poprzedniego kroku. W zasadzie handler to trigger, zdarzenie, które wywołuje jakąś funkcję bota. W naszym przykładzie takim triggerem jest wysłanie komendy /hi, i realizowane jest komendą hi_handler <- CommandHandler('hi', say_hello). Pierwszy argument funkcji CommandHandler() pozwala ci ustawić komendę, w naszym przypadku hi, na którą będzie reagował bot. Drugi argument pozwala wskazać metodę bota, będziemy wywoływać metodę say_hello, która będzie wykonywana, jeśli użytkownik wywoła wskazaną w pierwszym argumencie komendę;
  4. Następnie dodajemy stworzony handler do dispatcher naszej instancji klasy Updater. Można dodawać obsługiwacze na kilka sposobów, w powyższym przykładzie użyłem najprostszego, za pomocą znaku +, tzn. updater <- updater + hi_handler. To samo można zrobić za pomocą metody add_handler(), która należy do klasy Dispatcher, można znaleźć tę metodę w ten sposób: updater$dispatcher$add_handler();
  5. Uruchamiamy bota za pomocą polecenia start_polling().

Obsługiwacz wiadomości tekstowych i filtry

Zrozumieliśmy, jak wysyłać polecenia do bota, ale czasami potrzebujemy, aby bot reagował nie tylko na polecenia, ale także na zwykłe wiadomości tekstowe. W tym celu należy użyć obsługiwaczy wiadomości — MessageHandler.

Zwykły MessageHandler będzie reagować na absolutnie wszystkie przychodzące wiadomości. Dlatego często obsługiwacze wiadomości używane są razem z filtrami. Nauczmy bota witać się nie tylko na polecenie /hi, ale także zawsze, gdy w wiadomości wysłanej do bota pojawia się jedno z następujących słów: cześć, dzień dobry, salut, hej, bonjour.

Na razie nie będziemy pisać żadnych nowych metod, ponieważ już mamy metodę, za pomocą której bot się z nami wita. Od nas wymaga się tylko stworzenia odpowiedniego filtra i obsługiwacza wiadomości.

Kod 2: Dodajemy obsługiwacz wiadomości tekstowych i filtr

library(telegram.bot)

# tworzymy instancję klasy Updater
updater <- Updater('TOKEN TWOJEGO BOTA')

# Pisze metodę do powitania
## polecenie powitania
say_hello <- function(bot, update) {

  # Imię użytkownika, z którym trzeba się przywitać
  user_name <- update$message$from$first_name

  # Wysyłamy wiadomość powitalną
  bot$sendMessage(update$message$chat_id, 
                  text = paste0("Moje pozdrowienia, ", user_name, "!"),
                  parse_mode = "Markdown",
                  reply_to_message_id = update$message$message_id)

}

# tworzymy filtry
MessageFilters$hi <- BaseFilter(function(message) {

  # sprawdzamy, czy w treści wiadomości występują słowa: cześć, dzień dobry, salut, hej, bonjour
  grepl(x           = message$text, 
        pattern     = 'cześć|dzień dobry|salut|hej|bonjour',
        ignore.case = TRUE)
  }
)

# tworzymy obsługiwacz 
hi_handler <- CommandHandler('hi', say_hello) # obsługiwacz polecenia hi
hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi)

# dodajemy obsługiwacze do dispatcher
updater <- updater + 
             hi_handler +
             hi_txt_hnd

# uruchamiamy bota
updater$start_polling()

Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w pierwszym artykule).

Teraz spróbujemy wysłać do bota kilka wiadomości, w których będą występować wcześniej wymienione słowa powitalne:
Pisanie bota telegramowego w języku R (część 2): Dodajemy do bota wsparcie dla komend i filtry wiadomości

Zatem najpierw nauczyliśmy bota nie tylko witać, ale także odpowiadać na powitania. Zrobiliśmy to za pomocą argumentu reply_to_message_id, który jest dostępny w metodzie sendMessage(), do której należy przekazać id wiadomości, na którą trzeba odpowiedzieć. Id wiadomości można uzyskać w następujący sposób: update$message$message_id.

Ale najważniejsze jest to, że dodaliśmy do bota filtr za pomocą funkcji BaseFilter():

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

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

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

)

Jak mogliście zauważyć, filtry należy dodać do obiektu MessageFilters, w którym początkowo znajduje się niewielki zbiór gotowych filtrów. W naszym przykładzie do obiektu MessageFilters dodaliśmy element hi, to nowy filtr.

Do funkcji BaseFilter() musicie przekazać funkcję filtrującą. W zasadzie filtr to po prostu funkcja, która przyjmuje instancję wiadomości i zwraca PRAWDA lub FAŁSZ. W naszym przykładzie napisaliśmy prostą funkcję, która za pomocą podstawowej funkcji grepl() sprawdza tekst wiadomości, a jeśli odpowiada wyrażeniu regularnemu cześć|witaj|siema|hej|dzień dobry zwraca PRAWDA.

Następnie tworzymy obsługiwacz wiadomości hi_txt_hnd <- MessageHandler(say_hello, filters = MessageFilters$hi). Pierwszy argument funkcji MessageHandler() — metoda, która wywoła obsługiwacz, a drugi argument to filtr, według którego będzie wywoływana. W naszym przypadku jest to utworzony przez nas filtr MessageFilters$hi.

A na koniec dodajemy do programatora właśnie stworzony obsługiwacz hi_txt_hnd.

updater <- updater + 
             hi_hendler +
             hi_txt_hnd

Jak już wcześniej pisałem, w pakiecie telegram.bot i obiekcie MessageFilters już znajduje się zestaw wbudowanych filtrów, które możecie wykorzystać:

  • all — Wszystkie wiadomości
  • text — Wiadomości tekstowe
  • command — Komendy, tzn. wiadomości, które zaczynają się na /
  • reply — Wiadomości, które są odpowiedzią na inną wiadomość
  • audio — Wiadomości, w których zawarty jest plik audio
  • document — Wiadomości z przesłanym dokumentem
  • photo — Wiadomości z przesłanymi obrazami
  • sticker — Wiadomości z przesłanym naklejką
  • video — Wiadomości z wideo
  • voice — Wiadomości głosowe
  • contact — Wiadomości, w których zawarte są dane kontaktowe użytkownika telegramu
  • location — Wiadomości z geolokalizacją
  • venue — Przesyłane wiadomości
  • game — Gry

Jeśli chcesz połączyć niektóre filtry w jednym obsługiwaczu, po prostu użyj znaku | — jako logicznego LUB, a znaku & jako logicznego I. Na przykład, jeśli chcesz, aby bot wywoływał tę samą metodę, gdy otrzyma wideo, zdjęcie lub dokument, użyj następującego przykładu tworzenia obsługiwacza wiadomości:

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

Dodawanie komend z parametrami

Już wiemy, czym są komendy, jak je tworzyć i jak sprawić, by bot wykonał wymaganą komendę. Jednak w niektórych przypadkach, oprócz nazwy komendy, musimy przekazać pewne dane do jej wykonania.

Poniżej znajduje się przykład bota, który na podstawie podanej daty i kraju zwraca typ dnia z kalendarza roboczego.

Poniższy bot wykorzystuje API kalendarza roboczego isdayoff.ru.

Kod 3: Bot, który informuje o dacie i kraju

library(telegram.bot)

# tworzymy instancję klasy Updater
updater <- Updater('1165649194:AAFkDqIzQ6Wq5GV0YU7PmEZcv1gmWIFIB_8')

# Definiujemy metodę powitania
## komenda powitania
check_date <- function(bot, update, args) {

  # dane wejściowe
  day     <- args[1]  # data
  country <- args[2]  # kraj

  # sprawdzanie wprowadzonych parametrów
  if ( !grepl('\d{4}-\d{2}-\d{2}', day) ) {

    # Wyślij niestandardową klawiaturę
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(day, " - nieprawidłowa data, wprowadź datę w formacie RRRR-MM-DD"),
                    parse_mode = "Markdown")

  } else {
    day <- as.Date(day)
    # konwertujemy na format POSIXtl
    y <- format(day, "%Y")
    m <- format(day, "%m")
    d <- format(day, "%d")

  }

  # kraj dla sprawdzenia
  ## sprawdzamy, czy podano kraj
  ## jeśli nie, ustawiamy ru
  if ( ! country %in% c('ru', 'ua', 'by', 'kz', 'us') ) {

    # Wyślij niestandardową klawiaturę
    bot$sendMessage(update$message$chat_id, 
                    text = paste0(country, " - nieprawidłowy kod kraju, możliwe wartości: ru, by, kz, ua, us. Poproszono o dane dla Rosji."),
                    parse_mode = "Markdown")

    country <- 'ru'

  }

  # zapytanie danych z API
  # kompozycja zapytania HTTP
  url <- paste0("https://isdayoff.ru/api/getdata?",
                "year=",  y, "&",
                "month=", m, "&",
                "day=",   d, "&",
                "cc=",    country, "&",
                "pre=1&",
                "covid=1")

  # otrzymujemy odpowiedź
  res <- readLines(url)

  # interpretacja odpowiedzi
  out <- switch(res, 
                "0"   = "Dzień roboczy",
                "1"   = "Dzień wolny",
                "2"   = "Skrócony dzień roboczy",
                "4"   = "covid-19",
                "100" = "Błąd w dacie",
                "101" = "Dane nie znalezione",
                "199" = "Błąd serwisu")

  # wysyłamy wiadomość
  bot$sendMessage(update$message$chat_id, 
                  text = paste0(day, " - ", out),
                  parse_mode = "Markdown")

}

# tworzymy handler 
date_hendler <- CommandHandler('check_date', check_date, pass_args = TRUE)

# dodajemy handler do menedżera
updater <- updater + date_hendler

# uruchamiamy bota
updater$start_polling()

Uruchom powyższy przykład kodu, wcześniej zastępując ‘TWÓJ TOKEN BOTA’ prawdziwym tokenem, który otrzymałeś podczas tworzenia bota przez BotFather (o tworzeniu bota opowiadałem w pierwszym artykule).

Stworzyliśmy bota, który w swoim arsenale ma tylko jedną metodę check_date, ta metoda jest wywoływana za pomocą komendy o tej samej nazwie.

Jednak oprócz nazwy komendy, ta metoda oczekuje od Ciebie podania dwóch parametrów: kodu kraju i daty. Następnie bot sprawdza, czy dany dzień w podanym kraju jest dniem wolnym, skróconym lub roboczym zgodnie z oficjalnym kalendarzem pracy.

Aby tworzona przez nas metoda przyjmowała dodatkowe parametry razem z komendą, użyj argumentu pass_args = TRUE w funkcji CommandHandler(), a przy tworzeniu metody, oprócz obowiązkowych argumentów bot, update stwórz opcjonalny — args. Taka metoda będzie przyjmować parametry, które przekazujesz botowi po nazwie komendy. Parametry muszą być oddzielone spacją, a do metody trafią jako wektor tekstowy.

Uruchommy i przetestujmy naszego bota.

Pisanie bota telegramowego w języku R (część 2): Dodajemy do bota wsparcie dla komend i filtry wiadomości

Uruchamiamy bota w tle

Ostatni krok, który musimy wykonać — to uruchomienie bota w tle.

Aby to zrobić, postępuj zgodnie z poniższym algorytmem:

  1. Zapisz kod bota w pliku z rozszerzeniem R. W pracy w RStudio można to zrobić przez menu Plik, komendą Save As….
  2. Dodaj ścieżkę do folderu bin, który znajduje się w folderze, w którym zainstalowałeś język R, do zmiennej Path, instrukcja tutaj.
  3. Utwórz zwykły plik tekstowy, w którym wpisz jedną linię: R CMD BATCH C:UsersAlseyDocumentsmy_bot.R. Zamiast C:UsersAlseyDocumentsmy_bot.R wpisz ścieżkę do swojego skryptu bota. Ważne jest, aby w ścieżce nie było liter cyrylicy ani spacji, ponieważ może to spowodować problemy podczas uruchamiania bota. Zapisz go i zmień jego rozszerzenie z txt na bat.
  4. Otwórz harmonogram zadań Windows, jest wiele sposobów, aby to zrobić, na przykład otwórz dowolny folder i wprowadź w adresie %windir%system32taskschd.msc /s. Inne sposoby uruchamiania można znaleźć tutaj.
  5. W prawym górnym menu harmonogramu kliknij "Utwórz zadanie…".
  6. Na zakładce "Ogólne" nadaj dowolną nazwę swojej zadania i przełącz przełącznik w stan "Uruchamiaj dla wszystkich użytkowników".
  7. Przejdź do zakładki "Działania", kliknij "Utwórz". W polu "Program lub skrypt" kliknij "Przeglądaj", znajdź stworzony w drugim kroku bat plik i kliknij OK.
  8. Naciskamy OK, w razie potrzeby wprowadzamy hasło do swojego konta systemu operacyjnego.
  9. Szukamy w harmonogramie utworzonego zadania, zaznaczamy je i w prawym dolnym rogu klikamy przycisk "Uruchom".

Nasz bot działa w tle i będzie funkcjonować, dopóki nie zatrzymasz zadania lub nie wyłączysz swojego komputera lub serwera, na którym został uruchomiony.

Podsumowanie

W tym artykule omówiliśmy, jak napisać pełnoprawnego bota, który nie tylko potrafi wysyłać wiadomości, ale także reagować na przychodzące wiadomości i komendy. Zdobyta wiedza wystarczy do rozwiązania większości Twoich zadań.

W następnym artykule opiszemy, jak dodać botowi klawiaturę, aby ułatwić jego obsługę.

Zapisz się na mój telegram i youtube kanały.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster