Gestionar bot telegram [Python]

B

Buenas.

Estoy creando un pequeño bot en Telegram tirando de la api oficial con requests, sé que hay paquetes como python-telegram-bot pero creo que para lo que quiero hacer no me vale porque en mi caso, necesito llamar a las funciones desde el backend y no desde el chat de telegram. He estado mirando pero, a no ser que no haya buscado suficiente, no se puede hacer.

El flujo de acción sería el siguiente (Siento el cutre dibujo):

Tengo hecho todo pero me falla el que, tras mandar la información de la api al usuario, el bot se quede esperando a que el usuario responda sobre lo que se la ha mandado.

He estado mirando y hay algunos que optan por meter una base de datos para el usuario con un campo de status. Creo que haciendo que a la hora de mandar la info al usuario a través del bot se le cambie el atributo puede funcionar.

Ej:

Por defecto el atributo vale 0, por lo que todo lo que escriba el usuario en telegram no hará que se ejecute el último fichero .py y, si vale 1 pues sí, y automáticamente después de ejecutar el .py volver a dejarlo en 0.

Igual es una chapuza hacerlo así pero la verdad que le llevo dando vueltas a estas tontería bastante tiempo.

A ver qué me decís, gracias.

1
bornex

¿A que te refieres con "funciones desde el backend"? Esa librería se puede llamar desde una aplicación en el lado del servidor sin problema. Yo tengo un bot scraper para ofertas y chollos y utilizo una librería para comunicarme con la API de telegram (que funciona a través del protocolo HTTP).

La API que te provee esa librería te permite justo hacer lo que estas pidiendo de que se quede "esperando", te quita de tener que hacer las llamadas tu y te provee con mejor gestión de errores. No veo ninguna razón para no usarla.

En cuanto a tu duda, no he usado nunca la API de telegram directamente, pero seguramente tendrás que usar alguna funcionalidad que te deje proveer con una función callback que sea la que se llame cuando el usuario mande el comando que esperas. Puedes mirar: https://core.telegram.org/bots/api#forcereply. Si este tipo de funcionalidad no existe, tendrás que hacer polling al endpoint en cuestión: un bucle while(true) y GET al endpoint que sea cada X tiempo, con un try catch para gestionar los errores que puedas tener.

En cuanto a lo de la base de datos, no se a lo que te refieres, pero si es que cada usuario tiene un estado y pueden cambiarlo a través de mensajes (comandos que empiezan por '/' por ejemplo), tendrás que guardar el user-id de cada usuario para poder identificarlos únicamente cada vez que te llegue un mensaje. Esto puedes hacerlo en una base de datos, puedes hacerlo en memoria (ojo que cuando re-despliegues el bot perderás los datos) o incluso en un fichero directamente en disco.

Espero haberte ayudado aunque sea un poco, sinceramente he leído tu post varias veces pero no me he enterado de mucho xD

1 1 respuesta
B

#2 La verdad que sí que está explicado un poco como el culo.

He ingeniado una manera de solventarlo, cuando se manda el resultado de la llamada a la API externa, está viene con dos botones (si o no), el JSON que devuelve esta "encuesta" tiene una estructura diferente al JSON que se genera cuando escribes directamente en el chat por lo que he tirado por ahí.

Esto tiene bastantes inconvenientes, pero me hace el apaño de momento, además de que es un bot privado por lo que menos problema aún. Aunque vaya, me estoy dando cuenta de que siempre pongo esta excusa y me parece que una app debería estar siempre enfocada al público general aunque al final acabes usándola solamente tú.

Sobre lo de las llamadas desde el backend es básicamente que, usando esa librería, veo que siempre se ejecutan las funciones del bot (mandar mensajes, conversaciones) dependiendo de lo que mandes por el chat de Telegram y en mi caso no me interesa eso.

Lo que busco es parecido a lo tuyo de las ofertas, me hago peticiones a una api, y comparo el resultado nuevo con el viejo que se guarda en un .JSON, en el caso de que los JSON sean distintos toca llamar a una función del bot y es aquí donde he tenido problemas usando la librería, sin embargo, tirando directamente de la API de Telegram ha funcionado todo desde el primer momento.

Muchas gracias por tu tiempo.

1 respuesta
Yekale7

#3 No has mirado bien la documentación y tampoco te has explicado. Todo lo que comentas se puede hacer... ¿Sabes que la librería que has indicado permite crear tareas recurrentes? Y sí, puede hacer llamadas a funciones de otros módulos o peticiones a una DB...

Además, la interacción con el usuario (flujo) puede implementarse como una máquina de estados. Lo dicho, revisa la documentación y aclara lo que quieres hacer...

1 respuesta
B

#4 Sí, tienes toda la razón.

Volveré a pararme a leer toda la docu bien y seguro que lo saco.

Gracias!

1 respuesta
Yekale7

#5 Revisando un poco lo que has puesto, creo que te he entendido.

Imagino que tienes ciertos scripts ejecutándose, llegado el momento quieres que envíen un mensaje y esperar la respuesta para hacer X.
Tienes dos formas:

  1. El bot ejecutando de forma periódica los scripts, y este siempre estaría activo
  2. Inicializadas el bot llamando al main, con una máquina de estado simple. Una vez recibas la respuesta lo devuelves al módulo que ha llamado al bot.

edit: antes de ir a pelo con la API de telegram, puedes usar: https://github.com/LonamiWebs/Telethon

2 respuestas
B

#6 Sí, a ver básicamente tengo un script que está funcionando todo el rato haciendo peticiones a una API, en cierto momento (cuando el script ha detectado un cambio) me interesa que le pase al bot la información que ha cambiado y la mande al usuario por telegram. Por lo que ambos scripts deben estar corriendo en todo momento (o levantar el bot cuando se produzca el cambio pero llevaría más tiempo, aunque fueran pocos segundos).

El problema era que con la librería no sabía si se podía llamar a una función del script del bot de telegram desde otro fichero porque los ejemplos que había visto iniciaban las funciones según lo que el usuario escribía en el chat.

Reviso la docu de #1, y telethon.

Muchas gracias.

B

Doble posteo para decir que ya está el proyecto acabado, al menos el uso inicialmente pensado.

Funciona todo, desde la petición a la api hasta el envío del mensaje a una web a través de Selenium por lo que me siento bastante satisfecho con el proyecto aunque sea una tontada, pero he usado cosas que nunca había utilizado.

Ahora creo que lo voy a mejorar metiendo base de datos para guardar mensaje y a qué elemento corresponde.

Gracias a todos y a #6 por enseñarme semejante librería.

1
B

Ya tengo la app en docker.

Ahora me queda mejorar ciertas cosas del código (variables en ficheros .env (supongo), dejarlo comentado, borrar partes obsoletas) y ponerme con toda la parte de la base de datos.

Usuarios habituales