fix capi response types, improve log clarity

This commit is contained in:
Elijah Duffy
2025-12-22 16:57:06 -08:00
parent 93e5c35d86
commit af1b66649b
6 changed files with 74 additions and 70 deletions

View File

@@ -1,25 +1,11 @@
import { dev } from '$app/environment';
import log from 'loglevel';
import type { CAPIEvent } from './event.ts';
import * as v from 'valibot';
import { capiResponseBodySchema, type CAPIResponseBody } from './handle.ts';
const GRAPH_VERSION = 'v24.0';
/**
* Response body from Meta Conversion API after sending events.
*/
export type CAPIRequestResponseBody = {
/** Dataset or Pixel ID to which the event successfully posted. */
pixelID: string;
/** fbtrace_id for debugging purposes. */
fbtrace_id: string;
/** Number of events received that were sent by the request. */
receivedEvents: number;
/** Number of events successfully posted by the request. */
processedEvents: number;
/** Messages returned by the server. */
messages: string[];
};
/**
* Connector class for Meta Conversion API (CAPI). Abstraction over direct HTTP
* requests to Meta's CAPI endpoint.
@@ -52,7 +38,7 @@ export class CAPIConnector {
* @returns The response from the Meta CAPI.
* @throws Will throw an error if the request fails or the API returns an error.
*/
async sendEvents(events: CAPIEvent[]): Promise<CAPIRequestResponseBody> {
async sendEvents(events: CAPIEvent[]): Promise<CAPIResponseBody> {
if (dev && !this._testEventCode) {
log.warn(
`[CAPIConnector] Sending ${events.length} event(s) in dev mode without a test event code. ` +
@@ -60,14 +46,17 @@ export class CAPIConnector {
);
}
const url = `https://graph.facebook.com/${GRAPH_VERSION}/${this._pixelID}/events?access_token=${this._accessToken}`;
const url = `https://graph.facebook.com/${GRAPH_VERSION}/${this._pixelID}/events`;
const body = {
data: events.map((e) => e.toObject()),
test_event_code: this._testEventCode
};
log.debug(
`[CAPIConnector] [${this._pixelID}] Sending ${events.length} event(s) to Meta CAPI at ${url} with body: ${JSON.stringify(body, null, 2)}`
);
const resp = await fetch(url, {
const resp = await fetch(`${url}?access_token=${this._accessToken}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
@@ -75,13 +64,20 @@ export class CAPIConnector {
body: JSON.stringify(body)
});
const json = await resp.json();
console.log('CAPI response:', json);
if (!resp.ok) {
throw new Error(`Meta CAPI error ${resp.status}: ${JSON.stringify(json, null, 2)}`);
}
return {} as CAPIRequestResponseBody;
try {
const parsed = v.parse(capiResponseBodySchema, json);
log.info(
`[CAPIConnector] [${this._pixelID}] Successfully sent ${events.length} event(s) to Meta CAPI.`
);
return parsed as CAPIResponseBody;
} catch (err) {
throw new Error(`[CAPIConnector] Invalid response shape: ${(err as Error).message}`);
}
}
/**
@@ -91,7 +87,7 @@ export class CAPIConnector {
* @returns The response from the Meta CAPI.
* @throws Will throw an error if the request fails or the API returns an error.
*/
async trackEvent(event: CAPIEvent): Promise<CAPIRequestResponseBody> {
async trackEvent(event: CAPIEvent): Promise<CAPIResponseBody> {
return this.sendEvents([event]);
}
}