JavaRush /Java Blog /Random EN /Adding a telegram bot to the project - "Java project from...

Adding a telegram bot to the project - "Java project from A to Z"

Published in the Random EN group
Greetings, my dear friends. Yes, yes, exactly friends. I have already become so familiar with this series of articles that those people who regularly write their gratitude in the comments and/or show that they have read and understood the material have already become close. You and I are moving from both sides towards the same goal. You want to understand, but I want to explain. And we have the same final goal - a written application that is understandable to you from start to finish. You may have already heard about much of what I will describe in this article. I don’t think that I will tell you anything new and extraordinary (but within the framework of the project it is necessary to know/repeat this). "Java project from A to Z": adding a telegram bot to the project - 1In the spring I wrote a bot for myself, so we will rely on its “patterns”.

We write JRTB-2

We will do the same as we did in the article with task JRTB-0 :
  1. We update the main branch in the local project using the ctrl + t combination ."Java project from A to Z": adding a telegram bot to the project - 2
  2. Based on the main branch, we create:"Java project from A to Z": adding a telegram bot to the project - 3
  3. Add a bot.
  4. We create a new commit with a description of what has been done and push it to GitHub.
  5. Create a pull request for the main branch and check it again. We are waiting for the build to go through (github actions), merge it into the main branch.
  6. Close the corresponding task.

What is a telegram bot

We, developers, can imagine working with a telegram bot like this: we use their client to work with them. We have a ready-made library for work. There is a set of actions after which the telegram bot will know that it is associated with our program. And already inside the program we will learn how to receive letters, commands and somehow process them. There is such a thing as a command in telegram bots : it begins with a slash “/”. After it, we immediately write the word together, and this will be considered a command. For example, there are two commands that everyone should know:
  • /start — start working with the bot;
  • /stop - end work with the bot.
We'll do the rest ourselves. Let me make a reservation right away: we will do exactly what and in the way that I learned. And when working with a bot, I am sure that it will be possible to do better. And if someone wants to do this, I will be only happy and will support this endeavor in every possible way. By the way, the very first thing that would be cool is if someone explained to me how to program the description of commands through code, and not through the bot settings in the telegram. I didn't learn this. We have several articles on our resource that describe how to make a basic bot: today we will do something similar. If you have any more questions, I recommend skimming through this article.

Create a bot with BotFather

To connect a bot, you first need to create it. Telegram has an approach - creating a bot with its own unique name. It will also be accompanied by a token (a large string that works like a password). I have already created a bot for JavaRush - @javarush_community_bot . This bot is still empty and can’t do anything. The main thing is that there should be _bot at the end of the name . To show how to do this, I will create a bot on which we will test our functionality. In terms of real projects, this would be a test environment. And our main one will be the prod environment (prod - production, that is, the real environment on which the project will be executed). Of course, it would be possible to add another environment - a sandbox environment: a common sandbox, more changeable and accessible to all development participants. But this will only complicate the situation at the project creation stage. For now, let's create two more bots for test and for sandbox environment. The first step is to create (register) a bot in Telegram itself. We need to find the bot: @BotFather and write the command to it: /newbot"Java project from A to Z": adding a telegram bot to the project - 4 Next, we are asked to give a name to this bot. Since this is a bot for testing tasks, its name will be appropriate: [TEST] JavarushBot"Java project from A to Z": adding a telegram bot to the project - 5 Now it’s time to give a unique name by which it can always be found - its username: test_javarush_community"Java project from A to Z": adding a telegram bot to the project - 6 As I said above, you need to add the _bot suffix for username, so we write again: test_javarush_community_bot"Java project from A to Z": adding a telegram bot to the project - 7 And that’s it! The bot has been created. Now, using username and token, it can be connected to our project. Of course, for the smooth operation of the test server, I will not display the token (essentially a password to access the bot) of this bot for public viewing.

We connect the bot to the project

We will not include the library as usual, but will immediately take advantage of our skeleton - SpringBoot. He has such a thing as Starter. By including the library, we can use it to let SpringBoot know that we want to configure the project correctly. If we were to go the usual route, which is described in many places, we would need to create a configuration somewhere that would have something like this:
ApiContextInitializer.init();
TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
try {
  telegramBotsApi.registerBot(Bot.getBot());
} catch (TelegramApiRequestException e) {
  e.printStackTrace();
}
Here an object is created with which you can establish a connection with the bot. In our case, the starter that we want to connect will do everything for us somewhere “under the hood” (this is also a translation of a frequently used phrase in IT - under the hood). Here is a link to this starter . You can immediately see from the README.md file what it is, why and how to use it. To connect it, you just need to add this dependency to the memory. That's all :) Here is the required dependency:
<dependency>
        <groupId>org.telegram</groupId>
        <artifactId>telegrambots-spring-boot-starter</artifactId>
        <version>5.0.1</version>
    </dependency>
We add it to our memory. We install the version as expected and update the Maven project. "Java project from A to Z": adding a telegram bot to the project - 8Based on the description, we just need to create a new class, inherit from TelegramLongPollingBot and add this class to the Application Context of our SpringBoot. Application Context is the place where the created objects for running the project are stored. To add a class, you need to use one of the annotations: @Component, @Service, @Repository, @Controller. Or the @Bean annotation if created through a method in a configuration class (that is, in a class that is marked with the Configuration annotation). I understand that all this may still seem incomprehensible. But when you start to figure it out, you will see that there is nothing complicated there. To quickly understand Spring Boot, I recommend a cool book - Spring In Action 5th edition. If there is a desire, I can write a series of articles based on this book. Let's go back. In the package that contains JavarushTelegramBotApplication, we create the bot package , which will contain our telegram bot. Its name will be JavaRushTelegramBot :
package com.github.javarushcommunity.jrtb.bot;

import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.objects.Update;

/**
* Telegrambot for Javarush Community from Javarush community.
*/
@Component
public class JavarushTelegramBot extends TelegramLongPollingBot {

   @Override
   public void onUpdateReceived(Update update) {

   }

   @Override
   public String getBotUsername() {
       return null;
   }

   @Override
   public String getBotToken() {
       return null;
   }
}
This class was abstract and three methods had to be implemented. Let's talk about them in more detail:
  • onUpdateReceived(Update update) - this is the entry point where messages from users will arrive. All new logic will come from here;
  • getBotUsername() - here you need to add the username of our bot to which we will connect;
  • getBotToken() - and this, accordingly, is the bot token.
Essentially it’s like a login and password for a site. We won't explicitly write this value for now. This is called “hardcoding” (that is, binding some particular value - as usual, tracing paper from English hard code). You shouldn't do that. We will go the other way - we will write this data into the application.properties class and read it from here. Why is this necessary? Then, so that when the application starts, we can set these values ​​externally. It's flexible, it's right. Go to the file src/main/resources/application.properties. There we will come up with names for these variables. Files with the .properties extension are read as a key-value structure separated by “=”, each pair being a separate line. So I came up with these variables:
  • bot.username ;
  • bot.token .
This is what it will look like: "Java project from A to Z": adding a telegram bot to the project - 9SpringBoot has a great annotation - @Value. If used correctly, it will pull up the values ​​from the application.properties file. We update the project with this:
package com.github.javarushcommunity.jrtb.bot;

import org.springframework.beans.factory.annotation.Value;
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
import org.telegram.telegrambots.meta.api.objects.Update;

/**
* Telegram bot for Javarush Community from Javarush community.
*/
@Component
public class JavarushTelegramBot extends TelegramLongPollingBot {

   @Value("${bot.username}")
   private String username;

   @Value("${bot.token}")
   private String token;

   @Override
   public void onUpdateReceived(Update update) {

   }

   @Override
   public String getBotUsername() {
       return username;
   }

