import asyncio import httpx from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup from telegram.ext import ApplicationBuilder, ContextTypes, CallbackQueryHandler, CommandHandler from database import AppConfig import logging logging.getLogger("httpx").setLevel(logging.WARNING) logging.getLogger("telegram").setLevel(logging.INFO) class TelegramManager: def __init__(self): self.app = None self.active_requests = {} self.is_connected = False async def check_internet(self): """Testa se o container tem internet""" try: async with httpx.AsyncClient(timeout=5.0) as client: await client.get("https://www.google.com") return True except: return False async def start(self): """Inicia o Bot""" token = AppConfig.get_val('telegram_token') chat_id = AppConfig.get_val('telegram_chat_id') if not token: print("🟡 Bot: Token não configurado.") return if self.is_connected: return print("🤖 Bot: Iniciando conexão...") if not await self.check_internet(): print("❌ Bot: Sem internet.") return try: self.app = ApplicationBuilder().token(token).build() self.app.add_handler(CommandHandler("start", self.cmd_start)) self.app.add_handler(CommandHandler("id", self.cmd_id)) self.app.add_handler(CallbackQueryHandler(self.handle_selection)) await self.app.initialize() await self.app.start() await self.app.updater.start_polling(drop_pending_updates=True) self.is_connected = True print("✅ Bot Online!") except Exception as e: print(f"❌ Falha no Bot: {e}") self.is_connected = False async def stop(self): """Para o Bot""" if self.app: try: if self.app.updater.running: await self.app.updater.stop() if self.app.running: await self.app.stop() await self.app.shutdown() except Exception as e: print(f"Erro ao parar bot: {e}") finally: self.is_connected = False self.app = None async def restart(self): """Reinicia a conexão (Útil após mudar token)""" print("🔄 Bot: Reiniciando serviço...") await self.stop() await asyncio.sleep(1) await self.start() # --- COMANDOS --- async def cmd_start(self, update: Update, context: ContextTypes.DEFAULT_TYPE): chat_id = update.effective_chat.id await update.message.reply_text(f"Olá! Configurado.\nSeu Chat ID é: `{chat_id}`", parse_mode='Markdown') async def cmd_id(self, update: Update, context: ContextTypes.DEFAULT_TYPE): await update.message.reply_text(f"`{update.effective_chat.id}`", parse_mode='Markdown') async def send_test_msg(self): """Envia mensagem de teste""" if not self.is_connected: return False chat_id = AppConfig.get_val('telegram_chat_id') if not chat_id: return False try: await self.app.bot.send_message(chat_id=chat_id, text="🚀 Clei-Flow: Teste de conexão bem sucedido!") return True except: return False # --- INTERAÇÃO --- async def ask_user_choice(self, filename, candidates): chat_id = AppConfig.get_val('telegram_chat_id') if not chat_id or not self.is_connected: return None request_id = f"req_{filename}" keyboard = [] for cand in candidates: text = f"{cand['title']} ({cand['year']})" callback_data = f"{request_id}|{cand['tmdb_id']}|{cand['type']}" keyboard.append([InlineKeyboardButton(text, callback_data=callback_data)]) keyboard.append([InlineKeyboardButton("🚫 Ignorar", callback_data=f"{request_id}|IGNORE|NONE")]) reply_markup = InlineKeyboardMarkup(keyboard) try: await self.app.bot.send_message( chat_id=chat_id, text=f"🤔 Clei-Flow:\nArquivo: {filename}", reply_markup=reply_markup, parse_mode='HTML' ) except: return None loop = asyncio.get_running_loop() future = loop.create_future() self.active_requests[request_id] = future try: result = await asyncio.wait_for(future, timeout=43200) return result except asyncio.TimeoutError: if request_id in self.active_requests: del self.active_requests[request_id] return None async def handle_selection(self, update: Update, context: ContextTypes.DEFAULT_TYPE): query = update.callback_query await query.answer() data = query.data.split('|') if len(data) < 3: return req_id = data[0] tmdb_id = data[1] media_type = data[2] if req_id in self.active_requests: future = self.active_requests[req_id] if tmdb_id == 'IGNORE': await query.edit_message_text(text=f"🚫 Ignorado.") future.set_result(None) else: await query.edit_message_text(text=f"✅ Processando...") future.set_result({'tmdb_id': int(tmdb_id), 'type': media_type}) del self.active_requests[req_id] else: await query.edit_message_text(text="⚠️ Expirado.") async def send_notification(self, message): chat_id = AppConfig.get_val('telegram_chat_id') if self.app and chat_id and self.is_connected: try: await self.app.bot.send_message(chat_id=chat_id, text=message) except: pass