capi: proper dev mode handling requiring test event code

This commit is contained in:
Elijah Duffy
2025-12-18 13:07:39 -08:00
parent 2e12d281ef
commit 82cce84a4e
2 changed files with 37 additions and 26 deletions

View File

@@ -1,12 +1,8 @@
import { import { CustomData, EventRequest, ServerEvent, UserData } from 'facebook-nodejs-business-sdk';
CustomData,
EventRequest,
EventResponse,
ServerEvent,
UserData
} from 'facebook-nodejs-business-sdk';
import type { StandardEventName } from '../types/fbq.js'; import type { StandardEventName } from '../types/fbq.js';
import type { ConversionUserData } from '$lib/types/conversion.js'; import type { ConversionResponseBody, ConversionUserData } from '$lib/types/conversion.js';
import { dev } from '$app/environment';
import log from 'loglevel';
/** /**
* Builds UserData for conversion events. * Builds UserData for conversion events.
@@ -90,7 +86,8 @@ export class ConversionControl {
} }
/** /**
* Sends a conversion event to Meta Pixel. * Sends a conversion event to Meta Pixel. Requires a test event code for
* events to be sent to Meta when in development mode.
* *
* @param eventName - The name of the standard event to send. * @param eventName - The name of the standard event to send.
* @param options - Additional options for the event. * @param options - Additional options for the event.
@@ -99,7 +96,7 @@ export class ConversionControl {
async trackEvent( async trackEvent(
eventName: StandardEventName, eventName: StandardEventName,
options: ConversionEventOptions options: ConversionEventOptions
): Promise<EventResponse> { ): Promise<ConversionResponseBody> {
const event = new ServerEvent() const event = new ServerEvent()
.setEventName(eventName) .setEventName(eventName)
.setEventTime(Math.floor(Date.now() / 1000)) .setEventTime(Math.floor(Date.now() / 1000))
@@ -110,8 +107,35 @@ export class ConversionControl {
if (options?.eventSourceURL) event.setEventSourceUrl(options.eventSourceURL); if (options?.eventSourceURL) event.setEventSourceUrl(options.eventSourceURL);
if (options?.customData) event.setCustomData(options.customData); if (options?.customData) event.setCustomData(options.customData);
// If we're in dev mode and missing a test event code, log and exit
if (dev && !this._testEventCode) {
log.info(
`[ConversionControl] ${eventName} event not sent - missing test event code in dev mode.`
);
return Promise.resolve({
pixelID: this._pixelID,
fbtrace_id: 'dev-mode-no-test-event-code',
receivedEvents: 1,
processedEvents: 0,
messages: ['Event not sent - missing test event code in dev mode.']
});
}
const req = new EventRequest(this._accessToken, this._pixelID).setEvents([event]); const req = new EventRequest(this._accessToken, this._pixelID).setEvents([event]);
if (this._testEventCode) req.setTestEventCode(this._testEventCode); if (this._testEventCode) req.setTestEventCode(this._testEventCode);
return req.execute(); const response = await req.execute();
const structuredResponse: ConversionResponseBody = {
pixelID: response.id,
fbtrace_id: response.fbtrace_id,
receivedEvents: response.events_received,
processedEvents: response.num_processed_entries,
messages: response.messages
};
log.debug(
`[ConversionControl] Sent ${eventName}, Event response: ${JSON.stringify(structuredResponse)}`
);
return structuredResponse;
} }
} }

View File

@@ -1,10 +1,6 @@
import { json, type RequestHandler } from '@sveltejs/kit'; import { json, type RequestHandler } from '@sveltejs/kit';
import { buildConversionUserData, buildCustomData, ConversionControl } from './control.ts'; import { buildConversionUserData, buildCustomData, ConversionControl } from './control.ts';
import type { import type { ConversionErrorResponseBody, ConversionRequestBody } from '$lib/types/conversion.js';
ConversionErrorResponseBody,
ConversionRequestBody,
ConversionResponseBody
} from '$lib/types/conversion.js';
import { StatusCodes } from 'http-status-codes'; import { StatusCodes } from 'http-status-codes';
@@ -46,16 +42,7 @@ export const createConversionRequestHandler: (control: ConversionControl) => Req
customData customData
}); });
// Structure the response return json(response, { status: StatusCodes.OK });
const structuredResponse: ConversionResponseBody = {
pixelID: response.id,
fbtrace_id: response.fbtrace_id,
receivedEvents: response.events_received,
processedEvents: response.num_processed_entries,
messages: response.messages
};
return json(structuredResponse, { status: StatusCodes.OK });
} catch (e) { } catch (e) {
return json( return json(
{ error: e instanceof Error ? e.message : String(e) } as ConversionErrorResponseBody, { error: e instanceof Error ? e.message : String(e) } as ConversionErrorResponseBody,