JavaRush /Java Blog /Random-JA /Telegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダ...
Vladimir Popov
レベル 41

Telegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダーに「ノー」と伝えます。パート1

Random-JA グループに公開済み
私の名前はウラジミールです。私は43歳です。そして、読者のあなたが 40 歳を超えているなら、そうです、40 歳を過ぎても、その気があればプログラマーになれるのです。私の仕事はプログラミングとは全く関係なく、自動化などの分野のプロジェクトマネージャーです。しかし、私は職業を変えるつもりです。ああ、これらの新しいトレンド… 5 ~ 7 年ごとに活動分野が変わります。 So : このプロジェクトは非常に大規模であることが判明したため、読者が Google の方法を知っていることを期待して、いくつかの点を省略するか、簡単に説明する必要があります。インターネットには、ロング ポーリングの原理に基づいて動作する電報ボットの出版物が溢れています。そして、Webhook の原則に基づいて機能するものはほとんどありません。それは何ですか? ロングポーリング- これは、アプリケーション自体が特定の頻度でゆっくりと電報サーバーにメッセージをポーリングすることを意味します。 Webhook - 電報サーバーがメッセージを指定したサーバーに即座にリダイレクトすることを意味します。私たちの場合は、Heraku サービスのおかげです。もちろん、これらすべてとボット全般について詳しくは、Telegram Web サイト - https://tlgrm.ru/docs/bots/api で読むことができます。 ボットのインターフェイスは次のようになります。 Telegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダーに「ノー」と伝えます。 - 1 私はこのアプリケーションをまさにトレーニングと考えています。理由は、トレーニング時よりも執筆時にこのボットからより多くの情報を学んだためです。プログラミングを学びたいですか? コードを書き始めましょう!!! しかし!アプリケーションを github にアップロードする方法やデータベースを作成する方法については、詳細な説明はありません。これについてはインターネット上にたくさんあり、詳細に説明されていますが、非常に長く読む必要があります。アプリケーションは次のように機能します: イベントの説明を入力し、イベントの日付と時刻を入力し、頻度を選択します (1 回だけ実行することも、毎日特定の時間にリマインダーを送信することも、1 回だけ実行することもできます)毎月の特定の時期、または年に 1 回)。通知のバリエーションは無限に追加できるので、アイデアはたくさんあります。次に、入力されたデータがデータベースに保存されます (これも Heroku に無料でデプロイされ、10,000 行が無料です)。その後、その日の始まり、サーバー時間の 0:00 に一度、Spring が基準に基づいてデータベースからすべてのイベントを取得します。これはその日に起動され、指定された時間に実行のために送信されます。注意!!!プログラムのこの部分は実験的なものです。よりシンプルで正確な実装があります。これは、特に TIME クラスがどのように機能するかを確認するために行われました。カートに @calendar_event_bot と入力すると、動作するボットに自分の手で触れることができますが、まだからかっているので当てにしないでください。コード - https://github.com/papoff8295/webHookBotForHabr 基本的に、独自のものを起動するには、次の手順を実行する必要があります。 • @BotFatherに登録します。難しいことではありません。トークンと名前を取得します。 • github でプロジェクトをフォークします。 • 登録します。Heroku上で、アプリケーションを作成し (段階的に説明します)、リポジトリからデプロイします。• Heroku 上にデータベースを作成します。 • リポジトリ内の対応するフィールドを独自のフィールドに置き換えます (トークン、エンティティ内のテーブルの名前、webHookPath、ユーザー名、パスワード、データベースへのパス、これらはすべて解析されます) • Heroku を 24 時間稼働させる/ 7 using 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://e9c658b548aa.ngrok.io 少し見てみましょう。 : https://api.telegram.org – 電報サーバー。 bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/ - bot という単語の後ろは、ボットの登録時に受け取る秘密のトークンです。 setWebhook?url=https://e9c658b548aa.ngrok.io – メソッドとそのパラメータの名前。この場合、Webhook サーバーがインストールされ、すべてのメッセージがそこに送信されます。一般的に、プロジェクトは公開するには小さすぎるわけではないが、手動で実装すると通常は読めなくなるだろうと判断しました。したがって、 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 を拡張したもので、実装する必要があるのは 1 つのメソッド ( onWebhookUpdateReceived )のみです。解析されたJSON をUpdate オブジェクトとして受け入れ、テレグラム サーバーが私たちから「聞きたい」ことを返します。ここにはLombokライブラリからの注釈があります。ロンボク島– プログラマーの生活を楽にします!! そうです。ゲッターとセッターを再定義する必要はありません。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 アノテーションは、Spring がデフォルトで認識している application.properties ファイルの対応する行を初期化します。@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 メソッドを使用して、登録された Webhook アドレスに JSON 形式でメッセージを送信します。コントローラーはそれを受信し、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結果が得られます: Telegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダーに「ノー」と伝えます。 - 6https://23b1a54ccbbd.ngrok.io - これは Webhook アドレスです。お気づきかと思いますが、Tomcat サーバーの起動時にプロパティ ファイルに server.port=5000 と記述しました。このサーバーはポート 5000 を占有します。これらのフィールドが同じであることを確認してください。また、演説時間は2時間であることを忘れないでください。コマンド ラインでは、これは [セッションの有効期限] フィールドによって監視されます。期限が切れた場合は、再度アドレスを取得して電報に登録する手続きが必要となります。次に、 https://api.telegram.org/bot1866835969:AAE6gJG6ptUyqhV2XX0MxyUak4QbAGGnz10/setWebhook?url=https://e9c658b548aa.ngrok.io という行を取得し、巧みな手の動きでトークンを私たちのものに、URL を私たちのものに置き換え、ペーストします。結果の行をブラウザに入力し、Enter をクリックします。次の結果が得られるはずです: Telegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダーに「ノー」と伝えます。 - 7これで、アプリケーションを実行できるようになります: mainTelegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダーに「ノー」と伝えます。 - 8メソッドを含むクラスが次のようになっていることを確認してください:
@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 でデータベースを作成するために必要になるため、2 回書かないようにするため、個別に作成することをお勧めします。少し歩きましょう。すぐに言っておきますが、 event_cashテーブルは、その仕様とTimeクラスを操作したいという私の飽くなき欲求のため、 Heroku で操作するには必要なだけであり、ローカル バージョンでは役に立ちません。ユーザーテーブルには、テレグラム ユーザーのアカウントのID、名前 (存在しない可能性があります)、ユーザーのタイム ゾーンが通知を正しく送信するために計算され、通知送信のオン/オフステータスが記録されます。ユーザーID 、通知時刻、説明をuser_eventsテーブルに記録し、イベントの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 と @GeneratedValue - データベースが存在しない場合に Spring によってデータベースを作成するために使用されます。 @Column は、テーブル内のフィールドが一致しない場合にフィールドの名前を示すために使用されますが、優れたコードの規則により、常にこれを記述することが推奨されます。OneToMany の態度- 時間をかけて、それが何であるかを理解することをお勧めします https://en.wikibooks.org/wiki/Java_Persistence これ以上明確に説明することはできませんが、信じてください。この場合、@OneToManyアノテーションは、1 人のユーザーが多数のイベントを持つことができ、それらはリストの形式で提供されることを示しているとだけ言っておきます。次に、テーブルからデータを取得する必要があります。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>
この場合、データ処理は行わず、単にテーブルからデータを取得します。これで、 TelegramFacadeクラスの完全なコードを提供し、ロジックの分析を開始する準備が整いました。
@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;
全員が 1 つのクラスでコードを作成すると、結局は足布を着た状態になってしまうため、テキスト メッセージを処理するロジックを MessageHandler クラスに割り当て、コールバッククエリ メッセージを処理するロジックをCallbackQueryHandlerクラスに割り当てます。allbackquery とは何なのか、そしてどのような種類のメニューがあるのか​​を理解しましょう。これを行うために、ボットのインターフェイスの別の図を示します。 Telegram ボット - Java の WebHook 経由でリマインダーを送信するか、Google カレンダーに「ノー」と伝えます。 - 10メニューには 2 種類があります。ウィンドウの下部に関連付けられているもの - メイン メニュー、およびメッセージに割り当てられているもの (削除、編集、ベルトの変更ボタンなど)。メイン メニュー ボタンをクリックすると、同じ名前のメッセージが送信されます。たとえば、「My Reminders」をクリックすると、 「My Reminders」というテキストが送信されます。また、callbackquery キーボードをインストールすると、各ボタンに特定の値が設定され、その値は画面に表示されずに送信されます。次に、 BotStateCashフィールドがあります。これはボットの状態を監視する特別に作成されたクラスですが、これは複雑な要素であるため、注意が必要です。文字数を超えましたが、ちなみに、それはどこにも書かれていません))。パート 2へのリンクはこちらです
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION