JavaRush /Blog Java /Random-PL /Tworzenie bota Telegramu w Javie: od pomysłu do wdrożenia...
John Watson
Poziom 27

Tworzenie bota Telegramu w Javie: od pomysłu do wdrożenia

Opublikowano w grupie Random-PL
Czym w ogóle są boty? Możesz o tym szczegółowo przeczytać tutaj . Najpierw musisz przeczytać oficjalną dokumentację biblioteki do tworzenia botów na Telegramie (zwaną dalej API). Ona tu leży . Tworzenie bota Telegramu w Javie: od pomysłu do wdrożenia - 1Wszystko tam jest bardzo przystępne i zrozumiałe. Wydawałoby się, że pisz i raduj się! Ale to nie jest takie proste. Po spędzeniu dużej ilości czasu w wyszukiwarkach znalazłem strzępy wiedzy na temat tworzenia botów, na przykład jak zrobić klawiaturę, przetwarzać CallbackQuery i tym podobne. Nigdy nie znalazłem kompletnego i wszechstronnego przewodnika dotyczącego tworzenia botów w Javie. To skłoniło mnie do napisania tego artykułu. W Internecie istnieje wiele witryn, w których można stworzyć własnego bota z gotowym wdrożeniem. Ale chodzi o to. że w większości tworzone są boty, które mogą dostarczać informacji ogólnych i tak dalej. Nasz bot to pełnoprawna aplikacja internetowa, z którą możesz powiązać bazę danych, wysyłać żądania do różnych API, analizować strony, wykonywać skomplikowane obliczenia itp. W tej kwestii ogranicza Cię jedynie Twoja wyobraźnia. Mam nadzieję, że w tych linijkach wyjaśniłem Wam trochę o czym będę pisać. Rejestracja bota w Telegramie jest bardzo prosta, proces ten szczegółowo opisano w dokumentacji pod powyższym linkiem. Do naszej aplikacji wystarczy znać nazwę bota i token, który otrzymasz po rejestracji. Zasadniczo bot to po prostu konsolowa aplikacja internetowa. Żadnych frontendów, czyste przetwarzanie poleceń. Jeśli chcesz dobrze opanować Hibernację lub nauczyć się parsować JSON, to ten projekt jest dla Ciebie. Zacznijmy od włączenia zależności do pom.xml (zakładamy, że używasz Mavena). Możesz to zrobić w ten sposób:
<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
Następnie tworzymy klasę Bot, dziedziczymy ją z klasy TelegramLongPollingBot, nadpisując jej metody:
public class Bot extends TelegramLongPollingBot {

    /**
     * Metoda odbierania komunikatów.
     * @param update Zawiera wiadomość od użytkownika.
     */
    @Override
    public void onUpdateReceived(Update update) {
	String message = update.getMessage().getText();
	sendMsg(update.getMessage().getChatId().toString(), message);
    }

    /**
     * Metoda ustawiania wiadomości i wysyłania jej.
     * @param chatId identyfikator czatu
     * @param s Ciąg do wysłania jako wiadomość.
     */
    public synchronized void sendMsg(String chatId, String s) {
        SendMessage sendMessage = new SendMessage();
        sendMessage.enableMarkdown(true);
        sendMessage.setChatId(chatId);
        sendMessage.setText(s);
        try {
            sendMessage(sendMessage);
        } catch (TelegramApiException e) {
            log.log(Level.SEVERE, "Exception: ", e.toString());
        }
    }

    /**
     * Metoda zwraca nazwę bota określoną podczas rejestracji.
     * @return nazwa bota
     */
    @Override
    public String getBotUsername() {
        returnBotName;
    }

    /**
     * Metoda zwraca token bota do komunikacji z serwerem Telegram
     * @return token dla bota
     */
    @Override
    public String getBotToken() {
        returnBotToken;
    }
}
Cóż, zawartość metody main:
public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
        try {
            telegramBotsApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
getBotUsername()Wpisując go w metody getBotToken()uruchamiamy bota. Na razie przekierowuje do nas jedynie wszelkie wiadomości, które do niego wysyłamy, jest to swego rodzaju „lustro”. Wszystko działa w następujący sposób: po uruchomieniu aplikacji zaczyna ona wysyłać żądanie GET do serwera Telegramu co n sekund pod następującym adresem URL: https://api.telegram.org/BotToken/getMe, gdzie znajduje się BotToken token Twojego bota, otrzymujący odpowiedź JSON zawierającą wszystkie wiadomości. Każdy taki komunikat jest przetwarzany przez bibliotekę i trafia do metody OnUpdateReceived(Update update)jako obiekt Update. Z tym właśnie współpracujemy. Na tym polega piękno botów Telegramu, mogą pracować na dowolnym komputerze, do przetestowania wystarczy uruchomić aplikację, nie trzeba jej instalować na hostingu po każdej zmianie. To jest bardzo wygodne. Bota można oczywiście skonfigurować do pracy z wykorzystaniem webhooka, instrukcję można znaleźć w Internecie, dla uproszczenia będziemy pracować przy użyciu LongPolling. To, jak przetwarzać wiadomości i co wysyłać w odpowiedzi, ograniczają tylko narzędzia językowe i biblioteka, wszystko inne zależy od Ciebie. Możesz stworzyć bota, który będzie za Ciebie wyszukiwał filmy na YouTube, możesz zrobić bota, który codziennie będzie Ci wysyłał to, co sam sobie wyślesz, np. za rok, swego rodzaju kapsuła czasu. Możesz też nauczyć się integrować z systemami CRM i tworzyć boty dla małych firm, wszystko ogranicza Twoja wyobraźnia. Zacząć robić. Ci, którzy korzystali z botów, wiedzą, że wygodnie jest z nimi wchodzić w interakcję za pomocą poleceń rozpoczynających się «/»np. od znaku /start. Ale jest wygodniejszy sposób - przyciski. Istnieją dwa typy przycisków: te, które pojawiają się pod polem wejściowym, ReplyKeyboardMarkuporaz przyciski, które pojawiają się bezpośrednio pod wiadomością, z którą są powiązane InlineKeyboardMarkup. W dokumentacji można pokrótce zapoznać się z ich opisem. OdpowiedzKlawiaturaMarkup. Zasadniczo jest to tablica tablic przycisków, List<KeyboardRow<KeyboardButton>>. Oto przykładowy kod tworzący klawiaturę
public synchronized void setButtons(SendMessage sendMessage) {
        // Utwórz klawiaturę
        ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
        sendMessage.setReplyMarkup(replyKeyboardMarkup);
        replyKeyboardMarkup.setSelective(true);
        replyKeyboardMarkup.setResizeKeyboard(true);
        replyKeyboardMarkup.setOneTimeKeyboard(false);

        // Utwórz listę ciągów klawiaturowych
        List<KeyboardRow> keyboard = new ArrayList<>();

        // Pierwsza linia klawiatury
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Dodaj przyciski do pierwszej linii klawiatury
        keyboardFirstRow.add(new KeyboardButton(“Привет”));

        // Druga linia klawiatury
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Dodaj przyciski do drugiego wiersza klawiatury
        keyboardSecondRow.add(new KeyboardButton(“Помощь”);

        // Dodaj wszystkie ciągi klawiatury do listy
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // i ustaw tę listę na naszej klawiaturze
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
W metodzie sendMsg()wywołujemy tę metodę, przekazując do niej wiadomość, ustawiając w ten sposób klawiaturę dla tej wiadomości. Gdy wyślemy tę wiadomość do użytkownika, zobaczy on ustawiony przez nas tekst wiadomości oraz 2 przyciski obok siebie z napisami Witam i Pomoc. Klikając na te przyciski, do bota zostanie wysłana wiadomość, której treść jest wpisana na przycisku. Oznacza to, że jeśli klient kliknie „Pomoc”, bot otrzyma wiadomość o treści „Pomoc”. Dla niego to tak, jakby klient sam napisał SMS-a „Pomoc” i mu go wysłał. Cóż, w takim razie przetwarzasz takie wiadomości. InlineKeyboardMarkup Jest to również tablica tablic, jest podobna do poprzedniego znacznika, ale logika działania jest tutaj nieco inna. Taka klawiatura jest powiązana z konkretną wiadomością i istnieje tylko dla niej. Oto metoda instalacji klawiatury Inline
private void setInline() {
        List<List<InlineKeyboardButton>> buttons = new ArrayList<>();
        List<InlineKeyboardButton> buttons1 = new ArrayList<>();
        buttons1.add(new InlineKeyboardButton().setText(“Кнопка“).setCallbackData(17));
        buttons.add(buttons1);

        InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup();
        markupKeyboard.setKeyboard(buttons);
    }
Utwórz Listw List, dodaj przycisk Inline do pierwszej linii. Taki przycisk może zawierać adres URL, link do kanału lub CallbackQuery, o czym napiszę nieco później. Tutaj ustawiamy tekst naszego przycisku, który zobaczy użytkownik, a następnie ustawiamy dane, które zostaną przesłane do bota. W naszym przykładzie użytkownik widzi „Hello”, a po kliknięciu do bota zostanie wysłany numer 17, to jest nasz plik CallbackQuery. Kilka słów o CallbackQuery. Aby uzyskać takie dane z obiektu Updatenależy wykonać update.getCallbackQuery(), ta metoda zwraca CallbackQuery, z której można już pobrać dane przesłane do bota. Nie ma potrzeby próbować uzyskać te dane metodą update.getMessage().getText()get NullPointerException.
@Override
    public void onUpdateReceived(Update update) {
        if(update.hasMessage()) {
            ThreadClass thread = new ThreadClass(update.getMessage());
        } else  if(update.hasCallbackQuery()) {
            AnswerCallbackThread answerThread = new AnswerCallbackThread(update.getCallbackQuery());
        }
    }
Jeśli pojawi się wiadomość, wysyłamy ją do przetworzenia do nowego wątku, jeśli jest wiadomość CallbackQuery, wysyłamy ją do przetworzenia do odpowiedniego wątku. Możesz CallbackQuerywysłać odpowiedź. Każdy obiekt w Telegramie ma swój własny identyfikator. Aby wysłać odpowiedź do konkretnego obiektu CallbackQuerywystarczy znać jego identyfikator, który otrzymamy od odpowiedniego obiektu. Aby wysłać odpowiedź, wywołaj tę metodę:
public synchronized void answerCallbackQuery(String callbackId, String message) {
        AnswerCallbackQuery answer = new AnswerCallbackQuery();
        answer.setCallbackQueryId(callbackId);
        answer.setText(message);
        answer.setShowAlert(true);
        try {
            answerCallbackQuery(answer);
        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }
WAŻNY:Tekst odpowiedzi CallbackQuerynie powinien być dłuższy niż 200 znaków! Wysyłając taką odpowiedź, Klient otrzyma wyskakujące okienko, w którym zostanie zapisana wiadomość. Takie okno może zniknąć po kilku sekundach od pojawienia się lub zawiesić się do czasu naciśnięcia przez użytkownika OK. Aby przełączyć te tryby, wywołujemy metodę answer.setShowAlert(true). Gdy trueokno zawiesza się do momentu naciśnięcia OK, gdy falseznika po 5 sekundach. W zasadzie są to wszystkie podstawowe funkcje biblioteki botów Telegramu. Jeśli chcesz, możesz dowiedzieć się z dokumentacji takich rzeczy, jak przesyłanie multimediów, geolokalizacja itp. Przejdźmy do wdrożenia naszego bota na hostingu. Do mojego projektu wybrałem Heroku, ponieważ moim zdaniem jest to dość wygodny hosting, który ma własne CLI. Jest to bezpłatne, ale przy takim tempie Twój bot przejdzie w stan hibernacji po 30 minutach, jeśli nie będzie żadnych żądań. Kiedy zostaje do niego wysłana prośba, budzi się. Dzieje się to dość szybko, nawet tego nie zauważysz (o ile oczywiście połączenie z bazą danych nie zostanie ponownie nawiązane). Limit darmowego planu to 5MB bazy danych, 100MB miejsca na dysku, 2TB ruchu miesięcznie, 1 dino. Dino to Twoja działająca aplikacja. Od razu powiem, że trudności sprawił mi etap wdrożenia, gdyż nigdy wcześniej nie wdrażałem swoich aplikacji. Podczas wdrażania Heroku wymaga pliku o nazwie Procfile (bez rozszerzenia). Tworzymy go w katalogu głównym projektu, tam wpisujemy worker: sh target/bin/workerBot workerBot - nazwa, którą podajemy w pom.xml polu. Zostanie uruchomiony skrypt sh wygenerowany za pomocą wtyczki Maven appassembler-maven-plugin. Skrypt opisuje uruchomienie skompilowanego słoika. Nazwa uruchamianej klasy jest wskazywana pomiędzy <mainClass></mainClass>, nazwa skryptu pomiędzy <name></name> pom.xml:
...
<build>
    <plugins>
        ...
       <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>1.1.1</version>
            <configuration>
                <assembleDirectory>target</assembleDirectory>
                <programs>
                    <program>
                        <mainClass>com.home.server.TelegramBot</mainClass>
                        <name>workerBot</name>
                    </program>
                </programs>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Przed rozpoczęciem tego procesu powinieneś zarejestrować się w Heroku, zainstalować Git i Heroku CLI. Jeśli Twoja aplikacja wymaga bazy danych, to rejestrując nową aplikację, nie zapomnij dodać bazy danych, której potrzebujesz. Następnie musisz znaleźć hosta, nazwę użytkownika, hasło i port swojej bazy danych, a następnie określić go w swojej aplikacji. Następnie, przed wdrożeniem, zbuduj swój projekt za pomocą Mavena.
mvn clean install
Na początek wchodzimy do katalogu naszego projektu, inicjujemy repozytorium komendągit init Następnie dodajemy nasz projekt do tego repozytorium
git add .
Po zatwierdzeniu zmian
git commit -m “First commit in project”
Następnie musisz zalogować się do Heroku, napisz w wierszu poleceń
heroku login
Wpisz swoje dane podane podczas rejestracji. Następnie musisz znaleźć adres URL swojego repozytorium w Heroku, odbywa się to w ustawieniach. Potem piszemy
git remote add heroku [url]
Zdalne repozytorium heroku zostanie dodane do twojego repozytorium. Dalej piszemy
git push heroku master
Czekamy... Jeśli wdrożenie aplikacji przebiegnie pomyślnie, wykonujemy polecenie
heroku ps:scale worker=1
I to wszystko, Twoja aplikacja działa. Jeśli tak się nie stanie, przyjrzyj się uważnie logom; najprawdopodobniej wystąpił błąd w aplikacji, który spowodował jej awarię. Dziękuję za przeczytanie tak długiego artykułu, mam nadzieję, że komuś się przyda i zaoszczędzi mnóstwo czasu w miejscach, w których natknąłem się podczas programowania.
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION