CodeGym /Java-blogg /Tilfeldig /Opprette en Telegram-bot i Java: fra unnfangelse til dist...
John Squirrels
Nivå
San Francisco

Opprette en Telegram-bot i Java: fra unnfangelse til distribusjon

Publisert i gruppen
Så hva er bots? Du kan lese mer om dette her . For å starte, må du se gjennom den offisielle dokumentasjonen for biblioteket som brukes til å utvikle Telegram-roboter (heretter "API"). Den finner du her .
Opprette en Telegram-bot i Java: fra unnfangelse til distribusjon - 1
Alt der er veldig tilgjengelig og oversiktlig. Det ser ut til at vi bare kan skrive kode og glede oss! Men det er ikke så enkelt. Etter å ha brukt mye tid på å søke, har jeg funnet kunnskaper om utvikling av roboter, for eksempel hvordan lage et tastatur, håndtere enCallbackQuery, og så videre. Men jeg fant ikke en fullstendig, uttømmende guide for Java-botutvikling. Det fikk meg til å skrive denne artikkelen. Det er mange nettsteder hvor du kan lage din egen enkelt distribuerbare bot. Men faktum er at de fleste av robotene som er opprettet, gir referanseinformasjon og lignende. Boten vår er en fullverdig nettapplikasjon. Du kan binde en database, utføre ulike API-forespørsler, analysere nettsteder, utføre komplekse beregninger og mer. Mulighetene begrenses kun av fantasien din. Jeg håper at ovenstående har bidratt til å tydeliggjøre hva jeg skal skrive om. Det er veldig enkelt å registrere en bot på Telegram. Denne prosessen er beskrevet i detalj i dokumentasjonen lenket til ovenfor. For vår applikasjon trenger du bare å vite botens navn og tokenet du mottar når du registrerer boten. I utgangspunktet, en bot er bare en konsollbasert nettapplikasjon. Det er ingen grensesnitt, bare ren kommandobehandling. Hvis du vil mestreGå i dvale eller lær hvordan du analyserer JSON , så er dette prosjektet for deg. La oss starte med å legge til en avhengighet til pom.xml(jeg antar at du bruker Maven). Du kan gjøre det slik:

<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
Lag deretter en Botklasse som arver TelegramLongPollingBotklassen, og overstyr metodene:

public class Bot extends TelegramLongPollingBot {

    /**
     * Method for receiving messages.
     * @param update Contains a message from the user.
     */
    @Override
    public void onUpdateReceived(Update update) {
    String message = update.getMessage().getText();
    sendMsg(update.getMessage().getChatId().toString(), message);
    }

    /**
     * Method for creating a message and sending it.
     * @param chatId chat id
     * @param s The String that you want to send as a message.
     */
    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());
        }
    }

    /**
     * This method returns the bot's name, which was specified during registration.
     * @return bot name
     */
    @Override
    public String getBotUsername() {
        return "BotName";
    }

    /**
     * This method returns the bot's token for communicating with the Telegram server
     * @return the bot's token
     */
    @Override
    public String getBotToken() {
        return "BotToken";
    }
}
Og nå innholdet i mainmetoden:

