라이브킷을 사용할때 web에서 room에 접속할때 agent metadata를 넘겨주는 방...
# ask-ai
l
라이브킷을 사용할때 web에서 room에 접속할때 agent metadata를 넘겨주는 방법이 있어?
t
Thanks for reaching out, Dan(송희웅). I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
요청하신 부분(웹에서 room 접속 시 agent metadata 전달 방법)에 대해 답드릴게요. 가능합니다. 웹 클라이언트가 room에 접속할 때 사용하는 액세스 토큰(access token)에 RoomConfiguration의
RoomAgentDispatch
항목으로 metadata를 JSON 문자열로 포함시키면 됩니다. 토큰으로 접속하면 해당 메타데이터가 에이전트에 전달되어 에이전트의 `JobContext.job.metadata`에서 확인할 수 있습니다. 간단한 흐름(요약): 1. 서버에서 AccessToken 생성 시
roomJoin
권한 추가 및 `roomConfig`에
agents
배열 설정 2. 각 `RoomAgentDispatch`에 `agentName`과 `metadata`(JSON 문자열) 포함 3. 생성한 JWT 토큰을 웹 클라이언트가 사용해 room에 접속 4. 에이전트는 `JobContext.job.metadata`에서 metadata를 파싱해 사용 예시(Node.js, 요약):
Copy code
const at = new AccessToken();
at.identity = 'user-identity';
at.addGrant({ roomJoin: true, room: 'my-room' });
at.roomConfig = new RoomConfiguration({
  agents: [
    new RoomAgentDispatch({
      agentName: 'my-agent',
      metadata: '{"user_id":"12345","user_name":"Alice"}'
    })
  ]
});
const token = await at.toJwt();
에이전트 쪽 접근 예:
Copy code
export default defineAgent({
  entry: async (ctx: JobContext) => {
    const metadata = JSON.parse(ctx.job.metadata);
    // metadata.user_id, metadata.user_name 사용
  }
});
원하시면: • 현재 사용 중인 언어(예: Python, Go) 예시 코드로 보여드릴게요. • 또는 실제로 넣고 싶은 metadata 구조를 알려주시면 적절한 샘플로 맞춰드릴게요. Sources: Agent dispatch | LiveKit docs
l
그런데 코드를 보니깐 Nextjs 웹 클라이언트에서 "useSession" 을 통해서 api 를 호출해 "participantToken" 를 발급할때, 그때 RoomAgentDispatch 를 통해 metadata를 넘기는데, 웹 클라이언트에서 useSession 을 통해 metadata 를 어떻게 넘기지?
t
좋은 질문이에요 — Next.js 클라이언트의 `useSession`으로 받은 유저 정보(또는 세션 데이터)를 API 호출에 포함시켜 서버에서 `RoomAgentDispatch.metadata`로 넣어주면 됩니다. 요점과 예시 코드를 간단히 드릴게요. 1) 클라이언트(Next.js): `useSession`에서 필요한 사용자 필드(예: id, name)를 읽어 POST 바디나 헤더로 전송
Copy code
// pages or components
import { useSession } from "next-auth/react";

const joinRoom = async () => {
  const { data: session } = useSession();
  const metadata = {
    user_id: session?.user?.id,
    user_name: session?.user?.name,
  };
  const res = await fetch("/api/participant-token", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ room: "my-room", metadata }),
  });
  const { token } = await res.json();
  // token으로 LiveKit 접속
};
2) 서버(API route): 클라이언트가 보낸 `metadata`를 받아 AccessToken 생성 시 `RoomAgentDispatch.metadata`에 JSON 문자열로 넣기
Copy code
// pages/api/participant-token.ts
import { NextApiRequest, NextApiResponse } from "next";
import { AccessToken, RoomConfiguration, RoomAgentDispatch } from "livekit-server-sdk"; // 예시 임포트

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const { room, metadata } = req.body;
  const at = new AccessToken();
  at.identity = "participant-" + Math.random().toString(36).slice(2);
  at.addGrant({ roomJoin: true, room });

  at.roomConfig = new RoomConfiguration({
    agents: [
      new RoomAgentDispatch({
        agentName: "my-agent",
        metadata: JSON.stringify(metadata),
      }),
    ],
  });

  const token = await at.toJwt();
  res.status(200).json({ token });
}
주의/권장: • 민감한 데이터(예: 토큰, 비밀번호)는 클라이언트에서 직접 넣지 말고 서버에서 검증 후 포함하세요. • metadata 크기를 적절히 제한하세요(짧은 JSON 권장). • 인증 검사(세션 유효성)를 서버에서 수행한 뒤 메타데이터를 신뢰할지 결정하세요. 원하시면: • 현재 사용 중인 인증(예: next-auth) 코드에 맞춰 구체적 예시로 맞춰드릴게요. • metadata 스키마를 알려주시면 보안/검증 체크리스트도 같이 드릴게요. 어느 쪽 도와드릴까요?
l
import { RoomAudioRenderer, SessionProvider, StartAudio, useSession, } from '@alert-easter-19258/components-react'; const tokenSource = useMemo(() => { return typeof process.env.NEXT_PUBLIC_CONN_DETAILS_ENDPOINT === 'string' ? getSandboxTokenSource(appConfig) : TokenSource.endpoint('/api/connection-details'); }, [appConfig]); const session = useSession( tokenSource, appConfig.agentName ? { agentName: appConfig.agentName } : undefined ); 코드가 이렇게 되어 있어! useSession 은 라이브킷의 컴포넌트야
t
좋습니다 — 주신 코드(라이브킷의
useSession
사용)를 보고 바로 답드립니다. 요지:
useSession
자체로는 metadata를 직접 전달할 수 없습니다. metadata는 클라이언트가 호출하는 토큰 발급 엔드포인트에서 서버 측으로 포함시켜 JWT에 넣어야 합니다. 즉, 클라이언트는 세션(예: `useSession`으로 얻은 사용자 정보)을 토큰 발급 API에 보내고, 서버가 받은 데이터를 `RoomAgentDispatch.metadata`(또는 AccessToken의
metadata
)로 JSON 문자열화해 토큰에 넣어 반환합니다. `useSession`에는 tokenSource만 넘기면 되고, tokenSource가 호출하는 `/api/connection-details`(혹은 당신의 엔드포인트)가 metadata를 포함한 토큰을 생성해야 합니다. 간단한 흐름 요약: 1. 클라이언트: `useSession`에서 사용자 정보 읽음 → POST로
/api/connection-details
호출 (body에 metadata 포함). 2. 서버(API): 사용자 인증/검증 후 AccessToken 생성 →
roomConfig.agents
또는 `at.metadata`에
JSON.stringify(metadata)
넣음 → JWT 발급 반환. 3. 클라이언트: 반환된 token으로 `useSession`/LiveKit 연결. 에이전트는
JobContext.job.metadata
또는 참가자 메타데이터에서 접근 가능. 원하시면 다음 중 하나 골라 도와드릴게요: • 당신 환경에 맞춘 구체적 예시 코드 (Next.js App Router vs Pages, TypeScript/JS). • `getSandboxTokenSource()`나
TokenSource.endpoint('/api/connection-details')
구현을 보여주시면, 클라이언트 쪽 요청 바디 예시와 서버 API 코드를 바로 작성해 드립니다. • metadata 스키마(어떤 필드)를 알려주시면 검증·보안 체크 포함한 샘플 제공. 어떤 걸로 도와드릴까요?
l
const tokenSource = useMemo(() => { return TokenSource.endpoint('/api/connection-details'); }, [appConfig]); const session = useSession( tokenSource, appConfig.agentName ? { agentName: appConfig.agentName } : undefined ); useSession 에서 POST 로 /api/connection-details 를 호출하는데, 이때 metadata 를 넘길수 있는 방법을 알려줘
t
좋은 질문이에요 — 핵심: 기본 `TokenSource.endpoint('/api/connection-details')`가 내부 호출에 커스텀 바디를 보낼 수 없다면, 클라이언트에서 metadata를 포함해 토큰을 요청하도록 TokenSource를 직접 구현하거나, 쿼리/헤더에 metadata를 실어 서버에서 읽도록 해야 합니다. 아래에 두 가지 실용적 방법과 예시 코드를 드릴게요. 옵션 A — 커스텀 TokenSource 구현 (권장) • `useSession`에 넘기는 TokenSource를 직접 만들어 POST 바디에 metadata를 포함해 호출하도록 구현합니다. 예시 (Next.js, TS/React):
Copy code
import { TokenSource } from "@livekit/components-react";

// custom token source
function createCustomTokenSource(getMetadata: () => any) {
  return {
    getToken: async () => {
      const metadata = getMetadata();
      const res = await fetch("/api/connection-details", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ metadata }),
      });
      const json = await res.json();
      return { token: json.token, serverUrl: json.serverUrl };
    },
  } as TokenSource;
}

// 사용
const tokenSource = useMemo(() => {
  return createCustomTokenSource(() => ({
    user_id: session?.user?.id,
    user_name: session?.user?.name,
  }));
}, [session]);
• 장점: 원하는 구조로 언제든 metadata 보낼 수 있고 인증된 세션에서 안전하게 추출 가능. 옵션 B — 엔드포인트에서 세션 기반으로 메타데이터 추출 • 클라이언트는 빈 요청(또는 최소한의 요청)만 보내고, 서버(API)가 NextAuth 세션 또는 쿠키에서 사용자 정보를 읽어 metadata를 구성해 토큰에 넣습니다. • 구현이 간단하며 클라이언트가 민감한 데이터를 전송하지 않아 보안상 유리합니다. 예시 서버 (pages/api/connection-details.ts):
Copy code
import { getServerSession } from "next-auth"; // 사용중이면
export default async function handler(req, res) {
  const session = await getServerSession(req, res, authOptions);
  if (!session) return res.status(401).json({ error: "Not authenticated" });

  const metadata = { user_id: session.user.id, user_name: session.user.name };
  // AccessToken 생성 후 metadata를 RoomAgentDispatch 또는 at.metadata에 넣음
  // res.json({ token, serverUrl });
}
서버 쪽: 받은 metadata를
RoomAgentDispatch.metadata
또는 AccessToken의 `metadata`에 `JSON.stringify(...)`로 넣어 JWT 발급. 주의사항(간단): • 클라이언트에서 보낼 경우 서버에서 반드시 검증(세션 확인)하세요. • metadata는 가능한 작게 유지하세요. • 민감한 정보는 서버에서만 추가하세요. 원하시면: • A 방식(커스텀 TokenSource) 전체 구현 코드를 app-router/pages-router에 맞춰 제공해 드릴게요. • 아니면 B 방식으로 현재 NextAuth 사용 중이면 서버 코드 예시를 바로 만들어 드릴게요. 어떤 방식으로 도와드릴까요?