JavaRush /Blog Java /Random-FR /Bot Telegram - rappel via webHook en Java ou dites non au...
Vladimir Popov
Niveau 41

Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google ! Partie 1

Publié dans le groupe Random-FR
Je m'appelle Vladimir. J'ai 43 ans. Et si vous, lecteur, avez plus de 40 ans, alors oui, après 40 ans, vous pouvez devenir programmeur si vous l'aimez. Mon travail n'a rien à voir du tout avec la programmation, je suis chef de projet dans le domaine de l'automatisation et tout ça. Mais j'envisage de changer de métier. Oh, ces nouvelles tendances... changez de domaine d'activité tous les 5 à 7 ans. Donc : Le projet s'est avéré assez vaste, donc certains points devront être omis ou évoqués brièvement, dans l'espoir que le lecteur sache comment Google. Internet regorge de publications de robots télégrammes fonctionnant sur le principe du Long Polling. Et il y en a très peu qui fonctionnent sur le principe du Webhook. Ce que c'est? Interrogation longue - cela signifie que votre application elle-même interrogera lentement le serveur de télégrammes pour rechercher des messages à une certaine fréquence. Webhook - signifie que le serveur de télégramme redirigera instantanément les messages vers le serveur que vous spécifiez. Dans notre cas, gracieuseté du service Heroku. Vous pouvez bien sûr en savoir plus sur tout cela et sur le bot en général sur le site Telegram - https://tlgrm.ru/docs/bots/api L'interface du bot ressemble à ceci : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 1 Je considère cette application précisément comme une formation projet pour la raison qu'en écrivant, j'ai appris plus d'informations de ce bot que lors de la formation. Voulez-vous apprendre à programmer? Commencez à écrire du code !!! Mais! Il n'y aura pas d'instructions détaillées sur la façon de télécharger l'application sur github ou sur la façon de créer une base de données. Il y en a beaucoup sur Internet et c'est décrit de manière très détaillée ; en outre, ce sera une lecture très longue. L'application fonctionnera comme suit : Saisissez une description de l'événement, saisissez la date et l'heure de l'événement, sélectionnez la fréquence (vous pouvez le faire une fois, vous pouvez avoir un rappel tous les jours à une certaine heure, vous pouvez l'avoir une fois un mois à une certaine heure, ou une fois par an). Des variantes de notifications peuvent être ajoutées à l’infini ; j’ai beaucoup d’idées. Ensuite, les données saisies sont enregistrées dans la base de données (également déployée gratuitement sur Heroku, 10 000 lignes sont gratuites) Puis, une fois en début de journée à 0h00 heure du serveur, Spring récupère de la base de données tous les événements en fonction des critères qui devrait se déclencher ce jour-là et les envoie pour exécution à l'heure spécifiée. ATTENTION!!! CETTE PARTIE DU PROGRAMME EST EXPÉRIMENTALE ! IL EXISTE UNE MISE EN ŒUVRE PLUS SIMPLE ET PLUS VRAIE ! CELA A ÉTÉ FAIT SPÉCIFIQUEMENT POUR VOIR COMMENT FONCTIONNE LA CLASSE TEMPS ! Vous pouvez toucher le robot fonctionnel de vos propres mains en tapant @calendar_event_bot dans le panier, mais ne comptez pas là-dessus, car je m'en moque toujours. code - https://github.com/papoff8295/webHookBotForHabr Fondamentalement, pour lancer le vôtre, vous devez suivre les étapes suivantes : • Inscrivez-vous auprès de @BotFather , ce n'est pas difficile, obtenez un jeton et un nom • Forkez le projet sur github • Inscrivez-vous sur Heroku, créez une application (nous la détaillerons étape par étape), déployez-la depuis votre référentiel. • Créez une base de données sur Heroku • Remplacez les champs correspondants dans le référentiel par les vôtres (jeton, nom des tables dans les entités, webHookPath, nom d'utilisateur, mot de passe et chemin d'accès à la base de données, tout cela sera analysé) • Faites fonctionner Heroku 24/24/ 7 en utilisant https://start.spring.com/ La structure finale du projet est la suivante : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 2 Commençons par créer un projet dans https://start.spring.io Sélectionnez les dépendances dont nous avons besoin comme indiqué dans la figure : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 3Sélectionnez la nôtre nom du projet et cliquez sur Générer . Ensuite, vous serez invité à enregistrer le projet sur votre disque. Il ne reste plus qu'à ouvrir le fichier pom.xml depuis votre environnement de développement. Il y a un projet terminé devant vous. Il ne nous reste plus qu'à ajouter notre bibliothèque principale. J'ai utilisé la bibliothèque de https://github.com/rubenlagus/TelegramBots. En général, vous pouvez vous perdre et vous en passer. Après tout, tout l'intérêt du travail est de concaténer une URL comme celle-ci : https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io Regardons ça un peu : https://api.telegram.org – serveur de télégramme. bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - après le mot bot se trouve un jeton secret que vous recevez lors de l'enregistrement d'un bot. setWebhook?url=https://e9c658b548aa.ngrok.io – nom de la méthode et ses paramètres. Dans ce cas, nous installons votre serveur webhook, tous les messages lui seront envoyés. En général, j'ai décidé que le projet n'était pas trop petit pour être publié, mais qu'avec une mise en œuvre manuelle, il serait généralement illisible. Ainsi, l'aspect final du fichier pom est :
<!--?xml version="1.0" encoding="UTF-8"?-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelversion>4.0.0</modelversion>
   <parent>
      <groupid>org.springframework.boot</groupid>
      <artifactid>spring-boot-starter-parent</artifactid>
      <version>2.5.0</version>
      <relativepath> <!-- lookup parent from repository -->
   </relativepath></parent>
   <groupid>ru.popov</groupid>
   <artifactid>telegrambot</artifactid>
   <version>0.0.1-SNAPSHOT</version>
   <name>telegrambot</name>
   <description>Demo project for Spring Boot</description>
   <properties>
      <java.version>1.8</java.version>
   </properties>
   <dependencies>
      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-web</artifactid>
      </dependency>

      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-data-jpa</artifactid>
      </dependency>

      <dependency>
         <groupid>org.springframework.boot</groupid>
         <artifactid>spring-boot-starter-test</artifactid>
         <scope>test</scope>
      </dependency>

      <!-- https://mvnrepository.com/artifact/org.telegram/telegrambots-spring-boot-starter -->
      <dependency>
         <groupid>org.telegram</groupid>
         <artifactid>telegrambots-spring-boot-starter</artifactid>
         <version>5.2.0</version>
      </dependency>

      <dependency>
         <groupid>org.projectlombok</groupid>
         <artifactid>lombok</artifactid>
         <version>1.18.16</version>
      </dependency>

      <dependency>
         <groupid>org.postgresql</groupid>
         <artifactid>postgresql</artifactid>
         <scope>runtime</scope>
      </dependency>

   </dependencies>

   <build>
      <plugins>
         <plugin>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-maven-plugin</artifactid>
         </plugin>
      </plugins>
   </build>

</project>
Tout est prêt pour écrire notre bot. Créons la classe TelegramBot . Je n'écrirai pas les noms des dossiers, vous pouvez les consulter dans la structure du projet ci-dessus.
@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TelegramBot extends SpringWebhookBot {
    String botPath;
    String botUsername;
    String botToken;

    private TelegramFacade telegramFacade;

    public TelegramBot(TelegramFacade telegramFacade, DefaultBotOptions options, SetWebhook setWebhook) {
        super(options, setWebhook);
        this.telegramFacade = telegramFacade;
    }
    public TelegramBot(TelegramFacade telegramFacade, SetWebhook setWebhook) {
        super(setWebhook);
        this.telegramFacade = telegramFacade;
    }

    @Override
    public BotApiMethod<!--?--> onWebhookUpdateReceived(Update update) {
        return telegramFacade.handleUpdate(update);
    }
}
La classe étend SpringWebhookBot à partir de notre bibliothèque de télégrammes, et nous n'avons besoin d'implémenter qu'une seule méthode, onWebhookUpdateReceived . Il accepte le JSON analysé en tant qu'objet Update et renvoie ce que le serveur de télégramme veut « entendre » de nous. Nous avons ici des annotations de la bibliothèque de Lombok . Lombok – faciliter la vie d'un programmeur !! Eh bien, c'est vrai. nous n'avons pas besoin de redéfinir les getters et les setters, Lombok le fait pour nous, et nous n'avons pas non plus besoin d'écrire un identifiant de niveau d'accès. Cela ne vaut plus la peine d'écrire que cela se fait par les annotations @Getter, @Setter, @FieldDefaults. Le champ botPath désigne notre adresse de webhook, que nous recevrons plus tard sur Heroku. Le champ botUsername signifie le nom de notre bot, que nous recevrons lors de l'enregistrement de notre bot dans Telegram. Le champ botToken est notre jeton, que nous recevrons lors de l'enregistrement de notre bot dans Telegram. Le champ telegramFacade est notre classe où aura lieu le traitement des messages, nous y reviendrons un peu plus tard, qu'il soit rouge pour l'instant. Il est maintenant temps pour nous de contacter @BotFather et d’obtenir le très convoité botToken et botUsername. Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 4Écrivez-lui simplement par télégramme et il vous dira tout. Nous écrivons les données dans notre application.properties, au final cela ressemblera à ceci :
server#server.port=5000

telegrambot.userName=@calendar_event_bot
telegrambot.botToken=1731265488:AAFDjUSk3vu5SFfgdfh556gOOFmuml7SqEjwrmnEF5Ak
#telegrambot.webHookPath=https://telegrambotsimpl.herokuapp.com/
telegrambot.webHookPath=https://f5d6beeb7b93.ngrok.io


telegrambot.adminId=39376213

eventservice.period =600000

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/telegramUsers
spring.datasource.username=postgres
spring.datasource.password=password

#spring.datasource.url=jdbc:postgresql:ec2-54-247-158-179.eu-west-1.compute.amazonaws.com:5432/d2um126le5notq?ssl=true&sslmode=require&sslfactory=org.postgresql.ssl.NonValidatingFactory
#spring.datasource.username=ulmbeywyhvsxa
#spring.datasource.password=4c7646c69dbbgeacb98fa96e8daa6d9b1bl4894e67f3f3ddd6a27fe7b0537fd
Cette configuration est configurée pour fonctionner avec une base de données locale ; nous apporterons plus tard les modifications nécessaires. Remplacez botToken et le nom d'utilisateur par les vôtres. Il n'est pas bon d'utiliser les données de application.properties directement dans l'application. Créons un bean ou une classe wrapper à partir de ces données.
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
Ici, l'annotation @Value initialise les lignes correspondantes du fichier application.properties, que Spring connaît par défaut. Et l'annotation @Component crée un Bean pour nous au démarrage de l'application. Regardons maintenant le fichier de configuration Spring :
@Configuration
public class AppConfig {
    private final TelegramBotConfig botConfig;

    public AppConfig(TelegramBotConfig botConfig) {
        this.botConfig = botConfig;
    }

    @Bean
    public SetWebhook setWebhookInstance() {
        return SetWebhook.builder().url(botConfig.getWebHookPath()).build();
    }

    @Bean
    public TelegramBot springWebhookBot(SetWebhook setWebhook, TelegramFacade telegramFacade) {
        TelegramBot bot = new TelegramBot(telegramFacade, setWebhook);
        bot.setBotToken(botConfig.getBotToken());
        bot.setBotUsername(botConfig.getUserName());
        bot.setBotPath(botConfig.getWebHookPath());

        return bot;
    }
}
Il n’y a pas de magie ici ; au démarrage, Spring crée pour nous les objets SetWebhook et TelegramBot. Créons maintenant des points d'entrée pour nos messages :
@RestController
public class WebhookController {

    private final TelegramBot telegramBot;

    public WebhookController(TelegramBot telegramBot) {
        this.telegramBot = telegramBot;
    }

// point for message
    @PostMapping("/")
    public BotApiMethod<!--?--> onUpdateReceived(@RequestBody Update update) {
        return telegramBot.onWebhookUpdateReceived(update);
    }

    @GetMapping
    public ResponseEntity get() {
        return ResponseEntity.ok().build();
    }
}
Le serveur Telegram envoie des messages au format JSON à l'adresse du webhook enregistré en utilisant la méthode POST, notre contrôleur les reçoit et les transmet à la bibliothèque de télégrammes sous la forme d'un objet Update. J'ai fait la méthode get juste comme ça) Il ne nous reste plus qu'à implémenter une logique de traitement des messages et des réponses dans la classe TelegramFacade , je vais donner son code court afin que vous puissiez lancer l'application puis suivre votre propre chemin ou passer au déploiement sur Heroku, alors ce sera la version complète :
@Component
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TelegramFacade {

    public BotApiMethod<!--?--> handleUpdate(Update update) {

        if (update.hasCallbackQuery()) {
            CallbackQuery callbackQuery = update.getCallbackQuery();
            return null;
        } else {

            Message message = update.getMessage();
            SendMessage sendMessage = new SendMessage();
            sendMessage.setChatId(String.valueOf(message.getChatId()));
            if (message.hasText()) {
                sendMessage.setText("Hello world");
                return sendMessage;
            }
        }
        return null;
    }

}
Cette méthode répondra à n’importe quel Hello world! Afin de lancer notre application, nous devons simplement nous assurer que nous pouvons tester notre application directement depuis IDEA. Pour ce faire, nous devons télécharger l'utilitaire ngrok. https://ngrok.com/download Cet utilitaire est une ligne de commande qui nous donne une adresse temporaire pendant 2 heures et redirige tous les messages vers le port spécifié du serveur local. Nous lançons et écrivons ngrok http 5000 dans la ligne (ou vous pouvez spécifier votre port) : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 5Nous obtenons le résultat : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 6https://23b1a54ccbbd.ngrok.io - c'est notre adresse webhook. Comme vous l'avez peut-être remarqué dans le fichier de propriétés que nous avons écrit server.port=5000 lors du démarrage du serveur Tomcat, il occupera le port 5000, assurez-vous que ces champs sont les mêmes. N'oubliez pas non plus que l'adresse est donnée pendant deux heures. Sur la ligne de commande, cela est surveillé par le champ Session Expires. Une fois le temps imparti, vous devrez récupérer l'adresse et suivre la procédure d'enregistrement sur télégramme. Maintenant, nous prenons la ligne https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io Et avec des mouvements de main habiles, nous remplaçons le jeton par le nôtre, l'url par le nôtre, collez la ligne résultante dans le navigateur et cliquez sur Entrée. Vous devriez obtenir le résultat suivant : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 7Ça y est, vous pouvez maintenant lancer l'application : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 8Vérifiez que votre classe avec la méthode main ressemblait à ceci :
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
Si vous avez tout fait correctement, votre bot répondra désormais à n'importe quel message avec la phrase « Bonjour tout le monde » . Ensuite, vous pourrez suivre votre propre chemin. Si vous êtes avec moi et que vous souhaitez suivre toutes les étapes, commençons à écrire des entités pour la base de données et créons la base de données elle-même. Commençons par la base de données : comme je l'ai déjà dit, je suppose que vous avez déjà des compétences minimales pour travailler avec la base de données et que vous avez installé une base de données postgreSQL locale , sinon suivez ce chemin. https://www.postgresql.org/download/ Dans le fichier application.properties, remplacez le login et le mot de passe de la base de données par les vôtres. Dans IDEA, il y a un onglet de base de données sur la droite, vous devez y cliquer sur +/Data source/PostgreSQL . Par conséquent, lorsque vous cliquez sur Tester la connexion, vous devriez obtenir un résultat satisfaisant : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - 9vous pouvez désormais créer une base de données avec des tables directement à partir de l'environnement de développement, ou vous pouvez utiliser l' interface Web pgadmin , qui se trouve dans le menu Démarrer. Nous aurons besoin de 3 tableaux :
CREATE TABLE users
(
    id               INTEGER PRIMARY KEY UNIQUE NOT NULL,
    name             VARCHAR,
    time_zone        INTEGER DEFAULT 0,
    on_off           BOOLEAN DEFAULT true
);

CREATE TABLE user_events
(
    user_id INTEGER ,
    time timestamp ,
    description varchar ,
    event_id serial,
    event_freq varchar default 'TIME',
    FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE
);

CREATE TABLE event_cash
(
    time timestamp ,
    description varchar ,
    user_id INTEGER ,
    id serial
);
Je recommande de créer ce script séparément, nous en aurons besoin pour créer une base de données sur Heroku, afin de ne pas l'écrire deux fois. Marchons un peu. Je dirai tout de suite que nous n'avons besoin que de la table event_cash pour travailler avec Heroku en raison de ses spécificités et de mon envie insatiable de travailler avec la classe Time ; elle ne sera pas utile dans la version locale. Dans le tableau des utilisateurs , nous enregistrerons l'identifiant du compte de l'utilisateur du télégramme, son nom, qui peut ne pas exister, le fuseau horaire de l'utilisateur sera calculé pour l'envoi correct des notifications, ainsi que l' état activé/désactivé de l'envoi des notifications. Nous enregistrerons l' identifiant de l'utilisateur, l'heure de notification, la description dans la table user_events , générerons automatiquement un identifiant pour l'événement et définirons la fréquence des notifications. La table event_cash enregistrera la notification avant qu'elle ne soit envoyée et, si elle est envoyée, la supprimera de la table. Les tables sont prêtes, ajoutons maintenant les entités.
@Entity
@Table(name = "user_events")
@Getter
@Setter
public class Event {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( name = "event_id", columnDefinition = "serial")
    private int eventId;

    @Column(name = "time")
    @NotNull(message = "Need date!")
    private Date date;

    @Column(name = "description")
    @Size(min = 4, max = 200, message = "Description must be between 0 and 200 chars!")
    private String description;

    @Column(name = "event_freq", columnDefinition = "TIME")
    @Enumerated(EnumType.STRING)
    private EventFreq freq;

    @ManyToOne(fetch=FetchType.EAGER)
    @JoinColumn(name="user_id")
    @OnDelete(action = OnDeleteAction.CASCADE)
    private User user;

    public Event() {
    }

    public Event(int eventId,
                 @NotNull(message = "Need date!") Date date,
                 @Size(min = 4, max = 200, message = "Description must be between 0 and 200 chars!")
                         String description,
                 EventFreq freq, User user) {
        this.eventId = eventId;
        this.date = date;
        this.description = description;
        this.freq = freq;
        this.user = user;
    }
}
@Entity
@Table(name = "users")
@Getter
@Setter
public class User {

    @Id
    @Column(name = "id")
    private long id;

    @Column(name = "name")
    private String name;

    @Column(name = "time_zone", columnDefinition = "default 0")
    //sets the broadcast time of events for your time zone
    private int timeZone;

    @OneToMany(mappedBy="user")
    private List<event> events;

    @Column(name = "on_off")
    // on/off send event
    private boolean on;

    public User() {
    }
}

</event>
@Entity
@Table(name = "event_cash")
@Getter
@Setter
//serves to save unhandled events after rebooting heroku
public class EventCashEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( name = "id", columnDefinition = "serial")
    private long id;

    @Column(name = "time")
    private Date date;

    @Column(name = "description")
    private String description;

    @Column(name = "user_id")
    private long userId;

    public EventCashEntity() {
    }

    public static EventCashEntity eventTo(Date date, String description, long userId) {
        EventCashEntity eventCashEntity = new EventCashEntity();
        eventCashEntity.setDate(date);
        eventCashEntity.setDescription(description);
        eventCashEntity.setUserId(userId);
        return eventCashEntity;
    }
}
Reprenons un peu les points principaux. @Entity – marque la classe pour notre dada jpa que cette classe est une entité pour la base de données, c'est-à-dire lors de la récupération des données de la base de données, elles nous seront présentées sous la forme d'un objet Event, User et EventCashEntity. @Table – nous disons le nom de notre table dans la base de données. Pour garantir que le nom de la table n'est pas souligné en rouge, nous devons accepter dans IDEA l'option de correction d'erreur proposée et cliquer sur Attribuer des sources de données. Et sélectionnez notre base là-bas. @id et @GeneratedValue - utilisés par Spring pour créer une base de données si elle n'existe pas déjà. @Column permet d'indiquer le nom des champs du tableau s'ils ne correspondent pas, mais les règles du bon code recommandent de toujours écrire ceci. Attitude OneToMany - Je recommande de passer du temps et de comprendre ce que c'est ici https://en.wikibooks.org/wiki/Java_Persistence Je ne peux pas l'expliquer plus clairement, croyez-moi. Permettez-moi simplement de dire que dans ce cas, l' annotation @OneToMany indique qu'un utilisateur peut avoir plusieurs événements, et ils nous seront fournis sous la forme d'une liste. Nous devons maintenant récupérer les données des tables. Dans la bibliothèque SRING DATA JPA , tout est déjà écrit pour nous, il suffit de créer une interface pour chaque table et de l'étendre depuis JpaRepository.
public interface EventRepository extends JpaRepository<event, long=""> {
    Event findByEventId(long id);
}
public interface UserRepository extends JpaRepository<user, long=""> {

    User findById(long id);
}
public interface EventCashRepository extends JpaRepository<eventcashentity, long=""> {
    EventCashEntity findById(long id);
}

</eventcashentity,></user,></event,>
La logique principale de travail avec la base de données est transférée à un service, appelé Data Access Object (DAO) :
@Service
public class UserDAO {

    private final UserRepository userRepository;

    @Autowired
    public UserDAO(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public User findByUserId(long id) {
        return userRepository.findById(id);
    }

    public List<user> findAllUsers() {
        return userRepository.findAll();
    }

    public void removeUser(User user) {
        userRepository.delete(user);
    }


    public void save(User user) {
        userRepository.save(user);
    }

    public boolean isExist(long id) {
        User user = findByUserId(id);
        return user != null;
    }
}
@Service
public class EventDAO {

    private final UserRepository userRepository;
    private final EventRepository eventRepository;

    @Autowired
    public EventDAO(UserRepository userRepository, EventRepository eventRepository) {
        this.userRepository = userRepository;
        this.eventRepository = eventRepository;
    }

    public List<event> findByUserId(long userId) {
        User user = userRepository.findById(userId);
        return user.getEvents();
    }
    public List<event> findAllEvent() {
       return eventRepository.findAll();
    }

    public Event findByEventId(long eventId) {
        return eventRepository.findByEventId(eventId);
    }

    public void remove(Event event) {
        eventRepository.delete(event);
    }

    public void save(Event event) {
        eventRepository.save(event);
    }
}

</event></event></user>
@Service
//handles events not dispatched after reboot heroku
public class EventCashDAO {

    private EventCashRepository eventCashRepository;

    @Autowired
    public void setEventCashRepository(EventCashRepository eventCashRepository) {
        this.eventCashRepository = eventCashRepository;
    }

    public List<eventcashentity> findAllEventCash() {
        return eventCashRepository.findAll();
    }

    public void save(EventCashEntity eventCashEntity) {
        eventCashRepository.save(eventCashEntity);
    }

    public void delete(long id) {
        eventCashRepository.deleteById(id);
    }
}

</eventcashentity>
Dans ce cas, nous n’avons aucun traitement de données, nous récupérons simplement les données des tables. Nous sommes tous prêts à fournir le code complet de la classe TelegramFacade et à commencer à analyser la logique.
@Component
@FieldDefaults(level = AccessLevel.PRIVATE)
public class TelegramFacade {

    final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;

    @Value("${telegrambot.adminId}")
    int adminId;


    public TelegramFacade(MessageHandler messageHandler, CallbackQueryHandler callbackQueryHandler, BotStateCash botStateCash) {
        this.messageHandler = messageHandler;
        this.callbackQueryHandler = callbackQueryHandler;
        this.botStateCash = botStateCash;
    }

    public BotApiMethod<!--?--> handleUpdate(Update update) {

        if (update.hasCallbackQuery()) {
            CallbackQuery callbackQuery = update.getCallbackQuery();
            return callbackQueryHandler.processCallbackQuery(callbackQuery);
        } else {

            Message message = update.getMessage();
            if (message != null && message.hasText()) {
                return handleInputMessage(message);
            }
        }
        return null;
    }

    private BotApiMethod<!--?--> handleInputMessage(Message message) {
        BotState botState;
        String inputMsg = message.getText();
        //we process messages of the main menu and any other messages
        //set state
        switch (inputMsg) {
            case "/start":
                botState = BotState.START;
                break;
            case "Мои напоминания":
                botState = BotState.MYEVENTS;
                break;
            case "Создать напоминание":
                botState = BotState.CREATE;
                break;
            case "Отключить напоминания":
            case "Включить напоминания":
                botState = BotState.ONEVENT;
                break;
            case "All users":
                if (message.getFrom().getId() == adminId)
                botState = BotState.ALLUSERS;
                else botState = BotState.START;
                break;
            case "All events":
                if (message.getFrom().getId() == adminId)
                botState = BotState.ALLEVENTS;
                else botState = BotState.START;
                break;
            default:
                botState = botStateCash.getBotStateMap().get(message.getFrom().getId()) == null?
                        BotState.START: botStateCash.getBotStateMap().get(message.getFrom().getId());
        }
        //we pass the corresponding state to the handler
        //the corresponding method will be called
        return messageHandler.handle(message, botState);

    }
}
Voyons à quels champs sont nécessaires
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
Si nous codons tous dans une classe, nous nous retrouverons avec un chausson sur la lune, par conséquent, nous attribuons la logique pour travailler avec des messages texte à la classe MessageHandler et la logique pour travailler avec des messages de requête de rappel à la classe CallbackQueryHandler . Il est temps de comprendre ce qu'est allbackquery et quels types de menus il existe. Pour ce faire, je vais vous donner une autre image de l’interface du bot : Bot Telegram - rappel via webHook en Java ou dites non au calendrier Google !  - dixIl existe deux types de menus. Ceux qui sont attachés au bas de la fenêtre - le menu principal et ceux qui sont affectés au message, par exemple les boutons de ceinture supprimer, modifier, modifier. Lorsque vous cliquez sur le bouton du menu principal, un message du même nom est envoyé, par exemple, lorsque vous cliquez sur « Mes rappels » , le texte « Mes rappels » sera simplement envoyé . Et lors de l'installation du clavier de requête de rappel, une valeur spécifique est définie pour chaque bouton et sa valeur sera envoyée sans l'afficher à l'écran. Nous avons ensuite le champ BotStateCash . Il s'agit d'une classe spécialement créée qui surveillera l'état du bot, et attention, c'est un élément complexe, vous devez vous efforcer. Le nombre de caractères a été dépassé, ce qui n'est d'ailleurs écrit nulle part)). Voici donc le lien vers la deuxième partie
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION