ForcePilot/backend/server/routers/webhook_router.py

57 lines
1.5 KiB
Python
Raw Normal View History

import logging
from fastapi import APIRouter, Request, Response
from yuxi.channel.gateway.routes import webhook_registry
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/webhook", tags=["webhook"])
def _extract_signature(headers: dict[str, str]) -> str | None:
sig = headers.get("x-hub-signature-256") or headers.get("x-signature")
if sig and sig.startswith("sha256="):
sig = sig[7:]
return sig
@router.api_route(
"/{channel_type}",
methods=["POST", "PUT", "PATCH"],
summary="接收渠道 Webhook 回调",
)
async def webhook_receive(
channel_type: str,
request: Request,
):
body = await request.body()
method = request.method
content_type = request.headers.get("content-type")
headers = {k.lower(): v for k, v in request.headers.items()}
guard_result, handler_result = await webhook_registry.dispatch_guarded(
channel_type=channel_type,
method=method,
content_type=content_type,
body=body,
signature=_extract_signature(headers),
extra_headers=headers,
)
if guard_result is not None:
logger.warning(
"Webhook guard blocked: channel=%s method=%s status=%d error=%s",
channel_type,
method,
guard_result.http_status,
guard_result.error_code,
)
return Response(
content=guard_result.error_message or "",
status_code=guard_result.http_status,
media_type="text/plain",
)
return handler_result or {"status": "ok"}