JavaRush /Blogue Java /Random-PT /Criando um bot do Telegram em Java: da ideia à implantaçã...
John Watson
Nível 27

Criando um bot do Telegram em Java: da ideia à implantação

Publicado no grupo Random-PT
Afinal, o que são bots? Você pode ler sobre isso em detalhes aqui . Primeiro, você precisa ler a documentação oficial da biblioteca de desenvolvimento de bots no Telegram (doravante denominada API). Ela está aqui . Criando um bot do Telegram em Java: da ideia à implantação - 1Tudo lá é muito acessível e compreensível. Parece que escreva e alegre-se! Mas não é tão simples. Depois de passar muito tempo em mecanismos de busca, encontrei fragmentos de conhecimento sobre desenvolvimento de bots, por exemplo, como fazer um teclado, processar CallbackQuery e assim por diante. Nunca encontrei um guia completo e abrangente para desenvolver bots em Java. Isso me levou a escrever este artigo. Existem muitos sites na Internet onde você pode criar seu próprio bot com uma implantação pronta. Mas a questão é. que, na maioria dos casos, são criados bots que podem fornecer informações básicas e assim por diante. Nosso bot é um aplicativo da web completo ao qual você pode vincular um banco de dados, fazer solicitações a várias APIs, analisar sites, realizar cálculos complexos, etc. O assunto é limitado apenas pela sua imaginação. Espero que nestas linhas eu tenha explicado um pouco sobre o que vou escrever. Cadastrar um bot no Telegram é muito simples, esse processo está descrito detalhadamente na documentação do link acima. Para nossa aplicação você só precisa saber o nome do bot e o token que receberá no ato do cadastro. Essencialmente, um bot é apenas um aplicativo web de console. Sem frontend, puro processamento de comandos. Se você deseja dominar bem o Hibernate ou aprender como analisar JSON, então este projeto é para você. Vamos começar incluindo a dependência em pom.xml (presumimos que você esteja usando Maven). Você pode fazer assim:
<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
Então criamos uma classe Bot, herdamos ela da classe TelegramLongPollingBot, substituindo seus métodos:
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 setting up a message and sending it.
     * @param chatId chat id
     * @param s The string 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());
        }
    }

    /**
     * The method returns the name of the bot specified during registration.
     * @return bot name
     */
    @Override
    public String getBotUsername() {
        returnBotName;
    }

    /**
     * The method returns the bot's token to communicate with the Telegram server
     * @return token for the bot
     */
    @Override
    public String getBotToken() {
        returnBotToken;
    }
}
Bem, o conteúdo do método main:
public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
        try {
            telegramBotsApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
Ao inseri-lo nos métodos getBotUsername(), getBotToken()lançamos o bot. Por enquanto, ele apenas nos redireciona as mensagens que lhe enviamos, uma espécie de “espelho”. Tudo funciona da seguinte maneira: quando você inicia o aplicativo, ele começa a enviar uma solicitação GET para o servidor Telegram uma vez a cada n segundos na seguinte URL: https://api.telegram.org/BotToken/getMe, onde BotToken é o token do seu bot, recebendo em uma resposta JSON contendo todas as mensagens. Cada mensagem é processada pela biblioteca e chega ao método OnUpdateReceived(Update update)como um objeto Update. É com isso que trabalhamos. Essa é a beleza dos bots do Telegram, eles podem funcionar em qualquer computador, para testar basta iniciar o aplicativo, não é necessário implantá-lo na hospedagem após cada alteração. É muito confortável. Claro, o bot pode ser configurado para funcionar usando um webhook; o manual pode ser encontrado na Internet; para simplificar, trabalharemos usando LongPolling. Como processar mensagens e o que enviar em resposta é limitado apenas pelas ferramentas de linguagem e pela biblioteca, todo o resto fica a seu critério. Você pode fazer um bot que vai procurar vídeos no YouTube para você, você pode fazer um bot que todos os dias vai te enviar o que você manda para si mesmo, por exemplo, daqui a um ano, uma espécie de cápsula do tempo. Ou você pode aprender como integrar sistemas de CRM e fazer bots para pequenas empresas, tudo é limitado pela sua imaginação. Vá em frente. Quem já utilizou bots sabe que é conveniente interagir com eles por meio de comandos que começam com o sinal «/», por exemplo /start. Mas existe uma maneira mais conveniente - botões. Existem dois tipos de botões: aqueles que aparecem abaixo do campo de entrada ReplyKeyboardMarkupe botões que aparecem diretamente abaixo da mensagem à qual estão vinculados InlineKeyboardMarkup. Na documentação você pode se familiarizar brevemente com sua descrição. ResponderKeyboardMarkup. Essencialmente, esta é uma matriz de matrizes de botões, List<KeyboardRow<KeyboardButton>>. Aqui está um exemplo de código que cria o teclado
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 strings
        List<KeyboardRow> keyboard = new ArrayList<>();

        // First line of the keyboard
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Add buttons to the first line of the keyboard
        keyboardFirstRow.add(new KeyboardButton(“Привет”));

        // Second line of the keyboard
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Add buttons to the second line of the keyboard
        keyboardSecondRow.add(new KeyboardButton(“Помощь”);

        // Add all keyboard strings to the list
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // and set this list to our keyboard
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
Em um método sendMsg(), chamamos esse método passando uma mensagem para ele, configurando assim o teclado para essa mensagem. Quando enviarmos esta mensagem ao usuário, ele verá o texto da mensagem que definimos, bem como 2 botões que dizem Olá e Ajuda, um ao lado do outro. Ao clicar nestes botões, será enviada uma mensagem ao bot, cujo texto é o que está escrito no botão. Ou seja, se o cliente clicar em “Ajuda”, o bot receberá uma mensagem com o texto “Ajuda”. Para ele, é como se o próprio cliente escrevesse o texto “Ajuda” e enviasse para ele. Bem, então você processa essas mensagens. InlineKeyboardMarkup Este também é um array de arrays, é semelhante ao Markup anterior, mas a lógica operacional aqui é um pouco diferente. Esse teclado está vinculado a uma mensagem específica e existe apenas para ela. Aqui está o método para instalar o teclado 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);
    }
Crie Listem List, adicione um botão Inline à primeira linha. Esse botão pode conter um URL, um link para um canal ou CallbackQuery, sobre o qual escreverei um pouco mais tarde. Aqui definimos o texto do nosso botão que o usuário verá e depois definimos os dados que serão enviados ao bot. No nosso exemplo, o usuário vê “Olá”, e ao clicar, será enviado ao bot o número 17, esse é o nosso CallbackQuery. Algumas palavras sobre CallbackQuery. Para obter esses dados de um objeto, Updatevocê precisa executar update.getCallbackQuery(), esse método retorna CallbackQuery, a partir do qual você já pode obter os dados transferidos para o bot. Não há necessidade de tentar obter esses dados através do método 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());
        }
    }
Se houver uma mensagem, enviamos a mensagem para processamento para um novo thread; se houver uma mensagem CallbackQuery, enviamos para processamento para o thread apropriado. Você CallbackQuerypode enviar uma resposta. Cada objeto no Telegram possui seu próprio id. Para enviar uma resposta a um determinado, CallbackQueryprecisamos apenas saber o seu id, que receberemos do objeto correspondente. Para enviar uma resposta, chame este método:
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();
        }
    }
IMPORTANTE:O texto da resposta CallbackQuerynão deve ter mais de 200 caracteres! Ao enviar tal resposta, o cliente receberá uma janela pop-up na qual a mensagem será escrita. Essa janela pode desaparecer alguns segundos depois de aparecer ou pode travar até que o usuário pressione OK. Para alternar esses modos, chamamos o arquivo answer.setShowAlert(true). Quando truea janela trava até você pressionar OK, falseela desaparece após 5 segundos. Em princípio, esses são todos os recursos básicos da biblioteca de bots do Telegram. Se desejar, você pode aprender coisas como envio de multimídia, geolocalização, etc. na documentação. Vamos prosseguir com a implantação do nosso bot na hospedagem. Para o meu projeto, escolhi o Heroku, porque na minha opinião é uma hospedagem bastante conveniente que possui sua própria CLI. É gratuito, mas nesse ritmo seu bot entrará em hibernação após 30 minutos se não houver solicitações. Quando uma solicitação é enviada a ele, ele acorda. Isso acontece muito rapidamente, você nem notará (a menos, é claro, que a conexão com o banco de dados seja restabelecida). O limite do plano gratuito é de 5 MB de banco de dados, 100 MB de espaço em disco, 2 TB de tráfego por mês, 1 dino. Dino é o seu aplicativo em execução. Direi desde já que foi a fase de implantação que me causou dificuldades, pois nunca havia implantado minhas aplicações antes. Ao implantar, o Heroku requer um arquivo chamado Procfile (sem extensão). worker: sh target/bin/workerBot Nós o criamos na raiz do projeto, escrevemos trabalhadorBot lá - o nome que especificamos em pom.xml O script sh gerado usando o plugin Maven appassembler-maven-plugin será iniciado. O script descreve a execução do jar compilado. O nome da classe a ser lançada é indicado entre <mainClass></mainClass>, o nome do script entre <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>
Antes de iniciar este processo, você deve se registrar no Heroku, instalar o Git e o Heroku CLI. Se o seu aplicativo requer um banco de dados, ao registrar um novo aplicativo, não se esqueça de adicionar o banco de dados necessário. Em seguida, você precisa descobrir o host, nome de usuário, senha e porta do seu banco de dados e, em seguida, especificá-los em seu aplicativo. A seguir, antes de implantar, construa seu projeto usando Maven.
mvn clean install
Para começar, vamos ao diretório do nosso projeto, inicializamos o repositório com o comandogit init Em seguida, adicionamos nosso projeto a este repositório
git add .
Depois de confirmarmos as alterações
git commit -m “First commit in project”
Em seguida, você precisa fazer login no heroku, escrever na linha de comando
heroku login
Insira seus dados especificados durante o registro. Então você precisa descobrir a URL do seu repositório no Heroku, isso é feito nas configurações. Então escrevemos
git remote add heroku [url]
O repositório remoto heroku será adicionado ao seu repositório. A seguir escrevemos
git push heroku master
Estamos aguardando... Se a implantação da aplicação for bem-sucedida, executamos o comando
heroku ps:scale worker=1
E pronto, seu aplicativo está em execução. Se isso não acontecer, observe atentamente os logs; provavelmente há um erro em seu aplicativo que causou o travamento. Obrigado por ler um artigo tão longo, espero que alguém o considere útil e economize muito tempo em lugares onde tropecei durante o desenvolvimento.
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION