import os import logging from dotenv import load_dotenv from telegram.ext import ( Application, CommandHandler, CallbackQueryHandler, ChatMemberHandler, MessageHandler, ConversationHandler, filters, ) from app.database import init_db from app.handlers import ( start, help_command, sync_groups_command, start_callback, manage_messages, manage_groups, list_messages, list_groups, send_message, my_chat_member, userbot_menu, userbot_settings, userbot_init, userbot_collect_groups, userbot_collect_members, userbot_parse_members, cancel_userbot, ) from app.handlers.message_manager import ( create_message_start, create_message_title, create_message_text, select_groups, handle_message_input, ) from app.handlers.telethon_client import telethon_manager from app.utils.keyboards import CallbackType from app.settings import Config # Загружаем переменные окружения load_dotenv() # Настройка логирования logging.basicConfig( format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG ) logger = logging.getLogger(__name__) async def debug_update_handler(update, context): """Обработчик для отладки всех обновлений""" logger.info(f"🎯 Получено обновление: {update}") if update.message: logger.info(f"📨 Сообщение от {update.effective_user.id}: {update.message.text}") elif update.callback_query: logger.info(f"🔘 Callback от {update.effective_user.id}: {update.callback_query.data}") else: logger.info(f"❓ Неизвестное обновление: {update.to_dict() if hasattr(update, 'to_dict') else str(update)}") return None # Получаем конфигурацию # Для UserBot контейнера: если есть TELETHON переменные и нет BOT_TOKEN - это ОК is_userbot_only = ( os.getenv('TELETHON_API_ID') and os.getenv('TELETHON_API_HASH') and os.getenv('TELETHON_PHONE') and not os.getenv('TELEGRAM_BOT_TOKEN') ) if not is_userbot_only: if not Config.validate(): raise ValueError("❌ Конфигурация некорректна. Проверьте .env файл") async def main() -> None: """Запуск бота с поддержкой гибридного режима""" # Инициализируем БД logger.info("Инициализация базы данных...") await init_db() logger.info("✅ База данных инициализирована") # Инициализируем Telethon если включен if Config.USE_TELETHON: logger.info("Инициализация Telethon клиента...") success = await telethon_manager.initialize() if success: logger.info("✅ Telethon клиент инициализирован") else: logger.warning("⚠️ Ошибка инициализации Telethon, продолжим с режимом бота") # Выводим информацию о режиме mode = Config.get_mode() logger.info(f"📡 Режим работы: {mode}") if mode == 'hybrid': logger.info("🔀 Бот будет использовать Telethon как fallback для закрытых групп") # Создаем приложение application = Application.builder().token(Config.TELEGRAM_BOT_TOKEN).build() # Добавляем отладчик для всех текстовых сообщений (самый низкий приоритет) application.add_handler(MessageHandler(filters.ALL, debug_update_handler), group=100) # Добавляем обработчики команд (высший приоритет, группа 0) application.add_handler(CommandHandler("start", start), group=0) application.add_handler(CommandHandler("help", help_command), group=0) application.add_handler(CommandHandler("sync_groups", sync_groups_command), group=0) # Добавляем обработчики callback'ов (группа 1) application.add_handler(CallbackQueryHandler(start_callback, pattern=f"^{CallbackType.MAIN_MENU.value}$"), group=1) application.add_handler(CallbackQueryHandler(manage_messages, pattern=f"^{CallbackType.MANAGE_MESSAGES.value}$"), group=1) application.add_handler(CallbackQueryHandler(manage_groups, pattern=f"^{CallbackType.MANAGE_GROUPS.value}$"), group=1) application.add_handler(CallbackQueryHandler(list_messages, pattern=f"^{CallbackType.LIST_MESSAGES.value}$"), group=1) application.add_handler(CallbackQueryHandler(list_groups, pattern=f"^{CallbackType.LIST_GROUPS.value}$"), group=1) application.add_handler(CallbackQueryHandler(send_message, pattern=r"^send_msg_\d+$"), group=1) # CREATE_MESSAGE обрабатывается отдельным handler'ом с управлением состоянием application.add_handler(CallbackQueryHandler(create_message_start, pattern=f"^{CallbackType.CREATE_MESSAGE.value}$"), group=1) # Добавляем обработчик CallbackQuery для управления UserBot application.add_handler(CallbackQueryHandler(userbot_menu, pattern="^userbot_menu$"), group=1) application.add_handler(CallbackQueryHandler(userbot_settings, pattern="^userbot_settings$"), group=1) application.add_handler(CallbackQueryHandler(userbot_init, pattern="^userbot_init$"), group=1) application.add_handler(CallbackQueryHandler(userbot_collect_groups, pattern="^userbot_collect_groups$"), group=1) application.add_handler(CallbackQueryHandler(userbot_collect_members, pattern="^userbot_collect_members$"), group=1) application.add_handler(CallbackQueryHandler(userbot_parse_members, pattern=r"^userbot_members_\d+$"), group=1) # Добавляем обработчик для кнопки UserBot в главном меню application.add_handler(CallbackQueryHandler(userbot_menu, pattern=f"^{CallbackType.MANAGE_USERBOT.value}$"), group=1) # Select group callbacks application.add_handler(CallbackQueryHandler(select_groups, pattern=r"^select_group_\d+$"), group=1) application.add_handler(CallbackQueryHandler(select_groups, pattern=r"^done_groups$"), group=1) # MessageHandler для текстового ввода (название и текст сообщения) # Использует dispatch-функцию для маршрутизации в зависимости от состояния application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message_input), group=1) # Обработчик добавления/удаления бота из групп (группа 3) application.add_handler(ChatMemberHandler(my_chat_member, ChatMemberHandler.MY_CHAT_MEMBER), group=3) # Запускаем бота logger.info("🚀 Бот запущен. Ожидание команд...") try: await application.run_polling(allowed_updates=["message", "callback_query", "my_chat_member"]) finally: # Завершить Telethon клиент при выходе if Config.USE_TELETHON: logger.info("Завершение работы Telethon клиента...") await telethon_manager.shutdown() logger.info("✅ Telethon клиент остановлен") if __name__ == "__main__": import asyncio asyncio.run(main())