55import traceback
66from telegram .constants import ParseMode
77from telegram .ext import Application , CommandHandler , CallbackQueryHandler , MessageHandler , filters
8+ from contextlib import asynccontextmanager
9+ from fastapi import FastAPI , Request , Response
10+ import uvicorn
811
912from bot_logic import COMMANDS , button
10- from models import init_db
1113from tg_ids import ROZEN_CHATID
1214
1315async def error_handler (update , context ):
@@ -54,16 +56,51 @@ async def post_init(application: Application):
5456 except Exception as e :
5557 logging .getLogger ("DCUBABOT" ).error (f"Failed to set bot commands: { e } " )
5658
59+ # Instancia global de la aplicación de Telegram
60+ application = Application .builder ().token (os .environ ["TELEGRAM_BOT_TOKEN" ]).post_init (post_init ).build ()
61+
62+ @asynccontextmanager
63+ async def lifespan (app : FastAPI ):
64+ # Setup de la aplicación de Telegram al arrancar FastAPI
65+ await application .initialize ()
66+ await application .start ()
67+
68+ webhook_url = os .environ ["WEBHOOK_URL" ]
69+ token = os .environ ["TELEGRAM_BOT_TOKEN" ]
70+ url = f'{ webhook_url .rstrip ("/" )} /{ token } '
71+ await application .bot .set_webhook (url = url )
72+
73+ yield
74+
75+ # Shutdown
76+ await application .stop ()
77+ await application .shutdown ()
78+
79+ app = FastAPI (lifespan = lifespan )
80+
81+ @app .post ("/{token}" )
82+ async def telegram_webhook (token : str , request : Request ):
83+ if token != os .environ ["TELEGRAM_BOT_TOKEN" ]:
84+ return Response (status_code = 403 )
85+
86+ try :
87+ data = await request .json ()
88+ update = telegram .Update .de_json (data = data , bot = application .bot )
89+ # Await the processing SYNCHRONOUSLY before returning 200 OK
90+ # This prevents Cloud Run from throttling the CPU while the bot is doing work
91+ await application .process_update (update )
92+ except Exception as e :
93+ logging .error (f"Failed to process update: { e } " )
94+
95+ return Response (status_code = 200 )
96+
5797def main ():
5898 """Start the bot."""
5999 logging .basicConfig (
60100 level = logging .INFO ,
61101 format = '[%(asctime)s] - [%(name)s] - [%(levelname)s] - %(message)s' ,
62102 )
63103
64-
65- application = Application .builder ().token (os .environ ["TELEGRAM_BOT_TOKEN" ]).post_init (post_init ).build ()
66-
67104 application .add_error_handler (error_handler )
68105
69106 # Add the logging middleware handler with a high priority
@@ -74,15 +111,9 @@ def main():
74111
75112 application .add_handler (CallbackQueryHandler (button ))
76113
77- webhook_url = os .environ ["WEBHOOK_URL" ]
78-
79- # Start the Bot
80- application .run_webhook (
81- listen = "0.0.0.0" ,
82- port = int (os .environ .get ("PORT" , 8080 )),
83- url_path = os .environ ["TELEGRAM_BOT_TOKEN" ],
84- webhook_url = f'{ webhook_url .rstrip ("/" )} /{ os .environ ["TELEGRAM_BOT_TOKEN" ]} ' ,
85- )
114+ # Run the FastAPI app via uvicorn
115+ port = int (os .environ .get ("PORT" , 8080 ))
116+ uvicorn .run (app , host = "0.0.0.0" , port = port )
86117
87118if __name__ == "__main__" :
88119 main ()
0 commit comments