/** * Proxy endpoint para obtener eventos de Frigate * GET /api/frigate/events?camera=X&limit=10 */ export default defineEventHandler(async (event) => { // Verificar autenticación via headers de Authentik const headers = getRequestHeaders(event) const username = headers['x-authentik-username'] if (!username) { throw createError({ statusCode: 401, message: 'No autenticado' }) } // Leer query params const query = getQuery(event) const camera = query.camera as string | undefined const limit = query.limit ? parseInt(query.limit as string) : 10 // URL interna de Frigate const FRIGATE_URL = process.env.FRIGATE_URL || 'http://192.168.87.29:5000' // Construir URL con filtros const params = new URLSearchParams() if (camera) { // Extraer nombre base de la cámara (sin _main o _sub) params.set('camera', camera.replace(/_main$|_sub$/, '')) } params.set('limit', limit.toString()) params.set('has_clip', 'true') // Solo eventos con clip try { const response = await fetch( `${FRIGATE_URL}/api/events?${params.toString()}`, { method: 'GET', headers: { 'Accept': 'application/json' } } ) if (!response.ok) { throw createError({ statusCode: response.status, message: `Error al obtener eventos: ${response.statusText}` }) } const events = await response.json() return events } catch (error: unknown) { console.error('[Frigate Events] Error:', error) if ((error as any).statusCode) { throw error } throw createError({ statusCode: 500, message: (error as Error)?.message || 'Error al obtener eventos' }) } })