JavaRush /Java Blog /Random-TL /Telegram bot - paalala sa pamamagitan ng webHook sa Java ...

Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar! Bahagi 1

Nai-publish sa grupo
Ang pangalan ko ay Vladimir. Ako ay 43 taong gulang. At kung ikaw, mambabasa, ay higit sa 40, pagkatapos ay oo, pagkatapos ng 40 maaari kang maging isang programmer kung gusto mo ito. Ang aking trabaho ay walang kinalaman sa programming, ako ay isang tagapamahala ng proyekto sa larangan ng automation at lahat ng iyon. Pero pinaplano kong baguhin ang aking trabaho. Oh, itong mga bagong uso... baguhin ang iyong larangan ng aktibidad tuwing 5-7 taon. Kaya : Ang proyekto ay naging medyo malaki, kaya ang ilang mga punto ay kailangang alisin o pag-usapan sa madaling sabi, sa pag-asang ang mambabasa ay marunong mag-Google. Ang Internet ay puno ng mga publikasyon ng telegram bots na gumagana sa prinsipyo ng Long polling. At kakaunti ang gumagana sa prinsipyo ng Webhook. Ano ito? Mahabang botohan - nangangahulugan ito na ang iyong application mismo ang magpo-poll sa telegram server para sa mga mensahe sa isang tiyak na dalas, nang dahan-dahan. Webhook - nangangahulugan na ang telegram server ay agad na magre-redirect ng mga mensahe sa server na iyong tinukoy. Sa aming kaso, kagandahang-loob ng serbisyo ng Heroku. Maaari mong, siyempre, magbasa nang higit pa tungkol sa lahat ng ito at tungkol sa bot sa pangkalahatan sa website ng Telegram - https://tlgrm.ru/docs/bots/api Ang interface ng bot ay ganito: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 1 Itinuturing kong tumpak ang application na ito bilang isang pagsasanay proyekto sa kadahilanang kapag nagsusulat ako ay natutunan ko ang higit pang impormasyon mula sa bot na ito kaysa noong nagsasanay. Gusto mo bang matutong magprograma? Simulan ang pagsusulat ng code!!! Ngunit! Walang mga detalyadong tagubilin kung paano i-upload ang application sa github o kung paano gumawa ng database. Mayroong maraming nito sa Internet at ito ay inilarawan sa mahusay na detalye, bukod pa, ito ay magiging isang napakahabang pagbabasa. Ang application ay gagana tulad ng sumusunod: Magpasok ng isang paglalarawan ng kaganapan, ilagay ang petsa at oras ng kaganapan, piliin ang dalas (maaari mong gawin ito nang isang beses, maaari kang magkaroon ng isang paalala araw-araw sa isang tiyak na oras, maaari mo itong gawin nang isang beses isang buwan sa isang tiyak na oras, o isang beses sa isang taon). Ang mga pagkakaiba-iba ng mga abiso ay maaaring idagdag nang walang katapusang; Mayroon akong maraming mga ideya. Susunod, ang inilagay na data ay nai-save sa database (na-deploy din nang libre sa Heroku, 10,000 row ang libre) Pagkatapos, isang beses sa simula ng araw sa 0:00 na oras ng server, kinukuha ng Spring mula sa database ang lahat ng mga kaganapan batay sa pamantayan na dapat sunog sa araw na iyon at ipadala ang mga ito para sa pagpapatupad sa tinukoy na oras. PANSIN!!! EKSPERIMENTAL ANG BAHAGI NA ITO NG PROGRAMA! MAY IMPLEMENTASYON NA MAS SIMPLE AT TOTOO! ITO AY SPECIFICAL NA GINAWA UPANG MAKITA KUNG PAANO GUMAGANA ANG TIME CLASS! Maaari mong hawakan ang gumaganang bot gamit ang iyong sariling mga kamay sa pamamagitan ng pag-type ng @calendar_event_bot sa cart, ngunit huwag umasa dito, dahil pinagtatawanan ko pa rin ito. code - https://github.com/papoff8295/webHookBotForHabr Karaniwan, upang mailunsad ang iyong sarili kailangan mong gawin ang mga sumusunod na hakbang: • Magrehistro sa @BotFather , hindi ito mahirap, kumuha ng token at pangalan • I-fork ang proyekto sa github • Magrehistro kay Heroku, lumikha ng isang application (dadaanan namin ito nang sunud-sunod), i-deploy mula sa iyong repository. • Lumikha ng database sa Heroku • Palitan ang mga kaukulang field sa repositoryo ng sarili mong (token, pangalan ng mga talahanayan sa mga entity, webHookPath, user name, password at path sa database, lahat ito ay ma-parse) • Gawing gumana ang Heroku 24/ 7 gamit ang https:/ /uptimerobot.com/ Ang huling istraktura ng proyekto ay ang mga sumusunod: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 2 Magsimula tayo sa pamamagitan ng paglikha ng isang proyekto sa https://start.spring.io Piliin ang mga dependency na kailangan natin tulad ng ipinapakita sa figure: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 3Piliin ang sarili natin pangalan para sa proyekto at i-click ang Bumuo . Susunod na sasabihan ka upang i-save ang proyekto sa iyong disk. Ang natitira na lang ay buksan ang pom.xm l file mula sa iyong development environment. May isang natapos na proyekto sa harap mo. Ngayon kailangan lang naming idagdag ang aming pangunahing aklatan. Ginamit ko ang library mula sa https://github.com/rubenlagus/TelegramBots Sa pangkalahatan, maaari kang malito at magawa nang wala ito. Pagkatapos ng lahat, ang buong punto ng trabaho ay upang pagsamahin ang isang URL na tulad nito: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.s look at it a little Let's look at it a little. : https://api.telegram.org – server ng telegrama. bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - pagkatapos ng salitang bot ay isang lihim na token na natatanggap mo kapag nagrerehistro ng bot. setWebhook?url=https://e9c658b548aa.ngrok.io – pangalan ng pamamaraan at mga parameter nito. Sa kasong ito, ini-install namin ang iyong webhook server, lahat ng mensahe ay ipapadala dito. Sa pangkalahatan, napagpasyahan ko na ang proyekto ay hindi masyadong maliit para sa paglalathala, ngunit sa manu-manong pagpapatupad ito ay karaniwang hindi nababasa. Kaya, ang huling hitsura ng pom file ay:
<!--?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>
Handa na ang lahat para isulat ang aming bot. Gawin natin ang klase ng TelegramBot . Hindi ko isusulat ang mga pangalan ng mga folder, maaari mong tingnan ang mga ito sa istraktura ng proyekto sa itaas.
@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);
    }
}
Pinapalawak ng klase ang SpringWebhookBot mula sa aming telegram library, at kailangan lang naming ipatupad ang isang paraan, onWebhookUpdateReceived . Tinatanggap nito ang naka-parse na JSON bilang isang bagay na Update at ibinabalik kung ano ang gustong "marinig" ng telegram server mula sa amin. Narito mayroon kaming mga anotasyon mula sa aklatan ng Lombok . Lombok – pinapadali ang buhay ng isang programmer!! Well, iyon ay. hindi namin kailangang muling tukuyin ang mga getter at setter, ginagawa ito ng Lombok para sa amin, at hindi rin namin kailangang magsulat ng identifier ng antas ng pag-access. Hindi na sulit na isulat na ito ay ginagawa ng mga anotasyong @Getter, @Setter, @FieldDefaults Ang patlang ng botPath ay nangangahulugang ang aming webhook address, na matatanggap namin sa Heroku sa ibang pagkakataon. Ang patlang ng botUsername ay nangangahulugang ang pangalan ng aming bot, na matatanggap namin kapag nirerehistro ang aming bot sa Telegram. Ang botToken field ay ang aming token, na matatanggap namin kapag nirerehistro ang aming bot sa Telegram. Ang field ng telegramFacade ay ang aming klase kung saan magaganap ang pagpoproseso ng mensahe, babalikan namin ito mamaya, hayaan itong maging pula sa ngayon. Ngayon ay oras na para makipag-ugnayan tayo sa @BotFather at makuha ang hinahangad na botToken at botUsername. Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 4Sumulat ka lang sa kanya sa telegram at sasabihin niya sa iyo ang lahat. Isinulat namin ang data sa aming application.properties, sa huli magiging ganito ang hitsura:
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
Ang pagsasaayos na ito ay na-configure upang gumana sa isang lokal na database; mamaya ay gagawin namin ang mga kinakailangang pagbabago. Palitan ang botToken at username ng iyong sarili. Hindi magandang gumamit ng data mula sa application.properties nang direkta sa application. Gumawa tayo ng bean o klase ng wrapper mula sa data na ito.
@Component
@Getter
@FieldDefaults(level = AccessLevel.PRIVATE)

