This commit is contained in:
eric
2026-03-31 12:57:57 -05:00
parent 836ca360cb
commit 7edac5674d

View File

@@ -7,6 +7,7 @@ import time
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
from datetime import datetime, timezone from datetime import datetime, timezone
from typing import Optional from typing import Optional
from urllib.parse import parse_qs
import httpx import httpx
from Crypto.Cipher import AES from Crypto.Cipher import AES
@@ -329,22 +330,43 @@ async def handle_business(data: dict) -> str:
async def _handle_wechat_request(request: Request, app_id: Optional[str], background_tasks: BackgroundTasks) -> str: async def _handle_wechat_request(request: Request, app_id: Optional[str], background_tasks: BackgroundTasks) -> str:
if app_id and app_id != APP_ID: if app_id and app_id != APP_ID:
logger.warning("chatbot app_id mismatch expected=%s actual=%s", APP_ID, app_id) logger.warning("chatbot app_id mismatch expected=%s actual=%s", APP_ID, app_id)
raw_body = (await request.body()).decode("utf-8").strip() raw_body = (await request.body()).decode("utf-8", errors="ignore").strip()
if not raw_body: if not raw_body:
raise HTTPException(status_code=400, detail="empty body") raise HTTPException(status_code=400, detail="empty body")
cipher_b64 = raw_body cipher_b64 = raw_body
if "encrypted" in raw_body: # 兼容三种请求体:
try: # 1) 纯密文 base64
outer = json.loads(raw_body) # 2) JSON: {"encrypted":"..."} / {"encrypt":"..."} / {"Encrypt":"..."}
if isinstance(outer, dict) and "encrypted" in outer: # 3) x-www-form-urlencoded: encrypted=... / encrypt=...
cipher_b64 = "".join(str(outer["encrypted"]).split()).strip() try:
except Exception: outer = json.loads(raw_body)
pass if isinstance(outer, dict):
for key in ("encrypted", "encrypt", "Encrypt"):
val = outer.get(key)
if isinstance(val, str) and val.strip():
cipher_b64 = val
break
except Exception:
form = parse_qs(raw_body, keep_blank_values=True)
for key in ("encrypted", "encrypt", "Encrypt"):
vals = form.get(key) or []
if vals and str(vals[0]).strip():
cipher_b64 = str(vals[0])
break
cipher_b64 = "".join(str(cipher_b64).split()).strip()
try: try:
decrypted = aes_decrypt_base64(cipher_b64, ENCODING_AES_KEY) decrypted = aes_decrypt_base64(cipher_b64, ENCODING_AES_KEY)
data = _parse_decrypted_payload(decrypted) data = _parse_decrypted_payload(decrypted)
except Exception: except Exception as error:
logger.error("chatbot decrypt failed") logger.error(
"chatbot decrypt failed app_id=%s content_type=%s body_prefix=%s err=%s",
app_id or "",
request.headers.get("content-type", ""),
raw_body[:160],
error,
)
raise HTTPException(status_code=400, detail="decrypt error") raise HTTPException(status_code=400, detail="decrypt error")
answer_text = await handle_business(data) answer_text = await handle_business(data)