JavaRush /Java блогу /Random-KY /Telegram боту - Java'дагы webHook аркылуу эскертме же Goo...
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 боюнча, тиркемени түзүңүз (биз аны этап-этабы менен карап чыгабыз), репозиторийиңизден жайылтыңыз. • Heroku'да маалымат базасын түзүңүз • Репозиторийдеги тиешелүү талааларды өзүңүз менен алмаштырыңыз (токен, an objectтердеги tableлардын аталышы, webHookPath, колдонуучунун аты, сырсөз жана маалымат базасына жол, мунун баары талданат) • Heroku 24/24 иштетет. 7 https:/ /uptimerobot.com/ колдонуу менен Долбоордун акыркы структурасы төмөнкүдөй: https://start.spring.ioTelegram боту - Java'дагы webHook аркылуу эскертме же Google календарына жок деп айт!  - 2 дарегинде долбоор түзүү менен баштайлы, сүрөттө көрсөтүлгөндөй бизге керектүү көз карандылыктарды тандаңыз: Өзүбүздүн тандаңыз долбоордун атын жана чыкылdateу түзүү . Андан кийин сизден долбоорду дискиңизге сактоо сунушталат. Өнүктүрүү чөйрөңүздөн pom.xm l файлын ачуу гана калды. Сиздин алдыңызда даяр долбоор турат. Эми биз жөн гана биздин негизги китепкананы кошуу керек. Мен https://github.com/rubenlagus/TelegramBots китепканасын колдондум. Жалпысынан алганда, сиз чаташып, ансыз деле кыла аласыз. Кантсе да, иштин максаты URL дарегин төмөнкүдөй бириктирүү: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548a. : 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ду Жаңыртуу an objectи катары кабыл алат жана телеграмма serverи бизден "уккусу" келген нерсени кайтарат. Бул жерде бизде Ломбок китепканасынан 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
Бул конфигурация жергorктүү маалымат базасы менен иштөө үчүн конфигурацияланган; кийинчерээк биз керектүү өзгөртүүлөрдү киргизебиз. 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сы жазгы демейки боюнча билген 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 an objectтерин түзөт. Эми билдирүүлөрүбүз үчүн кирүү чекиттерин түзөлү:
@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и POST ыкмасын колдонуу менен катталган webhook дарегине JSON форматындагы билдирүүлөрдү жөнөтөт, биздин контроллер аларды кабыл алып, Жаңыртуу an objectиси түрүндө телеграмма китепканасына өткөрүп берет. Мен алуу ыкмасын ушундай кылдым) Эми биз TelegramFacade классында билдирүүлөрдү жана жоопторду иштетүү үчүн кандайдыр бир логиканы ишке ашырышыбыз керек , мен анын кыска codeун берем, ошондо сиз тиркемени ишке киргизип, андан кийин өз жолуңуз менен кете аласыз же жайылтууга өтөсүз. Heroku боюнча, анда ал толук version болот:
@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;
    }

}
Бул ыкма каалаган Hello дүйнөсүнө жооп берет! Биздин тиркемени ишке киргизүү үчүн, биз IDEAдан түздөн-түз колдонмобузду сынап көрүшүбүз керек. Бул үчүн биз ngrok утorтасын жүктөп алышыбыз керек. https://ngrok.com/download Бул утorта бизге 2 саатка убактылуу дарек берүүчү жана бардык билдирүүлөрдү жергorктүү serverдин көрсөтүлгөн портуна багыттоочу буйрук сабы. Биз ишке киргизебиз жана ngrok http 5000 сапка жазабыз (же портуңузду көрсөтсөңүз болот): Telegram боту - Java'дагы webHook аркылуу эскертме же Google календарына жок деп айт!  - 5Биз натыйжаны алабыз: Telegram боту - Java'дагы webHook аркылуу эскертме же Google календарына жок деп айт!  - 6https://23b1a54ccbbd.ngrok.io - бул биздин вебхук дарегибиз. Сиз tomcat serverин ишке киргизүүдө server.port=5000 деп жазган касиеттер файлында байкаган болушуңуз керек, ал 5000-портту ээлейт, бул талаалар бирдей экендигин текшериңиз. Ошондой эле дарек эки саатка берилээрин унутпаңыз. Буйрук сабында бул Сессиянын мөөнөтү аяктайт талаасы тарабынан көзөмөлдөнөт. Убакыт бүткөндөн кийин, сиз даректи кайра алып, телеграммада каттоо proceduresасынан өтүшүңүз керек болот. Эми биз https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io линиясын алып жатабыз. пайда болгон сапты браузерге киргизип, чыкылдатыңыз. Сиз төмөнкү натыйжаны алышыңыз керек: 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);
   }
}
Эгер сиз бардыгын туура кылган болсоңуз, эми сиздин ботуңуз каалаган билдирүүгө " Салам дүйнө" деген сөз айкашы менен жооп берет . Андан кийин өз жолуң менен кете аласың. Эгерде сиз мени менен болсоңуз жана сиз бардык кадамдардан өтүүгө кызыкдар болсоңуз, анда келгиле, маалымат базасы үчүн an objectтерди жазууну баштайлы жана маалымат базасын өзү түзөлү. Берorштер базасынан баштайлы: Жогоруда айткандай, мен сизде маалымат базасы менен иштөө боюнча минималдуу көндүмдөрүңүз бар деп ойлойм жана сизде локалдык postgreSQL маалымат базасы орнотулган , эгерде жок болсо, ушул жол менен жүрүңүз. https://www.postgresql.org/download/ application.properties файлында маалымат базасынын логин менен сырсөзүн өзүңүзгө алмаштырыңыз. IDEAда оң жакта маалымат базасы өтмөгү бар, андагы +/Маалымат булагы/PostgreSQL чыкылdateу керек . Натыйжада, сиз "Тест Байланыш" баскычын чыкылдатканыңызда, сиз канааттандырарлык натыйжага ээ болушуңуз керек: Telegram боту - Java'дагы webHook аркылуу эскертме же Google календарына жок деп айт!  - 9Эми сиз түз иштеп чыгуу чөйрөсүнөн tableлар менен маалымат базасын түзө аласыз же баштоо менюсунда жайгашкан 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 менен иштөө үчүн event_cash tableсы гана керек , анткени анын өзгөчөлүктөрү жана менин Time классы менен иштөөгө болгон тойбогон каалоом ; ал жергorктүү versionда пайдалуу болбойт. Колдонуучулардын tableсында биз телеграмма колдонуучунун аккаунтунун идентификаторун , анын жок болушу мүмкүн болгон аты-жөнүн жазабыз , билдирүүлөрдү туура жөнөтүү үчүн колдонуучунун убакыт алкагы, ошондой эле билдирүүлөрдү жөнөтүүнү күйгүзүү/өчүрүү статусу эсептелет . Биз колдонуучунун идентификаторун , эскертме убактысын, сүрөттөмөсүн user_events tableсына жазабыз , окуя үчүн автоматтык түрдө идентификаторду түзөбүз жана эскертмелердин жыштыгын орнотобуз. Event_cash tableсы эскертмени жөнөтүлгөнгө чейин жазып алат жана эгер жөнөтүлсө, аны tableдан алып салат. Таблицалар даяр, эми an objectтерди кошолу.
@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 – биздин дада jpa үчүн классты белгилейт, бул класс маалымат базасы үчүн an object болуп саналат, б.а. маалымат базасынан маалыматтарды алууда, ал бизге Event, User жана EventCashEntity an objectиси түрүндө көрсөтүлөт. @Table - биз маалымат базасындагы table эмне деп аталарын айтабыз. Таблица аталышынын асты кызыл менен сызылып калбашы үчүн, биз IDEAда сунушталган катаны оңдоо опциясына макул болушубуз керек жана Маалымат булактарын дайындоо баскычын чыкылдатыңыз. Ал жерден биздин базаны тандаңыз. @id жана @GeneratedValue - Spring тарабынан, эгерде ал мурда жок болсо, маалымат базасын түзүү үчүн колдонулат. @Column, эгер алар дал келбесе, tableдагы талаалардын атын көрсөтүү үчүн колдонулат, бирок жакшы codeдун эрежелери дайыма муну жазууну сунуштайт. OneToMany мамилеси - Мен убакыт өткөрүүнү жана бул жерде анын эмне экенин түшүнүүнү сунуштайм https://en.wikibooks.org/wiki/Java_Persistence Мен муну так түшүндүрө албайм, мага ишен. Жөн эле айта кетейин, бул учурда @OneToMany annotationсында бир колдонуучу көптөгөн окуяларга ээ болушу мүмкүн экенин айтат жана алар бизге тизме түрүндө берилет. Эми биз tableлардан маалыматтарды алышыбыз керек. SRING DATA JPA китепканасында баары биз үчүн жазылган, биз жөн гана ар бир table үчүн интерфейс түзүп, аны 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>
Бул учурда бизде эч кандай маалыматтарды иштетүү жок, биз жөн гана tableлардан маалыматтарды алабыз. Биз баарыбыз 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Менюнун эки түрү бар. Терезенин ылдый жагына тиркелгендер - негизги меню жана кабарга ыйгарылгандар, мисалы, жок кылуу, өзгөртүү, кур баскычтары. Негизги меню баскычын чыкылдатканыңызда, ошол эле аталыштагы билдирүү жөнөтүлөт, мисалы, "Менин эскертүүлөрүм" дегенди басканда, жөн гана "Менин эскертүүлөрүм" тексти жөнөтүлөт . Ал эми callbackquery клавиатурасын орнотууда ар бир баскыч үчүн белгилүү бир маани коюлат жана анын мааниси экранда көрсөтүлбөстөн жөнөтүлөт. Кийинки бизде BotStateCash талаасы бар . Бул боттун абалын көзөмөлдөй турган атайын түзүлгөн класс жана көңүл бурат, бул татаал элемент, сиз чыңалуу керек. Белгилердин саны ашып кетти, демек, эч жерде жазылган эмес)). Ошентип, бул жерде экинчи бөлүккө шилтеме
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION