#935 IM Bot Channel Adapter 化 (Telegram POC + im_channel_routes schema)
This commit is contained in:
1 parent
048671870a
commit
6d5c2cf2c0
4 files changed
+477
-2
No files matched your search
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Channel Webhook 入口 — /app/api/channel/<channel_id>
|
||||
任务 #935 · 2026-08-09
|
||||
|
||||
- Telegram 走 POST JSON
|
||||
- secret_token 校验(头部 X-Telegram-Bot-Api-Secret-Token)
|
||||
- 其他渠道后续扩展(飞书 / 钉钉加密回调 / 企业微信 AES 解密各不同,放各 adapter 自己)
|
||||
"""
|
||||
from __future__ import annotations
|
||||
import hashlib
|
||||
import hmac
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
from fastapi import APIRouter, HTTPException, Request
|
||||
|
||||
from app.core.channel_adapter import ChannelRouter
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/app/api/channel", tags=["channel-webhook"])
|
||||
|
||||
|
||||
@router.post("/{channel_id}")
|
||||
async def channel_webhook(channel_id: str, request: Request) -> dict:
|
||||
r = ChannelRouter.shared()
|
||||
if channel_id not in r.channels:
|
||||
raise HTTPException(404, f"channel not registered: {channel_id}")
|
||||
adapter = r._adapters.get(channel_id) # noqa: SLF001 (内部访问 OK)
|
||||
raw = await request.body()
|
||||
# secret 校验(各家 header 名不同,Telegram: X-Telegram-Bot-Api-Secret-Token)
|
||||
expected_secret = getattr(adapter, "webhook_secret", "")
|
||||
if expected_secret:
|
||||
secret_header = request.headers.get("x-telegram-bot-api-secret-token", "")
|
||||
if not secret_header or not hmac.compare_digest(secret_header, expected_secret):
|
||||
raise HTTPException(401, "invalid secret")
|
||||
try:
|
||||
payload: Any = await request.json()
|
||||
except Exception:
|
||||
raise HTTPException(400, "invalid json")
|
||||
# 调对应 adapter 的 receive_update(Telegram 是同步 await;其他渠道可异步)
|
||||
if hasattr(adapter, "receive_update"):
|
||||
import asyncio
|
||||
await adapter.receive_update(payload)
|
||||
else:
|
||||
raise HTTPException(501, "channel has no receive_update impl")
|
||||
return {"ok": True}
|
||||
Reference in new issue
Block a user