JavaRush /Java Blogu /Random-AZ /Telegram botu - Java-da webHook vasitəsilə xatırlatma və ...
Vladimir Popov
Səviyyə

Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin! 1-ci hissə

Qrupda dərc edilmişdir
Mənim adım Vladimirdir. Mənim 43 yaşım var. Əgər siz, oxucu, 40-dan yuxarısınızsa, bəli, 40-dan sonra xoşunuza gəlsə, proqramçı ola bilərsiniz. İşimin proqramlaşdırma ilə heç bir əlaqəsi yoxdur, mən avtomatlaşdırma və bütün bunlar sahəsində layihə meneceriyəm. Amma peşəmi dəyişməyi planlaşdırıram. Oh, bu yeni tendensiyalar... 5-7 ildən bir fəaliyyət sahənizi dəyişir. Beləliklə : Layihə olduqca böyük oldu, buna görə oxucunun Google-u necə bildiyinə ümid edərək bəzi məqamları buraxmaq və ya qısaca danışmaq lazım olacaq. İnternet uzun sorğu prinsipi ilə işləyən teleqram botlarının nəşrləri ilə doludur. Və Webhook prinsipi ilə işləyənlər çox azdır. Bu nədir? Uzun sorğu - bu o deməkdir ki, tətbiqinizin özü teleqram serverini müəyyən tezlikdə, yavaş-yavaş mesajlar üçün sorğulayacaq. Webhook - o deməkdir ki, teleqram serveri mesajları dərhal sizin təyin etdiyiniz serverə yönləndirəcək. Bizim vəziyyətimizdə, Heroku xidmətinin izni ilə. Bütün bunlar və ümumiyyətlə bot haqqında, əlbəttə ki, Telegram saytında daha çox oxuya bilərsiniz - https://tlgrm.ru/docs/bots/api Bot interfeysi belə görünür: Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 1 Mən bu proqramı dəqiq təlim kimi qəbul edirəm. layihə yazarkən bu botdan məşq edərkən daha çox məlumat öyrəndiyim üçün. Proqramlamağı öyrənmək istəyirsiniz? Kod yazmağa başlayın!!! Amma! Tətbiqin github-a necə yüklənəcəyi və ya verilənlər bazası yaradılması ilə bağlı ətraflı təlimat olmayacaq. İnternetdə bunun çoxu var və o, çox təfərrüatlı şəkildə təsvir edilmişdir; üstəlik, çox uzun oxunacaq. Tətbiq aşağıdakı kimi işləyəcək: Tədbirin təsvirini daxil edin, tədbirin tarixini və vaxtını daxil edin, tezliyi seçin (bir dəfə edə bilərsiniz, hər gün müəyyən bir vaxtda xatırlatma ola bilər, bir dəfə də ola bilərsiniz. müəyyən vaxtda ayda və ya ildə bir dəfə). Bildirişlərin varyasyonları sonsuz olaraq əlavə edilə bilər; çoxlu fikirlərim var. Sonra, daxil edilmiş məlumatlar verilənlər bazasında saxlanılır (həmçinin Heroku-da pulsuz yerləşdirilir, 10.000 sıra pulsuzdur) Sonra, günün əvvəlində bir dəfə server vaxtı ilə 0:00-da, Spring meyarlara əsaslanaraq bütün hadisələri verilənlər bazasından alır. həmin gün atəş açmalı və müəyyən edilmiş vaxtda onları edam üçün göndərməlidir. DİQQƏT!!! PROQRAMIN BU HİSSƏSİ EKSPERİMENTALDIR! DAHA SADE VƏ HƏQİQİ OLAN BİR TƏTBİQ VAR! BU XÜSUSİ olaraq ZAMAN SİNFİNİN NECƏ İŞLƏDİYİNİ GÖRMƏK ÜÇÜN EDİLİB! Səbətə @calendar_event_bot yazaraq öz əllərinizlə işləyən bota toxuna bilərsiniz, lakin buna arxayın olmayın, çünki mən hələ də bununla lağ edirəm. kod - https://github.com/papoff8295/webHookBotForHabr Əsasən, özünüzü işə salmaq üçün aşağıdakı addımları atmalısınız: • @BotFather ilə qeydiyyatdan keçin , bu çətin deyil, nişan və ad əldə edin • Layihəni github-da bağlayın • Qeydiyyatdan keçin Heroku üzərində, bir proqram yaradın (addım-addım keçəcəyik), deponuzdan yerləşdirin. • Heroku-da verilənlər bazası yaradın • Anbarda müvafiq sahələri öz sahənizlə əvəz edin (token, obyektlərdəki cədvəllərin adı, webHookPath, istifadəçi adı, parol və verilənlər bazasına gedən yol, bunların hamısı təhlil ediləcək) • Heroku 24/24 işlək vəziyyətə gətirin. 7 https:/ /uptimerobot.com/ istifadə edərək , layihənin yekun strukturu belədir: https://start.spring.ioTelegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 2 saytında layihə yaratmaqla başlayaq şəkildə göstərildiyi kimi bizə lazım olan asılılıqları seçin: Özümüz seçin layihənin adını və Yarat düyməsini klikləyin . Sonra sizdən layihəni diskinizdə saxlamaq istəniləcək. Qalan tək şey inkişaf mühitinizdən pom.xm l faylını açmaqdır. Qarşınızda bitmiş bir layihə var. İndi sadəcə əsas kitabxanamızı əlavə etməliyik. Mən https://github.com/rubenlagus/TelegramBots saytından kitabxanadan istifadə etdim . Ümumiyyətlə, çaşqın ola bilərsiniz və onsuz da edə bilərsiniz. Axı, işin bütün məqsədi URL-i belə birləşdirməkdir: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548a.a bir az baxaq. : https://api.telegram.org – teleqram serveri. bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - bot sözündən sonra botu qeydiyyatdan keçirərkən əldə etdiyiniz gizli işarədir. setWebhook?url=https://e9c658b548aa.ngrok.io – metodun adı və onun parametrləri. Bu halda biz sizin webhook serverinizi quraşdırırıq, bütün mesajlar ona göndəriləcək. Ümumiyyətlə, layihənin nəşr üçün çox kiçik olmadığına qərar verdim, lakin əl ilə həyata keçirildikdə, ümumiyyətlə oxunmaz olacaq. Beləliklə, pom faylının son görünüşü : Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 3
<!--?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>
Botumuzu yazmaq üçün hər şey hazırdır. Gəlin TelegramBot sinfini yaradaq . Qovluqların adlarını yazmayacağam, onlara yuxarıdakı layihə strukturunda baxa bilərsiniz.
@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);
    }
}
Sinif SpringWebhookBot-u teleqram kitabxanamızdan genişləndirir və biz yalnız bir metodu, onWebhookUpdateReceived tətbiq etməliyik . O, təhlil edilmiş JSON-u Yeniləmə obyekti kimi qəbul edir və teleqram serverinin bizdən “eşitmək” istədiyini qaytarır. Burada Lombok kitabxanasından annotasiyalarımız var . Lombok - bir proqramçının həyatını asanlaşdırır! Yaxşı, yəni. alıcıları və tənzimləyiciləri yenidən təyin etməyə ehtiyacımız yoxdur, Lombok bunu bizim üçün edir və həmçinin giriş səviyyəsi identifikatoru yazmağa ehtiyacımız yoxdur. Bunun @Getter, @Setter, @FieldDefaults annotasiyaları ilə edildiyini yazmağa daha dəyməz. BotPath sahəsi sonradan Heroku-da alacağımız webhook ünvanımız deməkdir. BotUsername sahəsi Telegram-da botumuzu qeydiyyatdan keçirərkən alacağımız botumuzun adı deməkdir. BotToken sahəsi botumuzu Telegram-da qeydiyyatdan keçirərkən alacağımız nişanımızdır. telegramFacade sahəsi mesajın işlənməsinin aparılacağı sinifimizdir, bir az sonra ona qayıdacağıq, hələlik qırmızı olsun. İndi bizim @BotFather ilə əlaqə saxlamağın və arzulanan botToken və botUsername əldə etməyin vaxtıdır . Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 4Sadəcə ona teleqramda yazın, o sizə hər şeyi danışacaq. Məlumatları application.properties-ə yazırıq, sonda belə görünəcək:
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
Bu konfiqurasiya yerli verilənlər bazası ilə işləmək üçün konfiqurasiya edilmişdir, sonra biz lazımi dəyişiklikləri edəcəyik. BotToken və istifadəçi adını özünüzlə əvəz edin . Application.properties-dən olan məlumatları birbaşa tətbiqdə istifadə etmək yaxşı deyil. Gəlin bu verilənlərdən paxla və ya sarğı sinfi yaradaq.
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
Burada @Value annotasiyası Baharın standart olaraq bildiyi application.properties faylından müvafiq sətirləri işə salır. Tətbiq başlayanda @Component annotasiyası bizim üçün Fasulye yaradır. İndi Spring konfiqurasiya faylına baxaq:
@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;
    }
}
Burada heç bir sehr yoxdur; başlanğıcda Spring bizim üçün SetWebhook və TelegramBot obyektlərini yaradır. İndi mesajlarımız üçün giriş nöqtələri yaradaq:
@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();
    }
}
Telegram serveri POST metodundan istifadə edərək qeydiyyatdan keçmiş webhook ünvanına JSON formatında mesajlar göndərir, nəzarətçimiz onları qəbul edir və Update obyekti şəklində teleqram kitabxanasına ötürür. Mən get metodunu elə etdim) İndi sadəcə TelegramFacade sinfində mesajların və cavabların işlənməsi üçün bəzi məntiq tətbiq etməliyik , onun qısa kodunu verəcəm ki, siz proqramı işə salasınız və sonra öz yolu ilə gedə və ya yerləşdirməyə keçəsiniz. Heroku-da, o zaman tam versiya olacaq:
@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;
    }

}
Bu üsul istənilən Salam dünyasına cavab verəcək! Tətbiqimizi işə salmaq üçün tətbiqimizi birbaşa IDEA-dan sınaqdan keçirə biləcəyimizə əmin olmalıyıq. Bunun üçün ngrok yardım proqramını yükləməliyik. https://ngrok.com/download Bu yardım proqramı bizə 2 saat ərzində müvəqqəti ünvan verən və bütün mesajları yerli serverin müəyyən edilmiş portuna yönləndirən komanda xəttidir. Biz işə salırıq və sətirdə ngrok http 5000 yazırıq (və ya portunuzu göstərə bilərsiniz): Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 5Nəticəni alırıq: Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 6https://23b1a54ccbbd.ngrok.io - bu bizim veb-qanca ünvanımızdır. Tomcat serverini işə salarkən server.port=5000 yazdığımız xüsusiyyətlər faylında qeyd etdiyiniz kimi, o, 5000 portunu tutacaq, bu sahələrin eyni olduğundan əmin olun. Həm də unutmayın ki, ünvan iki saat verilir. Komanda xəttində bu, Sessiyanın Bitməsi sahəsi tərəfindən izlənilir. Vaxt bitdikdə ünvanı yenidən əldə etməli və teleqramda qeydiyyatdan keçmə prosedurundan keçməli olacaqsınız. İndi biz xətti götürürük https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io Və bacarıqlı əl hərəkətlərimizi keçmişimizlə əvəz edirik. nəticədə sətri brauzerə daxil edin və daxil edin. Aşağıdakı nəticəni almalısınız: Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 7Budur, indi tətbiqi işə sala bilərsiniz: ƏsasTelegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 8 metodla sinifinizin belə olduğunu yoxlayın:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
Hər şeyi düzgün etmisinizsə, indi botunuz istənilən mesaja “ Salam dünya” ifadəsi ilə cavab verəcəkdir . Sonra öz yolunuzla gedə bilərsiniz. Əgər siz mənimləsinizsə və bütün addımları keçməkdə maraqlısınızsa, o zaman verilənlər bazası üçün obyektlər yazmağa başlayaq və verilənlər bazasını özü yaradaq. Verilənlər bazasından başlayaq: Artıq dediyim kimi, güman edirəm ki, sizin verilənlər bazası ilə işləmək üçün artıq minimal bacarıqlarınız var və sizdə yerli postgreSQL verilənlər bazası quraşdırılıb , yoxsa, bu yolu izləyin. https://www.postgresql.org/download/ application.properties faylında verilənlər bazası loqini və parolunu özünüzlə əvəz edin. IDEA-da sağda verilənlər bazası nişanı var, orada +/Data source/PostgreSQL üzərinə klikləmək lazımdır . Nəticə olaraq, Test Bağlantısı üzərinə kliklədiyiniz zaman qənaətbəxş nəticə əldə etməlisiniz: Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 9İndi siz birbaşa inkişaf mühitindən cədvəllərlə verilənlər bazası yarada və ya başlanğıc menyusunda yerləşən pgadmin veb interfeysindən istifadə edə bilərsiniz. Bizə 3 masa lazımdır:
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
);
Bu skripti ayrıca yaratmağı tövsiyə edirəm; iki dəfə yazmamaq üçün Heroku-da verilənlər bazası yaratmaq üçün ona ehtiyacımız olacaq. Gəlin bir az gəzək. Dərhal deyəcəyəm ki, Heroku ilə işləmək üçün yalnız event_cash cədvəlinə ehtiyacımız var, onun xüsusiyyətlərinə və Time sinfi ilə işləmək istəyimə görə , o, yerli versiyada faydalı olmayacaq. İstifadəçilər cədvəlində biz teleqram istifadəçisinin hesabının id-sini , mövcud olmaya bilən adını qeyd edəcəyik , istifadəçinin saat qurşağı bildirişlərin düzgün göndərilməsi, həmçinin bildirişlərin göndərilməsinin aktiv/söndürülməsi statusu üçün hesablanacaq. Biz istifadəçi identifikatorunu , bildiriş vaxtını, təsviri user_events cədvəlində qeyd edəcəyik , avtomatik olaraq hadisə üçün id yaradacaq və bildirişlərin tezliyini təyin edəcəyik. Event_cash cədvəli bildiriş göndərilməzdən əvvəl qeyd edəcək və göndərildiyi təqdirdə onu cədvəldən çıxaracaq. Cədvəllər hazırdır, indi obyektləri əlavə edək.
@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;
    }
}
Əsas məqamları bir az nəzərdən keçirək. @Entity – bizim dada jpa üçün sinfi qeyd edir ki, bu sinif verilənlər bazası üçün obyektdir, yəni. verilənlər bazasından məlumat əldə edərkən o, bizə Event, User və EventCashEntity obyekti şəklində təqdim olunacaq. @Cədvəl – verilənlər bazasında cədvəlimizin adını deyirik. Cədvəl adının qırmızı rənglə vurğulanmamasını təmin etmək üçün biz IDEA-da təklif olunan xətanın düzəldilməsi seçimi ilə razılaşmalı və Məlumat mənbələrini təyin et düyməsini klikləməliyik. Və orada bazamızı seçin. @id və @GeneratedValue - Spring tərəfindən verilənlər bazası yaratmaq üçün istifadə olunur. @Column, uyğun gəlmirsə, cədvəldəki sahələrin adını göstərmək üçün istifadə olunur, lakin yaxşı kod qaydaları həmişə bunu yazmağı tövsiyə edir. OneToMany münasibəti - Mən vaxt sərf etməyi və burada nə olduğunu anlamağı tövsiyə edirəm https://en.wikibooks.org/wiki/Java_Persistence Bunu daha aydın izah edə bilmirəm, sadəcə mənə inanın. Sadəcə onu deyim ki, bu halda @OneToMany annotasiyasında deyilir ki, bir istifadəçinin çoxlu hadisələri ola bilər və onlar bizə siyahı şəklində təqdim olunacaq. İndi cədvəllərdən məlumatları əldə etməliyik. SRING DATA JPA kitabxanasında hər şey artıq bizim üçün yazılmışdır, sadəcə olaraq hər bir cədvəl üçün interfeys yaratmalı və onu JpaRepository-dən genişləndirməliyik.
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,>
Verilənlər bazası ilə işləmək üçün əsas məntiq Data Access Object (DAO) adlanan xidmətə ötürülür :
@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>
Bu halda, biz heç bir məlumat emal etmirik, biz sadəcə cədvəllərdən məlumatları alırıq. Biz hamımız T elegramFacade sinifinin tam kodunu təqdim etməyə və məntiqi təhlil etməyə hazırıq.
@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);

    }
}
Gəlin baxaq hansı sahələr üçün lazımdır
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
Hamımız bir sinifdə kodlasaq, onda aya ayaq örtüyü ilə yekunlaşacağıq; buna görə də mətn mesajları ilə işləmək üçün məntiqi MessageHandler sinfinə geri çağırış sorğusu mesajları ilə işləmə məntiqini CallbackQueryHandler sinfinə təyin edirik . Allbackquery-nin nə olduğunu və hansı növ menyular olduğunu anlamaq vaxtıdır . Bunu etmək üçün sizə botun interfeysinin başqa bir şəklini verəcəyəm: Telegram botu - Java-da webHook vasitəsilə xatırlatma və ya Google təqviminə yox deyin!  - 10İki növ menyu var. Pəncərənin altına əlavə olunanlar - əsas menyu və mesaja təyin olunanlar, məsələn, silmək, redaktə etmək, kəmər düymələrini dəyişdirmək. Əsas menyu düyməsini kliklədiyiniz zaman eyni adlı mesaj göndərilir, məsələn, “Mənim Xatırlatmalarım” düyməsini sıxdığınız zaman “Xatırlatmalarım” mətni sadəcə göndəriləcək . Geri çağırış klaviaturasını quraşdırarkən hər bir düymə üçün xüsusi bir dəyər təyin edilir və onun dəyəri ekranda göstərilmədən göndəriləcəkdir. Sonra bizdə BotStateCash sahəsi var . Bu botun vəziyyətini izləyəcək xüsusi yaradılmış bir sinifdir və diqqət yetirin, bu mürəkkəb bir elementdir, gərginləşdirmək lazımdır. Simvolların sayı aşıldı, bu, yeri gəlmişkən, heç bir yerdə yazılmayıb)). Beləliklə, burada ikinci hissəyə keçid var
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION