eb711fbf1a
Build and Deploy / build (push) Has been cancelled
- Email capture popup with scroll (10%) and exit intent triggers - First name field and full tracking (UTM, device, time on page) - Mautic API integration for contact creation - GeoIP detection for country/region - 4 locale support (sr, en, de, fr) - Mautic tracking script in layout
102 lines
2.6 KiB
TypeScript
102 lines
2.6 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server";
|
|
import { createMauticContact } from "@/lib/mautic";
|
|
|
|
const requestCache = new Map<string, number>();
|
|
const DEBOUNCE_MS = 5000;
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const body = await request.json();
|
|
const {
|
|
email,
|
|
locale,
|
|
country,
|
|
countryCode,
|
|
source,
|
|
trigger,
|
|
firstName,
|
|
lastName,
|
|
timeOnPage,
|
|
referrer,
|
|
pageUrl,
|
|
pageLanguage,
|
|
preferredLocale,
|
|
deviceName,
|
|
deviceOS,
|
|
userAgent,
|
|
utmSource,
|
|
utmMedium,
|
|
utmCampaign,
|
|
utmContent,
|
|
fbclid,
|
|
} = body;
|
|
|
|
if (!email || !email.includes("@")) {
|
|
return NextResponse.json(
|
|
{ error: "Invalid email" },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
const cacheKey = `${email}:${Date.now()}`;
|
|
const lastRequest = requestCache.get(cacheKey);
|
|
if (lastRequest && Date.now() - lastRequest < DEBOUNCE_MS) {
|
|
return NextResponse.json(
|
|
{ error: "Please wait before submitting again" },
|
|
{ status: 429 }
|
|
);
|
|
}
|
|
requestCache.set(cacheKey, Date.now());
|
|
|
|
const tags = [
|
|
"source:popup",
|
|
`locale:${locale || "en"}`,
|
|
`country:${countryCode || "XX"}`,
|
|
`popup_${trigger || "unknown"}`,
|
|
"lead:warm",
|
|
...(utmSource ? [`utm:${utmSource}`] : []),
|
|
...(deviceName ? [`device:${deviceName}`] : []),
|
|
];
|
|
|
|
const forwardedFor = request.headers.get("x-forwarded-for");
|
|
const realIP = request.headers.get("x-real-ip");
|
|
const ipAddress = forwardedFor?.split(",")[0]?.trim() || realIP || "unknown";
|
|
|
|
const result = await createMauticContact(email, tags, {
|
|
firstName: firstName || "",
|
|
lastName: lastName || "",
|
|
country: country || "",
|
|
preferredLocale: preferredLocale || locale || "en",
|
|
ipAddress,
|
|
utmSource: utmSource || "",
|
|
utmMedium: utmMedium || "",
|
|
utmCampaign: utmCampaign || "",
|
|
utmContent: utmContent || "",
|
|
pageUrl: pageUrl || request.headers.get("referer") || "",
|
|
});
|
|
|
|
console.log("Email capture success:", {
|
|
email,
|
|
firstName,
|
|
timeOnPage,
|
|
deviceName,
|
|
deviceOS,
|
|
utmSource,
|
|
utmMedium,
|
|
result
|
|
});
|
|
|
|
return NextResponse.json({
|
|
success: true,
|
|
alreadySubscribed: result.alreadyExists,
|
|
contactId: result.contactId,
|
|
});
|
|
} catch (error) {
|
|
console.error("Email capture error:", error);
|
|
return NextResponse.json(
|
|
{ error: "Failed to process subscription", details: error instanceof Error ? error.message : "Unknown error" },
|
|
{ status: 500 }
|
|
);
|
|
}
|
|
}
|