JavaRush /Java Blog /Random-TW /Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不!第1部分
Vladimir Popov
等級 41

Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不!第1部分

在 Random-TW 群組發布
我的名字是弗拉基米爾。我今年43歲。讀者,如果你已經超過 40 歲了,那麼是的,40 歲以後你可以成為一名程式設計師,如果你願意的話。我的工作與程式設計完全無關,我是自動化領域的專案經理等。但我正計劃改變我的職業。哦,這些新趨勢......每 5-7 年改變一次您的活動領域。 所以:這個項目相當大,所以有些地方必須省略或簡單地談一下,希望讀者知道如何谷歌。網路上充斥著根據長輪詢原理工作的電報機器人的出版品。而按照Webhook原理工作的卻很少。這是什麼? 長輪詢- 這意味著您的應用程式本身將以一定的頻率緩慢地輪詢電報伺服器以獲取訊息。 Webhook - 表示電報伺服器將立即將訊息重新導向到您指定的伺服器。在我們的例子中,這是由 Heroku 服務提供的。當然,您可以在 Telegram 網站上閱讀有關所有這些以及有關機器人的更多資訊 - https://tlgrm.ru/docs/bots/api 機器人介面如下所示:我認為 Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 1 這個應用程式正是作為一個訓練項目的原因是在寫作時我從這個機器人中學到了比訓練時更多的資訊。你想學習程式設計嗎?開始寫程式!!!但!不會有關於如何將應用程式上傳到 github 或如何建立資料庫的詳細說明。網路上有很多這樣的內容,並且描述得很詳細;此外,這將是一個很長的閱讀過程。應用程式的工作方式如下:輸入事件的描述,輸入事件的日期和時間,選擇頻率(您可以執行一次,您可以每天在某個時間提醒,您可以執行一次每月的某個時間,或每年一次)。通知的變體可以無限添加;我有很多想法。接下來,輸入的資料被保存到資料庫中(在 Heroku 上也是免費部署的,10,000 行是免費的)然後,在伺服器時間 0:00 的一天開始時,Spring 根據條件從資料庫中檢索所有事件應該在那天觸發並在指定時間發送它們執行。注意力!!!該計劃的這一部分是實驗性的!有一個更簡單、更真實的實作!這樣做是專門為了了解時間類別是如何運作的!您可以透過在購物車中輸入 @calendar_event_bot 來親手觸摸工作機器人,但不要指望它,因為我仍在取笑它。程式碼 - https://github.com/papoff8295/webHookBotForHabr 基本上,要啟動自己的項目,您需要執行以下步驟: • 向@BotFather註冊,這並不難,獲取令牌和名稱• 在github 上分叉此項目• 註冊在Heroku,建立一個應用程式(我們將逐步完成它),從您的儲存庫進行部署。• 在Heroku 上建立資料庫• 將儲存庫中的對應欄位替換為您自己的欄位(令牌、實體中資料表的名稱、webHookPath、使用者名稱、密碼和資料庫路徑,這些都會被解析) • 讓Heroku 運作24/ 7 使用https://uptimerobot.com/ 專案的最終結構如下: Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 2 首先我們在https://start.spring.io中建立一個專案選擇我們需要的依賴如圖: Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 3選擇我們自己的為專案命名並按一下“生成”。然後系統將提示您將項目儲存到磁碟。剩下的就是從開發環境中開啟pom.xml檔。您面前有一個已完成的項目。現在我們只需要新增我們的主庫。我使用了https://github.com/rubenlagus/TelegramBots中的函式庫 一般來說,您可能會感到困惑並且不需要它。畢竟,工作的全部要點就是連接這樣的 URL: https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548api.ngrok.io 讓我們稍微看一下 https .telegram.org – 電報伺服器。 bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - bot 一詞後面是您在註冊機器人時收到的秘密令牌。 setWebhook?url=https://e9c658b548aa.ngrok.io – 方法的名稱及其參數。在這種情況下,我們安裝您的 webhook 伺服器,所有訊息都會傳送到它。總的來說,我認為該項目對於發布來說並不算太小,但如果手動實現,它通常會難以閱讀。所以, pom檔的最終樣子是:
<!--?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作為 Update 對象,並返回電報伺服器想要從我們那裡「聽到」的內容。這裡我們有來自Lombok庫的註解。Lombok – 讓程式設計師的生活更輕鬆!嗯,就是這樣。我們不需要重新定義 getter 和 setter,Lombok 為我們做了這件事,而且我們也不需要編寫存取等級識別碼。不再值得寫的是,這是透過註解@Getter、@Setter、@FieldDefaults完成的。botPath 欄位表示我們的 webhook 地址,稍後我們將在 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 中的資料並不好。讓我們根據這些資料建立一個 bean 或一個包裝類別。
@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 註解初始化 application.properties 檔案中的對應行,Spring 預設情況下知道該檔案。並且@Component註解會在應用程式啟動時為我們建立一個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 伺服器使用 POST 方法將 JSON 格式的訊息傳送到已註冊的 webhook 位址,我們的控制器接收它們並以 Update 物件的形式將它們傳送到 telegram 程式庫。我就是這樣做的 get 方法)現在我們只需要在TelegramFacade類中實現一些處理消息和響應的邏輯,我將給出它的簡短代碼,以便您可以啟動應用程序,然後走自己的路或切換到部署在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;
    }

}
此方法將回應任何 Hello world! 為了啟動我們的應用程序,我們只需要確保我們可以直接從 IDEA 測試我們的應用程式。為此,我們需要下載 ngrok 實用程式。https://ngrok.com/download 這個實用程式是一個命令列,為我們提供了 2 小時的臨時位址,並將所有訊息重新導向到本地伺服器的指定連接埠。我們啟動並在行中寫入ngrok http 5000(或您可以指定您的連接埠): Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 5我們得到結果: https: Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 6//23b1a54ccbbd.ngrok.io - 這是我們的 webhook 位址。你可能已經注意到,在啟動tomcat伺服器時,我們在屬性檔案中寫入了server.port=5000,它將佔用5000端口,請確保這些欄位相同。另外,不要忘記該地址的有效期為兩個小時。在命令列上,這由「會話過期」欄位進行監控。當時間用完時,您將需要再次獲取地址並完成在電報上註冊的過程。現在我們採取https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io 行並透過靈活的手部動作,我們將透過靈活的手部令牌,我們將透過靈活的手部令牌來替換替換為我們的,貼上將結果行輸入瀏覽器並點擊 Enter。您應該得到以下結果: Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 7就是這樣,現在您可以執行該應用程式: Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 8檢查您的類別的main方法是否如下所示:
@SpringBootApplication
public class TelegramBotApplication {

   public static void main(String[] args) {
      SpringApplication.run(TelegramBotApplication.class, args);
   }
}
如果您所做的一切正確,現在您的機器人將用短語“ Hello world” 回應任何訊息。然後你就可以走自己的路了。如果您和我一樣並且有興趣完成所有步驟,那麼讓我們開始為資料庫編寫實體並建立資料庫本身。讓我們從資料庫開始:正如我已經說過的,我假設您已經具備了使用資料庫的最低技能,並且安裝了本地postgreSQL資料庫,如果沒有,請按照此路徑操作。https://www.postgresql.org/download/ 在 application.properties 檔案中,將資料庫登入名稱和密碼替換為您自己的。在IDEA中,右側有一個資料庫選項卡,您需要在其中按一下+/Data source/PostgreSQL。因此,當您按一下「測試連線」時,您應該會得到滿意的結果: Telegram 機器人 - 透過 Java 中的 webHook 提醒或對 Google 日曆說不! - 9現在您可以直接從開發環境建立具有表格的資料庫,或者您可以使用位於開始功能表中的pgadmin Web 介面。我們需要 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 上建立資料庫,以免寫兩次。我們走一會兒吧。我會立即說,由於它的具體情況以及我對使用Time類的無盡渴望,我們只需要event_cash表即可與 Heroku 一起使用;它在本地版本中沒有用處。在users表中,我們將記錄telegram 使用者的帳戶ID、姓名(可能不存在)、將計算使用者的時區以正確發送通知,以及發送通知的開/關狀態。我們將在user_events表中記錄使用者id 、通知時間、描述,自動產生事件的id,並設定通知的頻率。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 和 @GenerateValue - Spring 使用它來建立資料庫(如果資料庫尚不存在)。 @Column用於指示表中欄位的名稱(如果它們不符合),但良好程式碼的規則建議您始終這樣寫。OneToMany態度- 我建議花時間弄清楚它是什麼在這裡 https://en.wikibooks.org/wiki/Java_Persistence 我無法更清楚地解釋它,請相信我。我只想說,在這種情況下,@OneToMany註釋表示一個用戶可以有多個事件,並且它們將以列表的形式提供給我們。現在我們需要從表格中取得資料。在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,>
使用資料庫的主要邏輯被轉移到服務,即所謂的資料存取對象(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類別的完整程式碼並開始分析邏輯了。
@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;
如果我們都在一個類別中編寫程式碼,那麼我們最終會得到一塊登上月球的腳布;因此,我們將處理文字訊息的邏輯分配給 MessageHandler類,並將處理回調查詢訊息的邏輯分配CallbackQueryHandler類別。是時候弄清楚allbackquery是什麼以及有哪些類型的菜單了。為此,我將為您提供另一張機器人介面的圖片: Telegram bot — напоминалка через webHook на Java or скажи нет Google-календарю! - 10有兩種類型的菜單。那些附加到視窗底部的主選單,以及那些指派給訊息的按鈕,例如刪除、編輯、更改帶按鈕。當您按一下主選單按鈕時,會傳送一條同名訊息,例如,當您按一下「我的提醒」時,只會傳送文字「我的提醒」。並且在安裝callbackquery鍵盤時,會為每個按鈕設定一個特定值,並將發送該值而不將其顯示在螢幕上。接下來我們有BotStateCash字段。這是一個專門創建的類,它將監視機器人的狀態,注意,這是一個複雜的元素,你需要緊張。超出了字元數,順便說一下,任何地方都沒有寫))。這是第二部分的鏈接
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION