JavaRush /Java blogi /Random-UZ /Telegram boti - Java-dagi webHook orqali eslatma yoki Goo...

Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng! 1-qism

Guruhda nashr etilgan
Mening ismim Vladimir. Men 43 yoshdaman. Va agar siz, o'quvchi, 40 yoshdan oshgan bo'lsangiz, ha, 40 dan keyin sizga yoqsa, dasturchi bo'lishingiz mumkin. Mening ishim dasturlash bilan umuman aloqasi yo'q, men avtomatlashtirish sohasida loyiha menejeriman va bularning barchasi. Lekin men kasbimni o'zgartirishni rejalashtiryapman. Oh, bu yangi tendentsiyalar... har 5-7 yilda faoliyat sohangizni o'zgartiring. Shunday qilib : Loyiha juda katta bo'lib chiqdi, shuning uchun o'quvchi Google-ni qanday bilishini umid qilib, ba'zi fikrlarni qoldirib ketish yoki qisqacha gapirish kerak bo'ladi. Internet uzoq so'rov tamoyili asosida ishlaydigan telegram botlarining nashrlari bilan to'la. Webhook printsipi bo'yicha ishlaydiganlar juda kam. Bu nima? Uzoq so'rov - bu sizning ilovangizning o'zi telegram serverida ma'lum chastotadagi xabarlar uchun sekin so'rov o'tkazishini anglatadi. Webhook - telegram serveri xabarlarni bir zumda siz ko'rsatgan serverga yo'naltirishini bildiradi. Bizning holatlarimizda, Heroku xizmatining yordami bilan. Siz, albatta, bularning barchasi va umuman bot haqida Telegram veb-saytida ko'proq o'qishingiz mumkin - https://tlgrm.ru/docs/bots/api Bot interfeysi quyidagicha ko'rinadi: Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 1 men ushbu ilovani aynan trening deb bilaman. loyihani yozishda men ushbu botdan treningdan ko'ra ko'proq ma'lumot o'rgandim. Dasturlashni o'rganmoqchimisiz? Kod yozishni boshlang!!! Lekin! Ilovani github-ga qanday yuklash yoki ma'lumotlar bazasini yaratish bo'yicha batafsil ko'rsatmalar bo'lmaydi. Internetda bu juda ko'p va u batafsil tavsiflangan, bundan tashqari, bu juda uzoq o'qiladi. Ilova quyidagicha ishlaydi: Hodisa tavsifini kiriting, voqea sanasi va vaqtini kiriting, chastotani tanlang (bir marta qilishingiz mumkin, siz har kuni ma'lum bir vaqtda eslatma olishingiz mumkin, bir marta olishingiz mumkin. oyda ma'lum bir vaqtda yoki yiliga bir marta). Bildirishnomalarning xilma-xilligini cheksiz qo'shish mumkin; Menda juda ko'p fikrlar bor. Keyinchalik, kiritilgan ma'lumotlar ma'lumotlar bazasiga saqlanadi (shuningdek, Heroku-da bepul joylashtirilgan, 10 000 qator bepul) Keyin, kunning boshida bir marta server vaqti bilan soat 0:00 da Spring barcha voqealarni mezonlarga asoslangan holda ma'lumotlar bazasidan oladi. o'sha kuni otish kerak va belgilangan vaqtda ularni ijro etish uchun yuboradi. DIQQAT!!! DASTURNING BU QISMI EKSPERIMENTAL! ODDIY VA HAQIQIROQ AMALGA ISHLATISH BOR! BU MAXSUS VAQT SINFLARI QANDAY ISHLASHINI KO'RISH UCHUN QILGAN! Siz savatga @calendar_event_bot deb yozib o'z qo'lingiz bilan ishlaydigan botga tegishingiz mumkin, lekin bu bilan hisoblamang, chunki men hali ham uni masxara qilaman. kod - https://github.com/papoff8295/webHookBotForHabr Asosan, o'zingiznikini ishga tushirish uchun siz quyidagi amallarni bajarishingiz kerak: • @BotFather bilan ro'yxatdan o'ting , bu qiyin emas, token va nom oling • Loyihani githubda o'rnating • Ro'yxatdan o'ting Herokuda _, dastur yarating (biz uni bosqichma-bosqich ko'rib chiqamiz), omboringizdan joylashtiring. • Heroku-da ma'lumotlar bazasi yarating • Ombordagi tegishli maydonlarni o'zingizga o'zgartiring (token, ob'ektlardagi jadvallar nomi, webHookPath, foydalanuvchi nomi, parol va ma'lumotlar bazasiga yo'l, bularning barchasi tahlil qilinadi) • Heroku 24/24 ishlasin. 7 https:/ /uptimerobot.com/ yordamida loyihaning yakuniy tuzilishi quyidagicha: Keling, https://start.spring.ioTelegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 2 saytida loyiha yaratishdan boshlaylik, rasmda ko'rsatilganidek, bizga kerak bo'lgan bog'liqliklarni tanlang: O'zimizni tanlang. loyiha uchun nom va Generate ni bosing . Keyin sizdan loyihani diskingizga saqlash so'raladi. Faqat ishlab chiqish muhitingizdan pom.xm l faylini ochish qoladi. Sizning oldingizda tugallangan loyiha bor. Endi biz asosiy kutubxonamizni qo'shishimiz kerak. Men kutubxonadan https://github.com/rubenlagus/TelegramBots dan foydalanganman. Axir, ishning butun maqsadi URL-manzilni shunday birlashtirishdir: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548a.itga qarang. : https://api.telegram.org – telegram serveri. bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - bot so'zidan keyin botni ro'yxatdan o'tkazishda siz oladigan maxfiy token. setWebhook?url=https://e9c658b548aa.ngrok.io – usulning nomi va uning parametrlari. Bunday holda, biz sizning webhook serveringizni o'rnatamiz, barcha xabarlar unga yuboriladi. Umuman olganda, men loyiha nashr qilish uchun unchalik kichik emas, deb qaror qildim, lekin qo'lda amalga oshirilsa, uni umuman o'qib bo'lmaydi. Shunday qilib, pom faylining yakuniy ko'rinishi : Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 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>
Bizning botimizni yozish uchun hamma narsa tayyor. Keling, TelegramBot sinfini yarataylik . Men papkalarning nomlarini yozmayman, ularni yuqoridagi loyiha tuzilishida ko'rishingiz mumkin.
@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);
    }
}
Sinf SpringWebhookBot-ni telegram kutubxonamizdan kengaytiradi va biz faqat bitta usulni, onWebhookUpdateReceivedni amalga oshirishimiz kerak . U tahlil qilingan JSON-ni Yangilash ob'ekti sifatida qabul qiladi va telegram serveri bizdan "eshitmoqchi" bo'lgan narsani qaytaradi. Bu erda Lombok kutubxonasidan izohlar mavjud . Lombok - dasturchining hayotini osonlashtiradi! Xo'sh, bu. biz oluvchilar va sozlagichlarni qayta belgilashimiz shart emas, Lombok buni biz uchun qiladi, shuningdek, kirish darajasi identifikatorini yozishimiz shart emas. Bu @Getter, @Setter, @FieldDefaults izohlari orqali amalga oshirilganligini endi yozishning hojati yo'q botPath maydoni bizning veb-huk manzilimizni bildiradi, biz uni keyinchalik Heroku-da olamiz. BotUsername maydoni botimizning nomini bildiradi, biz botimizni Telegramda ro'yxatdan o'tkazishda olamiz. BotToken maydoni bizning tokenimiz bo'lib, biz botimizni Telegramda ro'yxatdan o'tkazishda olamiz. TelegramFacade maydoni - bu bizning sinfimiz bo'lib, u erda xabarlarni qayta ishlash amalga oshiriladi, biz unga birozdan keyin qaytamiz, hozircha qizil bo'lsin. Endi biz uchun @BotFather bilan bog'lanish va orzu qilingan botToken va botUsername olish vaqti keldi . Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 4Unga telegramda yozing, u sizga hamma narsani aytib beradi. Biz ma'lumotlarni application.properties ga yozamiz, oxirida u quyidagicha ko'rinadi:
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
Ushbu konfiguratsiya mahalliy ma'lumotlar bazasi bilan ishlash uchun tuzilgan, keyinroq biz kerakli o'zgarishlarni amalga oshiramiz. BotToken va foydalanuvchi nomini o'zingizga almashtiring . Application.properties ma'lumotlaridan to'g'ridan-to'g'ri ilovada foydalanish yaxshi emas. Keling, ushbu ma'lumotlardan loviya yoki o'rash sinfini yarataylik.
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
Bu erda @Value annotatsiyasi Spring sukut bo'yicha biladigan application.properties faylidan mos keladigan satrlarni ishga tushiradi. Ilova ishga tushganda @Component izohi biz uchun Bean yaratadi. Keling, Spring konfiguratsiya faylini ko'rib chiqaylik:
@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;
    }
}
Bu yerda hech qanday sehr yo'q; ishga tushirilganda Spring biz uchun SetWebhook va TelegramBot obyektlarini yaratadi. Keling, xabarlarimiz uchun kirish nuqtalarini yarataylik:
@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 JSON formatidagi xabarlarni ro‘yxatdan o‘tgan webhuk manziliga POST usuli yordamida jo‘natadi, bizning kontroller ularni qabul qiladi va Update obyekti ko‘rinishida telegram kutubxonasiga uzatadi. Men get usulini xuddi shunday qildim) Endi biz TelegramFacade sinfida xabarlar va javoblarni qayta ishlash uchun ba'zi bir mantiqni amalga oshirishimiz kerak , men uning qisqa kodini beraman, shunda siz ilovani ishga tushirishingiz va keyin o'z yo'lingizdan o'tishingiz yoki joylashtirishga o'tishingiz mumkin. Heroku-da, keyin u to'liq versiya bo'ladi:
@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 usul har qanday Salom dunyosiga javob beradi! Ilovamizni ishga tushirish uchun biz ilovamizni to'g'ridan-to'g'ri IDEA-dan sinab ko'rishimiz mumkinligiga ishonch hosil qilishimiz kerak. Buning uchun biz ngrok yordam dasturini yuklab olishimiz kerak. https://ngrok.com/download Ushbu yordamchi dastur bizga 2 soat davomida vaqtinchalik manzilni beruvchi va barcha xabarlarni mahalliy serverning belgilangan portiga yo'naltiruvchi buyruq qatoridir. Biz ngrok http 5000 ni ishga tushiramiz va satrga yozamiz (yoki siz portingizni ko'rsatishingiz mumkin): Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 5Natijani olamiz: Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 6https://23b1a54ccbbd.ngrok.io - bu bizning webhook manzilimiz. Tomcat serverini ishga tushirishda server.port=5000 deb yozgan xususiyatlar faylida payqagan bo'lsangiz, u 5000 portni egallaydi, bu maydonlar bir xil ekanligiga ishonch hosil qiling. Shuningdek, manzil ikki soat davomida berilganligini unutmang. Buyruqlar satrida bu Seans tugashi maydoni tomonidan nazorat qilinadi. Vaqt tugagach, manzilni qaytadan olishingiz va uni telegramda ro'yxatdan o'tkazish tartibidan o'tishingiz kerak bo'ladi. Endi biz https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io qatorini olamiz. olingan qatorni brauzerga kiriting va Enter tugmasini bosing. Siz quyidagi natijani olishingiz kerak: Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 7Hammasi shunday, endi siz dasturni ishga tushirishingiz mumkin: AsosiyTelegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 8 usul bilan sinfingiz shunday ekanligini tekshiring:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
Agar siz hamma narsani to'g'ri bajargan bo'lsangiz, endi sizning botingiz har qanday xabarga " Salom dunyo" iborasi bilan javob beradi . Keyin o'z yo'lingiz bilan borishingiz mumkin. Agar siz men bilan birga bo'lsangiz va barcha bosqichlarni bajarishga qiziqsangiz, keling, ma'lumotlar bazasi uchun ob'ektlarni yozishni boshlaymiz va ma'lumotlar bazasini o'zi yaratamiz. Ma'lumotlar bazasidan boshlaylik: Yuqorida aytganimdek, sizda allaqachon ma'lumotlar bazasi bilan ishlash bo'yicha minimal ko'nikmalaringiz bor deb taxmin qilaman va sizda mahalliy postgreSQL ma'lumotlar bazasi o'rnatilgan , agar bo'lmasa, ushbu yo'ldan boring. https://www.postgresql.org/download/ Application.properties faylida ma'lumotlar bazasiga kirish va parolni o'zingizga almashtiring. IDEA-da o'ng tomonda ma'lumotlar bazasi yorlig'i mavjud, unda siz +/Ma'lumotlar manbai/PostgreSQL ni bosishingiz kerak . Natijada, ulanishni sinab ko'rish tugmachasini bosganingizda, siz qoniqarli natijaga ega bo'lishingiz kerak: Telegram boti - Java-dagi webHook orqali eslatma yoki Google kalendariga yo'q deng!  - 9Endi siz to'g'ridan-to'g'ri ishlab chiqish muhitidan jadvallar bilan ma'lumotlar bazasini yaratishingiz mumkin yoki pgadmin veb-interfeysidan foydalanishingiz mumkin , bu ishga tushirish menyusida joylashgan. Bizga 3 ta jadval kerak bo'ladi:
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
);
Men ushbu skriptni alohida yaratishni maslahat beraman; uni ikki marta yozmaslik uchun Heroku-da ma'lumotlar bazasini yaratish uchun kerak bo'ladi. Keling, bir oz yuraylik. Men darhol aytamanki, Heroku bilan ishlash uchun bizga faqat event_cash jadvali kerak , chunki uning o'ziga xos xususiyatlari va Time klassi bilan ishlashga bo'lgan ishtiyoqim ; mahalliy versiyada bu foydali bo'lmaydi. Foydalanuvchilar jadvalida biz telegram foydalanuvchisi akkauntining identifikatorini , uning mavjud bo'lmasligi mumkin bo'lgan ism-sharifini yozib olamiz , foydalanuvchining vaqt zonasi bildirishnomalarni to'g'ri jo'natish uchun hisoblab chiqiladi, shuningdek bildirishnomalarni yuborishning yoqish/o'chirish holati. Biz foydalanuvchi identifikatorini , bildirishnoma vaqtini, tavsifni user_events jadvaliga yozamiz , avtomatik ravishda hodisa uchun identifikatorni yaratamiz va bildirishnomalar chastotasini o'rnatamiz. Event_cash jadvali xabarnoma yuborilishidan oldin uni yozib oladi va agar yuborilgan bo'lsa, uni jadvaldan olib tashlaydi. Jadvallar tayyor, endi ob'ektlarni qo'shamiz.
@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;
    }
}
Keling, asosiy fikrlarni biroz ko'rib chiqaylik. @Entity - bizning dada jpa uchun sinfni belgilaydi, bu sinf ma'lumotlar bazasi uchun ob'ektdir, ya'ni. ma'lumotlar bazasidan ma'lumotlarni olishda ular bizga Event, User va EventCashEntity ob'ekti ko'rinishida taqdim etiladi. @Table - biz ma'lumotlar bazasidagi jadvalimiz nima deb nomlanganini aytamiz. Jadval nomi qizil rang bilan chizilmaganligiga ishonch hosil qilish uchun biz IDEA da taklif qilingan xatoni tuzatish variantiga rozi bo'lishimiz va Ma'lumotlar manbalarini tayinlash tugmasini bosishimiz kerak. Va u erda bizning bazamizni tanlang. @id va @GeneratedValue - Spring tomonidan ma'lumotlar bazasi mavjud bo'lmasa, uni yaratish uchun ishlatiladi. @Column, agar ular mos kelmasa, jadvaldagi maydonlar nomini ko'rsatish uchun ishlatiladi, lekin yaxshi kod qoidalari buni har doim yozishni tavsiya qiladi. OneToMany munosabati - Men vaqt sarflashni va bu erda nima ekanligini aniqlashni tavsiya qilaman https://en.wikibooks.org/wiki/Java_Persistence Men buni aniqroq tushuntira olmayman, faqat menga ishoning. Aytmoqchimanki, bu holda @OneToMany izohida bitta foydalanuvchi ko'p voqealarga ega bo'lishi mumkinligini aytadi va ular bizga ro'yxat shaklida taqdim etiladi. Endi biz jadvallardan ma'lumotlarni olishimiz kerak. SRING DATA JPA kutubxonasida hamma narsa biz uchun yozilgan, shunchaki har bir jadval uchun interfeys yaratishimiz va uni JpaRepository-dan kengaytirishimiz kerak.
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,>
Ma'lumotlar bazasi bilan ishlashning asosiy mantiqi ma'lumotlarga kirish ob'ekti (DAO) deb ataladigan xizmatga o'tkaziladi :
@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>
Bunday holda, bizda ma'lumotlarni qayta ishlash yo'q, biz shunchaki jadvallardan ma'lumotlarni olamiz. Biz hammamiz T elegramFacade sinfining to'liq kodini taqdim etishga tayyormiz va mantiqni tahlil qilishni boshlaymiz.
@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);

    }
}
Keling, qanday maydonlar kerakligini ko'rib chiqaylik
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
Agar biz hammamiz bitta sinfda kodlashsak, biz oyga oyoq kiyimi bilan yakunlanamiz; shuning uchun biz matnli xabarlar bilan ishlash mantiqini MessageHandler sinfiga va qayta qo'ng'iroq qilish xabarlari bilan ishlash mantiqini CallbackQueryHandler sinfiga tayinlaymiz . Allbackquery nima ekanligini va qanday turdagi menyular mavjudligini aniqlash vaqti keldi . Buning uchun men sizga bot interfeysining yana bir rasmini beraman: Telegram bot — напоминалка через webHook на Java or скажи нет Google-календарю! - 10Ikki xil menyu mavjud. Oynaning pastki qismiga biriktirilganlar - asosiy menyu va xabarga tayinlanganlar, masalan, o'chirish, tahrirlash, o'zgartirish kamar tugmalari. Asosiy menyu tugmachasini bosganingizda, xuddi shu nomdagi xabar yuboriladi, masalan, "Mening eslatmalarim" tugmasini bosganingizda, "Mening eslatmalarim" matni yuboriladi . Va qayta qo'ng'iroq qilish klaviaturasini o'rnatishda har bir tugma uchun ma'lum bir qiymat o'rnatiladi va uning qiymati ekranda ko'rsatilmasdan yuboriladi. Keyin bizda BotStateCash maydoni mavjud . Bu botning holatini kuzatadigan maxsus yaratilgan sinf va e'tibor, bu murakkab element, siz kuchlanishingiz kerak. Belgilar soni oshib ketdi, bu, aytmoqchi, hech qaerda yozilmagan)). Shunday qilib, ikkinchi qismga havola
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION