Files
ai-video-fullstack/backend/services/webhooks/events.py
2026-08-07 14:08:49 +08:00

70 lines
2.0 KiB
Python

"""Build durable webhook events in the same transaction as domain updates."""
from __future__ import annotations
from datetime import UTC, datetime
import uuid
from typing import Any
from db.models import ConversationSession, SiteSetting, WebhookDelivery
from sqlalchemy.ext.asyncio import AsyncSession
ANALYSIS_WEBHOOK_KEY = "analysis_webhook"
ANALYSIS_COMPLETED_EVENT = "call.analysis.completed"
def analysis_completed_payload(
conversation: ConversationSession,
result: dict[str, Any],
*,
event_id: str,
timestamp: datetime,
) -> dict[str, Any]:
return {
"id": event_id,
"event": ANALYSIS_COMPLETED_EVENT,
"timestamp": timestamp.isoformat(),
"data": {
"conversationId": conversation.id,
"assistantId": conversation.assistant_id,
"assistantName": conversation.assistant_name,
"analysis": result,
},
}
async def enqueue_analysis_completed(
session: AsyncSession,
conversation: ConversationSession,
result: dict[str, Any],
) -> WebhookDelivery | None:
setting = await session.get(SiteSetting, ANALYSIS_WEBHOOK_KEY)
values = dict(setting.value or {}) if setting else {}
secrets = dict(setting.secrets or {}) if setting else {}
url = str(values.get("url") or "")
secret = str(secrets.get("secret") or "")
if not values.get("enabled") or not url or not secret:
return None
event_id = f"evt_{uuid.uuid4().hex}"
now = datetime.now(UTC)
delivery = WebhookDelivery(
id=f"dlv_{uuid.uuid4().hex}",
event_id=event_id,
event_type=ANALYSIS_COMPLETED_EVENT,
conversation_id=conversation.id,
payload=analysis_completed_payload(
conversation,
result,
event_id=event_id,
timestamp=now,
),
url=url,
secrets={"secret": secret},
status="pending",
next_attempt_at=now,
)
session.add(delivery)
return delivery