mirror of
https://github.com/Monadical-SAS/reflector.git
synced 2025-12-20 20:29:06 +00:00
feat(rooms): add webhook for transcript completion (#578)
* feat(rooms): add webhook notifications for transcript completion
- Add webhook_url and webhook_secret fields to rooms table
- Create Celery task with 24-hour retry window using exponential backoff
- Send transcript metadata, diarized text, topics, and summaries via webhook
- Add HMAC signature verification for webhook security
- Add test endpoint POST /v1/rooms/{room_id}/webhook/test
- Update frontend with webhook configuration UI and test button
- Auto-generate webhook secret if not provided
- Trigger webhook after successful file pipeline processing for room recordings
* style: linting
* fix: remove unwanted files
* fix: update openapi gen
* fix: self-review
* docs: add comprehensive webhook documentation
- Document webhook configuration, events, and payloads
- Include transcript.completed and test event examples
- Add security considerations and best practices
- Provide example webhook receiver implementation
- Document retry policy and signature verification
* fix: remove audio_mp3_url from webhook payload
- Remove audio download URL generation from webhook
- Update documentation to reflect the change
- Keep only frontend_url for accessing transcripts
* docs: remove unwanted section
* fix: correct API method name and type imports for rooms
- Fix v1RoomsRetrieve to v1RoomsGet
- Update Room type to RoomDetails throughout frontend
- Fix type imports in useRoomList, RoomList, RoomTable, and RoomCards
* feat: add show/hide toggle for webhook secret field
- Add eye icon button to reveal/hide webhook secret when editing
- Show password dots when webhook secret is hidden
- Reset visibility state when opening/closing dialog
- Only show toggle button when editing existing room with secret
* fix: resolve event loop conflict in webhook test endpoint
- Extract webhook test logic into shared async function
- Call async function directly from FastAPI endpoint
- Keep Celery task wrapper for background processing
- Fixes RuntimeError: event loop already running
* refactor: remove unnecessary Celery task for webhook testing
- Webhook testing is synchronous and provides immediate feedback
- No need for background processing via Celery
- Keep only the async function called directly from API endpoint
* feat: improve webhook test error messages and display
- Show HTTP status code in error messages
- Parse JSON error responses to extract meaningful messages
- Improved UI layout for webhook test results
- Added colored background for success/error states
- Better text wrapping for long error messages
* docs: adjust doc
* fix: review
* fix: update attempts to match close 24h
* fix: add event_id
* fix: changed to uuid, to have new event_id when reprocess.
* style: linting
* fix: alembic revision
This commit is contained in:
@@ -91,6 +91,14 @@ export const $CreateRoom = {
|
||||
type: "boolean",
|
||||
title: "Is Shared",
|
||||
},
|
||||
webhook_url: {
|
||||
type: "string",
|
||||
title: "Webhook Url",
|
||||
},
|
||||
webhook_secret: {
|
||||
type: "string",
|
||||
title: "Webhook Secret",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
@@ -103,6 +111,8 @@ export const $CreateRoom = {
|
||||
"recording_type",
|
||||
"recording_trigger",
|
||||
"is_shared",
|
||||
"webhook_url",
|
||||
"webhook_secret",
|
||||
],
|
||||
title: "CreateRoom",
|
||||
} as const;
|
||||
@@ -809,11 +819,11 @@ export const $Page_GetTranscriptMinimal_ = {
|
||||
title: "Page[GetTranscriptMinimal]",
|
||||
} as const;
|
||||
|
||||
export const $Page_Room_ = {
|
||||
export const $Page_RoomDetails_ = {
|
||||
properties: {
|
||||
items: {
|
||||
items: {
|
||||
$ref: "#/components/schemas/Room",
|
||||
$ref: "#/components/schemas/RoomDetails",
|
||||
},
|
||||
type: "array",
|
||||
title: "Items",
|
||||
@@ -869,7 +879,7 @@ export const $Page_Room_ = {
|
||||
},
|
||||
type: "object",
|
||||
required: ["items", "page", "size"],
|
||||
title: "Page[Room]",
|
||||
title: "Page[RoomDetails]",
|
||||
} as const;
|
||||
|
||||
export const $Participant = {
|
||||
@@ -969,6 +979,86 @@ export const $Room = {
|
||||
title: "Room",
|
||||
} as const;
|
||||
|
||||
export const $RoomDetails = {
|
||||
properties: {
|
||||
id: {
|
||||
type: "string",
|
||||
title: "Id",
|
||||
},
|
||||
name: {
|
||||
type: "string",
|
||||
title: "Name",
|
||||
},
|
||||
user_id: {
|
||||
type: "string",
|
||||
title: "User Id",
|
||||
},
|
||||
created_at: {
|
||||
type: "string",
|
||||
format: "date-time",
|
||||
title: "Created At",
|
||||
},
|
||||
zulip_auto_post: {
|
||||
type: "boolean",
|
||||
title: "Zulip Auto Post",
|
||||
},
|
||||
zulip_stream: {
|
||||
type: "string",
|
||||
title: "Zulip Stream",
|
||||
},
|
||||
zulip_topic: {
|
||||
type: "string",
|
||||
title: "Zulip Topic",
|
||||
},
|
||||
is_locked: {
|
||||
type: "boolean",
|
||||
title: "Is Locked",
|
||||
},
|
||||
room_mode: {
|
||||
type: "string",
|
||||
title: "Room Mode",
|
||||
},
|
||||
recording_type: {
|
||||
type: "string",
|
||||
title: "Recording Type",
|
||||
},
|
||||
recording_trigger: {
|
||||
type: "string",
|
||||
title: "Recording Trigger",
|
||||
},
|
||||
is_shared: {
|
||||
type: "boolean",
|
||||
title: "Is Shared",
|
||||
},
|
||||
webhook_url: {
|
||||
type: "string",
|
||||
title: "Webhook Url",
|
||||
},
|
||||
webhook_secret: {
|
||||
type: "string",
|
||||
title: "Webhook Secret",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
"id",
|
||||
"name",
|
||||
"user_id",
|
||||
"created_at",
|
||||
"zulip_auto_post",
|
||||
"zulip_stream",
|
||||
"zulip_topic",
|
||||
"is_locked",
|
||||
"room_mode",
|
||||
"recording_type",
|
||||
"recording_trigger",
|
||||
"is_shared",
|
||||
"webhook_url",
|
||||
"webhook_secret",
|
||||
],
|
||||
title: "RoomDetails",
|
||||
} as const;
|
||||
|
||||
export const $RtcOffer = {
|
||||
properties: {
|
||||
sdp: {
|
||||
@@ -1351,6 +1441,14 @@ export const $UpdateRoom = {
|
||||
type: "boolean",
|
||||
title: "Is Shared",
|
||||
},
|
||||
webhook_url: {
|
||||
type: "string",
|
||||
title: "Webhook Url",
|
||||
},
|
||||
webhook_secret: {
|
||||
type: "string",
|
||||
title: "Webhook Secret",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
required: [
|
||||
@@ -1363,6 +1461,8 @@ export const $UpdateRoom = {
|
||||
"recording_type",
|
||||
"recording_trigger",
|
||||
"is_shared",
|
||||
"webhook_url",
|
||||
"webhook_secret",
|
||||
],
|
||||
title: "UpdateRoom",
|
||||
} as const;
|
||||
@@ -1541,6 +1641,50 @@ export const $ValidationError = {
|
||||
title: "ValidationError",
|
||||
} as const;
|
||||
|
||||
export const $WebhookTestResult = {
|
||||
properties: {
|
||||
success: {
|
||||
type: "boolean",
|
||||
title: "Success",
|
||||
},
|
||||
message: {
|
||||
type: "string",
|
||||
title: "Message",
|
||||
default: "",
|
||||
},
|
||||
error: {
|
||||
type: "string",
|
||||
title: "Error",
|
||||
default: "",
|
||||
},
|
||||
status_code: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "integer",
|
||||
},
|
||||
{
|
||||
type: "null",
|
||||
},
|
||||
],
|
||||
title: "Status Code",
|
||||
},
|
||||
response_preview: {
|
||||
anyOf: [
|
||||
{
|
||||
type: "string",
|
||||
},
|
||||
{
|
||||
type: "null",
|
||||
},
|
||||
],
|
||||
title: "Response Preview",
|
||||
},
|
||||
},
|
||||
type: "object",
|
||||
required: ["success"],
|
||||
title: "WebhookTestResult",
|
||||
} as const;
|
||||
|
||||
export const $WherebyWebhookEvent = {
|
||||
properties: {
|
||||
apiVersion: {
|
||||
|
||||
Reference in New Issue
Block a user