import { NextResponse } from 'next/server'; import { Timestamp } from 'firebase/firestore'; import { getCallByVapiCallId, getUser, updateCallRecord, updateUserCredits } from '@/lib/firestore'; export async function POST(request: Request) { try { const payload = await request.json(); const eventType = payload?.event || payload?.type; const callPayload = payload?.call || payload?.data?.call || payload; const vapiCallId = callPayload?.id as string | undefined; if (!vapiCallId) { return NextResponse.json({ error: 'Missing call id.' }, { status: 400 }); } const callRecord = await getCallByVapiCallId(vapiCallId); if (!callRecord) { return NextResponse.json({ error: 'Call record not found.' }, { status: 404 }); } if (eventType === 'call-started' || eventType === 'call.started') { await updateCallRecord(callRecord.id, { status: 'started', startedAt: Timestamp.now(), }); } if (eventType === 'call-failed' || eventType === 'call.failed') { await updateCallRecord(callRecord.id, { status: 'failed', endedAt: Timestamp.now(), }); } if (eventType === 'call-ended' || eventType === 'call.ended') { const durationSeconds = Number(callPayload?.durationSeconds) || Number(callPayload?.duration) || 0; const creditsUsed = Math.ceil(durationSeconds / 60); await updateCallRecord(callRecord.id, { status: 'ended', endedAt: Timestamp.now(), durationSeconds, creditsUsed, recordingUrl: callPayload?.recordingUrl || callPayload?.recording?.url, transcript: callPayload?.transcript || callPayload?.summary, }); const user = await getUser(callRecord.userId); if (user) { const newBalance = Math.max(0, user.creditBalance - creditsUsed); await updateUserCredits(callRecord.userId, newBalance); } } return NextResponse.json({ received: true }); } catch (error) { console.error('Vapi webhook error:', error); return NextResponse.json({ error: 'Webhook processing failed.' }, { status: 500 }); } }