親愛なる皆さん、こんにちは。つまり、ボットはすでに動作しており、新しい記事に関する通知を送信しています。まだ使用していない場合は、リンクはJavarush Telegram Botです。さて、今日は管理者のみに機能するコマンドの追加について説明します。これらのコマンドの 1 つは、統計とヘルプ ボードです。なぜこれが必要なのでしょうか? 現時点では、実際の必要性よりも、このタスクの枠組み内で注釈を使用して作業を説明する方が興味深いです。そうですね、私たちは統計チームに行くので、それを拡張してより有益なものにすることができます。MVP の後は、たとえば作成者の統計を返すことができるようになります。ただし、それについては後で詳しく説明します...)
いいね!」 - 購読 - ベル、私たちのプロジェクトにスターを付け、コメントして記事を評価してください。次の記事でお会いしましょう!
管理者とそのコマンドの追加について理解しましょう
メイン ブランチを更新し、それに基づいて新しいブランチ STEP_9_JRTB-10 を作成することから作業を開始します。どのコマンドが管理者に適用され、どのコマンドが全員に適用されるかを判断するには、コマンドにラベルを付ける必要があります。これを行うには、アノテーションを作成しましょう。それはどういう意味ですか?これまでにこれを行ったことはありません。IDEAでクラスを作成する際に選択できます。今からお見せします。コマンド パッケージで、新しいアノテーションパッケージを作成し、その中に AdminCommand アノテーションを作成します。アノテーション自体は次のようになります。package com.github.javarushcommunity.jrtb.command.annotation;
import com.github.javarushcommunity.jrtb.command.Command;
import java.lang.annotation.Retention;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
/**
* Mark if {@link Command} can be viewed only by admins.
*/
@Retention(RUNTIME)
public @interface AdminCommand {
}
ここには他に何も必要ありません。次に、これを StatCommand コマンドに追加します。これですべてが機能するはずです...それともうまくいかないでしょうか? いいえ、もちろん)) CommandContainer に結果を正しく生成するように教える必要があります。これを行うには、渡された内容に応じて実行するコマンドを発行するretrieveCommandメソッドを更新しましょう。Telegram では彼のユーザー名を管理者識別子として使用します。chat_id よりもユニークで読みやすいです。入手方法は?これは Update オブジェクト内にあり、次のメッセージが表示されます。
update.getMessage().getFrom().getUserName()
上記をすべて要約して、CommandContainer#retrieveCommandメソッドを更新しましょう。
public Command retrieveCommand(String commandIdentifier, String username) {
Command orDefault = commandMap.getOrDefault(commandIdentifier, unknownCommand);
if (isAdminCommand(orDefault)) {
if (admins.contains(username)) {
return orDefault;
} else {
return unknownCommand;
}
}
return orDefault;
}
private boolean isAdminCommand(Command command) {
return nonNull(command.getClass().getAnnotation(AdminCommand.class));
}
ここでわかるように、指定されたコマンドに AdminCommand アノテーションがあるかどうかをチェックするisAdminCommandメソッドを追加しました。また、それが管理者専用コマンドの場合は、利用可能な管理者のコレクションにそのユーザー名があるかどうかを確認します。 ちなみに、これが OOP の真の姿です。単にインターフェイスを渡すだけです。インターフェイスは任意の実装にすることができます。ただし、渡すことができるのは、 Commandインターフェイスを実装するクラスのみです。 そして、管理者はどこから来たのかという 1 つのことを除いて、すべてが明らかになったようです。今からお見せします。現時点では、簡単に構成できるように、admins を環境変数として渡したいと思います。この変数には、管理者となるテレグラム ユーザーのすべてのユーザー名がカンマで区切られて示される行が含まれます。これを行うには、application.properties に以下を追加します。
bot.admins: robeskman,romankh3
CommandContainer コンストラクターで、管理者のコレクションを渡して初期化します。
public class CommandContainer {
private final ImmutableMap<String, Command> commandMap;
private final Command unknownCommand;
private final List<String> admins;
public CommandContainer(SendBotMessageService sendBotMessageService, TelegramUserService telegramUserService,
JavaRushGroupClient javaRushGroupClient, GroupSubService groupSubService,
List<String> admins) {
this.admins = admins;
そしてすでに JavaRushTelegramBot には、プロパティの文字列からコレクションを取得する魔法がすべて備わっています。
@Autowired
public JavarushTelegramBot(TelegramUserService telegramUserService, JavaRushGroupClient groupClient, GroupSubService groupSubService,
@Value("#{'${bot.admins}'.split(',')}") List<String> admins) {
this.commandContainer =
new CommandContainer(new SendBotMessageServiceImpl(this),
telegramUserService, groupClient, groupSubService, admins);
}
上記のコンストラクターからわかるように、ここでもValueアノテーション を使用し、そこにコレクションを作成するためのロジックを渡します。以上で、管理者の追加は完了です。現在、管理者以外のユーザーがボットの統計データを取得したい場合、次のような答えが返されます: 私は あなたのことを理解できません 😟、私が理解していることを調べるには /help と書いてください。 このようにして、ボット コマンドの役割を区別しました。
管理者用のヘルプ コマンドの追加
次に、管理者用に別のヘルプコマンドを作成するのが合理的です。将来的には、この部分が大きく成長する可能性があります。管理者ヘルプの値をCommandName に追加します。ADMIN_HELP("/ahelp")
コマンド パッケージに AdminHelpCommandクラス を作成します。
package com.github.javarushcommunity.jrtb.command;
import com.github.javarushcommunity.jrtb.service.SendBotMessageService;
import org.telegram.telegrambots.meta.api.objects.Update;
import static com.github.javarushcommunity.jrtb.command.CommandName.STAT;
import static java.lang.String.format;
/**
* Admin Help {@link Command}.
*/
public class AdminHelpCommand implements Command {
public static final String ADMIN_HELP_MESSAGE = format("✨<b>Доступные команды админа</b>✨\n\n"
+ "<b>Получить статистику</b>\n"
+ "%s - статистика бота\n",
STAT.getCommandName());
private final SendBotMessageService sendBotMessageService;
public AdminHelpCommand(SendBotMessageService sendBotMessageService) {
this.sendBotMessageService = sendBotMessageService;
}
@Override
public void execute(Update update) {
sendBotMessageService.sendMessage(update.getMessage().getChatId().toString(), ADMIN_HELP_MESSAGE);
}
}
ここまでは非常に簡単です。将来的にはかなり成長するかもしれません。このコマンドの場合、テンプレートからのテストは次のようになります。
package com.github.javarushcommunity.jrtb.command;
import org.junit.jupiter.api.DisplayName;
import static com.github.javarushcommunity.jrtb.command.AdminHelpCommand.ADMIN_HELP_MESSAGE;
import static com.github.javarushcommunity.jrtb.command.CommandName.ADMIN_HELP;
@DisplayName("Unit-level testing for AdminHelpCommand")
public class AdminHelpCommandTest extends AbstractCommandTest {
@Override
String getCommandName() {
return ADMIN_HELP.getCommandName();
}
@Override
String getCommandMessage() {
return ADMIN_HELP_MESSAGE;
}
@Override
Command getCommand() {
return new AdminHelpCommand(sendBotMessageService);
}
}
もちろん、コマンドをマップ内の CommandContainer に追加する必要があります。
.put(ADMIN_HELP.getCommandName(), new AdminHelpCommand(sendBotMessageService))
ボットにコマンドの説明を追加する
Telegram ボットにはもう 1 つの興味深い機能があります。受け入れられるコマンドの値と説明を追加して、ユーザーがコマンドを使いやすくすることができます。それはどのように見えますか?例として、最も重要な Telegram ボットであるBotFatherを見てみましょう。スラッシュ / を使用してメッセージを書き始めると、ボットはオプションを提供します:そして、書き続けると、フィルタリングされ、関連するオプションが表示されます:クールな機能ですね。なので、ここでも同じことをしてみたいと思います。Telegram アプリケーションを通じて、できる限り最善の方法で対応させていただきます。これはプログラムで実行できることはわかっています。でも、私は出来ません。これは、この一連の記事の目的には必要ありません。誰かがこれを行う方法を知っている場合は、私に書いてください。追加します。これに関するお手伝いは喜んで受け付けます。これは、私たちに適したコマンド パターンを通じて実行できると読んだことがあります。次に、これを行う方法を説明します。Telegram で BotFather を見つけ、構成したいボットを選択する必要があります。次に、ボットの編集とコマンドに関するセクションを選択します。ここで、Javarush 用のテスト ボットの例を使用してすべてを説明します。BotFather でコマンドを書きます: /mybots次に、必要なボットを選択します。私の場合、それは test_javarush_community_bot になります。ボタンのリストからわかるように、ここでトークンを表示し、ボットを削除し、次の場所に転送できます。他の誰か。ボットの編集に興味があるので、[ボットの編集]を選択します。そしてここで[コマンドの編集]を選択します。必要なのは、特定の形式でメッセージを提供することだけです。メッセージはコマンドとして記録されます。または、それらをすべて削除したい場合は、/empty と書き込みます。この目的のために、プロジェクトSET_UP_COMMANDS_BOT_FATHERのルートにファイルを作成します。このファイルにすべてのコマンドを記述し、何かが起こった場合に簡単に復元または更新できるようにします。 SET_UP_COMMANDS_BOT_FATHER:
start - ボットの作業を開始/復元します stop - ボットの作業を一時停止します addGroupSub - 記事のグループを購読します deleteGroupSub - 記事のグループを購読解除します listGroupSub - 購読しているグループのリスト help - 一緒に作業するためのヘルプを取得します
ここで管理コマンドを実行していないことは明らかです。管理者のみがそれらについて知っておく必要があります。このメッセージを受け取って、BotFather に渡しましょう。いつものことですが、最初はうまくいきませんでした。数分間考えた後、以前のようにキャメルケースではなく、すべてのコマンドを小文字で渡しました。すべてがうまくいきました。ファイル SET_UP_COMMANDS_BOT_FATHER を更新します。
start - ボットの作業を開始/復元します stop - ボットの作業を一時停止します addgroupsub - 記事のグループを購読します deletegroupsub - 記事のグループを購読解除します listgroupsub - 購読しているグループのリスト help - 協力するヘルプを取得します
これで、ボットにアクセスして、コマンドが自動的にロードされたかどうかを確認できます。見てください、とても美しくなりました。また、この記事の枠組みの中で統計の機能を拡張したいと考えていましたが、内容も意味もすでに膨大なものになってしまいました。したがって、次回に延期させていただきます。つまり、JRTB-10 のタスクは完全には完了していません。次の記事で完了します。同時に、既存のすべての変更をメインボットに追加します。 著者をサポートしたいのですが、方法がわかりませんか? それはとても簡単です - 私のtg チャンネル、私のGitHub アカウントを購読し、それらについての意見をここの記事に書いてください。このフィードバックは私にとって重要なので、彼らが読んで興味を持っていることは理解しています。
結論
今日私たちが経験したことを要約しましょう:- 独自の注釈を追加する方法と、それをチーム内の役割を示すマーカーとして使用する方法について説明しました。ちなみに、これはインターフェースを使用して行うこともできました。同様に、マーカー インターフェイスを作成し、到着したオブジェクトがこのインターフェイスを実装しているかどうかを確認します。
- 管理者向けのヘルプ コマンドを追加しました。私にとって、これはこのボットの開発において重要な部分でもあります。
- ボットにコマンドを記述するときにコマンドの説明とポップアップを追加する方法について説明しました。興味深い機能なので、間違いなく追加する価値があります。
GO TO FULL VERSION