Update main.py
This commit is contained in:
@@ -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:
|
||||
async with aiohttp.ClientSession() as session:
|
||||
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:
|
||||
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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user