45 lines
1.9 KiB
TypeScript

import { AccessToken } from 'livekit-server-sdk';
import { saveSession } from './store';
// API Route (POST) que crea una sesión y devuelve token + studioUrl + id
// Env required: LIVEKIT_API_KEY, LIVEKIT_API_SECRET, optionally STUDIO_URL or STUDIO_BASE_URL
export async function POST(req: Request) {
try {
const body = await req.json();
const room = body.room || 'e2e-room';
const username = body.username || 'visual-runner';
const ttl = body.ttl || 300; // segundos
const apiKey = process.env.LIVEKIT_API_KEY;
const apiSecret = process.env.LIVEKIT_API_SECRET;
if (!apiKey || !apiSecret) {
return new Response(JSON.stringify({ error: 'LIVEKIT_API_KEY and LIVEKIT_API_SECRET required' }), { status: 500, headers: { 'content-type': 'application/json' } });
}
const at = new AccessToken(apiKey, apiSecret, { identity: username, name: username, ttl: `${ttl}s` });
at.addGrant({
roomJoin: true,
room: room,
canPublish: true,
canSubscribe: true,
canPublishSources: ['camera', 'microphone', 'screen'],
} as any);
const token = at.toJwt();
const id = `sess_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;
// Construir studioUrl usando la estructura rooms/[roomName] por defecto
const studioBase = (process.env.STUDIO_BASE_URL || process.env.STUDIO_URL || process.env.BROADCAST_URL || '').trim();
const studioUrl = studioBase ? `${studioBase.replace(/\/$/, '')}/rooms/${encodeURIComponent(room)}` : '';
// Guardar sesión en store en memoria
saveSession(id, { token, room, username, studioUrl });
return new Response(JSON.stringify({ id, token, studioUrl }), { status: 200, headers: { 'content-type': 'application/json' } });
} catch (err) {
console.error('Error in /api/session', err);
return new Response(JSON.stringify({ error: 'internal' }), { status: 500, headers: { 'content-type': 'application/json' } });
}
}