From b79f525a33c824c04fc606446bbcbbdbdbd4946c Mon Sep 17 00:00:00 2001 From: ilyastar9999 Date: Thu, 4 Dec 2025 14:26:15 +0300 Subject: [PATCH] Update main.py --- tg-bot/main.py | 72 +++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 9 deletions(-) diff --git a/tg-bot/main.py b/tg-bot/main.py index bfa7907..5e58595 100644 --- a/tg-bot/main.py +++ b/tg-bot/main.py @@ -28,55 +28,71 @@ polling_task = None async def handle_button_click(callback_data: str, chat_id: int, message_id: int): """Handle inline button click""" + print(f"[BUTTON] Received callback: {callback_data} from chat {chat_id}") + if not callback_data.startswith("service_"): + print(f"[BUTTON] Invalid callback prefix: {callback_data}") return # Parse: service_{action}_{id_or_name} parts = callback_data.split("_", 2) if len(parts) != 3: + print(f"[BUTTON] Invalid callback format: {callback_data} (got {len(parts)} parts)") return action = parts[1] # start, stop, restart identifier = parts[2] # numeric service_id or 'name_{service_name}' + print(f"[BUTTON] Action: {action}, Identifier: {identifier}") # Determine if identifier is service_id (numeric) or service_name (prefixed with 'name_') if identifier.startswith('name_'): # Extract service name from identifier service_name = identifier[5:] # Remove 'name_' prefix service_id = None + print(f"[BUTTON] Looking up service by name: {service_name}") # Look up service_id from controller API try: + print(f"[BUTTON] Contacting controller at {CONTROLLER_API}/services") async with aiohttp.ClientSession() as session: headers = {"Authorization": f"Bearer {SECRET_TOKEN}"} async with session.get(f"{CONTROLLER_API}/services", headers=headers) as resp: + print(f"[BUTTON] Controller response: HTTP {resp.status}") if resp.status == 200: services = await resp.json() + print(f"[BUTTON] Found {len(services)} services: {[s.get('name') for s in services]}") # Find service by name for svc in services: if svc.get('name') == service_name: service_id = svc.get('id') + print(f"[BUTTON] Matched service '{service_name}' to ID {service_id}") break if not service_id: + error_msg = f"❌ Service '{service_name}' not registered in controller" + print(f"[BUTTON] {error_msg}") await bot.edit_message_text( chat_id=chat_id, message_id=message_id, - text=f"❌ Service '{service_name}' not registered in controller" + text=error_msg ) return else: + error_msg = f"❌ Failed to fetch services (HTTP {resp.status})" + print(f"[BUTTON] {error_msg}") await bot.edit_message_text( chat_id=chat_id, message_id=message_id, - text=f"❌ Failed to fetch services (HTTP {resp.status})" + text=error_msg ) return except Exception as e: + error_msg = f"❌ Error: {str(e)[:100]}" + print(f"[BUTTON] Exception during service lookup: {str(e)}") await bot.edit_message_text( chat_id=chat_id, message_id=message_id, - text=f"❌ Error: {str(e)[:100]}" + text=error_msg ) await log_message(chat_id, f"Service lookup error", False, str(e)) return @@ -84,32 +100,47 @@ async def handle_button_click(callback_data: str, chat_id: int, message_id: int) # Identifier is numeric service_id try: service_id = int(identifier) + print(f"[BUTTON] Using numeric service_id: {service_id}") except ValueError: + print(f"[BUTTON] Failed to parse service_id from: {identifier}") return try: + api_url = f"{CONTROLLER_API}/services/{service_id}/action" + print(f"[BUTTON] Executing {action} on service {service_id} at {api_url}") + async with aiohttp.ClientSession() as session: - api_url = f"{CONTROLLER_API}/services/{service_id}/action" headers = {"Authorization": f"Bearer {SECRET_TOKEN}"} data = {"action": action} + print(f"[BUTTON] Sending POST request with data: {data}") async with session.post(api_url, json=data, headers=headers, timeout=aiohttp.ClientTimeout(total=10)) as resp: + response_text = await resp.text() + print(f"[BUTTON] Controller response: HTTP {resp.status}") + print(f"[BUTTON] Response body: {response_text[:200]}") + if resp.status == 200: + success_msg = f"✅ Service action '{action}' executed successfully" + print(f"[BUTTON] Success: {success_msg}") await bot.edit_message_text( chat_id=chat_id, message_id=message_id, - text=f"✅ Service action '{action}' executed successfully" + text=success_msg ) await log_message(chat_id, f"Action: {action} on service {service_id}", True) else: - error_text = await resp.text() + error_msg = f"❌ Failed: {response_text[:100]}" + print(f"[BUTTON] Failed: {error_msg}") await bot.edit_message_text( chat_id=chat_id, message_id=message_id, - text=f"❌ Failed: {error_text[:100]}" + text=error_msg ) - await log_message(chat_id, f"Action failed: {action}", False, error_text) + await log_message(chat_id, f"Action failed: {action}", False, response_text) except Exception as e: + error_msg = f"❌ Exception: {str(e)[:100]}" + print(f"[BUTTON] Exception during action execution: {str(e)}") + print(f"[BUTTON] Full traceback:", exc_info=True) await log_message(chat_id, f"Action error: {action}", False, str(e)) async def poll_updates(): @@ -117,27 +148,37 @@ async def poll_updates(): global update_offset if not bot: + print("[POLLING] Bot not configured, skipping polling") return + print("[POLLING] Starting update polling") while True: try: updates = await bot.get_updates(offset=update_offset, timeout=30) + if updates: + print(f"[POLLING] Received {len(updates)} updates") + for update in updates: update_offset = update.update_id + 1 if update.callback_query: query = update.callback_query + print(f"[POLLING] Processing callback query: {query.data}") await handle_button_click( query.data, query.message.chat_id, query.message.message_id ) await bot.answer_callback_query(query.id) + print(f"[POLLING] Callback processed successfully") except asyncio.CancelledError: + print("[POLLING] Polling task cancelled") break except Exception as e: - print(f"Error in polling: {e}") + print(f"[POLLING] Error in polling: {e}") + import traceback + traceback.print_exc() await asyncio.sleep(5) class MessageRequest(BaseModel): @@ -182,14 +223,26 @@ async def log_message(chat_id: int, message: str, success: bool, error_message: @asynccontextmanager async def lifespan(app: FastAPI): global db_pool, bot, polling_task + print("[STARTUP] Initializing Telegram Bot API") + print(f"[STARTUP] DATABASE_URL: {DATABASE_URL}") + print(f"[STARTUP] CONTROLLER_API: {CONTROLLER_API}") + print(f"[STARTUP] TELEGRAM_BOT_TOKEN configured: {bool(TELEGRAM_BOT_TOKEN)}") + print(f"[STARTUP] TELEGRAM_CHAT_ID: {TELEGRAM_CHAT_ID}") + db_pool = await asyncpg.create_pool(DATABASE_URL, min_size=2, max_size=10) + print("[STARTUP] Database pool created") if TELEGRAM_BOT_TOKEN: bot = Bot(token=TELEGRAM_BOT_TOKEN) + print("[STARTUP] Telegram Bot initialized") polling_task = asyncio.create_task(poll_updates()) + print("[STARTUP] Polling task created") + else: + print("[STARTUP] WARNING: TELEGRAM_BOT_TOKEN not configured!") yield + print("[SHUTDOWN] Shutting down Telegram Bot API") if polling_task: polling_task.cancel() try: @@ -198,6 +251,7 @@ async def lifespan(app: FastAPI): pass await db_pool.close() + print("[SHUTDOWN] Database pool closed") app = FastAPI(title="Telegram Bot API", lifespan=lifespan)