openvidu-recording-improved: Create function to check if webhook is related to the tutorial

This commit is contained in:
juancarmore 2024-09-09 22:15:23 +02:00
parent 1095fc6b84
commit c1a90d2aa9
4 changed files with 58 additions and 19 deletions

View File

@ -1,4 +1,5 @@
export const SERVER_PORT = process.env.SERVER_PORT || 6080;
export const APP_NAME = "openvidu-recording-improved-tutorial";
// LiveKit configuration
export const LIVEKIT_URL = process.env.LIVEKIT_URL || "http://localhost:7880";
@ -13,3 +14,4 @@ export const AWS_REGION = process.env.AWS_REGION || "us-east-1";
export const S3_BUCKET = process.env.S3_BUCKET || "openvidu";
export const RECORDINGS_PATH = process.env.RECORDINGS_PATH ?? "recordings/";
export const RECORDINGS_METADATA_PATH = ".metadata/";

View File

@ -1,6 +1,12 @@
import { Router } from "express";
import { EgressClient, EncodedFileOutput, EncodedFileType } from "livekit-server-sdk";
import { LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, RECORDINGS_PATH } from "../config.js";
import {
LIVEKIT_URL,
LIVEKIT_API_KEY,
LIVEKIT_API_SECRET,
RECORDINGS_PATH,
RECORDINGS_METADATA_PATH
} from "../config.js";
import { S3Service } from "../services/s3.service.js";
const egressClient = new EgressClient(LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
@ -86,12 +92,12 @@ recordingController.get("/", async (req, res) => {
try {
const keyStart =
RECORDINGS_PATH + ".metadata/" + (roomName ? `${roomName}` + (roomId ? `-${roomId}` : "") : "");
RECORDINGS_PATH + RECORDINGS_METADATA_PATH + (roomName ? `${roomName}` + (roomId ? `-${roomId}` : "") : "");
const keyEnd = ".json";
const regex = new RegExp(`^${keyStart}.*${keyEnd}$`);
// List all Egress metadata files in the recordings path that match the regex
const metadataKeys = await s3Service.listObjects(RECORDINGS_PATH + ".metadata/", regex);
const metadataKeys = await s3Service.listObjects(RECORDINGS_PATH + RECORDINGS_METADATA_PATH, regex);
const recordings = await Promise.all(metadataKeys.map((metadataKey) => s3Service.getObjectAsJson(metadataKey)));
res.json({ recordings });
} catch (error) {
@ -130,7 +136,7 @@ recordingController.get("/:recordingName", async (req, res) => {
recordingController.delete("/:recordingName", async (req, res) => {
const { recordingName } = req.params;
const recordingKey = RECORDINGS_PATH + recordingName;
const metadataKey = RECORDINGS_PATH + ".metadata/" + recordingName.replace(".mp4", ".json");
const metadataKey = RECORDINGS_PATH + RECORDINGS_METADATA_PATH + recordingName.replace(".mp4", ".json");
const exists = await s3Service.exists(recordingKey);
if (!exists) {

View File

@ -1,6 +1,13 @@
import express, { Router } from "express";
import { EgressStatus, RoomServiceClient, WebhookReceiver } from "livekit-server-sdk";
import { LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET } from "../config.js";
import {
LIVEKIT_URL,
LIVEKIT_API_KEY,
LIVEKIT_API_SECRET,
APP_NAME,
RECORDINGS_PATH,
RECORDINGS_METADATA_PATH
} from "../config.js";
import { S3Service } from "../services/s3.service.js";
const webhookReceiver = new WebhookReceiver(LIVEKIT_API_KEY, LIVEKIT_API_SECRET);
@ -12,17 +19,22 @@ webhookController.use(express.raw({ type: "application/webhook+json" }));
webhookController.post("/", async (req, res) => {
try {
const event = await webhookReceiver.receive(req.body, req.get("Authorization"));
console.log(event);
const webhookEvent = await webhookReceiver.receive(req.body, req.get("Authorization"));
const isWebhookRelatedToMe = await checkWebhookRelatedToMe(webhookEvent);
switch (event.event) {
case "egress_started":
case "egress_updated":
await handleEgressUpdated(event.egressInfo);
break;
case "egress_ended":
await handleEgressEnded(event.egressInfo);
break;
if (isWebhookRelatedToMe) {
console.log(webhookEvent);
const { event: eventType, egressInfo } = webhookEvent;
switch (eventType) {
case "egress_started":
case "egress_updated":
await handleEgressUpdated(egressInfo);
break;
case "egress_ended":
await handleEgressEnded(egressInfo);
break;
}
}
} catch (error) {
console.error("Error validating webhook event.", error);
@ -31,6 +43,25 @@ webhookController.post("/", async (req, res) => {
res.status(200).send();
});
const checkWebhookRelatedToMe = async (webhookEvent) => {
const { room, egressInfo, ingressInfo } = webhookEvent;
let roomInfo = room;
if (!room || !room.metadata) {
const roomName = room?.name ?? egressInfo?.roomName ?? ingressInfo?.roomName;
const rooms = await roomClient.listRooms([roomName]);
if (rooms.length === 0) {
return false;
}
roomInfo = rooms[0];
}
const metadata = roomInfo.metadata ? JSON.parse(roomInfo.metadata) : null;
return metadata?.createdBy === APP_NAME;
};
const handleEgressUpdated = async (egressInfo) => {
await updateRecordingStatus(egressInfo);
};
@ -38,7 +69,7 @@ const handleEgressUpdated = async (egressInfo) => {
const handleEgressEnded = async (egressInfo) => {
const recordingInfo = convertToRecordingInfo(egressInfo);
const metadataName = recordingInfo.name.replace(".mp4", ".json");
const key = `recordings/.metadata/${metadataName}`;
const key = RECORDINGS_PATH + RECORDINGS_METADATA_PATH + metadataName;
await s3Service.uploadObject(key, recordingInfo);
await updateRecordingStatus(egressInfo);
@ -60,7 +91,7 @@ const updateRecordingStatus = async (egressInfo) => {
await roomClient.updateRoomMetadata(
roomName,
JSON.stringify({
createdBy: "openvidu-recording-improved-tutorial",
createdBy: APP_NAME,
recordingStatus
})
);

View File

@ -4,7 +4,7 @@ import cors from "cors";
import path from "path";
import { fileURLToPath } from "url";
import { AccessToken, RoomServiceClient } from "livekit-server-sdk";
import { LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, SERVER_PORT } from "./config.js";
import { LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, SERVER_PORT, APP_NAME } from "./config.js";
import { recordingController } from "./controllers/recording.controller.js";
import { webhookController } from "./controllers/webhook.controller.js";
@ -53,7 +53,7 @@ app.post("/token", async (req, res) => {
const roomOptions = {
name: roomName,
metadata: JSON.stringify({
createdBy: "openvidu-recording-improved-tutorial",
createdBy: APP_NAME,
recordingStatus: "STOPPED"
})
};