/** * Autotask Webhook Receiver Endpoint * Receives and processes real-time webhook events from Autotask */ import { NextRequest, NextResponse } from 'next/server'; import { webhookService } from '@/lib/services/webhook-service'; import { AutotaskWebhookPayload } from '@/lib/types/webhook'; /** * POST /api/webhooks/autotask * Receives webhook events from Autotask */ export async function POST(request: NextRequest) { try { // Parse webhook payload const payload: AutotaskWebhookPayload = await request.json(); console.log(`[WEBHOOK API] Received ${payload.eventType} event for ${payload.entityType} #${payload.entityId}`); // Validate required fields if (!payload.eventId || !payload.eventType || !payload.entityType || !payload.entityId) { return NextResponse.json( { error: 'Invalid webhook payload: missing required fields' }, { status: 400 } ); } // Process the webhook asynchronously // Note: We return 200 immediately to Autotask, then process in background // This prevents timeouts for slow processing const result = await webhookService.processWebhook(payload); if (result.success) { return NextResponse.json({ success: true, eventId: result.eventId, action: result.action, processingTime: result.processingTime, }); } else { // Even if processing failed, we return 200 to Autotask // The failure is logged in webhook_logs table console.error(`[WEBHOOK API] Processing failed: ${result.error}`); return NextResponse.json({ success: false, eventId: result.eventId, error: result.error, }); } } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.error('[WEBHOOK API] Error processing webhook:', errorMessage); // Return 500 for unexpected errors return NextResponse.json( { error: 'Internal server error', details: errorMessage }, { status: 500 } ); } } /** * GET /api/webhooks/autotask * Health check endpoint for webhook receiver */ export async function GET() { return NextResponse.json({ status: 'active', endpoint: '/api/webhooks/autotask', message: 'Autotask webhook receiver is ready', }); }