fix(telegram): route direct sends through gateway
This commit is contained in:
@@ -274,14 +274,13 @@ class AIRateLimiter:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from src.core.config import settings
|
from src.core.config import settings
|
||||||
|
from src.services.telegram_gateway import get_telegram_gateway
|
||||||
|
|
||||||
target_chat_id = settings.SRE_GROUP_CHAT_ID or settings.OPENCLAW_TG_CHAT_ID
|
target_chat_id = settings.SRE_GROUP_CHAT_ID or settings.OPENCLAW_TG_CHAT_ID
|
||||||
if not settings.OPENCLAW_TG_BOT_TOKEN or not target_chat_id:
|
if not settings.OPENCLAW_TG_BOT_TOKEN or not target_chat_id:
|
||||||
logger.warning("telegram_not_configured_for_cost_alert")
|
logger.warning("telegram_not_configured_for_cost_alert")
|
||||||
return
|
return
|
||||||
|
|
||||||
import httpx
|
|
||||||
|
|
||||||
message = (
|
message = (
|
||||||
f"🚨🚨🚨 <b>AI 成本超限警報</b> 🚨🚨🚨\n\n"
|
f"🚨🚨🚨 <b>AI 成本超限警報</b> 🚨🚨🚨\n\n"
|
||||||
f"Provider: <code>{provider.upper()}</code>\n"
|
f"Provider: <code>{provider.upper()}</code>\n"
|
||||||
@@ -292,15 +291,15 @@ class AIRateLimiter:
|
|||||||
f"<code>redis-cli DEL ai_rate:total_cost:{provider}</code>"
|
f"<code>redis-cli DEL ai_rate:total_cost:{provider}</code>"
|
||||||
)
|
)
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
gateway = get_telegram_gateway()
|
||||||
await client.post(
|
await gateway._send_request(
|
||||||
f"https://api.telegram.org/bot{settings.OPENCLAW_TG_BOT_TOKEN}/sendMessage",
|
"sendMessage",
|
||||||
json={
|
{
|
||||||
"chat_id": target_chat_id,
|
"chat_id": target_chat_id,
|
||||||
"text": message,
|
"text": message,
|
||||||
"parse_mode": "HTML",
|
"parse_mode": "HTML",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.error(
|
logger.error(
|
||||||
"ai_cost_alert_sent",
|
"ai_cost_alert_sent",
|
||||||
@@ -327,13 +326,12 @@ class AIRateLimiter:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from src.core.config import settings
|
from src.core.config import settings
|
||||||
|
from src.services.telegram_gateway import get_telegram_gateway
|
||||||
|
|
||||||
target_chat_id = settings.SRE_GROUP_CHAT_ID or settings.OPENCLAW_TG_CHAT_ID
|
target_chat_id = settings.SRE_GROUP_CHAT_ID or settings.OPENCLAW_TG_CHAT_ID
|
||||||
if not settings.OPENCLAW_TG_BOT_TOKEN or not target_chat_id:
|
if not settings.OPENCLAW_TG_BOT_TOKEN or not target_chat_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
import httpx
|
|
||||||
|
|
||||||
limit = COST_LIMITS[provider]["total_cost_usd"]
|
limit = COST_LIMITS[provider]["total_cost_usd"]
|
||||||
remaining = limit - current_cost
|
remaining = limit - current_cost
|
||||||
|
|
||||||
@@ -345,15 +343,15 @@ class AIRateLimiter:
|
|||||||
f"接近上限,請注意監控!"
|
f"接近上限,請注意監控!"
|
||||||
)
|
)
|
||||||
|
|
||||||
async with httpx.AsyncClient(timeout=10.0) as client:
|
gateway = get_telegram_gateway()
|
||||||
await client.post(
|
await gateway._send_request(
|
||||||
f"https://api.telegram.org/bot{settings.OPENCLAW_TG_BOT_TOKEN}/sendMessage",
|
"sendMessage",
|
||||||
json={
|
{
|
||||||
"chat_id": target_chat_id,
|
"chat_id": target_chat_id,
|
||||||
"text": message,
|
"text": message,
|
||||||
"parse_mode": "HTML",
|
"parse_mode": "HTML",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"ai_cost_warning_sent",
|
"ai_cost_warning_sent",
|
||||||
|
|||||||
@@ -838,9 +838,9 @@ class ApprovalExecutionService:
|
|||||||
f"{km_info}"
|
f"{km_info}"
|
||||||
)
|
)
|
||||||
|
|
||||||
await gateway._http_client.post(
|
await gateway._send_request(
|
||||||
f"https://api.telegram.org/bot{settings.OPENCLAW_TG_BOT_TOKEN}/sendMessage",
|
"sendMessage",
|
||||||
json={
|
{
|
||||||
"chat_id": target_chat_id,
|
"chat_id": target_chat_id,
|
||||||
"text": text,
|
"text": text,
|
||||||
"parse_mode": "HTML",
|
"parse_mode": "HTML",
|
||||||
|
|||||||
@@ -350,9 +350,9 @@ async def _send_rollback_proposal_alert(
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_chat_id = _settings.SRE_GROUP_CHAT_ID or _settings.OPENCLAW_TG_CHAT_ID
|
target_chat_id = _settings.SRE_GROUP_CHAT_ID or _settings.OPENCLAW_TG_CHAT_ID
|
||||||
await gateway._http_client.post(
|
await gateway._send_request(
|
||||||
f"https://api.telegram.org/bot{_settings.OPENCLAW_TG_BOT_TOKEN}/sendMessage",
|
"sendMessage",
|
||||||
json={
|
{
|
||||||
"chat_id": target_chat_id,
|
"chat_id": target_chat_id,
|
||||||
"text": text,
|
"text": text,
|
||||||
"parse_mode": "HTML",
|
"parse_mode": "HTML",
|
||||||
|
|||||||
@@ -4399,6 +4399,7 @@ HTTP:
|
|||||||
- 沒有正式 `run_id` 的 legacy 發送使用穩定 soft run id:`awoooi:legacy-telegram:{chat_id}:{provider_message_id}` 的 UUIDv5。
|
- 沒有正式 `run_id` 的 legacy 發送使用穩定 soft run id:`awoooi:legacy-telegram:{chat_id}:{provider_message_id}` 的 UUIDv5。
|
||||||
- legacy 訊息先映射成有限分類:`approval_request`、`final`、`error`,供 AwoooP Run / Timeline 後續彙整。
|
- legacy 訊息先映射成有限分類:`approval_request`、`final`、`error`,供 AwoooP Run / Timeline 後續彙整。
|
||||||
- 鏡像採 fail-open:DB / RLS / schema 或 Channel Hub 失敗時只寫 `telegram_outbound_mirror_failed`,不得影響 Telegram 原本送達。
|
- 鏡像採 fail-open:DB / RLS / schema 或 Channel Hub 失敗時只寫 `telegram_outbound_mirror_failed`,不得影響 Telegram 原本送達。
|
||||||
|
- 成本告警、審批執行結果、自愈 rollback 提案三條 direct Bot API 發送改為走 `TelegramGateway._send_request()`,發送目標與內容不變,但會進 outbound mirror。
|
||||||
|
|
||||||
### 驗證
|
### 驗證
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ Telegram 不應是完整執行日誌,也不應承載所有 AI 推理細節。T
|
|||||||
- `append_incident_update()` 對同一 incident 的相同狀態做 5 分鐘 Redis 去重。
|
- `append_incident_update()` 對同一 incident 的相同狀態做 5 分鐘 Redis 去重。
|
||||||
- `append_incident_update()` 對相同的「AI 自動修復失敗 / AI 診斷工具失敗」摘要增加 10 分鐘跨 incident 去重;每個 incident 仍會移除原卡危險按鈕,但 Telegram 不再重複 reply 同一個失敗摘要。
|
- `append_incident_update()` 對相同的「AI 自動修復失敗 / AI 診斷工具失敗」摘要增加 10 分鐘跨 incident 去重;每個 incident 仍會移除原卡危險按鈕,但 Telegram 不再重複 reply 同一個失敗摘要。
|
||||||
- `TelegramGateway._send_request()` 對成功送出的 legacy `sendMessage` 增加 AwoooP `awooop_outbound_message` 鏡像。鏡像失敗只記錄 `telegram_outbound_mirror_failed`,不能影響 Telegram 正常送達。
|
- `TelegramGateway._send_request()` 對成功送出的 legacy `sendMessage` 增加 AwoooP `awooop_outbound_message` 鏡像。鏡像失敗只記錄 `telegram_outbound_mirror_failed`,不能影響 Telegram 正常送達。
|
||||||
|
- 成本告警、審批執行結果、自愈 rollback 提案已由 direct Bot API 改走 `TelegramGateway._send_request()`,避免繞過 outbound mirror。
|
||||||
- 既有 `詳情 / 重診 / 歷史` 按鈕保留,讓 Telegram 保持輕量,細節回到控制台。
|
- 既有 `詳情 / 重診 / 歷史` 按鈕保留,讓 Telegram 保持輕量,細節回到控制台。
|
||||||
|
|
||||||
## 後續建議
|
## 後續建議
|
||||||
|
|||||||
Reference in New Issue
Block a user