diff --git a/backend/src/controllers/livekit-webhook.controller.ts b/backend/src/controllers/livekit-webhook.controller.ts index 6ad5fe1..d804568 100644 --- a/backend/src/controllers/livekit-webhook.controller.ts +++ b/backend/src/controllers/livekit-webhook.controller.ts @@ -37,8 +37,11 @@ export const lkWebhookHandler = async (req: Request, res: Response) => { case 'participant_joined': await lkWebhookService.handleParticipantJoined(room!, participant!); break; + case 'room_started': + await lkWebhookService.handleRoomStarted(room!); + break; case 'room_finished': - await lkWebhookService.handleMeetingFinished(room!); + await lkWebhookService.handleRoomFinished(room!); break; default: break; diff --git a/backend/src/services/livekit-webhook.service.ts b/backend/src/services/livekit-webhook.service.ts index 402030b..2c517f8 100644 --- a/backend/src/services/livekit-webhook.service.ts +++ b/backend/src/services/livekit-webhook.service.ts @@ -139,6 +139,28 @@ export class LivekitWebhookService { } } + /** + * Handles a room started event from LiveKit. + * + * This method retrieves the corresponding meet room from the room service using the LiveKit room name. + * If the meet room is found, it sends a webhook notification indicating that the meeting has started. + * If the meet room is not found, it logs a warning message. + */ + async handleRoomStarted(room: Room) { + try { + const meetRoom = await this.roomService.getMeetRoom(room.name); + + if (!meetRoom) { + this.logger.warn(`Room ${room.name} not found in OpenVidu Meet.`); + return; + } + + await this.openViduWebhookService.sendMeetingStartedWebhook(meetRoom); + } catch (error) { + this.logger.error('Error sending meeting started webhook:', error); + } + } + /** * Handles the event when a room is finished. * @@ -148,12 +170,18 @@ export class LivekitWebhookService { * @param {Room} room - The room object that has finished. * @returns {Promise} A promise that resolves when the webhook has been sent. */ - async handleMeetingFinished(room: Room): Promise { + async handleRoomFinished(room: Room): Promise { try { - const [meetRoom] = await Promise.all([ - this.roomService.getMeetRoom(room.name), + const meetRoom = await this.roomService.getMeetRoom(room.name); + + if (!meetRoom) { + this.logger.warn(`Room ${room.name} not found in OpenVidu Meet.`); + return; + } + + await Promise.all([ this.recordingService.releaseRecordingLockIfNoEgress(room.name), - this.openViduWebhookService.sendRoomFinishedWebhook(room) + this.openViduWebhookService.sendMeetingEndedWebhook(meetRoom) ]); if (meetRoom.markedForDeletion) { diff --git a/backend/src/services/openvidu-webhook.service.ts b/backend/src/services/openvidu-webhook.service.ts index 1b55443..a66e859 100644 --- a/backend/src/services/openvidu-webhook.service.ts +++ b/backend/src/services/openvidu-webhook.service.ts @@ -1,5 +1,6 @@ import { MeetRecordingInfo, + MeetRoom, MeetWebhookEvent, MeetWebhookEventType, MeetWebhookPayload, @@ -7,7 +8,6 @@ import { } from '@typings-ce'; import crypto from 'crypto'; import { inject, injectable } from 'inversify'; -import { Room } from 'livekit-server-sdk'; import { MEET_API_KEY } from '../environment.js'; import { LoggerService, MeetStorageService } from './index.js'; @@ -18,13 +18,20 @@ export class OpenViduWebhookService { @inject(MeetStorageService) protected globalPrefService: MeetStorageService ) {} - // TODO: Implement Room webhooks - async sendRoomFinishedWebhook(room: Room) { - // try { - // await this.sendWebhookEvent(MeetWebhookEventType.ROOM_FINISHED, data); - // } catch (error) { - // this.logger.error(`Error sending room finished webhook: ${error}`); - // } + async sendMeetingStartedWebhook(room: MeetRoom) { + try { + await this.sendWebhookEvent(MeetWebhookEventType.MEETING_STARTED, room); + } catch (error) { + this.logger.error(`Error sending meeting started webhook: ${error}`); + } + } + + async sendMeetingEndedWebhook(room: MeetRoom) { + try { + await this.sendWebhookEvent(MeetWebhookEventType.MEETING_ENDED, room); + } catch (error) { + this.logger.error(`Error sending meeting ended webhook: ${error}`); + } } async sendRecordingStartedWebhook(recordingInfo: MeetRecordingInfo) { diff --git a/typings/src/webhook.model.ts b/typings/src/webhook.model.ts index dd80c98..b9d4399 100644 --- a/typings/src/webhook.model.ts +++ b/typings/src/webhook.model.ts @@ -4,6 +4,8 @@ import { MeetRoom } from './room.js'; export type MeetWebhookPayload = MeetRecordingInfo | MeetRoom; export const enum MeetWebhookEventType { + MEETING_STARTED = 'meetingStarted', + MEETING_ENDED = 'meetingEnded', RECORDING_STARTED = 'recordingStarted', RECORDING_UPDATED = 'recordingUpdated', RECORDING_ENDED = 'recordingEnded', diff --git a/typings/sync-types.sh b/typings/sync-types.sh index bb01db4..6176517 100755 --- a/typings/sync-types.sh +++ b/typings/sync-types.sh @@ -1,7 +1,11 @@ #!/bin/sh HEADER_KEY="THIS HEADER IS AUTOGENERATED. DO NOT MODIFY MANUALLY." -HEADER="/** $HEADER_KEY For any changes, please update the '/openvidu-meet/typings' directory. */" +HEADER=" +/** +* $HEADER_KEY +* ! For any changes, please update the '/openvidu-meet/typings' directory. +**/" SOURCE_DIR="src" FRONTEND_DIR="../frontend/projects/shared-meet-components/src/lib/typings/ce"