mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
feat: Add calendar event data to transcript webhook payload (#689)
* feat: add calendar event data to transcript webhook payload and implement get_by_id method * Update server/reflector/worker/webhook.py Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com> * Update server/reflector/worker/webhook.py Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com> * style: format conditional time fields with line breaks for better readability * docs: add calendar event fields to transcript.completed webhook payload schema --------- Co-authored-by: pr-agent-monadical[bot] <198624643+pr-agent-monadical[bot]@users.noreply.github.com>
This commit is contained in:
@@ -14,7 +14,7 @@ Webhooks are configured at the room level with two fields:
|
|||||||
|
|
||||||
### `transcript.completed`
|
### `transcript.completed`
|
||||||
|
|
||||||
Triggered when a transcript has been fully processed, including transcription, diarization, summarization, and topic detection.
|
Triggered when a transcript has been fully processed, including transcription, diarization, summarization, topic detection and calendar event integration.
|
||||||
|
|
||||||
### `test`
|
### `test`
|
||||||
|
|
||||||
@@ -128,6 +128,27 @@ This event includes a convenient URL for accessing the transcript:
|
|||||||
"room": {
|
"room": {
|
||||||
"id": "room-789",
|
"id": "room-789",
|
||||||
"name": "Product Team Room"
|
"name": "Product Team Room"
|
||||||
|
},
|
||||||
|
"calendar_event": {
|
||||||
|
"id": "calendar-event-123",
|
||||||
|
"ics_uid": "event-123",
|
||||||
|
"title": "Q3 Product Planning Meeting",
|
||||||
|
"start_time": "2025-08-27T12:00:00Z",
|
||||||
|
"end_time": "2025-08-27T12:30:00Z",
|
||||||
|
"description": "Team discussed Q3 product roadmap, prioritizing mobile app features and API improvements.",
|
||||||
|
"location": "Conference Room 1",
|
||||||
|
"attendees": [
|
||||||
|
{
|
||||||
|
"id": "participant-1",
|
||||||
|
"name": "John Doe",
|
||||||
|
"speaker": "Speaker 1"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "participant-2",
|
||||||
|
"name": "Jane Smith",
|
||||||
|
"speaker": "Speaker 2"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -104,6 +104,11 @@ class CalendarEventController:
|
|||||||
results = await get_database().fetch_all(query)
|
results = await get_database().fetch_all(query)
|
||||||
return [CalendarEvent(**result) for result in results]
|
return [CalendarEvent(**result) for result in results]
|
||||||
|
|
||||||
|
async def get_by_id(self, event_id: str) -> CalendarEvent | None:
|
||||||
|
query = calendar_events.select().where(calendar_events.c.id == event_id)
|
||||||
|
result = await get_database().fetch_one(query)
|
||||||
|
return CalendarEvent(**result) if result else None
|
||||||
|
|
||||||
async def get_by_ics_uid(self, room_id: str, ics_uid: str) -> CalendarEvent | None:
|
async def get_by_ics_uid(self, room_id: str, ics_uid: str) -> CalendarEvent | None:
|
||||||
query = calendar_events.select().where(
|
query = calendar_events.select().where(
|
||||||
sa.and_(
|
sa.and_(
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ import structlog
|
|||||||
from celery import shared_task
|
from celery import shared_task
|
||||||
from celery.utils.log import get_task_logger
|
from celery.utils.log import get_task_logger
|
||||||
|
|
||||||
|
from reflector.db.calendar_events import calendar_events_controller
|
||||||
|
from reflector.db.meetings import meetings_controller
|
||||||
from reflector.db.rooms import rooms_controller
|
from reflector.db.rooms import rooms_controller
|
||||||
from reflector.db.transcripts import transcripts_controller
|
from reflector.db.transcripts import transcripts_controller
|
||||||
from reflector.pipelines.main_live_pipeline import asynctask
|
from reflector.pipelines.main_live_pipeline import asynctask
|
||||||
@@ -84,6 +86,18 @@ async def send_transcript_webhook(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Fetch meeting and calendar event if they exist
|
||||||
|
calendar_event = None
|
||||||
|
try:
|
||||||
|
if transcript.meeting_id:
|
||||||
|
meeting = await meetings_controller.get_by_id(transcript.meeting_id)
|
||||||
|
if meeting and meeting.calendar_event_id:
|
||||||
|
calendar_event = await calendar_events_controller.get_by_id(
|
||||||
|
meeting.calendar_event_id
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error("Error fetching meeting or calendar event", error=str(e))
|
||||||
|
|
||||||
# Build webhook payload
|
# Build webhook payload
|
||||||
frontend_url = f"{settings.UI_BASE_URL}/transcripts/{transcript.id}"
|
frontend_url = f"{settings.UI_BASE_URL}/transcripts/{transcript.id}"
|
||||||
participants = [
|
participants = [
|
||||||
@@ -116,6 +130,33 @@ async def send_transcript_webhook(
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Always include calendar_event field, even if no event is present
|
||||||
|
payload_data["calendar_event"] = {}
|
||||||
|
|
||||||
|
# Add calendar event data if present
|
||||||
|
if calendar_event:
|
||||||
|
calendar_data = {
|
||||||
|
"id": calendar_event.id,
|
||||||
|
"ics_uid": calendar_event.ics_uid,
|
||||||
|
"title": calendar_event.title,
|
||||||
|
"start_time": calendar_event.start_time.isoformat()
|
||||||
|
if calendar_event.start_time
|
||||||
|
else None,
|
||||||
|
"end_time": calendar_event.end_time.isoformat()
|
||||||
|
if calendar_event.end_time
|
||||||
|
else None,
|
||||||
|
}
|
||||||
|
|
||||||
|
# Add optional fields only if they exist
|
||||||
|
if calendar_event.description:
|
||||||
|
calendar_data["description"] = calendar_event.description
|
||||||
|
if calendar_event.location:
|
||||||
|
calendar_data["location"] = calendar_event.location
|
||||||
|
if calendar_event.attendees:
|
||||||
|
calendar_data["attendees"] = calendar_event.attendees
|
||||||
|
|
||||||
|
payload_data["calendar_event"] = calendar_data
|
||||||
|
|
||||||
# Convert to JSON
|
# Convert to JSON
|
||||||
payload_json = json.dumps(payload_data, separators=(",", ":"))
|
payload_json = json.dumps(payload_data, separators=(",", ":"))
|
||||||
payload_bytes = payload_json.encode("utf-8")
|
payload_bytes = payload_json.encode("utf-8")
|
||||||
|
|||||||
Reference in New Issue
Block a user