public class TelegramBotConfig {
    @Value("${telegrambot.webHookPath}")
    String webHookPath;
    @Value("${telegrambot.userName}")
    String userName;
    @Value("${telegrambot.botToken}")
    String botToken;
Dito pinasimulan ng @Value annotation ang mga kaukulang linya mula sa application.properties file, na alam ng Spring bilang default. At ang @Component annotation ay lumilikha ng Bean para sa amin kapag nagsimula ang application. Tingnan natin ngayon ang Spring configuration file:
@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;
    }
}
Walang magic dito; sa pagsisimula, ang Spring ay gumagawa ng mga bagay na SetWebhook at TelegramBot para sa amin. Gumawa tayo ngayon ng mga entry point para sa ating mga mensahe:
@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();
    }
}
Ang Telegram server ay nagpapadala ng mga mensahe sa JSON format sa nakarehistrong webhook address gamit ang POST method, tinatanggap ng aming controller ang mga ito at ipinapadala ang mga ito sa telegram library sa anyo ng isang Update object. Ginawa ko ang paraan ng pagkuha ng ganoon lang) Ngayon kailangan lang nating magpatupad ng ilang lohika para sa pagproseso ng mga mensahe at mga tugon sa klase ng TelegramFacade , ibibigay ko ang maikling code nito upang mailunsad mo ang application at pagkatapos ay pumunta sa iyong sariling paraan o lumipat sa pag-deploy sa Heroku, pagkatapos ito ay magiging buong bersyon:
@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;
    }

}
Ang pamamaraang ito ay tutugon sa anumang Hello world! Upang mailunsad ang aming aplikasyon, kailangan lang naming tiyakin na maaari naming subukan ang aming aplikasyon nang direkta mula sa IDEA. Upang gawin ito kailangan naming i-download ang ngrok utility. https://ngrok.com/download Ang utility na ito ay isang command line na nagbibigay sa amin ng pansamantalang address sa loob ng 2 oras at nire-redirect ang lahat ng mensahe sa tinukoy na port ng lokal na server. Naglulunsad kami at nagsusulat ng ngrok http 5000 sa linya (o maaari mong tukuyin ang iyong port): Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 5Nakukuha namin ang resulta: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 6https://23b1a54ccbbd.ngrok.io - ito ang aming webhook address. Tulad ng maaaring napansin mo sa file ng mga katangian na isinulat namin sa server.port=5000 noong sinimulan ang server ng tomcat, sasakupin nito ang port 5000, siguraduhing pareho ang mga field na ito. Gayundin, huwag kalimutan na ang address ay ibinigay sa loob ng dalawang oras. Sa command line, ito ay sinusubaybayan ng field ng Session Expires. Kapag naubos na ang oras, kakailanganin mong kunin muli ang address at dumaan sa pamamaraan ng pagpaparehistro nito sa telegrama. Ngayon ang linya ay https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io At sa maliksi na paggalaw ng kamay ay pinapalitan namin ang token ng sa amin, i-paste ang token ng sa amin ang resultang linya sa browser at i-click ang enter. Dapat mong makuha ang sumusunod na resulta: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 7Iyon lang, maaari mo na ngayong patakbuhin ang application: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 8Suriin na ang iyong klase na may pangunahing pamamaraan ay ganito:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
Kung ginawa mo nang tama ang lahat, ngayon ay tutugon ang iyong bot sa anumang mensahe gamit ang pariralang “ Hello world” . Pagkatapos ay maaari kang pumunta sa iyong sariling paraan. Kung ikaw ay kasama ko at interesado kang dumaan sa lahat ng mga hakbang, simulan natin ang pagsulat ng mga entity para sa database at likhain ang database mismo. Magsimula tayo sa database: Gaya ng nasabi ko na, ipinapalagay ko na mayroon ka nang kaunting mga kasanayan sa pagtatrabaho sa database, at mayroon kang naka-install na lokal na database ng postgreSQL , kung hindi, sundin ang landas na ito. https://www.postgresql.org/download/ Sa application.properties file, palitan ang database login at password ng iyong sarili. Sa IDEA mayroong isang tab ng database sa kanan, dito kailangan mong mag-click sa +/Data source/PostgreSQL . Bilang resulta, kapag nag-click ka sa Test Connection dapat kang makakuha ng isang kasiya-siyang resulta: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 9Ngayon ay maaari kang lumikha ng isang database na may mga talahanayan nang direkta mula sa development environment, o maaari mong gamitin ang pgadmin web interface , na matatagpuan sa start menu. Kakailanganin namin ang 3 talahanayan:
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
);
Inirerekomenda ko ang paglikha ng script na ito nang hiwalay; kakailanganin namin ito upang lumikha ng isang database sa Heroku, upang hindi ito maisulat nang dalawang beses. Maglakad tayo ng kaunti. Sasabihin ko kaagad na kailangan lang namin ang event_cash table para gumana kay Heroku dahil sa mga detalye nito at ang aking walang kasiyahang pagnanais na magtrabaho kasama ang Time class ; hindi ito magiging kapaki-pakinabang sa lokal na bersyon. Sa talahanayan ng mga gumagamit , itatala namin ang id ng account ng gumagamit ng telegrama, ang kanyang pangalan, na maaaring hindi umiiral, ang time zone ng gumagamit ay kakalkulahin para sa tamang pagpapadala ng mga abiso, pati na rin ang on/off status ng pagpapadala ng mga abiso. Itatala namin ang user id , oras ng notification, paglalarawan sa talahanayan ng user_events , awtomatikong bubuo ng id para sa kaganapan, at itatakda ang dalas ng mga notification. Ire-record ng event_cash table ang notification bago ito ipadala at, kung ipinadala, alisin ito sa table. Handa na ang mga talahanayan, idagdag natin ngayon ang mga entity.
@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;
    }
}
Balikan natin nang kaunti ang mga pangunahing punto. @Entity – minarkahan ang klase para sa aming dada jpa na ang klase na ito ay isang entity para sa database, ibig sabihin. kapag kinukuha ang data mula sa database, ipapakita ito sa amin sa anyo ng object ng Event, User at EventCashEntity. @Table – sinasabi namin ang pangalan ng aming table sa database. Upang matiyak na ang pangalan ng talahanayan ay hindi nakasalungguhit sa pula, kailangan naming sumang-ayon sa IDEA sa iminungkahing opsyon sa pagwawasto ng error at i-click ang Magtalaga ng mga mapagkukunan ng data. At piliin ang aming base doon. @id at @GeneratedValue - ginagamit ng Spring para gumawa ng database kung wala pa ito. Ginagamit ang @Column upang ipahiwatig ang pangalan ng mga patlang sa talahanayan kung hindi magkatugma ang mga ito, ngunit inirerekomenda ng mga panuntunan ng magandang code na palagi mong isulat ito. OneToMany saloobin - Inirerekomenda ko ang paggugol ng oras at pag-alam kung ano ito dito https://en.wikibooks.org/wiki/Java_Persistence Hindi ko ito maipaliwanag nang mas malinaw, maniwala ka lang sa akin. Sabihin ko lang na sa kasong ito ang @OneToMany annotation ay nagsasabi na ang isang user ay maaaring magkaroon ng maraming kaganapan, at ibibigay ang mga ito sa amin sa anyo ng isang listahan. Ngayon kailangan nating kumuha ng data mula sa mga talahanayan. Sa SRING DATA JPA library lahat ay nakasulat na para sa atin, kailangan lang nating gumawa ng interface para sa bawat table at i-extend ito mula sa 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,>
Ang pangunahing lohika para sa pagtatrabaho sa database ay inilipat sa isang serbisyo, ang tinatawag na 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>
Sa kasong ito, wala kaming anumang pagproseso ng data, kinukuha lang namin ang data mula sa mga talahanayan. Handa kaming lahat na ibigay ang kumpletong code ng klase ng T elegramFacade at magsimulang suriin ang lohika.
@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);

    }
}
Tingnan natin kung anong mga patlang ang kailangan
final MessageHandler messageHandler;
    final CallbackQueryHandler callbackQueryHandler;
    final BotStateCash botStateCash;
Kung lahat tayo ay nagko-code sa isang klase, magkakaroon tayo ng footcloth sa buwan; samakatuwid, itinatalaga natin ang logic para sa pagtatrabaho sa mga text message sa MessageHandler class , at ang logic para sa pagtatrabaho sa mga callbackquery message sa CallbackQueryHandler class . Oras na para malaman kung ano ang allbackquery at kung anong mga uri ng menu ang mayroon. Upang gawin ito, bibigyan kita ng isa pang larawan ng interface ng bot: Telegram bot - paalala sa pamamagitan ng webHook sa Java o tumanggi sa Google calendar!  - 10Mayroong dalawang uri ng mga menu. Ang mga naka-attach sa ibaba ng window - ang pangunahing menu, at ang mga itinalaga sa mensahe, halimbawa, ang tanggalin, i-edit, baguhin ang mga pindutan ng sinturon. Kapag nag-click ka sa pindutan ng pangunahing menu, isang mensahe ng parehong pangalan ang ipapadala, halimbawa, kapag na-click mo ang "Aking Mga Paalala" , ang tekstong "Aking Mga Paalala" ay ipapadala lamang . At kapag nag-i-install ng callbackquery keyboard, isang partikular na halaga ang itinakda para sa bawat button at ang halaga nito ay ipapadala nang hindi ito ipinapakita sa screen. Susunod ay mayroon kaming BotStateCash field . Ito ay isang espesyal na nilikha na klase na susubaybayan ang estado ng bot, at pansin, ito ay isang kumplikadong elemento, kailangan mong pilitin. Ang bilang ng mga character ay nalampasan, na, sa pamamagitan ng paraan, ay hindi nakasulat kahit saan)). Kaya eto ang link ng part two
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION