diff --git a/backend/openapi/components/parameters/x-signature.yaml b/backend/openapi/components/parameters/x-signature.yaml index 0e19af8..dff3175 100644 --- a/backend/openapi/components/parameters/x-signature.yaml +++ b/backend/openapi/components/parameters/x-signature.yaml @@ -1,5 +1,9 @@ -name: X-Signature +name: x-signature in: header -description: HMAC signature for webhook verification. +description: > + HMAC-SHA256 signature of the request body, created using your webhook secret. + + Use this to verify the webhook came from OpenVidu Meet and wasn't tampered with. +required: true schema: - type: string + type: string diff --git a/backend/openapi/components/parameters/x-timestamp.yaml b/backend/openapi/components/parameters/x-timestamp.yaml index 2b84992..0498fb6 100644 --- a/backend/openapi/components/parameters/x-timestamp.yaml +++ b/backend/openapi/components/parameters/x-timestamp.yaml @@ -1,6 +1,10 @@ -name: X-Timestamp +name: x-timestamp in: header -description: Timestamp of the webhook event (in Unix Epoch milliseconds). +description: > + Unix timestamp (in seconds) when the webhook was sent. + + Can be used to validate webhook age and prevent replay attacks. +required: true schema: type: string example: '1697030400000' diff --git a/backend/openapi/components/responses/webhook-success.yaml b/backend/openapi/components/responses/webhook-success.yaml new file mode 100644 index 0000000..9eb0dc3 --- /dev/null +++ b/backend/openapi/components/responses/webhook-success.yaml @@ -0,0 +1,7 @@ +description: > + Webhook received and processed successfully. + + Important: Webhook endpoints must return HTTP 200 OK promptly to acknowledge receipt. + Any processing should be done asynchronously after responding. + + Non-200 responses or timeouts will trigger retries according to the webhook delivery policy. \ No newline at end of file diff --git a/backend/openapi/components/schemas/recording-base.yaml b/backend/openapi/components/schemas/recording-base.yaml new file mode 100644 index 0000000..ef9c2ec --- /dev/null +++ b/backend/openapi/components/schemas/recording-base.yaml @@ -0,0 +1,23 @@ +type: object +required: + - recordingId + - roomId + - filename + - startDate +properties: + recordingId: + type: string + description: The unique identifier of the recording. + example: room-123--EG_XYZ--XX445 + roomId: + type: string + description: The ID of the room where the recording was made. + example: room-123 + filename: + type: string + description: The name of the recording file. + example: room-123--XX445.mp4 + startDate: + type: number + description: The date when the recording started (milliseconds since the Unix epoch). + example: 1620000000000 \ No newline at end of file diff --git a/backend/openapi/components/schemas/webhook-base-event.yaml b/backend/openapi/components/schemas/webhook-base-event.yaml new file mode 100644 index 0000000..181dd6c --- /dev/null +++ b/backend/openapi/components/schemas/webhook-base-event.yaml @@ -0,0 +1,17 @@ +type: object +required: + - creationDate + - event + - data +properties: + creationDate: + type: number + description: The date when the event was created (milliseconds since the Unix epoch). + example: 1620000000000 + event: + type: string + description: Event type identifier. + example: webhookEvent + data: + type: object + description: The data associated with the event. \ No newline at end of file diff --git a/backend/openapi/webhooks/webhooks.yaml b/backend/openapi/webhooks/webhooks.yaml index c65913a..9c2e3d5 100644 --- a/backend/openapi/webhooks/webhooks.yaml +++ b/backend/openapi/webhooks/webhooks.yaml @@ -5,51 +5,39 @@ recordingStarted: This webhook is triggered when a recording starts. > The recording can be in the `STARTING` status for a few seconds before it becomes `ACTIVE`. - operationId: recordingStartedWebhook parameters: - $ref: ../components/parameters/x-timestamp.yaml - $ref: ../components/parameters/x-signature.yaml - # TODO: Use defined schema for request body requestBody: required: true content: application/json: schema: - properties: - creationDate: - type: number - description: The date when the event was created (milliseconds since the Unix epoch). - example: 1620000000000 - event: - type: string - description: Event type identifier. - example: recordingStarted - data: - properties: - recordingId: - type: string - description: The unique identifier of the recording. - example: room-123--EG_XYZ--XX445 - roomId: - type: string - description: The ID of the room where the recording was made. - example: room-123 - status: - type: string - description: The status of the recording. - example: STARTING - filename: - type: string - description: The name of the recording file. - example: room-123--XX445.mp4 - startDate: - type: number - description: The date when the recording started (milliseconds since the Unix epoch). - example: 1620000000000 + type: object + allOf: + - $ref: ../components/schemas/webhook-base-event.yaml + - properties: + event: + example: recordingStarted + data: + type: object + required: + - recordingId + - roomId + - status + allOf: + - $ref: ../components/schemas/recording-base.yaml + - properties: + status: + type: string + enum: [STARTING] + description: The status of the recording. + example: STARTING responses: '200': - description: Webhook received successfully + $ref: ../components/responses/webhook-success.yaml + recordingUpdated: post: summary: Recording updated @@ -61,48 +49,35 @@ recordingUpdated: parameters: - $ref: ../components/parameters/x-timestamp.yaml - $ref: ../components/parameters/x-signature.yaml - # TODO: Use defined schema for request body requestBody: required: true content: application/json: schema: type: object - properties: - creationDate: - type: number - description: The date when the event was created (milliseconds since the Unix epoch). - example: 1620000000000 - event: - type: string - description: Event type identifier. - example: recordingUpdated - data: - properties: - recordingId: - type: string - description: The unique identifier of the recording. - example: room-123--EG_XYZ--XX445 - roomId: - type: string - description: The ID of the room where the recording was made. - example: room-123 - status: - type: string - enum: [ACTIVE, ENDING] - description: The status of the recording. - example: ACTIVE - filename: - type: string - description: The name of the recording file. - example: room-123--XX445.mp4 - startDate: - type: number - description: The date when the recording started (milliseconds since the Unix epoch). - example: 1620000000000 + allOf: + - $ref: ../components/schemas/webhook-base-event.yaml + - properties: + event: + example: recordingUpdated + data: + type: object + required: + - recordingId + - roomId + - status + allOf: + - $ref: ../components/schemas/recording-base.yaml + - properties: + status: + type: string + enum: [ACTIVE, ENDING] + description: The status of the recording. + example: ACTIVE responses: '200': - description: Webhook received successfully + $ref: ../components/responses/webhook-success.yaml + recordingEnded: post: summary: Recording ended @@ -114,62 +89,100 @@ recordingEnded: parameters: - $ref: ../components/parameters/x-timestamp.yaml - $ref: ../components/parameters/x-signature.yaml - # TODO: Use defined schema for request body requestBody: required: true content: application/json: schema: type: object - properties: - creationDate: - type: number - description: The date when the event was created (milliseconds since the Unix epoch). - example: 1620000000000 - event: - type: string - description: Event type identifier. - example: recordingEnded - data: - properties: - recordingId: - type: string - description: The unique identifier of the recording. - example: room-123--EG_XYZ--XX445 - roomId: - type: string - description: The ID of the room where the recording was made. - example: room-123 - status: - type: string - enum: [COMPLETE, FAILED, ABORTED, LIMITED_REACHED] - description: The status of the recording. - example: COMPLETE - filename: - type: string - description: The name of the recording file. - example: room-123--XX445.mp4 - startDate: - type: number - description: The date when the recording started (milliseconds since the Unix epoch). - example: 1620000000000 - endDate: - type: number - description: The date when the recording ended (milliseconds since the Unix epoch). - example: 1620000003600 - duration: - type: number - description: The duration of the recording in seconds. - example: 3.6 - size: - type: number - description: The size of the recording file in bytes. - example: 1024 - details: - type: string - description: Additional details about the recording. - example: Stopped using API - + allOf: + - $ref: ../components/schemas/webhook-base-event.yaml + - properties: + event: + example: recordingEnded + data: + type: object + required: + - recordingId + - roomId + - status + - endDate + allOf: + - $ref: ../components/schemas/recording-base.yaml + - properties: + status: + type: string + enum: [COMPLETE, FAILED, ABORTED, LIMITED_REACHED] + description: The status of the recording. + example: COMPLETE + endDate: + type: number + description: The date when the recording ended (milliseconds since the Unix epoch). + example: 1620000003600 + duration: + type: number + description: The duration of the recording in seconds. + example: 3.6 + size: + type: number + description: The size of the recording file in bytes. + example: 1024 + details: + type: string + description: Additional details about the recording. + example: Stopped using API responses: '200': - description: Webhook received successfully + $ref: ../components/responses/webhook-success.yaml + +meetingStarted: + post: + summary: Meeting started + description: > + This webhook is triggered when a meeting starts. + operationId: meetingStartedWebhook + parameters: + - $ref: ../components/parameters/x-timestamp.yaml + - $ref: ../components/parameters/x-signature.yaml + requestBody: + required: true + content: + application/json: + schema: + type: object + allOf: + - $ref: ../components/schemas/webhook-base-event.yaml + - properties: + event: + example: meetingStarted + data: + $ref: ../components/schemas/meet-room.yaml + responses: + '200': + $ref: ../components/responses/webhook-success.yaml + +meetingEnded: + post: + summary: Meeting ended + description: > + This webhook is triggered when a meeting ends. + operationId: meetingEndedWebhook + parameters: + - $ref: ../components/parameters/x-timestamp.yaml + - $ref: ../components/parameters/x-signature.yaml + requestBody: + required: true + content: + application/json: + schema: + type: object + allOf: + - $ref: ../components/schemas/webhook-base-event.yaml + - properties: + event: + example: meetingEnded + data: + $ref: ../components/schemas/meet-room.yaml + responses: + '200': + $ref: ../components/responses/webhook-success.yaml