CodeGym /Blog Java /Random-ES /Creación de un Telegram Bot en Java: desde la concepción ...
Autor
Edward Izraitel
Software Engineer at Champions Oncology

Creación de un Telegram Bot en Java: desde la concepción hasta la implementación

Publicado en el grupo Random-ES
Entonces, ¿qué son los bots? Puedes leer más sobre esto aquí . Para comenzar, debe revisar la documentación oficial de la biblioteca utilizada para desarrollar los bots de Telegram (en adelante, la "API"). Se puede encontrar aquí .
Creación de un Telegram Bot en Java: desde la concepción hasta la implementación - 1
Todo allí es muy accesible y claro. ¡Parece que podemos simplemente escribir código y regocijarnos! Pero no es tan simple. Después de pasar mucho tiempo buscando, encontré fragmentos de conocimiento sobre el desarrollo de bots, por ejemplo, cómo hacer un teclado, manejar unCallbackQuery, Etcétera. Pero no encontré una guía completa y exhaustiva para el desarrollo de bots de Java. Eso me impulsó a escribir este artículo. Hay muchos sitios web donde puede crear su propio bot fácilmente implementable. Pero el hecho es que la mayoría de los bots creados brindan información de referencia y similares. Nuestro bot es una aplicación web completa. Puede vincular una base de datos, ejecutar varias solicitudes de API, analizar sitios web, realizar cálculos complejos y más. Las posibilidades están limitadas únicamente por su imaginación. Espero que lo anterior haya ayudado a aclarar lo que voy a escribir. Es muy fácil registrar un bot en Telegram. Este proceso se describe en detalle en la documentación vinculada anteriormente. Para nuestra aplicación, solo necesita saber el nombre del bot y el token que recibe al registrar el bot. Básicamente, un bot es solo una aplicación web basada en consola. No hay front-end, solo procesamiento de comandos puro. Si quieres dominarHibernate o aprende a analizar JSON , entonces este es el proyecto para ti. Comencemos agregando una dependencia a pom.xml(supongo que está usando Maven). Puedes hacerlo así:

<dependency>
            <groupId>org.telegram</groupId>
            <artifactId>telegrambots</artifactId>
            <version>3.5</version>
</dependency>
A continuación, cree una Botclase que herede la TelegramLongPollingBotclase y anule sus métodos:

public class Bot extends TelegramLongPollingBot {

    /**
     * Method for receiving messages.
     * @param update Contains a message from the user.
     */
    @Override
    public void onUpdateReceived(Update update) {
    String message = update.getMessage().getText();
    sendMsg(update.getMessage().getChatId().toString(), message);
    }

    /**
     * Method for creating a message and sending it.
     * @param chatId chat id
     * @param s The String that you want to send as a message.
     */
    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());
        }
    }

    /**
     * This method returns the bot's name, which was specified during registration.
     * @return bot name
     */
    @Override
    public String getBotUsername() {
        return "BotName";
    }

    /**
     * This method returns the bot's token for communicating with the Telegram server
     * @return the bot's token
     */
    @Override
    public String getBotToken() {
        return "BotToken";
    }
}
Y ahora el contenido del mainmétodo:

public static void main(String[] args) {
        ApiContextInitializer.init();
        TelegramBotApi telegramBotApi = new TelegramBotApi();
        try {
            telegramBotApi.registerBot(Bot.getBot());
        } catch (TelegramApiRequestException e) {
            e.printStackTrace();
        }
}
Después de completar los métodos getBotUsername()y getBotToken(), inicie el bot. Por ahora, solo nos redirige cualquier mensaje que le enviemos, como una especie de " espejo ". Funciona así: cuando inicia la aplicación, comienza a enviar solicitudes al servidor de Telegram, una vez cada n segundos, en la siguiente URL: https://api.telegram.org/BotToken/getMe , donde BotToken es el token de su bot . En respuesta, recibe JSON que contiene todos los mensajes. Cada uno de estos mensajes es procesado por la biblioteca y se pasa al OnUpdateReceived(Update update)método como unUpdateobjeto. Y eso es con lo que trabajamos. Aquí radica la belleza de los bots de Telegram: pueden ejecutarse en cualquier computadora, probarlo solo requiere iniciar la aplicación y no es necesario implementarla en el host después de cada cambio. Esto es muy conveniente. Por supuesto, puede configurar un bot para que funcione con webhooks. Puede encontrar direcciones para eso en Internet. Para simplificar, usaremos LongPolling. La forma en que se procesan los mensajes y lo que envía en respuesta solo está limitada por las capacidades del idioma y la biblioteca. Todo lo demás depende de usted. Puedes crear un bot que buscará videos de YouTube por ti. Puedes hacer un bot que te envíe lo que te envías a ti mismo todos los días, como una cápsula del tiempo de hace un año. O puede aprender a integrarse con sistemas CRM y crear bots para pequeñas empresas: solo está limitado por su imaginación. Hacia adelante. Quienes han usado bots saben que es conveniente interactuar con ellos mediante comandos que comiencen con el /carácter " ", por ejemplo, /start. Pero hay una forma más conveniente: botones. Hay dos tipos de botones: los que aparecen debajo de un campo de entrada ( ReplyKeyboardMarkup) y los botones que están directamente debajo del mensaje al que están vinculados (InlineKeyboardMarkup). Puede obtener una comprensión básica de ellos a partir de sus descripciones en la documentación.

ResponderTecladoMarcado

En realidad, esta es una matriz de matrices de botones: List<KeyboardRow <KeyboardButton>>. Aquí hay un código de muestra que crea un teclado:

public synchronized void setButtons(SendMessage sendMessage) {
        // Create a keyboard
        ReplyKeyboardMarkup replyKeyboardMarkup = new ReplyKeyboardMarkup();
        sendMessage.setReplyMarkup(replyKeyboardMarkup);
        replyKeyboardMarkup.setSelective(true);
        replyKeyboardMarkup.setResizeKeyboard(true);
        replyKeyboardMarkup.setOneTimeKeyboard(false);

        // Create a list of keyboard rows
        List<KeyboardRow> keyboard = new ArrayList<>();

        // First keyboard row
        KeyboardRow keyboardFirstRow = new KeyboardRow();
        // Add buttons to the first keyboard row
        keyboardFirstRow.add(new KeyboardButton("Hi"));

        // Second keyboard row
        KeyboardRow keyboardSecondRow = new KeyboardRow();
        // Add the buttons to the second keyboard row
        keyboardSecondRow.add(new KeyboardButton("Help");

        // Add all of the keyboard rows to the list
        keyboard.add(keyboardFirstRow);
        keyboard.add(keyboardSecondRow);
        // and assign this list to our keyboard
        replyKeyboardMarkup.setKeyboard(keyboard);
    }
Llamamos a este método en el sendMsg()método, después de pasarle un mensaje. Así configuramos un teclado para ese mensaje. Cuando enviemos este mensaje al usuario, verá el texto de nuestro mensaje y 2 botones que dicen "Hola" y "Ayuda" , uno debajo del otro. Cuando se hace clic en uno de estos botones, se envía al bot un mensaje que contiene el texto del botón. Entonces, si el cliente hace clic en "Ayuda" , el bot recibirá un mensaje con "Ayuda". Para el bot, parecerá que el propio cliente escribió "Ayuda" y envió el texto al bot. Y luego procesas los mensajes.

Marcado de teclado en línea

Esta es también una matriz de matrices. Es similar al Markup anterior, pero la lógica funciona un poco diferente aquí. Este tipo de teclado se adjunta a un mensaje específico y existe solo para él. Aquí hay un método para configurar un teclado en línea:

private void setInline() {
        List<List<InlineKeyboardButton>> buttons = new ArrayList<>();
        List<InlineKeyboardButton> buttons1 = new ArrayList<>();
        buttons1.add(new InlineKeyboardButton().setText("Button").setCallbackData(17));
        buttons.add(buttons1);

        InlineKeyboardMarkup markupKeyboard = new InlineKeyboardMarkup();
        markupKeyboard.setKeyboard(buttons);
    }
Cree un Listdentro de Listy agregue el botón en línea a la primera fila. Este botón puede contener una URL, un enlace a un canal o un correo electrónico CallbackQuery, sobre el cual escribiré un poco más adelante. Aquí es donde configuramos el texto de nuestro botón, que es lo que verá el usuario, y luego configuramos los datos que se enviarán al bot. En nuestro ejemplo, el usuario ve "Hola", y cuando se presiona el botón, se enviará el número 17 al bot. Este es nuestro CallbackQuery. Unas palabras con respecto a CallbackQuery. Para obtener estos datos del Updateobjeto, debe ejecutar update.getCallbackQuery(). Este método devuelve un CallbackQuery, desde el cual puede acceder a los datos pasados ​​al bot. No intente obtener estos datos a través del update.getMessage().getText()método; obtendrá un 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 a un nuevo hilo para su procesamiento; si hay un CallbackQuery, lo enviamos al subproceso apropiado para su procesamiento. Puede enviar una respuesta a un CallbackQuery. Cada objeto en Telegram tiene su propia identificación. Para enviar una respuesta a un CallbackQuery, solo necesita saber su id, que obtenemos del objeto correspondiente. Para enviar una respuesta, llamamos 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 en una respuesta a un CallbackQueryno debe tener más de 200 caracteres! Después de enviar dicha respuesta, el cliente verá una ventana emergente que contiene el mensaje. Esta ventana puede desaparecer unos segundos después de aparecer, o puede persistir hasta que el usuario presione Aceptar. Para cambiar de modo, llamamos al answer.setShowAlert(true)método. Si pasa trueal método, la ventana persiste hasta que se presiona OK. Si pasa falso, desaparece después de 5 segundos. Estas son todas las características básicas de la biblioteca Telegram Bot . Si lo desea, puede aprender cosas como cómo enviar multimedia, geolocalización, etc. Pasemos a implementar nuestro bot en una plataforma de alojamiento. Para mi proyecto, elegí Heroku. Creo que es una plataforma de hospedaje bastante conveniente con su propia CLI. Es gratis, pero en este plan su bot hiberna después de 30 minutos de no recibir solicitudes. Se activará cuando se reciba una solicitud. Esto sucede tan rápido que ni siquiera lo notará (a menos, por supuesto, que la conexión a la base de datos no se reinicie). El plan gratuito está limitado por una base de datos de 5 MB, 100 MB de espacio en disco, 2 TB de datos por mes y 1 banco de pruebas. Un banco de pruebas es su aplicación en ejecución. Diré de inmediato que fue la implementación lo que me causó dificultades, ya que nunca antes había implementado mis aplicaciones. Durante la implementación, Heroku requiere un archivo llamado Procfile (sin extensión). Lo creamos en la raíz del proyecto. Dentro, escribimos worker: sh target/bin/workerBot, donde workerBot es el nombre especificado en pom.xml. una shSe iniciará el script, generado por el complemento Maven Application Assembler (appassembler-maven-plugin). El script describe cómo iniciar un archivo jar compilado. El nombre de la clase a lanzar se especifica entre <mainClass>y </mainClass>, mientras que el nombre del script se da entre <name>y </name>en 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 e instalar Git y la CLI de Heroku . Si su aplicación necesita una base de datos, no olvide agregar la base de datos requerida cuando cree una nueva aplicación. Además, debe determinar el host, el nombre de usuario, la contraseña y el puerto de su base de datos y luego indicarlos en su aplicación. A continuación, antes de implementarlo, cree su proyecto con Maven .

mvn clean install
Primero, vamos a nuestro directorio de proyectos e inicializamos el repositorio con el comando git init. Luego añadimos nuestro proyecto a este repositorio.

git add .
Luego cometemos los cambios.

git commit -m "First commit in the project"
A continuación, debe iniciar sesión en heroku. Escriba lo siguiente en la línea de comando

heroku login
Ingrese las credenciales que creó durante el registro. Después de eso, determine la URL de su repositorio en heroku. Esto lo haces en la configuración. Entonces escribimos

git remote add heroku [url]
Se agrega un repositorio heroku remoto para su repositorio. A continuación escribimos

git push heroku master
Luego esperamos… si la aplicación se despliega con éxito, ejecuta el siguiente comando

heroku ps:scale worker=1
Y eso es todo, su aplicación está en funcionamiento. Si no es así, mire los registros cuidadosamente. Lo más probable es que un error en su aplicación haya hecho que falle. Gracias por leer un artículo tan largo. Espero que alguien lo encuentre útil y que le ahorre mucho tiempo en las áreas que me dieron problemas durante el desarrollo.
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION