JavaRush /Java Blog /Random-IT /Bot di Telegram: promemoria tramite webHook in Java o dì ...
Vladimir Popov
Livello 41

Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google! Parte 1

Pubblicato nel gruppo Random-IT
Il mio nome è Vladimir. Ho 43 anni. E se tu, lettore, hai più di 40 anni, allora sì, dopo i 40 puoi diventare un programmatore se ti piace. Il mio lavoro non ha nulla a che fare con la programmazione, sono un project manager nel campo dell'automazione e tutto il resto. Ma ho intenzione di cambiare lavoro. Oh, queste nuove tendenze... cambiano il tuo campo di attività ogni 5-7 anni. Quindi : il progetto si è rivelato piuttosto ampio, quindi alcuni punti dovranno essere omessi o discussi brevemente, nella speranza che il lettore sappia come cercare su Google. Internet è pieno di pubblicazioni di bot di Telegram che lavorano secondo il principio del polling lungo. E ce ne sono pochissimi che funzionano secondo il principio del Webhook. Cos'è? Polling lungo : ciò significa che la tua stessa applicazione eseguirà il polling del server Telegram per i messaggi con una certa frequenza, lentamente. Webhook : significa che il server Telegram reindirizzerà immediatamente i messaggi al server specificato. Nel nostro caso, per gentile concessione del servizio Heroku. Ovviamente puoi leggere di più su tutto questo e sul bot in generale sul sito web di Telegram - https://tlgrm.ru/docs/bots/api L'interfaccia del bot si presenta così: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  -1 Considero questa applicazione proprio come un corso di formazione progetto perché durante la scrittura ho imparato più informazioni da questo bot rispetto alla formazione. Vuoi imparare a programmare? Inizia a scrivere il codice!!! Ma! Non ci saranno istruzioni dettagliate su come caricare l'applicazione su github o su come creare un database. Ce n'è in abbondanza su Internet ed è descritto in grande dettaglio; inoltre, sarà una lettura molto lunga. L'applicazione funzionerà nel seguente modo: Inserisci una descrizione dell'evento, inserisci la data e l'ora dell'evento, seleziona la frequenza (puoi farlo una volta, puoi avere un promemoria ogni giorno ad una certa ora, puoi averlo una volta un mese ad una determinata ora o una volta all'anno). Le variazioni delle notifiche possono essere aggiunte all'infinito; ho molte idee. Successivamente, i dati inseriti vengono salvati nel database (distribuito anche gratuitamente su Heroku, 10.000 righe sono gratuite) Quindi, una volta all'inizio della giornata alle 0:00 ora del server, Spring recupera dal database tutti gli eventi in base ai criteri che dovrebbe attivarsi quel giorno e inviarli per l'esecuzione all'ora specificata. ATTENZIONE!!! QUESTA PARTE DEL PROGRAMMA È SPERIMENTALE! ESISTE UN'IMPLEMENTAZIONE PIÙ SEMPLICE E VERA! QUESTO È STATO FATTO SPECIFICAMENTE PER VEDERE COME FUNZIONA LA TIME CLASS! Puoi toccare con mano il bot funzionante digitando @calendar_event_bot nel carrello, ma non contare su di esso, perché lo sto ancora prendendo in giro. code - https://github.com/papoff8295/webHookBotForHabr Fondamentalmente, per avviare il tuo devi seguire i seguenti passaggi: • Registrati con @BotFather , non è difficile, ottieni un token e un nome • Effettua il fork del progetto su github • Registrati su Heroku, crea un'applicazione (la esamineremo passo dopo passo), distribuiscila dal tuo repository. • Crea un database su Heroku • Sostituisci i campi corrispondenti nel repository con i tuoi (token, nome delle tabelle nelle entità, webHookPath, nome utente, password e percorso del database, tutto questo verrà analizzato) • Fai funzionare Heroku 24 ore su 24 7 utilizzando https://start.spring.io La struttura finale del progetto è la seguente: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 2 Iniziamo creando un progetto in https://start.spring.io Seleziona le dipendenze di cui abbiamo bisogno come mostrato in figura: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 3Seleziona la nostra nome del progetto e fare clic su Genera . Successivamente ti verrà richiesto di salvare il progetto sul tuo disco. Non resta che aprire il file pom.xm l dal tuo ambiente di sviluppo. C'è un progetto finito davanti a te. Ora dobbiamo solo aggiungere la nostra libreria principale. Ho usato la libreria da https://github.com/rubenlagus/TelegramBots In generale, puoi confonderti e farne a meno. Dopotutto, lo scopo centrale del lavoro è concatenare un URL come questo: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io Guardiamolo un po' : https://api.telegram.org – server di telegrammi. bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - dopo la parola bot c'è un token segreto che ricevi quando registri un bot. setWebhook?url=https://e9c658b548aa.ngrok.io – nome del metodo e suoi parametri. In questo caso, installiamo il tuo server webhook, tutti i messaggi verranno inviati ad esso. In generale, ho deciso che il progetto non era troppo piccolo per la pubblicazione, ma con l'implementazione manuale sarebbe generalmente illeggibile. Quindi, l'aspetto finale del file pom è:
<!--?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>
Tutto è pronto per scrivere il nostro bot. Creiamo la classe TelegramBot . Non scriverò i nomi delle cartelle, puoi guardarli nella struttura del progetto sopra.
@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 estende SpringWebhookBot dalla nostra libreria di telegrammi e dobbiamo solo implementare un metodo, onWebhookUpdateReceived . Accetta JSON analizzato come oggetto Update e restituisce ciò che il server Telegram vuole "sentire" da noi. Qui abbiamo annotazioni dalla biblioteca di Lombok . Lombok – semplificare la vita del programmatore!! Bene, questo è. non abbiamo bisogno di ridefinire getter e setter, Lombok lo fa per noi e non abbiamo nemmeno bisogno di scrivere un identificatore del livello di accesso. Non vale più la pena scrivere che ciò avviene tramite le annotazioni @Getter, @Setter, @FieldDefaults. Il campo botPath indica il nostro indirizzo webhook, che riceveremo su Heroku in seguito. Il campo botUsername indica il nome del nostro bot, che riceveremo quando registreremo il nostro bot su Telegram. Il campo botToken è il nostro token, che riceveremo quando registreremo il nostro bot su Telegram. Il campo telegramFacade è la nostra classe in cui avrà luogo l'elaborazione dei messaggi, ci torneremo un po' più tardi, per ora lasciamo che sia rosso. Ora è il momento di contattare @BotFather e ottenere gli ambiti botToken e botUsername. Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 4Basta scrivergli su Telegram e ti racconterà tutto. Scriviamo i dati nella nostra application.properties, alla fine sarà simile a questo:
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
Questa configurazione è configurata per funzionare con un database locale; in seguito apporteremo le modifiche necessarie. Sostituisci botToken e nome utente con i tuoi. Non è consigliabile utilizzare i dati di application.properties direttamente nell'applicazione. Creiamo un bean o una classe wrapper da questi dati.
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
Qui l'annotazione @Value inizializza le righe corrispondenti dal file application.properties, di cui Spring è a conoscenza per impostazione predefinita. E l'annotazione @Component crea un Bean per noi all'avvio dell'applicazione. Diamo ora un'occhiata al file di configurazione di 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;
    }
}
Non c'è magia qui; all'avvio, Spring crea per noi oggetti SetWebhook e TelegramBot. Creiamo ora punti di ingresso per i nostri messaggi:
@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();
    }
}
Il server Telegram invia messaggi in formato JSON all'indirizzo webhook registrato utilizzando il metodo POST, il nostro controller li riceve e li trasmette alla libreria telegram sotto forma di oggetto Update. Ho eseguito il metodo get proprio così) Ora dobbiamo solo implementare un po' di logica per l'elaborazione dei messaggi e delle risposte nella classe TelegramFacade , fornirò il suo codice breve in modo che tu possa avviare l'applicazione e poi andare per la tua strada o passare a deploy su Heroku, allora sarà la versione completa:
@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;
    }

}
Questo metodo risponderà a qualsiasi Hello world! Per poter lanciare la nostra applicazione dobbiamo solo assicurarci di poter testare la nostra applicazione direttamente da IDEA. Per fare ciò, dobbiamo scaricare l'utilità ngrok. https://ngrok.com/download Questa utility è una riga di comando che ci fornisce un indirizzo temporaneo per 2 ore e reindirizza tutti i messaggi alla porta specificata del server locale. Lanciamo e scriviamo ngrok http 5000 nella riga (oppure puoi specificare la tua porta): Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 5otteniamo il risultato: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 6https://23b1a54ccbbd.ngrok.io - questo è il nostro indirizzo webhook. Come avrai notato nel file delle proprietà che abbiamo scritto server.port=5000 all'avvio del server Tomcat, occuperà la porta 5000, assicurati che questi campi siano gli stessi. Inoltre, non dimenticare che l'indirizzo viene fornito per due ore. Sulla riga di comando, questo viene monitorato dal campo Scadenza sessione. Allo scadere del tempo, dovrai ottenere nuovamente l'indirizzo e seguire la procedura di registrazione su Telegram. Adesso prendiamo la linea https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io E con abili movimenti della mano sostituiamo il token con il nostro, l'url con il nostro, incolliamo la riga risultante nel browser e fare clic su Invio. Dovresti ottenere il seguente risultato: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  -7Ecco fatto, ora puoi eseguire l'applicazione: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  -8Controlla che la tua classe con il metodo main fosse così:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
Se hai fatto tutto correttamente, ora il tuo bot risponderà a qualsiasi messaggio con la frase “ Ciao mondo” . Allora puoi andare per la tua strada. Se sei con me e sei interessato a seguire tutti i passaggi, allora iniziamo a scrivere le entità per il database e a creare il database stesso. Cominciamo con il database: come ho già detto, presumo che tu abbia già competenze minime nell'utilizzo del database e che tu abbia installato un database PostgreSQL locale , in caso contrario segui questo percorso. https://www.postgresql.org/download/ Nel file application.properties, sostituire il login e la password del database con i propri. In IDEA c'è una scheda database sulla destra, in essa devi fare clic su +/Data source/PostgreSQL . Di conseguenza, quando fai clic su Test connessione dovresti ottenere un risultato soddisfacente: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 9ora puoi creare un database con tabelle direttamente dall'ambiente di sviluppo, oppure puoi utilizzare l' interfaccia web pgadmin , che si trova nel menu di avvio. Avremo bisogno di 3 tabelle:
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
);
Consiglio di creare questo script a parte; ci servirà per creare un database su Heroku, così da non riscriverlo due volte. Camminiamo un po'. Dirò subito che abbiamo bisogno solo della tabella event_cash per funzionare con Heroku a causa delle sue specificità e del mio insaziabile desiderio di lavorare con la classe Time ; non sarà utile nella versione locale. Nella tabella utenti registreremo l’id dell’account dell’utente telegram, il suo nome, che potrebbe non esistere, verrà calcolato il fuso orario dell’utente per il corretto invio delle notifiche, nonché lo stato di attivazione/disattivazione dell’invio delle notifiche. Registreremo l' ID utente, l'ora della notifica e la descrizione nella tabella user_events , genereremo automaticamente un ID per l'evento e imposteremo la frequenza delle notifiche. La tabella event_cash registrerà la notifica prima che venga inviata e, se inviata, la rimuoverà dalla tabella. Le tabelle sono pronte, aggiungiamo ora le entità.
@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;
    }
}
Esaminiamo un po' i punti principali. @Entity – contrassegna la classe per il nostro dada jpa indicando che questa classe è un'entità per il database, ad es. quando recuperiamo i dati dal database, questi ci verranno presentati sotto forma di oggetto Event, User ed EventCashEntity. @Table – diciamo il nome della nostra tabella nel database. Per garantire che il nome della tabella non sia sottolineato in rosso, dobbiamo concordare in IDEA con l'opzione di correzione degli errori proposta e fare clic su Assegna origini dati. E seleziona la nostra base lì. @id e @GeneratedValue : utilizzati da Spring per creare un database se non esiste già. @Colonna serve per indicare il nome dei campi della tabella se non corrispondono, ma le regole del buon codice consigliano di scriverlo sempre. Atteggiamento OneToMany : consiglio di dedicare del tempo e capire di cosa si tratta qui https://en.wikibooks.org/wiki/Java_Persistence Non posso spiegarlo più chiaramente, credimi. Lasciatemi solo dire che in questo caso l' annotazione @OneToMany dice che un utente può avere molti eventi e questi ci verranno forniti sotto forma di elenco. Ora dobbiamo ottenere i dati dalle tabelle. Nella libreria SRING DATA JPA è già tutto scritto per noi, dobbiamo solo creare un'interfaccia per ogni tabella ed estenderla da 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 logica principale per lavorare con il database viene trasferita a un servizio, il cosiddetto 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>
In questo caso non effettuiamo alcun trattamento dei dati, recuperiamo semplicemente i dati dalle tabelle. Siamo tutti pronti a fornire il codice completo della classe TelegramFacade e cominciare ad analizzarne la logica.
@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);

    }
}
Diamo un'occhiata a quali campi sono necessari
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
Se codifichiamo tutti in una classe, ci ritroveremo con una coperta sulla luna; pertanto, assegniamo la logica per lavorare con i messaggi di testo alla classe MessageHandler e la logica per lavorare con i messaggi callbackquery alla classe CallbackQueryHandler . È tempo di capire cos'è allbackquery e quali tipi di menu esistono. Per fare ciò, ti darò un’altra immagine dell’interfaccia del bot: Bot di Telegram: promemoria tramite webHook in Java o dì no al calendario di Google!  - 10esistono due tipi di menu. Quelli che sono allegati nella parte inferiore della finestra: il menu principale e quelli che sono assegnati al messaggio, ad esempio i pulsanti Elimina, Modifica, Cambia cintura. Quando si fa clic sul pulsante del menu principale, viene inviato un messaggio con lo stesso nome, ad esempio, quando si fa clic su "I miei promemoria" verrà semplicemente inviato il testo "I miei promemoria" . E quando si installa la tastiera callbackquery, viene impostato un valore specifico per ciascun pulsante e il suo valore verrà inviato senza visualizzarlo sullo schermo. Successivamente abbiamo il campo BotStateCash . Questa è una classe creata appositamente che monitorerà lo stato del bot e attenzione, questo è un elemento complesso, devi sforzarti. È stato superato il numero di caratteri, che, tra l'altro, non è scritto da nessuna parte)). Quindi ecco il collegamento alla seconda parte
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION