大家好,我亲爱的朋友们。因此,该机器人已经开始工作并发送有关新文章的通知。如果您还没有使用它,请点击以下链接:Javarush Telegram Bot。好吧,今天我们将讨论添加仅适用于管理员的命令。这些命令之一是统计和帮助板。为什么这是必要的?目前,在这个任务的框架内用注释来描述工作比实际需要更有趣。好吧,既然我们要加入统计团队,我们就可以扩展它并使其提供更多信息。例如,在 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));
}
正如您在此处看到的,我添加了isAdminCommand方法,该方法检查所提供的命令上是否有 AdminCommand 注释。如果它是仅限管理员的命令,我们会检查可用管理员集合中是否有该用户名。 顺便说一句,这就是 OOP 的全部荣耀:我们只需传递一个接口,它可以是任何实现。但我们只能传递实现Command接口的类。 一切似乎都很清楚,除了一件事:管理员从哪里来?我现在就给你看。现在我想将 admins 作为环境变量传递,以便可以轻松配置。该变量将包含一行,其中指示将成为管理员的电报用户的所有用户名,并以逗号分隔。为此,请添加到 application.properties:
bot.admins: robeskman,romankh3
在 CommandContainer 构造函数中,我们将传递 admins 集合并对其进行初始化:
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 机器人还有另一个有趣的功能:您可以添加其接受的命令的值和描述,以便用户更轻松地使用命令。它是什么样子的?举个例子,让我们看看BotFather——最重要的 Telegram 机器人。如果您开始用斜杠 / 编写消息,机器人将提供选项:如果您继续编写,它将过滤并显示相关选项:很酷的功能,对吧?所以我想在这里做同样的事情。我将尽我所能 - 通过 Telegram 应用程序。我知道这可以通过编程来完成。但是我不能。对于本系列文章的目的而言,这不是必需的。如果有人知道如何做到这一点,请写信给我,我们将添加它。我很乐意接受任何有关这方面的帮助。我曾经读到这可以通过适合我们的命令模式来完成。现在我将向您展示如何做到这一点:我们需要在 Telegram 中找到 BotFather,选择我们要配置的机器人。接下来,选择编辑机器人和有关命令的部分。现在我将使用我的 Javarush 测试机器人示例来展示所有内容。在 BotFather 中,我们编写命令: /mybots接下来,选择我们需要的机器人,在我的例子中它将是 test_javarush_community_bot:正如您从按钮列表中看到的,在这里您可以查看令牌,删除机器人,并将其转移到其他人。我们对编辑机器人感兴趣,所以我们选择编辑机器人:在这里我们选择编辑命令:我们只需要提供特定格式的消息,它将被记录为命令。或者,如果我们想将它们全部删除,请写/empty。为此,我将在项目的根目录中创建一个文件SET_UP_COMMANDS_BOT_FATHER,在其中写入所有命令,以便在出现问题时可以轻松恢复或更新。 SET_UP_COMMANDS_BOT_FATHER:
开始 - 开始/恢复与机器人的工作 停止 - 暂停与机器人的工作 addGroupSub - 订阅一组文章 deleteGroupSub - 取消订阅一组文章 listGroupSub - 您订阅的组列表 帮助 - 获取与我一起工作的帮助
很明显,我们这里不携带管理命令。只有管理员应该了解它们。让我们获取此消息并将其传递给 BotFather:与通常的情况一样,第一次并没有成功。经过几分钟的思考,我以小写形式传递了所有命令,而不是像以前那样以驼峰命名,一切都很顺利。我们在文件中更新: SET_UP_COMMANDS_BOT_FATHER:
开始 - 开始/恢复与机器人的工作 停止 - 暂停与机器人的工作 addgroupsub - 订阅一组文章 deletegroupsub - 取消订阅一组文章 listgroupsub - 您订阅的组列表 帮助 - 获得与我一起工作的帮助
现在您可以转到我们的机器人,看看命令是否已自动加载:看看它现在多漂亮!我还想在本文的框架内扩展统计的功能,但材料在含义和内容上都已经很庞大了。因此,我们将推迟到下次。也就是说,JRTB-10的任务还没有完全完成:我们将在下一篇文章中完成。同时,我会将所有已存在的更改添加到主机器人中。 想要支持作者,但不知道如何支持?非常简单 - 订阅我的tg 频道、我的GitHub 帐户,并在此处的文章中写下您对它们的看法。这些反馈对我来说很重要,所以我知道他们已阅读并且对它们感兴趣。
结论
我们来总结一下今天的经历:- 我们讨论了如何添加您自己的注释以及如何将其用作标记来描述团队中的角色。顺便说一句,这可以使用界面来完成。同样,我们创建一个标记接口,然后检查到达的对象是否实现了该接口。
- 为管理员添加了帮助命令。对我来说,这也是这个机器人开发过程中的一个重要部分。
- 我们讨论了在机器人中编写命令时如何添加命令的描述和弹出窗口。有趣的功能,绝对值得添加。
GO TO FULL VERSION