Spaces:
Running
Running
| """Webhook 管理 API(admin):/admin/api/webhooks | |
| - GET /admin/api/webhooks 列出全部 | |
| - POST /admin/api/webhooks 创建 | |
| - GET /admin/api/webhooks/{id} 获取 | |
| - PUT /admin/api/webhooks/{id} 更新 | |
| - DELETE /admin/api/webhooks/{id} 删除 | |
| - POST /admin/api/webhooks/{id}/test 发送测试事件 | |
| """ | |
| from __future__ import annotations | |
| from fastapi import APIRouter, Body, Depends | |
| from ..errors import HttpError | |
| from ..services import webhook_store | |
| from ._common import ok_with_cors | |
| from .admin import _require_admin | |
| router = APIRouter(prefix="/admin/api/webhooks", tags=["webhooks"]) | |
| async def list_wh(_admin: str = Depends(_require_admin)): | |
| return ok_with_cors({"items": webhook_store.list_webhooks()}) | |
| async def create_wh( | |
| body: dict = Body(default={}), | |
| _admin: str = Depends(_require_admin), | |
| ): | |
| name = body.get("name") | |
| url = body.get("url") | |
| events = body.get("events") or [] | |
| if not name or not url: | |
| raise HttpError("name and url are required", status=400, code="bad_request") | |
| if not isinstance(events, list): | |
| raise HttpError("events must be a list", status=400, code="bad_request") | |
| wh = webhook_store.create_webhook( | |
| name=name, | |
| url=url, | |
| events=events, | |
| enabled=bool(body.get("enabled", True)), | |
| ) | |
| return ok_with_cors({"webhook": wh}) | |
| async def get_wh(webhook_id: int, _admin: str = Depends(_require_admin)): | |
| wh = webhook_store.get_webhook(webhook_id) | |
| if not wh: | |
| raise HttpError(f"webhook not found: {webhook_id}", status=404, code="not_found") | |
| return ok_with_cors({"webhook": wh}) | |
| async def update_wh( | |
| webhook_id: int, | |
| body: dict = Body(default={}), | |
| _admin: str = Depends(_require_admin), | |
| ): | |
| events = body.get("events") | |
| if events is not None and not isinstance(events, list): | |
| raise HttpError("events must be a list", status=400, code="bad_request") | |
| wh = webhook_store.update_webhook( | |
| webhook_id, | |
| name=body.get("name"), | |
| url=body.get("url"), | |
| events=events, | |
| enabled=body.get("enabled"), | |
| ) | |
| if not wh: | |
| raise HttpError(f"webhook not found: {webhook_id}", status=404, code="not_found") | |
| return ok_with_cors({"webhook": wh}) | |
| async def delete_wh(webhook_id: int, _admin: str = Depends(_require_admin)): | |
| ok = webhook_store.delete_webhook(webhook_id) | |
| return ok_with_cors({"deleted": ok, "id": webhook_id}) | |
| async def test_wh(webhook_id: int, _admin: str = Depends(_require_admin)): | |
| wh = webhook_store.get_webhook(webhook_id) | |
| if not wh: | |
| raise HttpError(f"webhook not found: {webhook_id}", status=404, code="not_found") | |
| await webhook_store.notify( | |
| "test.ping", | |
| {"webhook_id": webhook_id, "name": wh["name"], "message": "test from admin"}, | |
| ) | |
| return ok_with_cors({"sent": True, "id": webhook_id}) | |