Spaces:
Running
Running
| # backend/api β Moduli Telegram (M2 Split) | |
| > **Refactor M2 β 2 Luglio 2026** | |
| > Il monolite `telegram_webhook.py` (2844 righe, 5 hotfix consecutivi) Γ¨ stato | |
| > spezzato in 6 moduli a responsabilitΓ singola. Hotfix futuri toccano **un solo file**. | |
| --- | |
| ## Grafo delle dipendenze | |
| ``` | |
| telegram_tg_client.py (stdlib + httpx only) | |
| β | |
| ββββΊ telegram_keyboards.py (solo costanti/dict β zero import interni) | |
| β β | |
| β ββββΊ telegram_cmd_monitoring.py | |
| β β ββββΊ (esposto via telegram_webhook.py) | |
| β β | |
| β ββββΊ telegram_cmd_ai.py | |
| β β ββββΊ (esposto via telegram_webhook.py) | |
| β β | |
| β ββββΊ telegram_callbacks.py | |
| β βββ importa _cmd_do, _cmd_autofix ... da telegram_cmd_ai | |
| β βββ importa _cmd_help, _cmd_status ... da telegram_cmd_monitoring | |
| β | |
| ββββΊ telegram_webhook.py (router FastAPI puro β importa da tutti) | |
| ββββΊ montato in backend/main.py come _tg_webhook_router | |
| ``` | |
| --- | |
| ## Moduli | |
| ### `telegram_tg_client.py` β 276 righe | |
| **Ruolo:** Telegram Bot API puro. Layer 0 senza dipendenze interne. | |
| | Simbolo | Descrizione | | |
| |---------|-------------| | |
| | `_get_bot_token()` | Legge `TELEGRAM_BOT_TOKEN` dall'env | | |
| | `_log_tg_exc(task)` | Log eccezioni fire-and-forget (Gap-2.6) | | |
| | `_fmt_elapsed(sec)` | Formatta durata in human-readable | | |
| | `_tg_reply(chat_id, text)` | Invia messaggio con parse_mode=HTML | | |
| | `_tg_send(chat_id, text)` | Come reply, ritorna `message_id` | | |
| | `_tg_edit(chat_id, msg_id, text)` | Modifica messaggio esistente | | |
| | `_tg_photo(chat_id, url, caption)` | Invia foto via URL | | |
| | `_tg_typing(chat_id)` | Invia `sendChatAction typing` | | |
| | `_tg_react(chat_id, msg_id, emoji)` | Imposta reaction emoji | | |
| | `_tg_answer_callback(callback_id)` | Risponde a `callback_query` (β€3s) | | |
| **Import:** `asyncio, html, logging, os, time, httpx` | |
| --- | |
| ### `telegram_keyboards.py` β 109 righe | |
| **Ruolo:** Costanti UI e keyboards. Zero logica, zero import interni. | |
| | Simbolo | Tipo | Descrizione | | |
| |---------|------|-------------| | |
| | `_QUICK_PICK_KB` | `dict` | Inline keyboard selezione task rapida | | |
| | `_MAIN_KB` | `dict` | Reply keyboard principale | | |
| | `_BENCH_ACTION_KB` | `dict` | Keyboard post-benchmark | | |
| | `_TASK_MENU_KB` | `dict` | Sub-menu task | | |
| | `_STATUS_MENU_KB` | `dict` | Sub-menu stato sistema | | |
| | `_PERF_MENU_KB` | `dict` | Sub-menu performance | | |
| | `_HEALTH_MENU_KB` | `dict` | Sub-menu health | | |
| | `_DEV_MENU_KB` | `dict` | Sub-menu developer | | |
| | `_LAST_GOAL` | `dict[int,str]` | Memoria per bottone π Rifai | | |
| | `_BENCH_CACHE` | `dict[int,dict]` | Ultimo run benchmark per chat | | |
| | `_after_task_kb(chat_id)` | func | Keyboard dinamica post-task | | |
| **Import:** solo `from __future__ import annotations` | |
| --- | |
| ### `telegram_cmd_monitoring.py` β 456 righe | |
| **Ruolo:** Comandi di monitoraggio, stato e diagnostica. | |
| | Comando / Funzione | Trigger Telegram | | |
| |--------------------|-----------------| | |
| | `_cmd_help(chat_id)` | `/start` `/help` `tgw_help` | | |
| | `_cmd_logs(chat_id)` | `/logs` `tgw_logs` | | |
| | `_cmd_status(chat_id)` | `/stato` `tgw_status` | | |
| | `_cmd_commit_summary(chat_id)` | `/commit` `tgw_commits` | | |
| | `_cmd_check(chat_id)` | `/salute` `tgw_health` | | |
| | `_cmd_tasks(chat_id)` | `/attivitΓ ` `tgw_tasks` | | |
| | `_cmd_git(chat_id, args)` | `/git` `tgw_git` | | |
| | `_cmd_coord(chat_id)` | `/coord` `tgw_coord` | | |
| | `_cmd_scan_now(chat_id)` | `/scan` `tgw_scan` | | |
| | `_cmd_telemetry(chat_id)` | `/telemetria` `tgw_telemetry` | | |
| **Import:** stdlib + `telegram_tg_client` + `telegram_keyboards` | |
| --- | |
| ### `telegram_cmd_ai.py` β 1152 righe | |
| **Ruolo:** Comandi AI, LLM e operativi. Modulo piΓΉ pesante β contiene lo streaming loop. | |
| | Comando / Funzione | Trigger Telegram | | |
| |--------------------|-----------------| | |
| | `_cmd_do(chat_id, goal)` | `/avvia` β lancia task AI con streaming | | |
| | `_cmd_autofix(chat_id)` | `/fix` `tgw_autofix` | | |
| | `_cmd_nota(chat_id, text)` | `/nota` `tgw_nota` | | |
| | `_cmd_cerca(chat_id, query)` | `/cerca` `tgw_cerca` | | |
| | `_cmd_meteo(chat_id, city)` | `/meteo` `tgw_meteo` | | |
| | `_cmd_riepilogo(chat_id)` | `/riepilogo` `tgw_briefing` | | |
| | `_cmd_score(chat_id)` | `/score` `tgw_score` | | |
| | `_cmd_bench(chat_id)` | `/bench` `tgw_bench` | | |
| | `_cmd_improve(chat_id, target)` | `/migliora` `tgw_improve` | | |
| **Import:** stdlib + `telegram_tg_client` + `telegram_keyboards` | |
| --- | |
| ### `telegram_callbacks.py` β 353 righe | |
| **Ruolo:** Smista `callback_query` e `inline_query` in arrivo da Telegram. | |
| | Funzione | Descrizione | | |
| |----------|-------------| | |
| | `_handle_inline(iq, token)` | Risponde alle inline query (`@ARJagent_ap_bot testo`) | | |
| | `_handle_callback(cb, token)` | Dispatch per tutti i `callback_data` `tgw_*` / `agent` / `qp_*` | | |
| **Import:** `telegram_tg_client` + `telegram_keyboards` + `telegram_cmd_ai` + `telegram_cmd_monitoring` | |
| > β οΈ **Questo modulo crea dipendenze circolari potenziali** β non importare | |
| > `telegram_callbacks` da `telegram_cmd_ai` o `telegram_cmd_monitoring`. | |
| --- | |
| ### `telegram_webhook.py` β 605 righe *(era 2844)* | |
| **Ruolo:** Router FastAPI puro. Solo endpoint HTTP, zero logica di business. | |
| | Endpoint | Metodo | Descrizione | | |
| |----------|--------|-------------| | |
| | `/api/telegram/webhook` | POST | Ricezione update getUpdates (polling daemon) | | |
| | `/api/telegram/process` | POST | Endpoint alternativo per CF Pages proxy | | |
| | `/api/telegram/config/invalidate` | POST | Invalida cache config bot | | |
| **Import:** FastAPI + tutti i 5 moduli sopra | |
| **Montato in:** `backend/main.py` β `app.include_router(_tg_webhook_router)` | |
| --- | |
| ## Regole per gli hotfix | |
| | Vuoi cambiare... | Tocca solo... | | |
| |------------------|---------------| | |
| | Aspetto di un bottone / label | `telegram_keyboards.py` | | |
| | Risposta a un comando /help, /stato⦠| `telegram_cmd_monitoring.py` | | |
| | Logica task AI / streaming / bench | `telegram_cmd_ai.py` | | |
| | Routing dei bottoni inline (tgw_*) | `telegram_callbacks.py` | | |
| | Helpers HTTP verso api.telegram.org | `telegram_tg_client.py` | | |
| | Routing endpoint FastAPI | `telegram_webhook.py` | | |
| --- | |
| ## Daemon Node.js (scripts/lib/daemon-callbacks.mjs) | |
| Il daemon usa **getUpdates polling** (non webhook registrato). | |
| Riceve gli update, li smista ai command handler Python via HTTP interno. | |
| Il flusso `callback_data tgw_*` viene elaborato da `telegram_callbacks.py::_handle_callback`. | |
| ``` | |
| Telegram βββΊ getUpdates daemon βββΊ POST /api/telegram/process | |
| β | |
| telegram_webhook.py (router) | |
| β | |
| βββββββββββββ΄ββββββββββββ | |
| message? callback_query? | |
| β β | |
| telegram_cmd_*.py telegram_callbacks.py | |
| ::_handle_callback | |
| ``` | |