Update main.py

This commit is contained in:
ilyastar9999
2025-12-04 14:26:15 +03:00
parent 154c0cda75
commit b79f525a33

View File

@@ -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)