JavaRush /Blog Java /Random-ES /Agregamos la capacidad de trabajar como administrador y e...

Agregamos la capacidad de trabajar como administrador y estadísticas para él: "Proyecto Java de la A a la Z"

Publicado en el grupo Random-ES
Hola a todos, mis queridos amigos. Entonces, el bot ya está funcionando y enviando notificaciones sobre nuevos artículos. Si aún no lo usas, aquí te dejamos el enlace: Javarush Telegram Bot . Bueno, hoy hablaremos sobre cómo agregar comandos que solo funcionan para administradores. Uno de estos comandos es el tablero de estadísticas y ayuda. ¿Por qué es esto necesario? Por el momento, es más interesante describir el trabajo con anotaciones en el marco de esta tarea que su necesidad real. "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él - 1Bueno, ya que vamos al equipo de estadísticas, podemos ampliarlo y hacerlo más informativo. Después del MVP, será posible devolver estadísticas de autores, por ejemplo. Pero hablaremos de eso más adelante...)

Entendamos cómo agregar administradores y comandos para ellos.

Comenzamos nuestro trabajo actualizando la rama principal y creando una nueva basada en ella: STEP_9_JRTB-10. Para saber qué comando se aplica a los administradores y cuál se aplica a todos, debe etiquetar el comando. Para hacer esto, creemos una anotación. ¿Qué significa? No hemos hecho esto antes. Esto se puede seleccionar al crear una clase en IDEA. Te lo mostraré ahora. En el paquete de comandos, cree un nuevo paquete de anotaciones y en él la anotación AdminCommand: "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 2La anotación en sí será así:
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 {
}
No necesitamos nada más aquí. A continuación, lo agregamos a nuestro comando StatCommand: "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 3Ahora todo debería funcionar... ¿O no? No, por supuesto)) Necesitamos enseñarle a nuestro CommandContainer a producir correctamente el resultado. Para hacer esto, actualicemos el método retrieveCommand , que emite un comando para ejecutar dependiendo de lo que se le pasa. Usaremos su nombre de usuario en Telegram como identificador de administrador. Es único y más fácil de leer que chat_id. ¿Cómo conseguirlo? Está en el objeto Actualizar, que viene con el mensaje:
update.getMessage().getFrom().getUserName()
Resumiendo todo lo anterior, actualicemos el 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 puede ver aquí, agregué el método isAdminCommand , que verifica si hay una anotación AdminCommand en el comando proporcionado. Y si es un comando solo para administradores, verificamos si tenemos ese nombre de usuario en nuestra colección de administradores disponibles. Por cierto, aquí está la programación orientada a objetos, en todo su esplendor: simplemente pasamos una interfaz, que puede ser cualquier implementación. Pero solo podemos pasar la clase que implementa la interfaz Command . Y todo parece claro, excepto una cosa: ¿de dónde vienen los administradores? Te lo mostraré ahora. Por ahora quiero pasar admins como variable de entorno para que pueda configurarse fácilmente. Esta variable contendrá una línea en la que se indican todos los nombres de usuario de los usuarios de Telegram que serán administradores, separados por comas. Para hacer esto, agregue a application.properties:
bot.admins: robeskman,romankh3
En el constructor CommandContainer pasaremos la colección de administradores y la 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;
Y ya en JavaRushTelegramBot estará toda la magia de obtener una colección a partir de una cadena en propiedades:
@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 puede ver en el constructor anterior, nuevamente usamos la anotación Valor , a la que pasamos la lógica para crear la colección. Y listo, se acabó agregar el administrador. Ahora, cuando un no administrador quiera obtener datos sobre las estadísticas del bot, recibirá la siguiente respuesta: No te entiendo 😟, escribe /ayuda para saber qué entiendo. De esta manera diferenciamos los roles de los comandos del bot.

Agregar un comando de ayuda para administradores

A continuación, sería lógico crear un comando de ayuda independiente para los administradores. En el futuro, esta parte puede crecer significativamente. Agregue el valor de ayuda del administrador a CommandName:
ADMIN_HELP("/ahelp")
Cree la clase AdminHelpCommand en el paquete 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);
   }
}
Hasta ahora es muy sencillo. Es posible que crezca bastante bien en el futuro. Para este comando, una prueba de nuestra plantilla:
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);
   }
}
Por supuesto, el comando debe agregarse al CommandContainer en nuestro mapa:
.put(ADMIN_HELP.getCommandName(), new AdminHelpCommand(sendBotMessageService))

Agregar una descripción de comandos al bot

Los bots de Telegram tienen otra característica interesante: puedes agregar valores y descripciones de los comandos que acepta para facilitar al usuario el uso de los comandos. Cómo se ve? Por ejemplo, vayamos a BotFather , el bot de Telegram más importante. Si comienzas a escribir un mensaje con una barra /, el bot te ofrecerá opciones: "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 4Y si continúas escribiendo, filtrará y mostrará opciones relevantes: "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 5Funcionalidad genial, ¿verdad? Entonces quiero hacer lo mismo aquí. Lo haré de la mejor manera que pueda: a través de la aplicación Telegram. Sé que esto se puede hacer mediante programación. Pero no puedo. Esto no es necesario para los propósitos de esta serie de artículos. Si alguien sabe cómo hacer esto que me escriba, lo agregaremos. Con mucho gusto aceptaré cualquier ayuda con esto. Una vez leí que esto se puede hacer mediante el patrón de comando que nos funciona. Ahora te mostraré cómo puedo hacer esto: necesitamos encontrar BotFather en Telegram, seleccionar el bot que queremos configurar. A continuación, seleccione editar el bot y la sección sobre comandos. Ahora mostraré todo usando el ejemplo de mi bot de prueba para Javarush. En BotFather escribimos el comando: /mybots"Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 6 Luego seleccionamos el bot que necesitamos, en mi caso será test_javarush_community_bot: "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 7Como puedes ver en la lista de botones, aquí puedes ver el token, eliminar el bot y transferirlo a alguien más. Estamos interesados ​​en editar el bot, así que seleccionamos Editar bot : "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 8y aquí seleccionamos Editar comandos : "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 9solo necesitamos proporcionar un mensaje en un formato específico y se registrará como comandos. O si queremos eliminarlos todos escribimos /empty. Para ello, crearé un archivo en la raíz del proyecto SET_UP_COMMANDS_BOT_FATHER , en el que escribiré todos nuestros comandos para que sea fácil de restaurar o actualizar si sucede algo. SET_UP_COMMANDS_BOT_FATHER:
start - iniciar/restaurar el trabajo con el bot stop - pausar el trabajo con el bot addGroupSub - suscribirse a un grupo de artículos eliminarGroupSub - darse de baja de un grupo de artículos listGroupSub - lista de grupos a los que está suscrito ayuda - obtener ayuda para trabajar conmigo
Está claro que aquí no llevamos comandos de administrador. Sólo los administradores deberían conocerlos. Tomemos este mensaje y pasémoslo a BotFather: "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 10Como suele ser el caso, no funcionó la primera vez. Después de pensar unos minutos, pasé todos los comandos en minúsculas, y no en CamelCase como antes, y todo salió bien. Actualizamos en nuestro archivo: SET_UP_COMMANDS_BOT_FATHER:
start - iniciar/restaurar el trabajo con el bot stop - pausar el trabajo con el bot addgroupsub - suscribirse a un grupo de artículos eliminargroupsub - darse de baja de un grupo de artículos listgroupsub - lista de grupos a los que está suscrito ayuda - obtener ayuda para trabajar conmigo
Ahora puedes ir a nuestro bot y ver si los comandos se han cargado automáticamente: ¡ "Proyecto Java de la A a la Z": agregando la capacidad de trabajar como administrador y estadísticas para él.  Parte 1 - 11Mira que bonito está ahora! También quería ampliar la funcionalidad de las estadísticas en el marco de este artículo, pero el material ya era voluminoso tanto en significado como en contenido. Por lo tanto, lo pospondremos para la próxima vez. Es decir, la tarea de JRTB-10 no está completamente terminada: la completaremos en el próximo artículo. Al mismo tiempo, agregaré todos los cambios que ya existen al bot principal. ¿Quieres apoyar al autor, pero no sabes cómo? Es muy simple: suscríbete a mi canal tg , mi cuenta de GitHub y escribe tu opinión sobre ellos en los artículos aquí. Estos comentarios son importantes para mí, por eso entiendo que los leen y están interesados ​​en ellos.

conclusiones

Resumamos lo que pasamos hoy:
  1. Discutimos cómo agregar su propia anotación y cómo puede usarse como marcador para delinear roles en los equipos. Por cierto, esto se podría haber hecho usando la interfaz. De la misma forma crearíamos una interfaz de marcador y luego comprobaríamos si el objeto que llega implementa esta interfaz o no.
  2. Se agregó el comando de Ayuda para administradores. En lo que a mí respecta, esto también es una parte importante en el desarrollo de este bot.
  3. Discutimos cómo agregar una descripción y una ventana emergente de comandos al escribirlos en un bot. Característica interesante, definitivamente vale la pena agregarla.
Basándome en este artículo, creé una solicitud de extracción , puedes ver sus detalles. Gracias a todos por su atención, como siempre: me gusta - suscríbase - campana , destaque nuestro proyecto, comente y califique el artículo. ¡Nos vemos en el próximo artículo!

Al principio de este artículo encontrará una lista de todos los materiales de la serie.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION