Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import hashlib | |
| import hmac | |
| from src.utils.logger import get_logger as _get_logger | |
| import logging | |
| from typing import Any | |
| from fastapi import APIRouter, Header, HTTPException, Request | |
| from src.confluence_agent.config import confluence_config | |
| from src.confluence_agent.tasks import confluence_process_page, confluence_sync_space | |
| logger = _get_logger(__name__) | |
| router = APIRouter(tags=["confluence"]) | |
| def _verify_confluence_signature(body: bytes, signature: str, secret: str) -> bool: | |
| if not secret: | |
| return True | |
| expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest() | |
| return hmac.compare_digest(expected, signature) | |
| async def confluence_webhook( | |
| request: Request, | |
| x_hub_signature: str = Header(default=""), | |
| ) -> dict[str, Any]: | |
| body = await request.body() | |
| if confluence_config.confluence_webhook_secret: | |
| if not _verify_confluence_signature(body, x_hub_signature, confluence_config.confluence_webhook_secret): | |
| logger.warning("confluence_webhook_bad_signature", extra={"path": "/webhooks/confluence"}) | |
| raise HTTPException(status_code=401, detail="Invalid Confluence webhook signature") | |
| payload = await request.json() | |
| event = payload.get("webhookEvent", "") | |
| if event not in ("page_created", "page_updated"): | |
| return {"status": "ignored", "event": event} | |
| page = payload.get("page", {}) | |
| page_id = str(page.get("id", "")) | |
| space_key = (page.get("space") or {}).get("key", "") | |
| if not page_id: | |
| raise HTTPException(status_code=400, detail="Missing page.id in payload") | |
| task = confluence_process_page.delay(page_id, space_key, confluence_config.team_id) | |
| logger.info("confluence_webhook_accepted", extra={"task_id": task.id, "page_id": page_id, "event": event}) | |
| return {"status": "accepted", "task_id": task.id, "page_id": page_id} | |
| async def trigger_confluence_sync(space_key: str) -> dict[str, Any]: | |
| task = confluence_sync_space.delay(space_key, confluence_config.team_id) | |
| logger.info("confluence_sync_triggered", extra={"task_id": task.id, "space_key": space_key}) | |
| return {"status": "accepted", "task_id": task.id, "space_key": space_key} | |