supervisor_telegram / webhook_server.py
louissoume's picture
Update webhook_server.py
5eeb485 verified
Raw
History Blame Contribute Delete
7.38 kB
"""
webhook_server.py
══════════════════════════════════════════════════════════════
Webhook Telegram β€” avec client HTTP custom pour contourner
les restrictions rΓ©seau de Hugging Face Spaces
══════════════════════════════════════════════════════════════
"""
import asyncio
import os
import json
import logging
import httpx
from fastapi import FastAPI, Request, HTTPException
from superviseur import travailler_ensemble, formater_pour_telegram
# ─────────────────────────────────────────────
# CONFIG
# ─────────────────────────────────────────────
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN", "")
TELEGRAM_API = f"https://api.telegram.org/bot{TELEGRAM_TOKEN}"
WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET", "")
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = FastAPI()
# ─────────────────────────────────────────────
# ENVOI TELEGRAM via httpx direct (pas python-telegram-bot)
# ─────────────────────────────────────────────
async def send(chat_id: int, text: str):
"""Envoie un message Telegram via httpx avec timeout long."""
chunks = [text[i:i+4000] for i in range(0, len(text), 4000)]
async with httpx.AsyncClient(timeout=60) as client:
for chunk in chunks:
try:
await client.post(
f"{TELEGRAM_API}/sendMessage",
json={
"chat_id": chat_id,
"text": chunk,
"parse_mode": "Markdown",
}
)
except Exception:
try:
# Retry sans Markdown si erreur de formatage
await client.post(
f"{TELEGRAM_API}/sendMessage",
json={"chat_id": chat_id, "text": chunk}
)
except Exception as e:
logger.error(f"Impossible d'envoyer le message : {e}")
async def send_and_get_id(chat_id: int, text: str) -> int | None:
"""Envoie un message et retourne son message_id."""
async with httpx.AsyncClient(timeout=60) as client:
try:
resp = await client.post(
f"{TELEGRAM_API}/sendMessage",
json={
"chat_id": chat_id,
"text": text,
"parse_mode": "Markdown",
}
)
data = resp.json()
if data.get("ok"):
return data["result"]["message_id"]
except Exception as e:
logger.warning(f"send_and_get_id: {e}")
return None
async def edit_message(chat_id: int, message_id: int, text: str):
"""Met Γ  jour un message existant."""
async with httpx.AsyncClient(timeout=60) as client:
try:
await client.post(
f"{TELEGRAM_API}/editMessageText",
json={
"chat_id": chat_id,
"message_id": message_id,
"text": text,
"parse_mode": "Markdown",
}
)
except Exception as e:
logger.warning(f"edit_message: {e}")
async def delete_message(chat_id: int, message_id: int):
"""Supprime un message."""
async with httpx.AsyncClient(timeout=30) as client:
try:
await client.post(
f"{TELEGRAM_API}/deleteMessage",
json={"chat_id": chat_id, "message_id": message_id}
)
except Exception as e:
logger.warning(f"delete_message: {e}")
# ─────────────────────────────────────────────
# GESTION DES MESSAGES
# ─────────────────────────────────────────────
AIDE = (
"πŸ‘‹ *Bienvenue ! Je suis votre Γ©quipe IA.*\n\n"
"🐍 *Hermes* \\+ πŸ¦… *Openclaw* travaillent ensemble pour vous\\.\n\n"
"πŸ“Œ *Comment utiliser :*\n"
"Envoyez simplement votre tΓ’che, par exemple :\n\n"
"β€’ _Fais\\-moi une analyse SWOT de Netflix_\n"
"β€’ _RΓ©dige un plan de cours sur la blockchain_\n"
"β€’ _Propose une stratΓ©gie marketing pour une app mobile_\n\n"
"Les agents analyseront, se rΓ©partiront le travail et vous livreront un rΓ©sultat complet\\."
)
async def handle_update(update: dict):
"""Traite un message Telegram entrant."""
message = update.get("message") or update.get("edited_message")
if not message or "text" not in message:
return
chat_id = message["chat"]["id"]
text = message["text"].strip()
# Commandes système
if text in ("/start", "/aide", "/help"):
await send(chat_id, AIDE)
return
# Toute autre tΓ’che β†’ collaboration inter-agents
tache = text
status_id = [None] # liste pour mutabilitΓ© dans la closure
async def on_progress(msg: str):
try:
if status_id[0] is None:
mid = await send_and_get_id(chat_id, msg)
status_id[0] = mid
else:
await edit_message(chat_id, status_id[0], msg)
except Exception as e:
logger.warning(f"on_progress: {e}")
try:
await on_progress("πŸš€ *Vos agents prennent en charge la tΓ’che...*")
resultat = await travailler_ensemble(tache, on_progress=on_progress)
# Supprimer le message de statut
if status_id[0]:
await delete_message(chat_id, status_id[0])
# Envoyer rΓ©sumΓ© + livrable
messages = formater_pour_telegram(tache, resultat)
for msg in messages:
await send(chat_id, msg)
except Exception as e:
logger.exception("Erreur collaboration agents")
if status_id[0]:
await delete_message(chat_id, status_id[0])
await send(chat_id, f"❌ Erreur : {str(e)[:200]}")
# ─────────────────────────────────────────────
# ENDPOINT WEBHOOK
# ─────────────────────────────────────────────
@app.post("/webhook")
async def webhook(request: Request):
if WEBHOOK_SECRET:
if request.headers.get("X-Telegram-Bot-Api-Secret-Token", "") != WEBHOOK_SECRET:
raise HTTPException(status_code=403, detail="Forbidden")
data = await request.json()
asyncio.create_task(handle_update(data))
return {"ok": True}
@app.get("/")
async def root():
return {"status": "running", "equipe": ["Hermes", "Openclaw"]}
@app.get("/health")
async def health():
return {"status": "ok"}