refactor conversion API to avoid facebook-nodejs-business-sdk
uses direct meta graph endpoints instead.
This commit is contained in:
@@ -11,18 +11,18 @@ import { loadMetaPixel } from '../util/meta-pixel-loader.ts';
|
||||
import { resolveGetter, type MaybeGetter } from '../util/getter.ts';
|
||||
import log from 'loglevel';
|
||||
import { dev } from '$app/environment';
|
||||
import { ConversionClient } from '../conversion/client.ts';
|
||||
import type { ConversionEventParams } from '$lib/types/conversion.js';
|
||||
import { CAPIClient } from '../conversion/client.ts';
|
||||
import { ActionSource, CAPIEvent, type CAPIStandardParams } from '../conversion/event.ts';
|
||||
|
||||
const pixelParamsToCustomData = (params: CommonParams & CustomParams): ConversionEventParams => {
|
||||
const customData: ConversionEventParams = {};
|
||||
const pixelParamsToCustomData = (params: CommonParams & CustomParams): CAPIStandardParams => {
|
||||
const customData: CAPIStandardParams = {};
|
||||
if (params.value) customData.value = params.value;
|
||||
if (params.currency) customData.currency = params.currency;
|
||||
if (params.content_name) customData.content_name = params.content_name;
|
||||
if (params.content_category) customData.content_category = params.content_category;
|
||||
if (params.content_ids) customData.content_ids = params.content_ids;
|
||||
if (params.contents) {
|
||||
const acc: ConversionEventParams['contents'] = [];
|
||||
const acc: CAPIStandardParams['contents'] = [];
|
||||
customData.contents = params.contents.reduce((acc, content) => {
|
||||
acc.push({
|
||||
id: content.id.toString(),
|
||||
@@ -66,7 +66,7 @@ export class PixelControl {
|
||||
private _pixelID: string;
|
||||
private _testEventCode?: string = undefined;
|
||||
private _trackingManager: MaybeGetter<TrackingManager | undefined>;
|
||||
private _conversionClient?: ConversionClient = undefined;
|
||||
private _conversionClient?: CAPIClient = undefined;
|
||||
|
||||
private static _baseLoaded: boolean = false;
|
||||
private static _registeredPixels: Record<string, PixelControl> = {};
|
||||
@@ -98,10 +98,7 @@ export class PixelControl {
|
||||
|
||||
const resolvedTrackingManager = resolveGetter(trackingManager);
|
||||
if (options?.conversionHref && resolvedTrackingManager) {
|
||||
this._conversionClient = new ConversionClient(
|
||||
options.conversionHref,
|
||||
resolvedTrackingManager
|
||||
);
|
||||
this._conversionClient = new CAPIClient(options.conversionHref, resolvedTrackingManager);
|
||||
} else if (options?.conversionHref) {
|
||||
log.warn(
|
||||
`[PixelControl] Conversion Client ${options.conversionHref} for Meta Pixel [${this._pixelID}] not initialized, TrackingManager is required for user consent.`
|
||||
@@ -196,48 +193,61 @@ export class PixelControl {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a PageView event
|
||||
* Shorthand utility to send a PageView event
|
||||
* @param disableCAPI If true, disables sending this event to the Conversion API
|
||||
* @throws Error if the Meta Pixel is not initialized.
|
||||
*/
|
||||
pageView(disableCAPI: boolean = false) {
|
||||
if (!this.consentGuard()) return;
|
||||
this.track('PageView', undefined, undefined, disableCAPI);
|
||||
}
|
||||
|
||||
let eventID: string | undefined = undefined;
|
||||
// Optionally, send to conversion API endpoint if configured
|
||||
if (this._conversionClient && !disableCAPI) {
|
||||
/**
|
||||
* Forwards an event to the Conversion API client if configured.
|
||||
*
|
||||
* @param event - The event name.
|
||||
* @param params - The event parameters.
|
||||
* @param eventID - Optional event ID for deduplication.
|
||||
* @returns The event ID used, either provided or generated.
|
||||
*/
|
||||
private forwardToCAPI(
|
||||
event: StandardEventName | string,
|
||||
params?: CommonParams & CustomParams,
|
||||
eventID?: string
|
||||
): string | undefined {
|
||||
if (!this._conversionClient) return eventID;
|
||||
|
||||
if (!eventID) {
|
||||
eventID = crypto.randomUUID();
|
||||
this._conversionClient
|
||||
.trackEvent('PageView', { eventID })
|
||||
.then((response) => {
|
||||
log.debug(
|
||||
`[PixelControl] [${this._pixelID}] PageView event sent to Conversion API with Event ID: ${eventID}, Response: ${JSON.stringify(
|
||||
response
|
||||
)}`
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
log.error(
|
||||
`[PixelControl] [${this._pixelID}] Failed to send PageView event to Conversion API with Event ID: ${eventID}`,
|
||||
error
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Send the PageView event to Meta
|
||||
if (!dev || this._testEventCode) {
|
||||
window.fbq('track', 'PageView', undefined, {
|
||||
test_event_code: this._testEventCode,
|
||||
eventID
|
||||
this._conversionClient
|
||||
.trackEvent(
|
||||
CAPIEvent.fromOpts({
|
||||
eventName: event,
|
||||
eventID: eventID,
|
||||
actionSource: ActionSource.Website,
|
||||
eventTime: new Date(),
|
||||
userData: {
|
||||
clientUserAgent: navigator.userAgent
|
||||
},
|
||||
customData: params ? pixelParamsToCustomData(params) : undefined
|
||||
})
|
||||
)
|
||||
.then((response) => {
|
||||
log.debug(
|
||||
`[PixelControl] [${this._pixelID}] ${event} event sent to Conversion API with Event ID: ${eventID}, Response: ${JSON.stringify(
|
||||
response,
|
||||
null,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
log.error(
|
||||
`[PixelControl] [${this._pixelID}] Failed to send ${event} event to Conversion API with Event ID: ${eventID}`,
|
||||
error
|
||||
);
|
||||
});
|
||||
log.debug(
|
||||
`[PixelControl] [${this._pixelID}] PageView event sent${dev && ` (test code: ${this._testEventCode})`}.`
|
||||
);
|
||||
} else {
|
||||
log.info(
|
||||
`[PixelControl] [${this._pixelID}] PageView event not sent in development mode without a test event code.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -256,27 +266,12 @@ export class PixelControl {
|
||||
) {
|
||||
if (!this.consentGuard()) return;
|
||||
|
||||
// Optionally, send to conversion API endpoint if configured
|
||||
if (this._conversionClient && !disableCAPI) {
|
||||
eventID = eventID ?? crypto.randomUUID();
|
||||
this._conversionClient
|
||||
.trackEvent(event, { eventID: eventID, customData: pixelParamsToCustomData(params ?? {}) })
|
||||
.then((response) => {
|
||||
log.debug(
|
||||
`[PixelControl] [${this._pixelID}] ${event} event sent to Conversion API with Event ID: ${eventID}, Response: ${JSON.stringify(
|
||||
response
|
||||
)}`
|
||||
);
|
||||
})
|
||||
.catch((error) => {
|
||||
log.error(
|
||||
`[PixelControl] [${this._pixelID}] Failed to send ${event} event to Conversion API with Event ID: ${eventID}`,
|
||||
error
|
||||
);
|
||||
});
|
||||
// Optionally, send to conversion API endpoint
|
||||
if (!disableCAPI) {
|
||||
eventID = this.forwardToCAPI(event, params, eventID);
|
||||
}
|
||||
|
||||
// Send the PageView event to Meta
|
||||
// Send the event to Meta via the pixel
|
||||
if (!dev || this._testEventCode) {
|
||||
window.fbq('trackSingle', this._pixelID, event, params, {
|
||||
eventID,
|
||||
@@ -294,10 +289,26 @@ export class PixelControl {
|
||||
|
||||
/**
|
||||
* Tracks a custom event for this pixel (uses `trackSingleCustom` under the hood)
|
||||
* @param event Custom event name
|
||||
* @param params Event parameters
|
||||
* @param eventID Optional event ID for deduplication with Conversion API
|
||||
* @param disableCAPI If true, disables sending this event to the Conversion API
|
||||
* @throws Error if the Meta Pixel is not initialized.
|
||||
*/
|
||||
trackCustom(event: string, params?: CommonParams & CustomParams, eventID?: string) {
|
||||
trackCustom(
|
||||
event: string,
|
||||
params?: CommonParams & CustomParams,
|
||||
eventID?: string,
|
||||
disableCAPI: boolean = false
|
||||
) {
|
||||
if (!this.consentGuard()) return;
|
||||
|
||||
// Optionally, send to conversdion API endpoint
|
||||
if (!disableCAPI) {
|
||||
eventID = this.forwardToCAPI(event, params, eventID);
|
||||
}
|
||||
|
||||
// Send the event to Meta via the pixel
|
||||
if (!dev || this._testEventCode) {
|
||||
window.fbq('trackSingleCustom', this._pixelID, event, params, {
|
||||
eventID,
|
||||
|
||||
Reference in New Issue
Block a user