backend: Saved recording preferences into the room_metadata json file

This commit is contained in:
Carlos Santos 2025-04-22 12:56:22 +02:00
parent 47350f1b10
commit c33ee7218b
2 changed files with 42 additions and 29 deletions

View File

@ -199,7 +199,10 @@ export class LivekitWebhookService {
// Send webhook notification
switch (webhookAction) {
case 'started':
tasks.push(this.openViduWebhookService.sendRecordingStartedWebhook(recordingInfo));
tasks.push(
this.saveRoomMetadataFileIfNeeded(roomId),
this.openViduWebhookService.sendRecordingStartedWebhook(recordingInfo)
);
break;
case 'updated':
tasks.push(this.openViduWebhookService.sendRecordingUpdatedWebhook(recordingInfo));
@ -217,7 +220,6 @@ export class LivekitWebhookService {
break;
case 'ended':
tasks.push(
this.saveRoomSecretsFileIfNeeded(roomId),
this.openViduWebhookService.sendRecordingEndedWebhook(recordingInfo),
this.recordingService.releaseRoomRecordingActiveLock(roomId)
);
@ -235,20 +237,22 @@ export class LivekitWebhookService {
}
/**
* Saves room secrets to an S3 bucket if they haven't been saved already.
* Saves room metadata to a JSON file in the S3 bucket if it doesn't already exist.
*
* This method checks if secrets for the specified room exist in the S3 storage.
* If they don't exist, it retrieves the room information, extracts the publisher
* and moderator secrets, and saves them to an S3 bucket under the path
* `${INTERNAL_CONFIG.S3_RECORDINGS_PREFIX}/.metadata/${roomId}/secrets.json`.
* This method checks if the metadata file for the given room already exists in the
* S3 bucket. If not, it retrieves the room information, extracts the necessary
* secrets and preferences, and saves them to a metadata JSON file in the
* .metadata/{roomId}/ directory of the S3 bucket.
*
* @param roomId - The unique identifier of the room
*/
protected async saveRoomSecretsFileIfNeeded(roomId: string): Promise<void> {
protected async saveRoomMetadataFileIfNeeded(roomId: string): Promise<void> {
try {
const filePath = `${INTERNAL_CONFIG.S3_RECORDINGS_PREFIX}/.metadata/${roomId}/secrets.json`;
const filePath = `${INTERNAL_CONFIG.S3_RECORDINGS_PREFIX}/.metadata/${roomId}/room_metadata.json`;
const fileExists = await this.s3Service.exists(filePath);
if (fileExists) {
this.logger.debug(`Room secrets already saved for room ${roomId}`);
this.logger.debug(`Room metadata already saved for room ${roomId} in recordings bucket`);
return;
}
@ -256,15 +260,18 @@ export class LivekitWebhookService {
if (room) {
const { publisherSecret, moderatorSecret } = MeetRoomHelper.extractSecretsFromRoom(room);
const secrets = {
const roomMetadata = {
publisherSecret,
moderatorSecret
moderatorSecret,
preferences: {
recordingPreferences: room.preferences?.recordingPreferences
}
};
await this.s3Service.saveObject(filePath, secrets);
this.logger.debug(`Room secrets saved for room ${roomId}`);
await this.s3Service.saveObject(filePath, roomMetadata);
this.logger.debug(`Room metadata saved for room ${roomId} in recordings bucket`);
}
} catch (error) {
this.logger.error(`Error saving room secrets for room ${roomId}: ${error}`);
this.logger.error(`Error saving room metadata for room ${roomId} in recordings bucket: ${error}`);
}
}
}

View File

@ -401,15 +401,15 @@ export class RecordingService {
const recordingPath = `${INTERNAL_CONFIG.S3_RECORDINGS_PREFIX}/${RecordingHelper.extractFilename(recordingInfo)}`;
newFilesToDelete.add(recordingPath);
// Get secrets.json file path if it is the only file remaining in the room's metadata directory
const secretsFilePath = await this.getSecretsFilePathIfOnlyRemaining(
// Get room_metadata.json file path under recordings bucket if it is the only file remaining in the room's metadata directory
const roomMetadataFilePath = await this.getRoomMetadataFilePathIfOnlyRemaining(
recordingInfo.roomId,
metadataFilePath,
Array.from(new Set([...filesAlreadyAddedForDeletion, ...newFilesToDelete]))
);
if (secretsFilePath) {
newFilesToDelete.add(secretsFilePath);
if (roomMetadataFilePath) {
newFilesToDelete.add(roomMetadataFilePath);
}
return { filesToDelete: newFilesToDelete, recordingInfo };
@ -537,15 +537,21 @@ export class RecordingService {
}
/**
* Determines if the secrets.json file should be deleted by checking if it would be
* the only file remaining in the room's metadata directory after deletion.
* Determines if the room_metadata.json file would be the only file remaining in a room's metadata
* directory after specified files are deleted.
*
* @param roomId - Room identifier
* @param metadataFilePath - Path of the metadata file being deleted (for single deletion)
* @param filesToDeleteArray - Array of all files being deleted (for bulk deletion)
* @returns Path of the secrets.json file if it should be deleted, or null otherwise
* This method examines the contents of a room's metadata directory in S3 storage and checks whether,
* after the deletion of specified files, only the room_metadata.json file would remain. The method
* handles both single file deletion and bulk deletion scenarios.
*
* @param roomId - The identifier of the room whose metadata directory is being checked
* @param metadataFilePath - The full path of the metadata file being considered for deletion
* @param filesToDeleteArray - Optional array of file paths that are planned for deletion
*
* @returns The path to the room_metadata.json file if it would be the only remaining file after deletion,
* or null if multiple files would remain or if an error occurs during the process
*/
protected async getSecretsFilePathIfOnlyRemaining(
protected async getRoomMetadataFilePathIfOnlyRemaining(
roomId: string,
metadataFilePath: string,
filesToDeleteArray: string[] = []
@ -568,7 +574,7 @@ export class RecordingService {
).map((item) => item.Key!);
// If only secrets.json remains, return its path
if (remainingFiles.length === 1 && remainingFiles[0].endsWith('secrets.json')) {
if (remainingFiles.length === 1 && remainingFiles[0].endsWith('room_metadata.json')) {
return remainingFiles[0];
}
} else {
@ -584,8 +590,8 @@ export class RecordingService {
const otherFiles = Contents.filter((item) => !item.Key?.endsWith(metadataBaseName || ''));
// If the only other file is secrets.json, return its path
if (otherFiles.length === 1 && otherFiles[0].Key?.endsWith('secrets.json')) {
return `${INTERNAL_CONFIG.S3_RECORDINGS_PREFIX}/.metadata/${roomId}/secrets.json`;
if (otherFiles.length === 1 && otherFiles[0].Key?.endsWith('room_metadata.json')) {
return `${INTERNAL_CONFIG.S3_RECORDINGS_PREFIX}/.metadata/${roomId}/room_metadata.json`;
}
}