link-stack/apps/link/app/api/formstack/route.ts

65 lines
2 KiB
TypeScript
Raw Normal View History

2025-10-15 16:08:53 +02:00
import { NextRequest, NextResponse } from "next/server";
import { createLogger } from "@link-stack/logger";
import { getWorkerUtils } from "@link-stack/bridge-common";
const logger = createLogger('formstack-webhook');
export async function POST(req: NextRequest): Promise<NextResponse> {
try {
// Get the shared secret from environment variable
const expectedSecret = process.env.FORMSTACK_SHARED_SECRET;
if (!expectedSecret) {
logger.error('FORMSTACK_SHARED_SECRET environment variable is not configured');
return NextResponse.json(
{ error: "Server configuration error" },
{ status: 500 }
);
}
// Get the shared secret from the request body
const body = await req.json();
const receivedSecret = body.HandshakeKey;
// Verify the shared secret
if (receivedSecret !== expectedSecret) {
logger.warn({ receivedSecret }, 'Invalid shared secret received');
return NextResponse.json(
{ error: "Unauthorized" },
{ status: 401 }
);
}
// Log the entire webhook payload to see the data structure
logger.info({
payload: body,
headers: Object.fromEntries(req.headers.entries()),
}, 'Received Formstack webhook');
// Enqueue a bridge-worker task to process this form submission
const worker = await getWorkerUtils();
await worker.addJob('formstack/create-ticket-from-form', {
formData: body,
receivedAt: new Date().toISOString(),
});
logger.info('Formstack webhook task enqueued successfully');
return NextResponse.json({
status: "success",
message: "Webhook received and queued for processing"
});
} catch (error) {
logger.error({
error: error instanceof Error ? error.message : error,
stack: error instanceof Error ? error.stack : undefined,
}, 'Error processing Formstack webhook');
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}