diff --git a/app/api/connection-details/route.ts b/app/api/connection-details/route.ts index d46c1c2..0a5cfab 100644 --- a/app/api/connection-details/route.ts +++ b/app/api/connection-details/route.ts @@ -5,6 +5,7 @@ import { } from "livekit-server-sdk"; import { NextResponse } from "next/server"; +// NOTE: you are expected to define the following environment variables in `.env.local`: const API_KEY = process.env.LIVEKIT_API_KEY; const API_SECRET = process.env.LIVEKIT_API_SECRET; const LIVEKIT_URL = process.env.LIVEKIT_URL; @@ -18,25 +19,28 @@ export type ConnectionDetails = { export async function GET() { try { - // Generate participant token - const participantIdentity = `voice_assistant_user_${Math.round( - Math.random() * 10_000 - )}`; - const participantToken = await createParticipantToken( - { - identity: participantIdentity, - }, - "roomName" - ); - if (LIVEKIT_URL === undefined) { throw new Error("LIVEKIT_URL is not defined"); } + if (API_KEY === undefined) { + throw new Error("LIVEKIT_API_KEY is not defined"); + } + if (API_SECRET === undefined) { + throw new Error("LIVEKIT_API_SECRET is not defined"); + } + + // Generate participant token + const participantIdentity = `voice_assistant_user_${Math.floor(Math.random() * 10_000)}`; + const roomName = `voice_assistant_room_${Math.floor(Math.random() * 10_000)}`; + const participantToken = await createParticipantToken( + { identity: participantIdentity }, + roomName, + ); // Return connection details const data: ConnectionDetails = { serverUrl: LIVEKIT_URL, - roomName: "voice_assistant_room", + roomName, participantToken: participantToken, participantName: participantIdentity, }; @@ -44,7 +48,6 @@ export async function GET() { } catch (error) { if (error instanceof Error) { console.error(error); - return new NextResponse(error.message, { status: 500 }); } } @@ -54,8 +57,10 @@ function createParticipantToken( userInfo: AccessTokenOptions, roomName: string ) { - const at = new AccessToken(API_KEY, API_SECRET, userInfo); - at.ttl = "5m"; + const at = new AccessToken(API_KEY, API_SECRET, { + ...userInfo, + ttl: "15m", + }); const grant: VideoGrant = { room: roomName, roomJoin: true, diff --git a/app/page.tsx b/app/page.tsx index a59b488..a8f8b7b 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -24,9 +24,18 @@ export default function Page() { const [agentState, setAgentState] = useState("disconnected"); const onConnectButtonClicked = useCallback(async () => { + // Generate room connection details, including: + // - A random Room name + // - A random Participant name + // - An Access Token to permit the participant to join the room + // - The URL of the LiveKit server to connect to + // + // In real-world application, you would likely allow the user to specify their + // own participant name, and possibly to choose from existing rooms to join. + const url = new URL( process.env.NEXT_PUBLIC_CONN_DETAILS_ENDPOINT ?? - "/api/connection-details", + "/api/connection-details", window.location.origin ); const response = await fetch(url.toString());