Files
nucleoWhisper/nuxt4/server/api/frigate/event.post.ts
josedario87 8e555b543d
All checks were successful
build-and-deploy / build-and-deploy (push) Successful in 59s
Agregar dropdown de eventos Frigate y corregir endpoint de creacion
- Agregar toggle Live/Eventos en StreamViewer
- Agregar dropdown para seleccionar eventos recientes (max 10)
- Reproducir clips de eventos en el mismo reproductor
- Crear endpoint proxy /api/frigate/events para listar eventos
- Corregir URL de creacion de eventos: /api/events/:camera/:label/create
- Actualizar useFrigateEvents con fetchEvents, formatEventTime, getEventClipUrl
2025-12-30 04:02:36 -06:00

103 lines
2.6 KiB
TypeScript

/**
* Proxy endpoint para crear eventos en Frigate
* POST /api/frigate/event
* Body: { camera: string, label: string, sub_label?: string, duration?: number, include_recording?: boolean }
* Usa URL interna del servidor Frigate
*/
interface EventRequestBody {
camera: string
label: string
sub_label?: string
duration?: number
include_recording?: boolean
}
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 body
const body = await readBody<EventRequestBody>(event)
if (!body.camera || !body.label) {
throw createError({
statusCode: 400,
message: 'Se requiere camera y label'
})
}
// Extraer nombre base de la cámara (sin _main o _sub)
const cameraName = body.camera.replace(/_main$|_sub$/, '')
// Preparar payload para Frigate
const frigatePayload: Record<string, unknown> = {}
if (body.sub_label) {
frigatePayload.sub_label = body.sub_label
}
if (body.duration) {
frigatePayload.duration = body.duration
}
if (body.include_recording !== undefined) {
frigatePayload.include_recording = body.include_recording
}
// URL interna de Frigate (sin pasar por Traefik/Authentik)
const FRIGATE_URL = process.env.FRIGATE_URL || 'http://192.168.87.29:5000'
try {
// API: POST /api/events/:camera_name/:label/create
const response = await fetch(
`${FRIGATE_URL}/api/events/${cameraName}/${body.label}/create`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(frigatePayload)
}
)
if (!response.ok) {
const errorText = await response.text()
console.error('[Frigate Proxy] Error response:', errorText)
throw createError({
statusCode: response.status,
message: `Error al crear evento: ${response.statusText}`
})
}
const data = await response.json()
console.log(`[Frigate Proxy] Evento creado por ${username}: ${body.label} en ${cameraName}`)
return {
success: true,
...data
}
} catch (error: unknown) {
console.error('[Frigate Proxy] Error:', error)
if ((error as any).statusCode) {
throw error
}
throw createError({
statusCode: 500,
message: (error as Error)?.message || 'Error al crear evento'
})
}
})