public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotApi telegramBotApi = new TelegramBotApi();
        try {
            telegramBotApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
Etter å ha fylt ut metodene getBotUsername()og getBotToken(), start boten. Foreløpig omdirigerer den bare til oss alle meldinger vi sender til den, på en måte som et " speil ". Det fungerer slik: når du starter applikasjonen, begynner den å sende forespørsler til Telegram-serveren, en gang hvert n. sekund, på følgende URL: https://api.telegram.org/BotToken/getMe , hvor BotToken er botens token . Som svar mottar den JSON som inneholder alle meldingene. Hver av disse meldingene behandles av biblioteket og sendes til OnUpdateReceived(Update update)metoden som enUpdategjenstand. Og det er det vi jobber med. Her ligger skjønnheten til Telegram-roboter: de kan kjøres på hvilken som helst datamaskin, å teste den krever bare å starte applikasjonen, og du trenger ikke å distribuere den til verten etter hver endring. Dette er veldig praktisk. Selvfølgelig kan du konfigurere en bot til å fungere ved hjelp av webhooks. Du kan finne veibeskrivelser for det på Internett. For enkelhets skyld bruker vi LongPolling. Hvordan meldinger behandles og hva du sender som svar er kun begrenset av funksjonene til språket og biblioteket. Alt annet er opp til deg. Du kan lage en bot som søker etter YouTube-videoer for deg. Du kan lage en bot som sender deg det du sender deg selv hver dag, som en tidskapsel fra et år siden. Eller du kan lære å integrere med CRM-systemer og lage roboter for små bedrifter – du er bare begrenset av fantasien din. Går videre. De som har brukt roboter vet at det er praktisk å samhandle med dem ved å bruke kommandoer som starter med tegnet " /", for eksempel /start. Men det er en mer praktisk måte: knapper. Det er to typer knapper: de som vises under et inndatafelt ( ReplyKeyboardMarkup) og knapper som er rett under meldingen de er koblet til (InlineKeyboardMarkup). Du kan få en grunnleggende forståelse av dem fra beskrivelsene deres i dokumentasjonen.

ReplyKeyboardMarkup

I virkeligheten er dette en rekke knappematriser: List<KeyboardRow <KeyboardButton>>. Her er eksempelkoden som lager et tastatur:

public synchronized void setButtons(SendMessage sendMessage) {
        // Create a keyboard
        ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
        sendMessage.setReplyMarkup(replyKeyboardMarkup);
        replyKeyboardMarkup.setSelective(true);
        replyKeyboardMarkup.setResizeKeyboard(true);
        replyKeyboardMarkup.setOneTimeKeyboard(false);

        // Create a list of keyboard rows
        List<KeyboardRow> keyboard = new ArrayList<>();

        // First keyboard row
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Add buttons to the first keyboard row
        keyboardFirstRow.add(new KeyboardButton("Hi"));

        // Second keyboard row
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Add the buttons to the second keyboard row
        keyboardSecondRow.add(new KeyboardButton("Help");

        // Add all of the keyboard rows to the list
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // and assign this list to our keyboard
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
Vi kaller denne metoden i sendMsg()metoden, etter å ha sendt den en melding. Dette er hvordan vi setter opp et tastatur for den meldingen. Når vi sender denne meldingen til brukeren, vil han se teksten i meldingen vår og 2 knapper som sier "Hei" og "Hjelp" , den ene under den andre. Når en av disse knappene klikkes, får roboten tilsendt en melding som inneholder knappeteksten. Så hvis klienten klikker "Hjelp" vil boten motta en melding med "Hjelp". For boten vil det virke som om klienten selv skrev «Hjelp» og sendte teksten til boten. Og så behandler du meldingene.

InlineKeyboardMarkup

Dette er også en rekke matriser. Det ligner på forrige Markup, men logikken fungerer litt annerledes her. Denne typen tastatur er knyttet til en spesifikk melding og eksisterer kun for den. Her er en metode for å sette opp et innebygd tastatur:

private void setInline() {
        List<List<InlineKeyboardButton>> buttons = new ArrayList<>();
        List<InlineKeyboardButton> buttons1 = new ArrayList<>();
        buttons1.add(new InlineKeyboardButton().setText("Button").setCallbackData(17));
        buttons.add(buttons1);

        InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup();
        markupKeyboard.setKeyboard(buttons);
    }
Opprett en Listi List, og legg til innebygd-knappen i den første raden. Denne knappen kan inneholde en URL, en lenke til en kanal eller en CallbackQuery, som jeg skal skrive om litt senere. Det er her vi setter knappens tekst, som er hva brukeren vil se, og deretter setter vi dataene som skal sendes til boten. I vårt eksempel ser brukeren "Hei", og når knappen trykkes vil tallet 17 sendes til boten. Dette er vår CallbackQuery. Noen få ord vedr CallbackQuery. For å få disse dataene fra objektet Update, må du kjøre update.getCallbackQuery(). Denne metoden returnerer en CallbackQuery, hvorfra du kan få tilgang til dataene som sendes til boten. Ikke prøv å få disse dataene gjennom update.getMessage().getText()metoden – du får en 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());
        }
    }
Hvis det er en melding, sender vi den til en ny tråd for behandling; hvis det er en CallbackQuery, sender vi til den aktuelle tråden for behandling. Du kan sende et svar til en CallbackQuery. Hvert objekt i Telegram har sin egen id. For å sende et svar til et spesifikt CallbackQuery, trenger du bare å kjenne dens ID, som vi får fra det tilsvarende objektet. For å sende et svar kaller vi denne metoden:

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();
        }
    }
VIKTIG:Teksten i et svar på a CallbackQuerymå ikke være lengre enn 200 tegn! Etter å ha sendt et slikt svar, vil klienten se et popup-vindu som inneholder meldingen. Dette vinduet kan forsvinne noen sekunder etter at det vises, eller det kan vedvare til brukeren trykker OK. For å bytte modus kaller vi answer.setShowAlert(true)metoden. Hvis du går over truetil metoden, vedvarer vinduet til du trykker på OK. Hvis du gir feil, forsvinner den etter 5 sekunder. Dette er alle de grunnleggende funksjonene til Telegram Bot-biblioteket . Hvis du vil, kan du lære ting som hvordan du sender multimedia, geolokalisering osv. La oss gå videre til å distribuere boten vår til en vertsplattform. For prosjektet mitt valgte jeg Heroku. Jeg synes det er en ganske praktisk vertsplattform med sin egen CLI. Det er gratis, men på denne planen vil boten din gå i dvale etter 30 minutter uten å ha mottatt forespørsler. Den våkner når en forespørsel mottas. Dette skjer så raskt at du ikke en gang legger merke til det (med mindre, selvfølgelig, databasetilkoblingen ikke starter på nytt). Gratisplanen er begrenset av en 5 MB database, 100 MB diskplass, 2 TB data per måned og 1 dyno. En dyno er din kjørende applikasjon. Jeg vil si med en gang at det var utplassering som forårsaket meg vanskeligheter, siden jeg aldri hadde distribuert applikasjonene mine før. Under distribusjon krever Heroku en fil som heter Procfile (uten utvidelse). Vi lager det i prosjektroten. Inne skriver vi worker: sh target/bin/workerBot, hvor workerBot er navnet spesifisert i pom.xml. En shskriptet, generert av Maven Application Assembler Plugin (appassembler-maven-plugin), vil starte. Skriptet beskriver hvordan du starter en kompilert jar-fil. Navnet på klassen som skal lanseres er spesifisert mellom <mainClass>og </mainClass>, mens navnet på skriptet er gitt mellom <name>og </name>i 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>
Før du starter denne prosessen, bør du registrere deg på Heroku og installere både Git og Heroku CLI . Hvis applikasjonen din trenger en database, så ikke glem å legge til den nødvendige databasen når du oppretter en ny applikasjon. Videre må du bestemme verten, brukernavnet, passordet og porten for databasen din, og deretter angi dem i søknaden din. Deretter, før du distribuerer, bygg prosjektet ditt med Maven .

mvn clean install
Først går vi til prosjektkatalogen vår og initialiserer depotet med kommandoen git init. Deretter legger vi prosjektet vårt til dette depotet.

git add .
Så forplikter vi endringene

git commit -m "First commit in the project"
Deretter må du logge på heroku. Skriv følgende på kommandolinjen

heroku login
Skriv inn legitimasjonen du opprettet under registreringen. Deretter bestemmer du depotets URL på heroku. Dette gjør du i innstillingene. Så skriver vi

git remote add heroku [url]
Et eksternt heroku-depot er lagt til for ditt depot. Neste skriver vi

git push heroku master
Så venter vi ... hvis applikasjonen distribueres vellykket, utfør følgende kommando

heroku ps:scale worker=1
Og det er det, applikasjonen din er oppe og går. Hvis det ikke er det, se nøye på loggene. Mest sannsynlig har en feil i applikasjonen din ført til at den mislyktes. Takk for at du leste en så lang artikkel. Jeg håper noen vil finne det nyttig og at det vil spare deg for mye tid på de områdene som ga meg problemer under utviklingen.
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION