import { NextResponse } from 'next/server'; import { createCallRecord, getAgentSettings, getUser } from '@/lib/firestore'; const VAPI_BASE_URL = 'https://api.vapi.ai'; const vapiPrivateKey = process.env.VAPI_PRIVATE_KEY; export async function POST(request: Request) { try { if (!vapiPrivateKey) { return NextResponse.json({ error: 'Vapi not configured.' }, { status: 500 }); } const body = await request.json(); const phoneNumber = body?.phoneNumber as string | undefined; const scheduledTaskId = body?.scheduledTaskId as string | undefined; if (!phoneNumber) { return NextResponse.json({ error: 'Phone number is required.' }, { status: 400 }); } // TODO: Get userId from auth token const userId = body?.userId ?? 'test-user-id'; const user = await getUser(userId); if (!user || user.creditBalance < 1) { return NextResponse.json({ error: 'Insufficient credits.' }, { status: 400 }); } const agentSettings = await getAgentSettings(userId); const assistantPayload = { name: agentSettings?.agentName ?? 'HolaCompi', instructions: agentSettings?.agentInstructions ?? 'You are HolaCompi, a helpful Spanish friend who makes phone calls on behalf of users.', model: 'gpt-4o-mini', voice: { provider: 'openai', voice: 'alloy', }, language: agentSettings?.primaryCallLanguage ?? 'English', }; // Create assistant dynamically based on agent settings const assistantResponse = await fetch(`${VAPI_BASE_URL}/assistant`, { method: 'POST', headers: { Authorization: `Bearer ${vapiPrivateKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify(assistantPayload), }); if (!assistantResponse.ok) { const errorText = await assistantResponse.text(); return NextResponse.json({ error: errorText }, { status: 500 }); } const assistant = await assistantResponse.json(); // Initiate outbound call via Vapi API const callResponse = await fetch(`${VAPI_BASE_URL}/call`, { method: 'POST', headers: { Authorization: `Bearer ${vapiPrivateKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ assistantId: assistant.id, phoneNumber, // TODO: Adjust payload based on Vapi call schema (customer/from numbers) }), }); if (!callResponse.ok) { const errorText = await callResponse.text(); return NextResponse.json({ error: errorText }, { status: 500 }); } const callData = await callResponse.json(); await createCallRecord({ userId, phoneNumber, status: 'initiated', vapiCallId: callData.id, assistantId: assistant.id, scheduledTaskId, }); return NextResponse.json({ status: callData.status ?? 'initiated', callId: callData.id }); } catch (error) { console.error('Vapi create call error:', error); return NextResponse.json({ error: 'Failed to create call.' }, { status: 500 }); } }