import type { TrackingManager } from '$lib/tracking.svelte'; import type { ConversionErrorResponseBody, ConversionEventParams, ConversionRequestBody, ConversionResponseBody, ConversionUserData } from '$lib/types/conversion.js'; import type { StandardEventName } from '$lib/types/fbq.js'; /** * Client for sending conversion events to a server endpoint. */ export class ConversionClient { private _href: string; private _trackingManager: TrackingManager; /** * Creates a new ConversionClient. * * @param serverHref - The server endpoint URL. * @param trackingManager - The tracking manager instance. */ constructor(serverHref: string, trackingManager: TrackingManager) { this._href = serverHref; this._trackingManager = trackingManager; } /** * Sends a conversion event to the server. * * @param eventName - The name of the standard event to send. * @param options - Additional options for the event. * @returns A promise that resolves to the event response or error. */ async trackEvent( eventName: StandardEventName, options: { eventID: string; user?: Omit; customData?: ConversionEventParams; } ): Promise { // Extract user data const fbp = await cookieStore.get('_fbp'); const fbc = await cookieStore.get('_fbc'); const user: ConversionUserData = { ...options.user, fbp: fbp?.value, fbc: fbc?.value }; // Get event source URL & extract UTM params if present const eventSourceURL = window.location.href; const url = new URL(eventSourceURL); const utms: Record = {}; url.searchParams.forEach((value, key) => { if (key.startsWith('utm_')) { utms[key] = value; } }); // Build request body const requestBody: ConversionRequestBody = { consent: this._trackingManager.consent === true, eventName, eventID: options.eventID, user, eventSourceURL, utms, customData: options.customData }; // Send request to server const response = await fetch(this._href, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(requestBody) }); if (response.ok) { const data = (await response.json()) as ConversionResponseBody; return data; } else { const errorData = (await response.json()) as ConversionErrorResponseBody; return errorData; } } }