55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
import { createHmac } from "node:crypto";
|
|
import { AccessToken, RoomServiceClient, TrackSource } from "livekit-server-sdk";
|
|
import type { MeetingRole } from "./token";
|
|
|
|
function requiredEnv(name: "LIVEKIT_URL" | "LIVEKIT_API_KEY" | "LIVEKIT_API_SECRET"): string {
|
|
const value = process.env[name];
|
|
if (!value) throw new Error(`${name} is not set`);
|
|
return value;
|
|
}
|
|
|
|
export function getLiveKitClientUrl(): string {
|
|
return requiredEnv("LIVEKIT_URL").replace(/^http:/, "ws:").replace(/^https:/, "wss:").replace(/\/$/, "");
|
|
}
|
|
|
|
function getLiveKitApiUrl(): string {
|
|
return requiredEnv("LIVEKIT_URL").replace(/^ws:/, "http:").replace(/^wss:/, "https:").replace(/\/$/, "");
|
|
}
|
|
|
|
/** Stable opaque room name; the public event slug is never sent to LiveKit logs. */
|
|
export function getLiveKitRoomName(eventSlug: string): string {
|
|
const secret = requiredEnv("LIVEKIT_API_SECRET");
|
|
return `anouma-${createHmac("sha256", secret).update(eventSlug).digest("hex").slice(0, 32)}`;
|
|
}
|
|
|
|
export async function createLiveKitToken(args: {
|
|
eventSlug: string;
|
|
participantId: string;
|
|
name: string;
|
|
role: MeetingRole;
|
|
clientId?: string;
|
|
}): Promise<string> {
|
|
const room = getLiveKitRoomName(args.eventSlug);
|
|
const token = new AccessToken(requiredEnv("LIVEKIT_API_KEY"), requiredEnv("LIVEKIT_API_SECRET"), {
|
|
identity: args.participantId,
|
|
name: args.name,
|
|
ttl: "2h",
|
|
metadata: JSON.stringify({ role: args.role, clientId: args.clientId }),
|
|
});
|
|
token.addGrant({
|
|
roomJoin: true,
|
|
room,
|
|
canPublish: true,
|
|
canSubscribe: true,
|
|
canPublishData: true,
|
|
canPublishSources: args.role === "host"
|
|
? [TrackSource.CAMERA, TrackSource.MICROPHONE, TrackSource.SCREEN_SHARE, TrackSource.SCREEN_SHARE_AUDIO]
|
|
: [TrackSource.CAMERA, TrackSource.MICROPHONE],
|
|
});
|
|
return token.toJwt();
|
|
}
|
|
|
|
export function getLiveKitRoomService(): RoomServiceClient {
|
|
return new RoomServiceClient(getLiveKitApiUrl(), requiredEnv("LIVEKIT_API_KEY"), requiredEnv("LIVEKIT_API_SECRET"));
|
|
}
|