JavaRush /Blog Java /Random-ES /Crear un bot de Telegram en Java: de la idea al despliegu...
John Watson
Nivel 27

Crear un bot de Telegram en Java: de la idea al despliegue

Publicado en el grupo Random-ES
¿Qué son los bots de todos modos? Puedes leer sobre esto en detalle aquí . Primero, debe leer la documentación oficial de la biblioteca para desarrollar bots en Telegram (en adelante, API). Ella yace aquí . Creando un bot de Telegram en Java: de la idea al despliegue - 1Todo allí es muy accesible y comprensible. ¡Parecería que escribe y regocíjate! Pero no es tan simple. Después de pasar mucho tiempo en los motores de búsqueda, encontré fragmentos de conocimiento sobre el desarrollo de bots, por ejemplo, cómo hacer un teclado, procesar CallbackQuery y cosas por el estilo. Nunca encontré una guía completa y exhaustiva para desarrollar bots en Java. Esto me impulsó a escribir este artículo. Hay muchos sitios en Internet donde puedes crear tu propio bot con una implementación ya preparada. Pero el punto es. que en su mayor parte se crean bots que pueden proporcionar información básica, etc. Nuestro bot es una aplicación web completa a la que puede vincular una base de datos, realizar solicitudes a varias API, analizar sitios, realizar cálculos complejos, etc. El asunto está limitado únicamente por tu imaginación. Espero que en estas líneas os haya explicado un poco sobre lo que voy a escribir. Registrar un bot en Telegram es muy sencillo, este proceso se describe en detalle en la documentación en el enlace de arriba. Para nuestra aplicación solo necesitas saber el nombre del bot y el token que recibirás al registrarte. Básicamente, un bot es sólo una aplicación web de consola. Sin interfaz, procesamiento de comandos puro. Si desea dominar bien Hibernate o aprender a analizar JSON, entonces este proyecto es para usted. Comencemos incluyendo la dependencia en pom.xml (asumimos que estás usando Maven). Puedes hacerlo así:
<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
Luego creamos una clase Bot, la heredamos de la clase TelegramLongPollingBot, anulando sus métodos:
public class Bot extends TelegramLongPollingBot {

    /**
     * Método para recibir mensajes.
     * @param update Contiene un mensaje del usuario.
     */
    @Override
    public void onUpdateReceived(Update update) {
	String message = update.getMessage().getText();
	sendMsg(update.getMessage().getChatId().toString(), message);
    }

    /**
     * Método para configurar un mensaje y enviarlo.
     * @param chatId ID de chat
     * @param s La cadena para enviar como mensaje.
     */
    public synchronized void sendMsg(String chatId, String s) {
        SendMessage sendMessage = new SendMessage();
        sendMessage.enableMarkdown(true);
        sendMessage.setChatId(chatId);
        sendMessage.setText(s);
        try {
            sendMessage(sendMessage);
        } catch (TelegramApiException e) {
            log.log(Level.SEVERE, "Exception: ", e.toString());
        }
    }

    /**
     * El método devuelve el nombre del bot especificado durante el registro.
     * @return nombre del bot
     */
    @Override
    public String getBotUsername() {
        returnBotName;
    }

    /**
     * El método devuelve el token del bot para comunicarse con el servidor de Telegram
     * @return token para el bot
     */
    @Override
    public String getBotToken() {
        returnBotToken;
    }
}
Bueno, el contenido del método main:
public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotsApi telegramBotsApi = new TelegramBotsApi();
        try {
            telegramBotsApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
Al ingresarlo en los métodos getBotUsername(), getBotToken()lanzamos el bot. Por ahora sólo nos redirige los mensajes que le enviamos, una especie de “espejo”. Todo funciona de la siguiente manera: cuando inicia la aplicación, comienza a enviar una solicitud GET al servidor de Telegram una vez cada n segundos en la siguiente URL: https://api.telegram.org/BotToken/getMe, donde está BotToken el token de su bot, recibiendo una respuesta JSON que contiene todos los mensajes. Cada uno de estos mensajes es procesado por la biblioteca y llega al método OnUpdateReceived(Update update)como un objeto Update. Con eso trabajamos. Esta es la belleza de los bots de Telegram, pueden funcionar en cualquier computadora, para realizar pruebas solo necesita iniciar la aplicación, no es necesario implementarla en el alojamiento después de cada cambio. Es muy cómodo. Por supuesto, el bot se puede configurar para que funcione mediante un webhook; el manual se puede encontrar en Internet; para simplificar, trabajaremos utilizando LongPolling. Cómo procesar mensajes y qué enviar en respuesta está limitado únicamente por las herramientas de idioma y la biblioteca, todo lo demás queda a su discreción. Puedes hacer un bot que busque videos en YouTube por ti, puedes hacer un bot que todos los días te envíe lo que te envíes a ti mismo, por ejemplo, en un año, una especie de cápsula del tiempo. O puede aprender a integrarse en sistemas CRM y crear bots para pequeñas empresas, todo está limitado por su imaginación. Adelante. Quienes han utilizado bots saben que conviene interactuar con ellos mediante comandos que empiezan por el signo «/», por ejemplo /start. Pero hay una forma más conveniente: los botones. Hay dos tipos de botones: los que aparecen debajo del campo de entrada ReplyKeyboardMarkupy los botones que aparecen directamente debajo del mensaje al que están vinculados InlineKeyboardMarkup. En la documentación podrá familiarizarse brevemente con su descripción. ResponderMarcado del teclado. Básicamente, se trata de una serie de conjuntos de botones List<KeyboardRow<KeyboardButton>>. Aquí hay un código de ejemplo que crea el teclado.
public synchronized void setButtons(SendMessage sendMessage) {
        // Crear un teclado
        ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
        sendMessage.setReplyMarkup(replyKeyboardMarkup);
        replyKeyboardMarkup.setSelective(true);
        replyKeyboardMarkup.setResizeKeyboard(true);
        replyKeyboardMarkup.setOneTimeKeyboard(false);

        // Crear una lista de cadenas de teclado
        List<KeyboardRow> keyboard = new ArrayList<>();

        // Primera linea del teclado
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Agregar botones a la primera línea del teclado
        keyboardFirstRow.add(new KeyboardButton(“Привет”));

        // Segunda linea del teclado
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Agregar botones a la segunda línea del teclado
        keyboardSecondRow.add(new KeyboardButton(“Помощь”);

        // Agrega todas las cadenas de teclado a la lista
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // y establecemos esta lista en nuestro teclado
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
En un método sendMsg(), llamamos a este método pasándole un mensaje, configurando así el teclado para ese mensaje. Cuando enviemos este mensaje al usuario, verá el texto del mensaje que configuramos, así como 2 botones que dicen Hola y Ayuda, uno al lado del otro. Al hacer clic en estos botones, se enviará un mensaje al bot, cuyo texto es el que está escrito en el botón. Es decir, si el cliente hace clic en “Ayuda”, el bot recibirá un mensaje con el texto “Ayuda”. Para él, es como si el propio cliente escribiera el texto “Ayuda” y se lo enviara. Bueno, entonces procesas esos mensajes. InlineKeyboardMarkup Esta también es una matriz de matrices, es similar al marcado anterior, pero la lógica operativa aquí es ligeramente diferente. Un teclado de este tipo está vinculado a un mensaje específico y existe sólo para él. Este es el método para instalar el teclado en línea
private void setInline() {
        List<List<InlineKeyboardButton>> buttons = new ArrayList<>();
        List<InlineKeyboardButton> buttons1 = new ArrayList<>();
        buttons1.add(new InlineKeyboardButton().setText(“Кнопка“).setCallbackData(17));
        buttons.add(buttons1);

        InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup();
        markupKeyboard.setKeyboard(buttons);
    }
Cree Listen List, agregue un botón en línea a la primera línea. Un botón de este tipo puede contener una URL, un enlace a un canal o CallbackQueryalgo sobre lo que escribiré más adelante. Aquí configuramos el texto de nuestro botón que verá el usuario y luego configuramos los datos que se enviarán al bot. En nuestro ejemplo, el usuario ve "Hola" y, cuando hace clic, al bot se le enviará el número 17, este es nuestro archivo CallbackQuery. Algunas palabras sobre CallbackQuery. Para obtener dichos datos de un objeto, Updatedebe ejecutar update.getCallbackQuery(), este método devuelve CallbackQuery, desde donde ya puede obtener los datos transferidos al bot. No es necesario intentar obtener estos datos mediante el método update.getMessage().getText()get NullPointerException.
@Override
    public void onUpdateReceived(Update update) {
        if(update.hasMessage()) {
            ThreadClass thread = new ThreadClass(update.getMessage());
        } else  if(update.hasCallbackQuery()) {
            AnswerCallbackThread answerThread = new AnswerCallbackThread(update.getCallbackQuery());
        }
    }
Si hay un mensaje, lo enviamos para su procesamiento a un nuevo hilo; si hay un mensaje CallbackQuery, lo enviamos para su procesamiento al hilo apropiado. Puedes CallbackQueryenviar una respuesta. Cada objeto en Telegram tiene su propia identificación. Para enviar una respuesta a uno concreto CallbackQuerysólo necesitamos saber su id, que recibiremos del objeto correspondiente. Para enviar una respuesta, llame a este método:
public synchronized void answerCallbackQuery(String callbackId, String message) {
        AnswerCallbackQuery answer = new AnswerCallbackQuery();
        answer.setCallbackQueryId(callbackId);
        answer.setText(message);
        answer.setShowAlert(true);
        try {
            answerCallbackQuery(answer);
        } catch (TelegramApiException e) {
            e.printStackTrace();
        }
    }
IMPORTANTE:¡El texto de la respuesta CallbackQueryno debe tener más de 200 caracteres! Al enviar dicha respuesta, el cliente recibirá una ventana emergente en la que se escribirá el mensaje. Una ventana de este tipo puede desaparecer unos segundos después de su aparición o puede bloquearse hasta que el usuario presione Aceptar. Para cambiar estos modos, llamamos al answer.setShowAlert(true). Cuando truela ventana se cuelga hasta que presionas OK, cuando falsedesaparece después de 5 segundos. En principio, estas son todas las características básicas de la biblioteca de bots de Telegram. Si lo deseas, puedes aprender cosas como envío multimedia, geolocalización, etc. desde la documentación. Pasemos a implementar nuestro bot en hosting. Para mi proyecto, elegí Heroku porque, en mi opinión, es un hosting bastante conveniente que tiene su propia CLI. Es gratis, pero a este ritmo tu bot entrará en hibernación después de 30 minutos si no hay solicitudes. Cuando le envían una solicitud, se despierta. Esto sucede bastante rápido, ni siquiera lo notarás (a menos, por supuesto, que se restablezca la conexión a la base de datos). El límite del plan gratuito es 5 MB de base de datos, 100 MB de espacio en disco, 2 TB de tráfico por mes, 1 dinosaurio. Dino es tu aplicación en ejecución. Diré de inmediato que fue la etapa de implementación la que me causó dificultades, ya que nunca antes había implementado mis aplicaciones. Al implementar, Heroku requiere un archivo llamado Procfile (sin extensión). worker: sh target/bin/workerBot Lo creamos en la raíz del proyecto, escribimos workBot allí ; pom.xml se ejecutará el nombre que especificamos en el script sh generado usando el complemento Maven appassembler-maven-plugin. El script describe la ejecución del jar compilado. El nombre de la clase a lanzar se indica entre <mainClass></mainClass>, el nombre del script entre <name></name> pom.xml:
...
<build>
    <plugins>
        ...
       <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>appassembler-maven-plugin</artifactId>
            <version>1.1.1</version>
            <configuration>
                <assembleDirectory>target</assembleDirectory>
                <programs>
                    <program>
                        <mainClass>com.home.server.TelegramBot</mainClass>
                        <name>workerBot</name>
                    </program>
                </programs>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>assemble</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
Antes de comenzar este proceso, debe registrarse en Heroku, instalar Git y Heroku CLI. Si su aplicación requiere una base de datos, al registrar una nueva aplicación, no olvide agregar la base de datos que necesita. A continuación, debe averiguar el host, el nombre de usuario, la contraseña y el puerto de su base de datos y luego especificarlo en su aplicación. A continuación, antes de implementarlo, cree su proyecto usando Maven.
mvn clean install
Para comenzar, vamos al directorio de nuestro proyecto, inicializamos el repositorio con el comandogit init Luego agregamos nuestro proyecto a este repositorio
git add .
Después de confirmar los cambios
git commit -m “First commit in project”
Luego debes iniciar sesión en heroku, escribir en la línea de comando
heroku login
Ingrese los datos especificados durante el registro. Luego necesitas averiguar la URL de tu repositorio en Heroku, esto se hace en la configuración. Entonces escribimos
git remote add heroku [url]
El repositorio remoto de heroku se agregará a su repositorio. A continuación escribimos
git push heroku master
Estamos esperando... Si el despliegue de la aplicación es exitoso, ejecutamos el comando
heroku ps:scale worker=1
Y listo, tu aplicación se está ejecutando. Si esto no sucede, mire atentamente los registros; lo más probable es que haya un error en su aplicación que provocó que fallara. Gracias por leer un artículo tan largo, espero que alguien lo encuentre útil y le ahorre mucho tiempo en los lugares donde tropecé durante el desarrollo.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION