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