   @Override
   public String getBotToken() {
       return token;
   }
}
It can be seen that we passed the value of the variable to the annotation. And when SpringBoot creates our bot object, the values ​​will be taken from the properties (again, tracing paper from English - properties). We're almost there. You need to make the bot answer something. Therefore, let's update the onUpdateReceived method . We need to retrieve the message that came to the bot and pass it back. This way we will know that the bot is working. To do this, we will roughly and quickly write what is needed:
@Override
public void onUpdateReceived(Update update) {
   if(update.hasMessage() && update.getMessage().hasText()) {
       String message = update.getMessage().getText().trim();
       String chatId = update.getMessage().getChatId().toString();

       SendMessage sm = new SendMessage();
       sm.setChatId(chatId);
       sm.setText(message);

       try {
           execute(sm);
       } catch (TelegramApiException e) {
           //todo add logging to the project.
           e.printStackTrace();
       }
   }
}
Everything here is extremely simple: we check that the message really exists, so we extract the message itself ( message ) and the chat ID ( chatId ) in which the correspondence is taking place. Next, we create an object for sending a message SendMessage , pass the message itself and the chat ID to it - that is, what to send to the bot and where. We already have enough of this. Next, we run the main method in the JavarushTelegramBotApplication class and look for our bot in Telegram: "Java project from A to Z": adding a telegram bot to the project - 10From the logs we see that the bot has started. So, it’s time to go to Telegram and write to the bot: "Java project from A to Z": adding a telegram bot to the project - 11We click start and we immediately receive an answer: "Java project from A to Z": adding a telegram bot to the project - 12Let’s write some more crap to check: "Java project from A to Z": adding a telegram bot to the project - 13And that’s it, at this point we can say that our JRTB-2 task is completed. You can’t really write any tests here yet, so we’ll leave everything as it is. Next you need to create a new commit: "Java project from A to Z": adding a telegram bot to the project - 14Pay attention to the name of the commit: again I draw your attention to this. A commit first contains the name of the task, and then a more detailed description of what has been done. Click Commit and Push... and confirm by clicking Push again : "Java project from A to Z": adding a telegram bot to the project - 15Go to our project . As before, GitHub has already seen the new branch and offers to create a pull request for main. We don’t resist and create it: "Java project from A to Z": adding a telegram bot to the project - 16As usual, we have already chosen a label, a project and assigned it to me. Finally, click Create Pull Request. Let's wait a little while the build goes through - and that's it, the pull request is ready for merging:"Java project from A to Z": adding a telegram bot to the project - 17

Versioning

I somehow missed the point that we need to do versioning. To do this, we will make a few more changes in our branch. We go back to IDEA and look at the project version in the memory: "Java project from A to Z": adding a telegram bot to the project - 18The version is 0.0.1-SNAPSHOT . This is the duty version. And we will start by updating the version of the project with each new solved problem. Until we reach MVP, the version will come with the suffix -SNAPSHOT. What will be the versioning scheme? XYZ-SNAPSHOT Where:
  • X - major version update, often contains problems with backward compatibility with the previous version;
  • Y - not very big changes, fully compatible with the previous version;
  • Z is a counter of defects that we found and repaired.
Based on this, we will have the first version - 0.1.0-SNAPSHOT - that is, we have not yet had major updates, just a little bit of everything, and we have not yet reached MVP, so there is a suffix -SNAPSHOT. Let's change this in the memory: "Java project from A to Z": adding a telegram bot to the project - 19Go to the RELEASE_NOTES file, where we will describe the changes to the project with each new version: "Java project from A to Z": adding a telegram bot to the project - 20Our first entry. Now, with each subsequent version update, we will describe here what exactly happened. We commit this case, write a description: JRTB-2: updated project version and added to RELEASE_NOTES Everything is exactly the same as before. We are waiting for the build to pass and we can merge our changes. Only here it will be a little different. I want to make sure that each task in the main branch is a separate commit, so simply pushing a Merge pull request won’t work for us. Git has the git squash option, which collects all commits into one and merges them. We select this option: "Java project from A to Z": adding a telegram bot to the project - 21Click Squash and Merge, and we are offered to edit the message, which will be in the end: "Java project from A to Z": adding a telegram bot to the project - 22Very convenient and most importantly, what is in demand. By the way, I haven’t seen such a feature on bitbucket =/ Confirm the merge. The only thing left is to change the task status to Done in our board, write a comment with a link to the pull request and close it: "Java project from A to Z": adding a telegram bot to the project - 23Our board now looks like this:"Java project from A to Z": adding a telegram bot to the project - 24

Conclusion

Today we created a telegram bot step by step and implemented it in our SpringBoot project. The bot works and gives answers. We immediately made access to the bot data through properties. More to come: we will do a big piece - perform JRTB-3 - adding a Command Pattern for our project. Oh, one more thing... I told you that I would not publish the token so that it would not be used. But since I was writing the article closer to midnight and after work, it turned out that I had posted a valid token in the repository, and GitGuardian told me about this in a letter: "Java project from A to Z": adding a telegram bot to the project - 25Thanks to them for this! What to do now? It will no longer be possible to delete it from the git, since even if I upload a new commit without this token, it will still remain in the old one. But I don’t want to delete and roll back the commit. So I went and deactivated the token from the already mentioned BotFather. Now the token is there, but it is no longer valid. Subscribe to my GitHub account to see all the code for it before publishing the article. Thank you all for reading, see you soon.

A list of all materials in the series is at the beginning of this article.

Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION