JavaRush /Blogue Java /Random-PT /Adicionamos a capacidade de trabalhar como administrador ...
Roman Beekeeper
Nível 35

Adicionamos a capacidade de trabalhar como administrador e estatísticas para ele - “Projeto Java de A a Z”

Publicado no grupo Random-PT
Olá a todos, meus queridos amigos. Então, o bot já está funcionando e enviando notificações sobre novos artigos. Se você ainda não usa, aqui está o link: Javarush Telegram Bot . Bem, hoje falaremos sobre como adicionar comandos que funcionam apenas para administradores. Um desses comandos é o quadro de estatísticas e ajuda. Por que isso é necessário? No momento, é mais interessante descrever o trabalho com anotações no âmbito desta tarefa do que a real necessidade dele. "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele - 1Bom, já que vamos para a equipe de estatística, podemos ampliá-la e torná-la mais informativa. Após o MVP será possível retornar estatísticas para autores, por exemplo. Mas falaremos mais sobre isso depois...)

Vamos entender como adicionar administradores e comandos para eles

Começamos nosso trabalho atualizando o branch principal e criando um novo baseado nele - STEP_9_JRTB-10. Para descobrir qual comando se aplica aos administradores e qual se aplica a todos, você precisa rotular a equipe. Para fazer isso, vamos criar uma anotação. O que isso significa? Nós não fizemos isso antes. Isso pode ser selecionado ao criar uma classe no IDEA. Eu vou te mostrar agora. No pacote de comandos, crie um novo pacote de anotações e nele a anotação AdminCommand: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 2A anotação em si ficará assim:
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 {
}
Não precisamos de mais nada aqui. A seguir, adicionamos ao nosso comando StatCommand: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 3Agora tudo deve funcionar... Ou não? Não, claro)) Precisamos ensinar nosso CommandContainer a produzir o resultado corretamente. Para fazer isso, vamos atualizar o método retrieveCommand , que emite um comando para ser executado dependendo do que é passado para ele. Usaremos seu nome de usuário no Telegram como identificador de administrador. É único e mais fácil de ler do que chat_id. Como conseguir isso? Está no objeto Update, que vem com a mensagem:
update.getMessage().getFrom().getUserName()
Resumindo tudo acima, vamos atualizar o método 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));
}
Como você pode ver aqui, adicionei o método isAdminCommand , que verifica se há uma anotação AdminCommand no comando fornecido. E se for um comando somente de administrador, verificamos se temos esse nome de usuário em nossa coleção de administradores disponíveis. A propósito, aqui está, OOP, em toda a sua glória: simplesmente passamos uma interface, que pode ser qualquer implementação. Mas só podemos passar a classe que implementa a interface Command . E tudo parece claro, exceto uma coisa: de onde vieram os administradores? Eu vou te mostrar agora. Por enquanto quero passar admins como uma variável de ambiente para que possa ser facilmente configurada. Esta variável conterá uma linha na qual serão indicados todos os nomes de usuários dos usuários do telegrama que serão administradores, separados por vírgulas. Para fazer isso, adicione ao application.properties:
bot.admins: robeskman,romankh3
No construtor CommandContainer passaremos a coleção de admins e inicializaremos:
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;
E já no JavaRushTelegramBot haverá toda a magia de obter uma coleção de uma string nas propriedades:
@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);
}
Como você pode ver no construtor acima, usamos novamente a anotação Value , na qual passamos a lógica para criar a coleção. E pronto, a adição do administrador acabou. Agora, quando um não-administrador quiser obter dados sobre as estatísticas do bot, ele receberá a seguinte resposta: Não te entendo 😟, escreva /help para saber o que entendi. Dessa forma diferenciamos as funções dos comandos do bot.

Adicionando um comando de ajuda para administradores

Em seguida, seria lógico criar um comando de ajuda separado para administradores. No futuro, esta parte poderá crescer significativamente. Adicione o valor de ajuda admin ao CommandName:
ADMIN_HELP("/ahelp")
Crie a classe AdminHelpCommand no pacote de comandos:
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);
   }
}
Até agora é muito simples. Pode muito bem crescer muito bem no futuro. Para este comando, um teste do nosso modelo:
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);
   }
}
Claro, o comando precisa ser adicionado ao CommandContainer em nosso mapa:
.put(ADMIN_HELP.getCommandName(), new AdminHelpCommand(sendBotMessageService))

Adicionando uma descrição de comandos ao bot

Os bots do Telegram possuem outro recurso interessante: você pode adicionar valores e descrições dos comandos que ele aceita para facilitar o uso dos comandos pelo usuário. Com o que se parece? Por exemplo, vamos ao BotFather – o bot mais importante do Telegram. Se você começar a escrever uma mensagem com uma barra /, o bot oferecerá opções: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 4E se você continuar escrevendo, ele filtrará e mostrará opções relevantes: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 5Funcionalidade legal, certo? Então eu quero fazer o mesmo aqui. Farei isso da melhor maneira possível - através do aplicativo Telegram. Eu sei que isso pode ser feito programaticamente. Mas eu não posso. Isto não é necessário para os propósitos desta série de artigos. Se alguém souber como fazer isso, escreva para mim, iremos adicionar. Terei prazer em aceitar qualquer ajuda com isso. Certa vez, li que isso pode ser feito por meio do padrão de comando que funciona para nós. Agora vou mostrar como posso fazer isso: precisamos encontrar o BotFather no Telegram, selecionar o bot que queremos configurar. A seguir, selecione a edição do bot e a seção sobre comandos. Agora vou mostrar tudo usando o exemplo do meu bot de teste para Javarush. No BotFather escrevemos o comando: /mybots"Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 6 Em seguida, selecione o bot que precisamos, no meu caso será test_javarush_community_bot: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 7Como você pode ver na lista de botões, aqui você pode visualizar o token, excluir o bot e transferi-lo para alguém. Estamos interessados ​​​​em editar o bot, então selecionamos Editar Bot : "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 8E aqui selecionamos Editar Comandos : "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 9Só precisamos fornecer uma mensagem em um formato específico, e ela será gravada como comandos. Ou se quisermos remover todos eles, escreva /empty. Para isso, criarei um arquivo na raiz do projeto SET_UP_COMMANDS_BOT_FATHER , no qual escreverei todos os nossos comandos para que seja fácil restaurar ou atualizar caso algo aconteça. SET_UP_COMMANDS_BOT_FATHER:
start - iniciar/restaurar o trabalho com o bot stop - pausar o trabalho com o bot addGroupSub - inscrever-se em um grupo de artigos deleteGroupSub - cancelar a assinatura de um grupo de artigos listGroupSub - lista de grupos nos quais você está inscrito help - obter ajuda para trabalhar comigo
É claro que não carregamos comandos de administrador aqui. Somente os administradores devem saber sobre eles. Vamos pegar esta mensagem e repassá-la ao BotFather: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 10Como costuma acontecer, não deu certo na primeira vez. Após alguns minutos de reflexão, passei todos os comandos em letras minúsculas, e não em CamelCase como antes, e tudo correu bem. Atualizamos em nosso arquivo: SET_UP_COMMANDS_BOT_FATHER:
start - iniciar/restaurar o trabalho com o bot stop - pausar o trabalho com o bot addgroupsub - inscrever-se em um grupo de artigos deletegroupsub - cancelar a assinatura de um grupo de artigos listgroupsub - lista de grupos nos quais você está inscrito help - obter ajuda para trabalhar comigo
Agora você pode acessar nosso bot e ver se os comandos foram carregados automaticamente: "Projeto Java de A a Z": Adicionando a capacidade de trabalhar como administrador e estatísticas para ele.  Parte 1 - 11Olha que lindo agora! Eu também queria expandir a funcionalidade das estatísticas no âmbito deste artigo, mas o material já era volumoso tanto em significado quanto em conteúdo. Portanto, adiaremos isso para a próxima vez. Ou seja, a tarefa do JRTB-10 não está totalmente concluída: iremos completá-la no próximo artigo. Ao mesmo tempo, adicionarei todas as alterações que já existem ao bot principal. Quer apoiar o autor, mas não sabe como? É muito simples - inscreva-se no meu canal tg , na minha conta GitHub e escreva sua opinião sobre eles em artigos aqui. Esse feedback é importante para mim, então entendo que eles são lidos e interessados ​​neles.

conclusões

Vamos resumir o que passamos hoje:
  1. Discutimos como adicionar sua própria anotação e como ela pode ser usada como marcador para delinear funções nas equipes. A propósito, isso poderia ter sido feito usando a interface. Da mesma forma, criaríamos uma interface de marcador e depois verificaríamos se o objeto que chega implementa esta interface ou não.
  2. Adicionado comando de ajuda para administradores. Quanto a mim, esta também é uma parte importante no desenvolvimento deste bot.
  3. Discutimos como adicionar uma descrição e pop-up de comandos ao escrevê-los em um bot. Recurso interessante, definitivamente vale a pena adicionar.
Com base neste artigo, criei um pull request , você pode ver seus detalhes. Obrigado a todos pela atenção, como sempre: curta - inscreva-se - sininho , estrela nosso projeto, comente e avalie o artigo! Vejo você no próximo artigo!

Uma lista de todos os materiais da série está no início deste artigo.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION