JavaRush /Java блогы /Random-KK /Telegram боты – Java тіліндегі webHook арқылы еске салу н...
Vladimir Popov
Деңгей

Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз! 1 бөлім

Топта жарияланған
Менің атым Владимир. Мен 43 жастамын. Ал егер сіз, оқырман, 40-тан асқан болсаңыз, иә, 40-тан кейін сізге ұнаса, бағдарламашы бола аласыз. Менің жұмысымның бағдарламалауға мүлдем қатысы жоқ, мен автоматтандыру саласындағы жоба менеджерімін және осының бәрі. Бірақ мен кәсібімді өзгертуді жоспарлап отырмын. О, бұл жаңа трендтер... әр 5-7 жыл сайын қызмет саласын өзгертіп отырады. Сонымен : Жоба өте үлкен болды, сондықтан оқырман Google-ді біледі деген үмітпен кейбір тармақтарды алып тастауға немесе қысқаша айтуға тура келеді. Интернет ұзақ сауалнама принципі бойынша жұмыс істейтін телеграмма боттарының жарияланымдарына толы. Webhook принципімен жұмыс істейтіндер өте аз. Бұл не? Ұзақ сауалнама - бұл сіздің қолданбаңыздың өзі телеграмма serverінен белгілі бір жиіліктегі хабарларды баяу сұрайтынын білдіреді. Webhook – телеграмма serverі хабарларды сіз көрсеткен serverге бірден қайта бағыттайтынын білдіреді. Біздің жағдайда, Heroku қызметінің сыпайылығы. Сіз, әрине, бұл туралы және жалпы бот туралы толығырақ Telegram веб-сайтында оқи аласыз - https://tlgrm.ru/docs/bots/api Бот интерфейсі келесідей көрінеді: Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 1 мен бұл қосымшаны дәл оқыту ретінде қарастырамын. Жобаны жазу кезінде мен жаттығудан гөрі осы боттан көбірек ақпарат алдым. Бағдарламалауды үйренгіңіз келе ме? Код жазуды бастаңыз!!! Бірақ! Қолданбаны github-қа жүктеп салу немесе дерекқорды жасау туралы егжей-тегжейлі нұсқаулар болмайды. Интернетте бұл өте көп және ол егжей-тегжейлі сипатталған, сонымен қатар бұл өте ұзақ оқылатын болады. Қолданба келесідей жұмыс істейді: Оқиғаның сипаттамасын енгізіңіз, оқиғаның күні мен уақытын енгізіңіз, жиілікті таңдаңыз (бір рет жасай аласыз, күн сайын белгілі бір уақытта еске салғыш аласыз, оны бір рет аласыз. белгілі бір уақытта айына немесе жылына бір рет). Хабарландырулардың нұсқаларын шексіз қосуға болады; Менде көптеген идеялар бар. Әрі қарай, енгізілген деректер дерекқорға сақталады (сонымен қатар Heroku-да тегін орналастырылған, 10 000 жол тегін) Содан кейін, күннің басында бір рет server уақытымен 0:00-де Spring барлық оқиғаларды критерийлерге негізделген дерекқордан шығарады. сол күні атуы керек және оларды белгіленген уақытта орындауға жібереді. НАЗАР АУДАРЫҢЫЗ!!! БАҒДАРЛАМАНЫҢ БҰЛ БӨЛІМІ ЭКСПЕРИМЕНТАЛДЫ! ҚАРАПАЙЫМ ЖӘНЕ ДҰРЫСТЫ ЖҮЗЕГЕ АСЫРУ БАР! БҰЛ УАҚЫТ САБАҚТЫҢ ҚАЛАЙ ӨТЕТІНІН КӨРУ ҮШІН АРНАЙЫ ЖАСАЛДЫ! Арбаға @calendar_event_bot деп теру арқылы жұмыс істейтін ботқа өз қолыңызбен тиюге болады, бірақ оған сенбеңіз, өйткені мен оны әлі де мазақ етіп жүрмін. code - https://github.com/papoff8295/webHookBotForHabr Негізінде, өзіңізді іске қосу үшін келесі қадамдарды орындауыңыз керек: • @BotFather арқылы тіркелу , бұл қиын емес, таңбалауыш пен атауды алыңыз • Жобаны github-та айырыңыз • Тіркелу Херокуда _, қолданбаны жасаңыз (біз оны кезең-кезеңімен қарастырамыз), репозиторийден орналастырыңыз. • Heroku-да дерекқор жасаңыз • Репозиторийдегі сәйкес өрістерді өзіңіздікімен ауыстырыңыз (таңбалауыш, нысандардағы кестелердің атауы, webHookPath, пайдаланушы аты, құпия сөз және дерекқорға жол, мұның бәрі талданады) • Heroku 24/24 жұмыс істейді. 7 https:/ /uptimerobot.com/ пайдалану арқылы жобаның соңғы құрылымы келесідей: https://start.spring.ioTelegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 2 сайтында жоба жасаудан бастайық Суретте көрсетілгендей бізге қажет тәуелділіктерді таңдаңыз: Өзімізді таңдаңыз. жобаның атын және Жасау түймесін басыңыз . Әрі қарай жобаны дискіге сақтау ұсынылады. Әзірлеу ортасынан pom.xm l файлын ашу ғана қалады. Сіздің алдыңызда дайын жоба тұр. Енді бізге негізгі кітапханамызды қосу керек. Мен кітапхананы https://github.com/rubenlagus/TelegramBots сайтынан пайдаландым . Жалпы алғанда, сіз шатасып, онсыз жасай аласыз. Ақыр соңында, жұмыстың барлық мәні мына сияқты URL мекенжайын біріктіру болып табылады: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548a.it biraz қараңыз.' : https://api.telegram.org – телеграмма serverі. bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - бот сөзінен кейін сіз ботты тіркеген кезде алатын құпия таңбалауыш болып табылады. setWebhook?url=https://e9c658b548aa.ngrok.io – әдіс атауы және оның параметрлері. Бұл жағдайда біз сіздің вебхук serverіңізді орнатамыз, оған барлық хабарламалар жіберіледі. Тұтастай алғанда, мен жобаны жариялау үшін тым кішкентай емес деп шештім, бірақ қолмен орындаған кезде оны оқуға болмайды. Сонымен, pom файлының соңғы көрінісі : Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 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>
Біздің ботты жазуға бәрі дайын. TelegramBot сыныбын жасайық . Мен қалталардың атауларын жазбаймын, оларды жоғарыдағы жоба құрылымында қарауға болады.
@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);
    }
}
Сынып SpringWebhookBot бағдарламасын телеграмма кітапханасынан кеңейтеді және бізге тек бір әдісті, onWebhookUpdateReceived енгізу керек . Ол талданған JSON-ды Жаңарту нысаны ретінде қабылдайды және телеграмма serverі бізден «естгісі келетінін» қайтарады. Мұнда біз Lombok кітапханасының annotationлары бар . Ломбок – бағдарламашының өмірін жеңілдетеді! Ал, бұл. бізге қабылдағыштар мен орнатушыларды қайта анықтаудың қажеті жоқ, Lombok мұны біз үшін жасайды, сонымен қатар кіру деңгейінің идентификаторын жазудың қажеті жоқ. Бұл @Getter, @Setter, @FieldDefaults annotationлары арқылы жасалатынын жазудың қажеті жоқ botPath өрісі кейінірек Heroku-да алатын веб-хук мекенжайымызды білдіреді. botUsername өрісі біздің ботымыздың атын білдіреді, біз оны Telegram-да ботты тіркеген кезде аламыз. botToken өрісі біздің токеніміз болып табылады, оны Telegram-да ботты тіркеген кезде аламыз. TelegramFacade өрісі - бұл хабарламаларды өңдеу жүзеге асырылатын біздің сынып, біз оған сәл кейінірек ораламыз, әзірше қызыл болсын. Енді бізге @BotFather хабарласып , сүйікті botToken мен botUsername алатын кез келді. Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 4Тек оған телеграмға жазыңыз, ол сізге бәрін айтып береді. Деректерді application.properties файлымызға жазамыз, соңында ол келесідей болады:
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
Бұл конфигурация жергілікті дерекқормен жұмыс істеу үшін конфигурацияланған, кейінірек біз қажетті өзгерістерді енгіземіз. botToken және пайдаланушы атын өзіңіздікімен ауыстырыңыз . Application.properties деректерін қолданбада тікелей пайдалану жақсы емес. Осы деректерден бұршақ немесе орауыш класын жасайық.
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
Мұнда @Value annotationсы Spring әдепкі бойынша білетін application.properties файлындағы сәйкес жолдарды инициализациялайды. Ал @Component annotationсы қолданба іске қосылғанда біз үшін Bean жасайды. Енді 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;
    }
}
Мұнда ешқандай сиқыр жоқ; іске қосу кезінде Spring біз үшін SetWebhook және TelegramBot нысандарын жасайды. Енді хабарларымыз үшін кіру нүктелерін жасайық:
@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 serverі JSON пішіміндегі хабарламаларды тіркелген webhook мекенжайына POST әдісі арқылы жібереді, біздің контроллер оларды қабылдап, Жаңарту нысаны түрінде телеграмма кітапханасына жібереді. Метод get я сделал просто так ) Теперь нам осталось реализовать Howую-то логику обработки сообщений и ответа в классе TelegramFacade , я приведу его краткий code, чтобы уже можно было запускать приложение и дальше идти своим путем or перейти уже у deploy на Heroku, потом будет толық нұсқа:
@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;
    }

}
Бұл әдіс кез келген Сәлем әлеміне жауап береді! Қолданбаны іске қосу үшін біз IDEA-дан қолданбамызды тікелей тексере алатынымызға көз жеткізуіміз керек. Ол үшін ngrok утorтасын жүктеп алу керек. https://ngrok.com/download Бұл утorта бізге 2 сағатқа уақытша мекенжай беретін және барлық хабарларды жергілікті serverдің көрсетілген портына қайта бағыттайтын пәрмен жолы болып табылады. Біз жолға ngrok http 5000 енгіземіз және жазамыз (немесе портыңызды көрсете аласыз): Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 5Нәтиже аламыз: Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 6https://23b1a54ccbbd.ngrok.io - бұл біздің вебхук мекенжайымыз. Tomcat serverін іске қосқан кезде біз server.port=5000 деп жазған сипаттар файлында байқаған боларсыз, ол 5000 портты алады, бұл өрістердің бірдей екеніне көз жеткізіңіз. Сондай-ақ, мекенжай екі сағатқа берілетінін ұмытпаңыз. Пәрмен жолында бұл сеанстың аяқталуы өрісі арқылы бақыланады. Уақыт біткенде мекен-жайды қайтадан алып, оны telegram-да тіркеу proceduresасынан өту керек. Енді біз https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io жолын аламыз. алынған жолды шолғышқа енгізіп, enter түймесін басыңыз. Сіз келесі нәтижені алуыңыз керек: Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 7Міне, енді сіз қолданбаны іске қоса аласыз: НегізгіTelegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 8 әдіспен сыныптың келесідей екенін тексеріңіз:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
Егер сіз бәрін дұрыс жасасаңыз, енді сіздің ботыңыз кез келген хабарламаға « Сәлем әлем» сөзімен жауап береді . Сонда сіз өз жолыңызбен кете аласыз. Егер сіз менімен бірге болсаңыз және сіз барлық қадамдардан өтуге қызығушылық танытсаңыз, онда дерекқор үшін нысандарды жазуды бастайық және дерекқордың өзін жасайық. Дерекқордан бастайық: Жоғарыда айтқанымдай, сізде дерекқормен жұмыс істеуде ең аз дағдыларыңыз бар деп ойлаймын және сізде жергілікті postgreSQL дерекқоры орнатылған , егер жоқ болса, осы жолмен жүріңіз. https://www.postgresql.org/download/ application.properties файлында дерекқордың логин мен құпия сөзін өзіңіздікімен ауыстырыңыз. IDEA-да оң жақта дерекқор қойындысы бар, оның ішінде +/Data source/PostgreSQL түймесін басу керек . Нәтижесінде, сынақ қосылымын басқан кезде қанағаттанарлық нәтижеге қол жеткізу керек: Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 9Енді әзірлеу ортасынан тікелей кестелермен дерекқор жасай аласыз немесе бастау мәзірінде орналасқан pgadmin веб-интерфейсін пайдалана аласыз. Бізге 3 кесте қажет:
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
);
Мен бұл сценарийді бөлек жасауды ұсынамын; оны екі рет жазбау үшін Херокуде дерекқор жасау үшін қажет болады. Кішкене жүрейік. Мен бірден айтамын, бізге Heroku-мен жұмыс істеу үшін оқиға_cash кестесі оның ерекшеліктеріне және Time сыныбымен жұмыс істеуге деген тойымсыз қалауыма байланысты қажет ; ол жергілікті нұсқада пайдалы болмайды. Пайдаланушылар кестесінде біз telegram пайдаланушысының тіркелгісінің идентификаторын жазамыз , оның аты жоқ болуы мүмкін, пайдаланушының уақыт белдеуі хабарламаларды дұрыс жіберу үшін есептеледі, сондай-ақ хабарландыруларды жіберудің қосу/өшіру күйі. Біз пайдаланушы идентификаторын , хабарландыру уақытын, сипаттаманы user_events кестесіне жазамыз , оқиға үшін идентификаторды автоматты түрде жасаймыз және хабарландырулар жиілігін орнатамыз. Event_cash кестесі хабарландыруды жіберілмес бұрын жазып алады және жіберілсе, оны кестеден алып тастайды. Кестелер дайын, енді нысандарды қосамыз.
@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;
    }
}
Негізгі ойларға аздап тоқталайық. @Entity – біздің dada jpa үшін сыныпты белгілейді, бұл класс дерекқорға арналған нысан болып табылады, яғни. дерекқордан деректерді алу кезінде ол бізге Event, User және EventCashEntity нысаны түрінде ұсынылады. @Table – дерекқордағы кестеміз қалай аталатынын айтамыз. Кесте атауы қызыл түспен сызылмағанына көз жеткізу үшін IDEA-да ұсынылған қатені түзету опциясымен келісіп, Деректер көздерін тағайындау түймесін басыңыз. Және сол жерде біздің базамызды таңдаңыз. @id және @GeneratedValue - егер ол бұрыннан жоқ болса, дерекқорды жасау үшін Spring арқылы пайдаланылады. @Column сәйкес келмесе, кестедегі өрістердің атын көрсету үшін пайдаланылады, бірақ жақсы code ережелері мұны әрқашан жазуды ұсынады. OneToMany қатынасы - мен уақытты өткізіп, оның не екенін осында білуге ​​кеңес беремін https://en.wikibooks.org/wiki/Java_Persistence Мен оны анық түсіндіре алмаймын, маған сеніңіз. Бұл жағдайда @OneToMany annotationсында бір пайдаланушыда көптеген оқиғалар болуы мүмкін екенін және олар бізге тізім түрінде берілетінін айтайын . Енді кестелерден мәліметтер алуымыз керек. SRING DATA JPA кітапханасында бәрі біз үшін жазылған, бізге тек әрбір кесте үшін интерфейс жасап, оны 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,>
Дерекқормен жұмыс істеудің негізгі логикасы 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>
Бұл жағдайда бізде деректерді өңдеу жоқ, біз жай ғана кестелерден деректерді аламыз. Біз бәріміз T elegramFacade класының толық codeын беруге дайынбыз және логиканы талдауды бастаймыз.
@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);

    }
}
Қандай өрістер қажет екенін қарастырайық
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
Егер біз бәріміз бір сыныпта codeтасақ, онда біз айға аяқ киіммен аяқталамыз; сондықтан мәтіндік хабарламалармен жұмыс істеу логикасын MessageHandler сыныбына , ал кері шақыру хабарламаларымен жұмыс істеу логикасын CallbackQueryHandler сыныбына тағайындаймыз . Allbackquery деген не екенін және мәзірлердің қандай түрлері бар екенін анықтау уақыты келді . Мұны істеу үшін мен сізге бот интерфейсінің тағы бір суретін беремін: Telegram боты – Java тіліндегі webHook арқылы еске салу немесе Google күнтізбесіне «жоқ» деңіз!  - 10мәзірдің екі түрі бар. Терезенің төменгі жағында бекітілгендер - негізгі мәзір және хабарламаға тағайындалғандар, мысалы, белдік түймелерін жою, өңдеу, өзгерту. Негізгі мәзір түймесін басқан кезде аттас хабарлама жіберіледі, мысалы, «Менің еске салғыштарым» түймесін басқанда, «Менің еске салғыштарым» мәтіні жай ғана жіберіледі . Ал кері шақыру пернетақтасын орнату кезінде әрбір түйме үшін белгілі бір мән орнатылады және оның мәні экранда көрсетілмей жіберіледі. Әрі қарай бізде BotStateCash өрісі бар . Бұл боттың күйін қадағалайтын арнайы жасалған класс, және назар аударыңыз, бұл күрделі элемент, сіз штамм жасауыңыз керек. Таңбалар саны асып кетті, айтпақшы, еш жерде жазылмаған)). Міне, екінші бөлімге сілтеме
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION