Estamos desarrollando un bot de Telegram para rastrear películas en NodeJS y TypeScript



Se te ocurrió que vienes al cine y ves trailers antes del comienzo de la película, mientras que algunos se aferran a ti con bastante fuerza y ​​te prometes ver esta película si no en el cine, al menos más tarde, cuando esté disponible para descargar ? Me atrevo a sugerir que sí. Pero a menudo termina con el hecho de que se olvida con éxito y, en el mejor de los casos, encuentra accidentalmente esta película desplazándose por la lista de películas ya lanzadas.

A menudo me encontré con ese problema y decidí crearlo con Eve - Telegram-bot, que me ayuda a no olvidar los lanzamientos de mis películas favoritas. ¡Qué es, cómo funciona y cómo se desarrolló, puede leer debajo del corte!



Prólogo


Este artículo no es una guía detallada sobre cómo crear bots de Telegram. Y aunque en el curso del artículo a menudo me referiré a mi proyecto, el propósito de este material es una historia sobre el desarrollo en general, es decir, la elección de tecnologías, puntos clave y dificultades que encontré.

Por qué


Entonces, como escribí anteriormente, a menudo olvido ver esas películas cuyo trailer me gustó. He estado pensando en una solución a este problema durante mucho tiempo. Lo primero que se me ocurrió fue la creación de una aplicación nativa para teléfonos inteligentes, pero desde Nunca antes había hecho esto, tomaría mucho tiempo y no el hecho de que el resultado final satisfaría mis necesidades, así como las necesidades de los usuarios potenciales.

La siguiente idea fue crear una PWA. Es una opción bastante interesante para familiarizarse con la tecnología, pero decidí dejarla para el futuro. Al mismo tiempo, he estado usando Telegram durante mucho tiempo y durante todo este tiempo he acumulado una cantidad suficiente de bots que periódicamente hacen que mi vida sea un poco más fácil. Finalmente, después de sopesar todos los pros y los contras, decidí que esta plataforma es perfecta para esta idea.

Selección de tecnología


Si pasas por Github para bots de Telegram, puedes ver que la mayoría de ellos están escritos en Python. Python es realmente un gran lenguaje y excelente para esta idea, pero quería implementar este proyecto específicamente en NodeJS + TypeScript. Aplicando los filtros apropiados, encontré 2 herramientas bastante populares: node-telegram-bot-api y Telegraf.js .

Antes de esta experiencia en el desarrollo de bots no tenía, por lo que al elegir entre estos dos no estaba claro qué parámetros se deben mirar. Como resultado, después de mirar la documentación y revisar los problemas de cada una de las bibliotecas, me decidí por Telegraf.js. El factor decisivo fue la disponibilidad de middlewares, que está diseñado de la misma manera que en el popular framework Express.js. Telegraf.js también tiene un historial de actualizaciones más frecuente y documentación bien estructurada, lo que sugiere que los desarrolladores están haciendo un esfuerzo suficiente para mejorar la herramienta. Además, contiene sugerencias para TypeScript, que definitivamente es una ventaja para la pila seleccionada.

Telegraf.js


Telegraf.js es la biblioteca principal en la que se escribió el proyecto. Utiliza varios enfoques interesantes que le permiten crear bots complejos mientras mantiene la simplicidad del código. A continuación se detallan los mecanismos más interesantes:

  • Middlewares : sí, estos son los mismos middlewares que están disponibles en Express.js. Cuando el usuario envía algo al bot, el mensaje primero pasa por todos los middlewares registrados y luego llega al controlador. Middlewares puede modificar el contexto, así como suspender la ejecución de la solicitud, por ejemplo, si un usuario normal intenta ingresar al área para los administradores. Telegraf.js proporciona algunos middlewares extremadamente útiles listos para usar, pero también puede usarlos usted mismo. Es decir, los middlewares se consideran características asesinas de Telegraf.js
  • Sesiones : sesiones que pueden almacenar información que no está vinculada al controlador. Puede dar una analogía con variables globales a las que se puede acceder desde cualquier parte del bot. Una cosa muy conveniente, que se utiliza, por ejemplo, para la localización. Es posible almacenar sesiones en diferentes modos: DB, redis, archivos locales, etc.
  • Webooks : el bot puede funcionar en dos modos: sondeo largo o Webhooks . Y aunque funcionan igualmente rápido, es mejor usar la segunda opción en un entorno de producción. Por lo tanto, el bot no necesitará tocar el servidor de Telegram, sino que recibirá todas las actualizaciones él mismo.

    Importante: Un requisito previo para Webhooks es la compatibilidad con el servidor SSL / TLS. También asegúrese de que el puerto en el que se ejecuta Webhook esté abierto y accesible desde el exterior.
  • Marcado : con esta clase puedes enseñarle al bot a responder en marcado / marcado de descuento. Esto es importante si, por ejemplo, está creando un juego HTML. Sin embargo, en mi proyecto, lo usé solo para texto en negrita / cursiva.
  • Stage es un módulo extremadamente interesante que me ayudó a mantener los nervios y algunas horas de desarrollo. Aquí lo contaré con más detalle.
    El bot puede escuchar los mensajes del usuario y, según el tipo o el contenido del mensaje, redirigirlo a un controlador en particular que realizará su función y enviará una respuesta al usuario. Se ve así:

    bot.hears('hello', async ctx => { await ctx.reply('Hello!'); }); 

    Funciona simplemente: si escribes hola al bot, simplemente responderá ¡Hola! Conociendo este aspecto del trabajo, tratemos de imaginar cómo puede funcionar el bot para buscar películas:

    1. El usuario escribe que quiere ir a buscar películas;
    2. El usuario conduce el nombre de la película;
    3. El bot devuelve una lista de películas y le pide al usuario que guarde la película seleccionada en su biblioteca;
    4. ...

    ¡Atención, una pregunta! ¿Cómo puede distinguir un bot cuando un usuario le escribe que quiere comenzar a buscar una película y cuando escribe el nombre de la película a buscar?

    Sí, puede tomar cualquier texto enviado como el nombre de la película, pero queremos que el bot con blackjack y hookers sea una buena interfaz.

    ¡Y aquí entran en escena las escenas! Será más fácil saberlo con el ejemplo anterior. Cuando el usuario dice que quiere ir a buscar películas, lanzamos la escena. Dentro de esta escena hay controladores de texto separados: bot.hears (...). Por lo tanto, todos los mensajes posteriores se relacionarán directamente con la búsqueda de películas hasta que el usuario escriba un mensaje para salir y abandonar la escena. Después de eso, los controladores dentro de esta escena se desactivan hasta que el usuario regrese allí nuevamente. A continuación, describiré cómo usé las escenas para hacer que el manejo de eventos sea lo más simple posible.


Estructura del proyecto


Existe la sospecha de que el artículo resultará bastante voluminoso y, por lo tanto, para no estirarlo aún más, omitiré algunos puntos. Por ejemplo, para que el bot comience a funcionar, debe comenzar obteniendo el token API Telegram Bot. Puede leer sobre cómo hacerlo en la documentación oficial de Telegram o en la documentación de Telegraf.js.

La estructura de archivos del proyecto es la siguiente:

Estructura del proyecto


Funciona de la siguiente manera:

  • src / controllers : estas son las escenas sobre las que se escribió anteriormente. En este proyecto, cada escena es un controlador separado que procesa las solicitudes correspondientes.
  • src / locales : traducciones para diferentes idiomas. Telegraf.js hace que sea relativamente fácil agregar localización al bot usando middlewares.
  • src / models - modelos para MongoDB.
  • src / types : sugerencias para TypeScript. Desafortunadamente, no todas las bibliotecas utilizadas en el proyecto tienen tiempos predeterminados.
  • src / util : varias funciones auxiliares que se utilizan en diferentes partes del proyecto. Aquí puede ver cómo funciona la disponibilidad de la película para descargar, administrar sesiones, crear teclados, manejadores de errores y mucho más.
  • src / bot.ts : el archivo principal donde se realiza toda la preparación y el lanzamiento del bot.
  • src / telegram.ts : en este caso, creamos un objeto de la clase Telegram de la biblioteca Telegraf.js. Usando este objeto, podemos enviar mensajes a los usuarios primero, usando su ID, y no esperar hasta que escriban algo. Por ejemplo, en este proyecto, enviamos al usuario un mensaje indicando que la película que estaba siguiendo ya se puede descargar. Por supuesto, este objeto proporciona muchas más funciones.
  • Todo lo demás son configuraciones para diferentes partes del proyecto que no se discutirán en este artículo.

Inicialización y Lanzamiento


Cuando descubrimos la estructura del proyecto, veamos cómo comienza realmente el bot. Nuevamente, para acortar el artículo, no insertaré el código completo aquí, sino que solo hablaré sobre los momentos principales, en mi opinión. Puede ver el código completo en el repositorio, cuyo enlace está disponible al final del artículo.

Todo comienza con la conexión a la base de datos, que almacena información sobre los usuarios y las películas que rastrean. Después de una conexión exitosa, registramos todas las escenas utilizadas en el proyecto, establecemos parámetros para la localización y agregamos varios middlewares: sesiones de procesamiento, localización, configuración de escenas, así como varias de las nuestras. Uno de ellos, por ejemplo, recibe toda la información sobre el usuario de acuerdo con su ID y la agrega al contexto que se utiliza en los controladores. Finalmente, después de todas las preparaciones básicas, lanzamos el bot en modo de desarrollo (sondeo largo) o de producción (Webhooks).

Importante: si utiliza diferentes métodos para recibir actualizaciones (sondeo largo y Webhooks), cuando inicie el bot en modo de sondeo largo, primero elimine el Webhook que escucha utilizando la solicitud GET en api.telegram.org/botYOUR_TOKEN/deleteWebhook . De lo contrario, el bot podría no funcionar correctamente.

Manejar la entrada del usuario


¡Hurra! El bot funciona, está conectado a la base de datos y está listo para recibir mensajes de los usuarios. ¿Pero cómo hacerlo bien?

En primer lugar, será conveniente para los usuarios utilizar el teclado Telegram incorporado. De hecho, cuando hace clic en los botones de este teclado, los mensajes se envían con el contenido de estos botones. A continuación, simplemente agregamos controladores para este texto y realizamos ciertas acciones.

El archivo bot.ts contiene dichos controladores. Como el bot admite dos idiomas, los botones también pueden contener texto diferente, en ruso e inglés. Telegraf-i18n tiene una función de coincidencia que puede manejar hacer clic en el mismo botón con diferentes idiomas.

La mayoría de los controladores en bot.ts realizan una sola función: lanzan al usuario a la escena correspondiente. Por lo tanto, tenemos varias secciones: búsqueda de películas, mi colección, configuraciones y contactos. Cada sección tiene su propia escena y su propio botón, cuando se hace clic, el usuario se mueve a la escena correspondiente.

Importante: asegúrese de agregar un controlador que libere al usuario de la escena, de lo contrario se arriesga a quedarse allí para siempre. También será útil hacer un comando general (/ saveme se usa en el bot), que se agregará a cada escena y al archivo principal. Este comando servirá como una salida de cualquier escena, así como restablecer la configuración del usuario.

Y ahora, el usuario quiere ir a buscar películas. Al hacer clic en el botón apropiado, lo movemos a la escena de búsqueda. Por conveniencia, cada escena tiene su propia carpeta con archivos, cada uno de los cuales realiza una función específica.

Dentro de la escena, puede usar sus middlewares, que están en el archivo middlewares.ts. Por ejemplo, al usar middleware en la escena de búsqueda, simplemente podemos reenviar toda la información sobre la película a los métodos apropiados, en lugar de realizar la misma función cada vez dentro de ellos.

Telegram también tiene un teclado en línea. Quizás haya encontrado mensajes con votos, debajo de los cuales hay varios botones translúcidos, y cuando hace clic en uno de ellos, el número de votos cambia. Estos botones son el teclado en línea.

Así se ve Eve


Cada botón contiene información, cuando hace clic en el botón, se transmitirá al controlador correspondiente. ¡El tamaño de la información transmitida no debe exceder los 64 bytes! Para enseñarle al bot a escuchar clics en los botones, debemos registrarlos usando bot.action (/ trigger /, callback). El primer parámetro contiene todos los datos vinculados al botón. Decidí usar algo como Acciones de Redux, donde se adjunta un objeto de la forma {a: actionName, p: payload} a cada botón. Al registrar oyentes, podemos usar un RegExp simple, por ejemplo: bot.action (/ actionName /, callBack). Todos los controladores para el teclado en línea están en los archivos actions.ts.

Además, en algunas escenas hay archivos helpers.ts, que contienen pequeñas funciones para descargar los archivos restantes. En su mayor parte, hay generadores de teclado para diversas acciones del usuario.

Localización


Como este es un tema importante, creo que vale la pena mencionarlo por separado. Como dije antes, Telegraf.js contiene una cantidad bastante grande de middlewares, uno de los cuales es telegraf-i18n . El repositorio contiene instrucciones detalladas y no tuve ningún problema especial con esto, pero agregaré algunas palabras sobre cómo funciona esto en este proyecto.

Hay una carpeta local donde se encuentran los archivos para la localización, que son un objeto JSON de la forma {"clave": "traducción"}. Además, siempre que necesitemos usar diferentes idiomas, usamos el método de esta biblioteca, donde transferimos la traducción que necesitamos por clave, y en la salida obtenemos la traducción correspondiente. Se puede usar una sesión para almacenar información sobre el idioma seleccionado por el usuario. También vale la pena mencionar nuevamente los botones. Hay una función de coincidencia en la misma biblioteca, por lo que si el texto en el botón cambia según el idioma, esta función lo ayudará a colgar al oyente correcto.

Importante: si va a utilizar la localización y escribir un bot en TypeScript, no olvide agregar la carpeta de traducción a tsconfig.json, de lo contrario el código no se compilará. Por ejemplo:

 "include": ["src/locales/*.json"] 

Conclusión


¡Gracias por leer hasta el final! En este artículo, traté de describir el proceso de creación de un bot de Telegram en su conjunto lo más detallado posible, sin un fuerte apego a mi proyecto. Espero que después de leer este artículo, además de estudiar el código fuente de Eve, puedas crear fácilmente un bot que pueda ayudarte.

Según lo prometido, puede ver el código fuente en GitHub e intentar Eve en acción aquí . Estaré inmensamente agradecido por cualquier crítica y sugerencia de mejora.

También me gustaría señalar la sección en la documentación de Telegraf.js con proyectos interesantes de código abierto que puede ver e inspirarse en la arquitectura y las soluciones. Yo, a su vez, quiero mencionar uno de ellos: The Guard Bot . Un bot realmente grande y bien hecho, de donde tomé prestadas algunas de las soluciones para mi desarrollo.

Y en el momento en que dije todo lo que quería, ¡con gusto responderé sus preguntas, sugerencias y comentarios!

Source: https://habr.com/ru/post/443876/


All Articles