diff --git a/src/moai/bot/main.py b/src/moai/bot/main.py new file mode 100644 index 0000000..1546731 --- /dev/null +++ b/src/moai/bot/main.py @@ -0,0 +1,82 @@ +"""MoAI Telegram bot entry point. + +Sets up and runs the Telegram bot with database lifecycle hooks. + +Usage: + python -m moai.bot.main +""" + +import logging + +from telegram.ext import Application, ApplicationBuilder + +from moai.bot.config import BotConfig +from moai.bot.handlers import register_handlers +from moai.core.database import close_db, create_tables, init_db + +# Module-level config reference for post_init callback +_config: BotConfig | None = None + + +async def post_init(application: Application) -> None: + """Initialize database after bot application is built. + + Called automatically by python-telegram-bot after Application.build(). + Sets up the database engine and creates tables if needed. + """ + logger = logging.getLogger(__name__) + + if _config is None: + raise RuntimeError("Config not initialized before post_init") + + init_db(_config.database_url) + await create_tables() + logger.info("Database initialized") + + +async def post_shutdown(application: Application) -> None: + """Clean up database on bot shutdown. + + Called automatically by python-telegram-bot during Application shutdown. + Disposes database engine and releases connections. + """ + logger = logging.getLogger(__name__) + await close_db() + logger.info("Database closed") + + +def main() -> None: + """Run the MoAI Telegram bot. + + Loads configuration from environment, sets up the Application with + database lifecycle hooks, registers handlers, and starts polling. + """ + global _config + + _config = BotConfig.from_env() + + logging.basicConfig( + level=getattr(logging, _config.log_level.upper(), logging.INFO), + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", + ) + logger = logging.getLogger(__name__) + + app = ( + ApplicationBuilder() + .token(_config.bot_token) + .post_init(post_init) + .post_shutdown(post_shutdown) + .build() + ) + + # Store config in bot_data for handler access + app.bot_data["config"] = _config + + register_handlers(app) + + logger.info("Starting MoAI bot...") + app.run_polling() + + +if __name__ == "__main__": + main()