Terminal / api /TELEGRAM_MODULES.md
Baida—-
fix(registry): unterminated string literal line 692 — force re-sync [skip ci]
889ea3f verified
|
Raw
History Blame Contribute Delete
7.18 kB
# 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
```