shopkit-analytics 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +193 -3
- package/dist/adapters/index.d.mts +3 -2
- package/dist/adapters/index.d.ts +3 -2
- package/dist/adapters/index.js +1220 -615
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +4 -2
- package/dist/{chunk-3TQR5DOP.mjs → chunk-3NR2AKE4.mjs} +1 -31
- package/dist/chunk-3NR2AKE4.mjs.map +1 -0
- package/dist/chunk-4RDPDMGW.mjs +68 -0
- package/dist/chunk-4RDPDMGW.mjs.map +1 -0
- package/dist/{chunk-JVEGG6JV.mjs → chunk-HCA4E2RA.mjs} +19 -13
- package/dist/chunk-HCA4E2RA.mjs.map +1 -0
- package/dist/chunk-NC25KOAF.mjs +156 -0
- package/dist/chunk-NC25KOAF.mjs.map +1 -0
- package/dist/chunk-NGPUKV7E.mjs +46 -0
- package/dist/chunk-NGPUKV7E.mjs.map +1 -0
- package/dist/{chunk-4MZH5OLR.mjs → chunk-NJQ2MOM2.mjs} +1145 -618
- package/dist/chunk-NJQ2MOM2.mjs.map +1 -0
- package/dist/chunk-NKDB4KX2.mjs +2 -0
- package/dist/{chunk-P4OJDCEZ.mjs → chunk-QCS5UARA.mjs} +3 -3
- package/dist/events/index.d.mts +9 -41
- package/dist/events/index.d.ts +9 -41
- package/dist/events/index.js +973 -498
- package/dist/events/index.js.map +1 -1
- package/dist/events/index.mjs +11 -11
- package/dist/experiment/index.d.mts +25 -0
- package/dist/experiment/index.d.ts +25 -0
- package/dist/experiment/index.js +74 -0
- package/dist/experiment/index.js.map +1 -0
- package/dist/experiment/index.mjs +15 -0
- package/dist/experiment/index.mjs.map +1 -0
- package/dist/{index-BnNRgdUv.d.ts → index-D_8w5bL_.d.ts} +87 -17
- package/dist/{index-GODWc1s6.d.mts → index-th6sBtE3.d.mts} +87 -17
- package/dist/index.d.mts +10 -6
- package/dist/index.d.ts +10 -6
- package/dist/index.js +1408 -660
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +31 -10
- package/dist/index.mjs.map +1 -1
- package/dist/services/index.d.mts +51 -0
- package/dist/services/index.d.ts +51 -0
- package/dist/services/index.js +180 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/index.mjs +11 -0
- package/dist/services/index.mjs.map +1 -0
- package/dist/{subscriber-43gnCKWe.d.ts → subscriber-BDAm_BAi.d.ts} +38 -2
- package/dist/{subscriber-sWesj_5p.d.mts → subscriber-BoyOlh9t.d.mts} +38 -2
- package/dist/subscriber-VF3IYUCU.mjs +8 -0
- package/dist/subscriber-VF3IYUCU.mjs.map +1 -0
- package/dist/types-C__2IBCj.d.mts +7 -0
- package/dist/types-C__2IBCj.d.ts +7 -0
- package/dist/types.d.mts +4 -340
- package/dist/types.d.ts +4 -340
- package/dist/types.js +0 -30
- package/dist/types.js.map +1 -1
- package/dist/types.mjs +1 -1
- package/dist/utils/index.d.mts +19 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.js +93 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +12 -0
- package/dist/utils/index.mjs.map +1 -0
- package/package.json +21 -8
- package/templates/nextjs/README.md +206 -0
- package/templates/nextjs/api-events-route.ts +62 -0
- package/dist/chunk-3TQR5DOP.mjs.map +0 -1
- package/dist/chunk-4MZH5OLR.mjs.map +0 -1
- package/dist/chunk-JVEGG6JV.mjs.map +0 -1
- package/dist/subscriber-IFZJU57V.mjs +0 -8
- /package/dist/{subscriber-IFZJU57V.mjs.map → chunk-NKDB4KX2.mjs.map} +0 -0
- /package/dist/{chunk-P4OJDCEZ.mjs.map → chunk-QCS5UARA.mjs.map} +0 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/utils/event-id.ts
|
|
22
|
+
var event_id_exports = {};
|
|
23
|
+
__export(event_id_exports, {
|
|
24
|
+
generateEventId: () => generateEventId,
|
|
25
|
+
getBrowserInfo: () => getBrowserInfo,
|
|
26
|
+
getClientIpAddress: () => getClientIpAddress
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(event_id_exports);
|
|
29
|
+
function generateEventId(eventType) {
|
|
30
|
+
const timestamp = Date.now();
|
|
31
|
+
const randomString = Math.random().toString(36).substring(2, 8);
|
|
32
|
+
return `${timestamp}_${randomString}_${eventType}`;
|
|
33
|
+
}
|
|
34
|
+
function getBrowserInfo() {
|
|
35
|
+
if (typeof window === "undefined") {
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
const userAgent = navigator.userAgent;
|
|
39
|
+
const fbc = getFacebookClickId();
|
|
40
|
+
const fbp = getFacebookBrowserId();
|
|
41
|
+
return {
|
|
42
|
+
clientUserAgent: userAgent,
|
|
43
|
+
fbc,
|
|
44
|
+
fbp
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function getFacebookClickId() {
|
|
48
|
+
if (typeof window === "undefined") {
|
|
49
|
+
return void 0;
|
|
50
|
+
}
|
|
51
|
+
const urlParams = new URLSearchParams(window.location.search);
|
|
52
|
+
const fbclid = urlParams.get("fbclid");
|
|
53
|
+
if (fbclid) {
|
|
54
|
+
return `fb.1.${Date.now()}.${fbclid}`;
|
|
55
|
+
}
|
|
56
|
+
const cookies = document.cookie.split(";");
|
|
57
|
+
for (const cookie of cookies) {
|
|
58
|
+
const [name, value] = cookie.trim().split("=");
|
|
59
|
+
if (name === "_fbc") {
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return void 0;
|
|
64
|
+
}
|
|
65
|
+
function getFacebookBrowserId() {
|
|
66
|
+
if (typeof window === "undefined") {
|
|
67
|
+
return void 0;
|
|
68
|
+
}
|
|
69
|
+
const cookies = document.cookie.split(";");
|
|
70
|
+
for (const cookie of cookies) {
|
|
71
|
+
const [name, value] = cookie.trim().split("=");
|
|
72
|
+
if (name === "_fbp") {
|
|
73
|
+
return value;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return void 0;
|
|
77
|
+
}
|
|
78
|
+
function getClientIpAddress(request) {
|
|
79
|
+
if (!request) {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
const forwarded = request.headers.get("x-forwarded-for");
|
|
83
|
+
const realIp = request.headers.get("x-real-ip");
|
|
84
|
+
const cfConnectingIp = request.headers.get("cf-connecting-ip");
|
|
85
|
+
return forwarded?.split(",")[0] || realIp || cfConnectingIp || void 0;
|
|
86
|
+
}
|
|
87
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
88
|
+
0 && (module.exports = {
|
|
89
|
+
generateEventId,
|
|
90
|
+
getBrowserInfo,
|
|
91
|
+
getClientIpAddress
|
|
92
|
+
});
|
|
93
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/event-id.ts"],"sourcesContent":["/**\n * Generate a unique event ID for deduplication\n * Format: timestamp_randomString_eventType\n */\nexport function generateEventId(eventType: string): string {\n const timestamp = Date.now();\n const randomString = Math.random().toString(36).substring(2, 8);\n return `${timestamp}_${randomString}_${eventType}`;\n}\n\n/**\n * Extract browser information for CAPI user data\n */\nexport function getBrowserInfo(): {\n clientUserAgent?: string;\n fbc?: string;\n fbp?: string;\n} {\n if (typeof window === \"undefined\") {\n return {};\n }\n\n const userAgent = navigator.userAgent;\n\n // Get Facebook click ID from URL or cookies\n const fbc = getFacebookClickId();\n const fbp = getFacebookBrowserId();\n\n return {\n clientUserAgent: userAgent,\n fbc,\n fbp,\n };\n}\n\n/**\n * Get Facebook click ID (fbc) from URL parameters or cookies\n */\nfunction getFacebookClickId(): string | undefined {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n // Check URL parameters first\n const urlParams = new URLSearchParams(window.location.search);\n const fbclid = urlParams.get(\"fbclid\");\n\n if (fbclid) {\n return `fb.1.${Date.now()}.${fbclid}`;\n }\n\n // Check cookies\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === \"_fbc\") {\n return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Get Facebook browser ID (fbp) from cookies\n */\nfunction getFacebookBrowserId(): string | undefined {\n if (typeof window === \"undefined\") {\n return undefined;\n }\n\n const cookies = document.cookie.split(\";\");\n for (const cookie of cookies) {\n const [name, value] = cookie.trim().split(\"=\");\n if (name === \"_fbp\") {\n return value;\n }\n }\n\n return undefined;\n}\n\n/**\n * Get client IP address (this will be handled server-side)\n */\nexport function getClientIpAddress(request?: Request): string | undefined {\n if (!request) {\n return undefined;\n }\n\n // Try different headers for IP address\n const forwarded = request.headers.get(\"x-forwarded-for\");\n const realIp = request.headers.get(\"x-real-ip\");\n const cfConnectingIp = request.headers.get(\"cf-connecting-ip\");\n\n return forwarded?.split(\",\")[0] || realIp || cfConnectingIp || undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,SAAS,gBAAgB,WAA2B;AACzD,QAAM,YAAY,KAAK,IAAI;AAC3B,QAAM,eAAe,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AAC9D,SAAO,GAAG,SAAS,IAAI,YAAY,IAAI,SAAS;AAClD;AAKO,SAAS,iBAId;AACA,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,YAAY,UAAU;AAG5B,QAAM,MAAM,mBAAmB;AAC/B,QAAM,MAAM,qBAAqB;AAEjC,SAAO;AAAA,IACL,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,EACF;AACF;AAKA,SAAS,qBAAyC;AAChD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,IAAI,gBAAgB,OAAO,SAAS,MAAM;AAC5D,QAAM,SAAS,UAAU,IAAI,QAAQ;AAErC,MAAI,QAAQ;AACV,WAAO,QAAQ,KAAK,IAAI,CAAC,IAAI,MAAM;AAAA,EACrC;AAGA,QAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC7C,QAAI,SAAS,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,uBAA2C;AAClD,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,SAAS,OAAO,MAAM,GAAG;AACzC,aAAW,UAAU,SAAS;AAC5B,UAAM,CAAC,MAAM,KAAK,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG;AAC7C,QAAI,SAAS,QAAQ;AACnB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,mBAAmB,SAAuC;AACxE,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AAGA,QAAM,YAAY,QAAQ,QAAQ,IAAI,iBAAiB;AACvD,QAAM,SAAS,QAAQ,QAAQ,IAAI,WAAW;AAC9C,QAAM,iBAAiB,QAAQ,QAAQ,IAAI,kBAAkB;AAE7D,SAAO,WAAW,MAAM,GAAG,EAAE,CAAC,KAAK,UAAU,kBAAkB;AACjE;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shopkit-analytics",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A comprehensive analytics package combining event tracking and affiliate tracking for e-commerce applications with multiple platform adapters",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -21,11 +21,26 @@
|
|
|
21
21
|
"import": "./dist/affiliate/index.mjs",
|
|
22
22
|
"require": "./dist/affiliate/index.js"
|
|
23
23
|
},
|
|
24
|
+
"./experiment": {
|
|
25
|
+
"types": "./dist/experiment/index.d.ts",
|
|
26
|
+
"import": "./dist/experiment/index.mjs",
|
|
27
|
+
"require": "./dist/experiment/index.js"
|
|
28
|
+
},
|
|
24
29
|
"./adapters": {
|
|
25
30
|
"types": "./dist/adapters/index.d.ts",
|
|
26
31
|
"import": "./dist/adapters/index.mjs",
|
|
27
32
|
"require": "./dist/adapters/index.js"
|
|
28
33
|
},
|
|
34
|
+
"./services": {
|
|
35
|
+
"types": "./dist/services/index.d.ts",
|
|
36
|
+
"import": "./dist/services/index.mjs",
|
|
37
|
+
"require": "./dist/services/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./utils": {
|
|
40
|
+
"types": "./dist/utils/index.d.ts",
|
|
41
|
+
"import": "./dist/utils/index.mjs",
|
|
42
|
+
"require": "./dist/utils/index.js"
|
|
43
|
+
},
|
|
29
44
|
"./types": {
|
|
30
45
|
"types": "./dist/types.d.ts",
|
|
31
46
|
"import": "./dist/types.mjs",
|
|
@@ -34,6 +49,7 @@
|
|
|
34
49
|
},
|
|
35
50
|
"files": [
|
|
36
51
|
"dist",
|
|
52
|
+
"templates",
|
|
37
53
|
"README.md",
|
|
38
54
|
"LICENSE"
|
|
39
55
|
],
|
|
@@ -55,6 +71,8 @@
|
|
|
55
71
|
"tracking",
|
|
56
72
|
"events",
|
|
57
73
|
"affiliate",
|
|
74
|
+
"experiment",
|
|
75
|
+
"ab-testing",
|
|
58
76
|
"utm",
|
|
59
77
|
"google-analytics",
|
|
60
78
|
"facebook-pixel",
|
|
@@ -78,8 +96,7 @@
|
|
|
78
96
|
"homepage": "https://github.com/shopkit/analytics#readme",
|
|
79
97
|
"peerDependencies": {
|
|
80
98
|
"react": ">=16.8.0",
|
|
81
|
-
"react-dom": ">=16.8.0"
|
|
82
|
-
"pino-pretty": ">=10.0.0"
|
|
99
|
+
"react-dom": ">=16.8.0"
|
|
83
100
|
},
|
|
84
101
|
"peerDependenciesMeta": {
|
|
85
102
|
"react": {
|
|
@@ -87,15 +104,11 @@
|
|
|
87
104
|
},
|
|
88
105
|
"react-dom": {
|
|
89
106
|
"optional": true
|
|
90
|
-
},
|
|
91
|
-
"pino-pretty": {
|
|
92
|
-
"optional": true
|
|
93
107
|
}
|
|
94
108
|
},
|
|
95
109
|
"dependencies": {
|
|
96
110
|
"@moengage/web-sdk": "^2.61.0",
|
|
97
|
-
"@shopify/hydrogen-react": "^2025.5.0"
|
|
98
|
-
"pino": "^10.1.0"
|
|
111
|
+
"@shopify/hydrogen-react": "^2025.5.0"
|
|
99
112
|
},
|
|
100
113
|
"devDependencies": {
|
|
101
114
|
"@types/node": "^20.8.10",
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Facebook CAPI Setup Guide for Next.js
|
|
2
|
+
|
|
3
|
+
This guide helps you set up Facebook Conversions API (CAPI) server-side tracking with the @shopkit/analytics package.
|
|
4
|
+
|
|
5
|
+
## Quick Setup
|
|
6
|
+
|
|
7
|
+
### 1. Environment Variables
|
|
8
|
+
|
|
9
|
+
Add these to your `.env.local` file:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Required for Facebook CAPI
|
|
13
|
+
FACEBOOK_CAPI_ACCESS_TOKEN="your_facebook_access_token"
|
|
14
|
+
NEXT_PUBLIC_PIXEL_ID="123456789"
|
|
15
|
+
|
|
16
|
+
# Optional (for testing)
|
|
17
|
+
FACEBOOK_TEST_EVENT_CODE="TEST12345"
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Create API Route
|
|
21
|
+
|
|
22
|
+
**For Next.js App Router (app directory):**
|
|
23
|
+
|
|
24
|
+
Create `app/api/events/route.ts` and copy the contents from `api-events-route.ts` in this directory.
|
|
25
|
+
|
|
26
|
+
**For Next.js Pages Router (pages directory):**
|
|
27
|
+
|
|
28
|
+
Create `pages/api/events.ts`:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import { createFacebookCAPIService } from "@shopkit/analytics/services";
|
|
32
|
+
import { TEvent } from "@shopkit/analytics/types";
|
|
33
|
+
import type { NextApiRequest, NextApiResponse } from "next";
|
|
34
|
+
|
|
35
|
+
function getClientIpAddress(req: NextApiRequest): string | undefined {
|
|
36
|
+
const forwarded = req.headers["x-forwarded-for"];
|
|
37
|
+
const realIp = req.headers["x-real-ip"];
|
|
38
|
+
const cfConnectingIp = req.headers["cf-connecting-ip"];
|
|
39
|
+
|
|
40
|
+
if (typeof forwarded === "string") {
|
|
41
|
+
return forwarded.split(",")[0];
|
|
42
|
+
}
|
|
43
|
+
if (typeof realIp === "string") {
|
|
44
|
+
return realIp;
|
|
45
|
+
}
|
|
46
|
+
if (typeof cfConnectingIp === "string") {
|
|
47
|
+
return cfConnectingIp;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export default async function handler(
|
|
53
|
+
req: NextApiRequest,
|
|
54
|
+
res: NextApiResponse
|
|
55
|
+
) {
|
|
56
|
+
if (req.method !== "POST") {
|
|
57
|
+
return res.status(405).json({ error: "Method not allowed" });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const { events, userInfo } = req.body;
|
|
62
|
+
|
|
63
|
+
if (!Array.isArray(events) || events.length === 0) {
|
|
64
|
+
return res.status(400).json({ error: "Invalid events data" });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const capiService = createFacebookCAPIService({
|
|
68
|
+
accessToken: process.env.FACEBOOK_CAPI_ACCESS_TOKEN!,
|
|
69
|
+
pixelId: process.env.NEXT_PUBLIC_PIXEL_ID!,
|
|
70
|
+
testEventCode: process.env.FACEBOOK_TEST_EVENT_CODE,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!capiService) {
|
|
74
|
+
console.warn("Facebook CAPI service not available - missing configuration");
|
|
75
|
+
return res.status(500).json({ error: "CAPI service not configured" });
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const enhancedUserInfo = {
|
|
79
|
+
...userInfo,
|
|
80
|
+
clientIpAddress: getClientIpAddress(req),
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
await capiService.sendEvents(events as TEvent[], enhancedUserInfo);
|
|
84
|
+
|
|
85
|
+
return res.json({
|
|
86
|
+
success: true,
|
|
87
|
+
message: `Successfully sent ${events.length} events to Facebook CAPI`,
|
|
88
|
+
});
|
|
89
|
+
} catch (error) {
|
|
90
|
+
console.error("API Events Error:", error);
|
|
91
|
+
return res.status(500).json({ error: "Failed to process events" });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 3. CAPI Configuration (Enabled by Default)
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
import { ShopkitAnalytics } from "@shopkit/analytics";
|
|
100
|
+
|
|
101
|
+
<ShopkitAnalytics
|
|
102
|
+
config={{
|
|
103
|
+
facebookPixel: {
|
|
104
|
+
pixelId: process.env.NEXT_PUBLIC_PIXEL_ID!,
|
|
105
|
+
// enableCAPI: true, // Default: enabled for better data reliability
|
|
106
|
+
// enableCAPI: false, // Uncomment to disable server-side tracking
|
|
107
|
+
},
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
<YourApp />
|
|
111
|
+
</ShopkitAnalytics>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**Important**: CAPI is **enabled by default** to provide better data reliability and privacy compliance. The system will gracefully handle cases where the API endpoint is not set up - client-side tracking will continue to work normally.
|
|
115
|
+
|
|
116
|
+
## Getting Facebook Access Token
|
|
117
|
+
|
|
118
|
+
1. Go to [Facebook Business Manager](https://business.facebook.com/)
|
|
119
|
+
2. Navigate to **Business Settings** → **System Users**
|
|
120
|
+
3. Create a new system user or select existing one
|
|
121
|
+
4. Generate an access token with these permissions:
|
|
122
|
+
- `ads_management`
|
|
123
|
+
- `business_management`
|
|
124
|
+
5. Copy the access token to your environment variables
|
|
125
|
+
|
|
126
|
+
## Testing
|
|
127
|
+
|
|
128
|
+
### Development Testing
|
|
129
|
+
|
|
130
|
+
1. Set the test event code in your environment:
|
|
131
|
+
```bash
|
|
132
|
+
FACEBOOK_TEST_EVENT_CODE="TEST12345"
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
2. Trigger some events in your app
|
|
136
|
+
|
|
137
|
+
3. Check Facebook Events Manager → Test Events to see if events are received
|
|
138
|
+
|
|
139
|
+
### Production Verification
|
|
140
|
+
|
|
141
|
+
1. Remove or comment out `FACEBOOK_TEST_EVENT_CODE`
|
|
142
|
+
2. Monitor Facebook Events Manager for real events
|
|
143
|
+
3. Check your server logs for any CAPI errors
|
|
144
|
+
|
|
145
|
+
## Troubleshooting
|
|
146
|
+
|
|
147
|
+
### Common Issues
|
|
148
|
+
|
|
149
|
+
1. **"CAPI service not configured"**
|
|
150
|
+
- Ensure `FACEBOOK_CAPI_ACCESS_TOKEN` and `NEXT_PUBLIC_PIXEL_ID` are set
|
|
151
|
+
- Verify environment variables are loaded correctly
|
|
152
|
+
|
|
153
|
+
2. **"Method not allowed" (Pages Router)**
|
|
154
|
+
- Ensure you're using POST requests
|
|
155
|
+
- Check the API route is created correctly
|
|
156
|
+
|
|
157
|
+
3. **Events not appearing in Facebook**
|
|
158
|
+
- Verify your access token has correct permissions
|
|
159
|
+
- Check if test event code is set (events go to Test Events tool)
|
|
160
|
+
- Monitor server logs for error messages
|
|
161
|
+
|
|
162
|
+
4. **CORS errors**
|
|
163
|
+
- API route should be on the same domain as your app
|
|
164
|
+
- Next.js API routes handle CORS automatically
|
|
165
|
+
|
|
166
|
+
### Debug Logging
|
|
167
|
+
|
|
168
|
+
Enable debug logging to see detailed information:
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
<ShopkitAnalytics
|
|
172
|
+
config={{
|
|
173
|
+
logger: {
|
|
174
|
+
enabled: true,
|
|
175
|
+
level: "debug",
|
|
176
|
+
prettyPrint: true,
|
|
177
|
+
},
|
|
178
|
+
facebookPixel: {
|
|
179
|
+
pixelId: process.env.NEXT_PUBLIC_PIXEL_ID!,
|
|
180
|
+
enableCAPI: true,
|
|
181
|
+
},
|
|
182
|
+
}}
|
|
183
|
+
/>
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## How It Works
|
|
187
|
+
|
|
188
|
+
1. **Event Triggered**: User performs an action (add to cart, etc.)
|
|
189
|
+
2. **Dual Tracking**: Event sent to both client-side pixel and server-side CAPI (enabled by default)
|
|
190
|
+
3. **Event ID**: Unique ID prevents double counting
|
|
191
|
+
4. **Enhanced Data**: Automatically includes experiment and affiliate data
|
|
192
|
+
5. **Deduplication**: Facebook uses event ID to merge client/server events
|
|
193
|
+
6. **Graceful Fallback**: If API endpoint is missing, only client-side tracking runs (no errors)
|
|
194
|
+
|
|
195
|
+
### Default Behavior
|
|
196
|
+
|
|
197
|
+
- **CAPI is enabled by default** for all Facebook Pixel configurations
|
|
198
|
+
- **No setup required** for basic client-side tracking
|
|
199
|
+
- **API endpoint optional** - system works without it (client-side only)
|
|
200
|
+
- **Better data quality** when API endpoint is properly configured
|
|
201
|
+
|
|
202
|
+
## Support
|
|
203
|
+
|
|
204
|
+
- Check the main package README for more details
|
|
205
|
+
- Monitor browser console and server logs for errors
|
|
206
|
+
- Use Facebook's Test Events tool during development
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createFacebookCAPIService } from "@shopkit/analytics/services";
|
|
2
|
+
import { TEvent } from "@shopkit/analytics/types";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Get client IP address from request headers
|
|
6
|
+
*/
|
|
7
|
+
function getClientIpAddress(request: Request): string | undefined {
|
|
8
|
+
// Try different headers for IP address
|
|
9
|
+
const forwarded = request.headers.get("x-forwarded-for");
|
|
10
|
+
const realIp = request.headers.get("x-real-ip");
|
|
11
|
+
const cfConnectingIp = request.headers.get("cf-connecting-ip");
|
|
12
|
+
|
|
13
|
+
return forwarded?.split(",")[0] || realIp || cfConnectingIp || undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function POST(request: Request) {
|
|
17
|
+
try {
|
|
18
|
+
const { events, userInfo } = await request.json();
|
|
19
|
+
|
|
20
|
+
// Validate events array
|
|
21
|
+
if (!Array.isArray(events) || events.length === 0) {
|
|
22
|
+
return Response.json({ error: "Invalid events data" }, { status: 400 });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Create CAPI service with explicit configuration
|
|
26
|
+
const capiService = createFacebookCAPIService({
|
|
27
|
+
accessToken: process.env.FACEBOOK_CAPI_ACCESS_TOKEN!,
|
|
28
|
+
pixelId: process.env.NEXT_PUBLIC_PIXEL_ID!,
|
|
29
|
+
testEventCode: process.env.FACEBOOK_TEST_EVENT_CODE,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (!capiService) {
|
|
33
|
+
console.warn(
|
|
34
|
+
"Facebook CAPI service not available - missing configuration"
|
|
35
|
+
);
|
|
36
|
+
return Response.json(
|
|
37
|
+
{ error: "CAPI service not configured" },
|
|
38
|
+
{ status: 500 }
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Enhance user info with server-side data
|
|
43
|
+
const enhancedUserInfo = {
|
|
44
|
+
...userInfo,
|
|
45
|
+
clientIpAddress: getClientIpAddress(request),
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
// Send events to Facebook CAPI
|
|
49
|
+
await capiService.sendEvents(events as TEvent[], enhancedUserInfo);
|
|
50
|
+
|
|
51
|
+
return Response.json({
|
|
52
|
+
success: true,
|
|
53
|
+
message: `Successfully sent ${events.length} events to Facebook CAPI`,
|
|
54
|
+
});
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error("API Events Error:", error);
|
|
57
|
+
return Response.json(
|
|
58
|
+
{ error: "Failed to process events" },
|
|
59
|
+
{ status: 500 }
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["\n/**\n * Event types that can be tracked across the application\n */\nexport enum EventType {\n PRODUCT_VIEW = \"product_view\",\n STARTED_ORDER = \"started_order\",\n PAGE_VIEW = \"page_view\",\n BUTTON_CLICK = \"button_click\",\n FORM_SUBMISSION = \"form_submission\",\n VIEW_ITEM = \"view_item\",\n VIEWED_PRODUCT = \"viewed_product\",\n CHECKOUT_PAYMENT = \"checkout_payment\",\n COLLECTION_VIEW = \"collection_view\",\n ADD_TO_CART = \"add_to_cart\",\n REMOVE_FROM_CART = \"remove_from_cart\",\n CHECKOUT_STARTED = \"checkout_started\",\n CHECKOUT_COMPLETED = \"checkout_completed\",\n SEARCH = \"search\",\n CART_PAGE_LAND = \"cart_page_land\",\n CLOSE_CART = \"close_cart\",\n QUANTITY_CHANGE = \"quantity_change\",\n FILTER_APPLIED = \"filter_applied\",\n NEWSLETTER_SUBSCRIPTION = \"newsletter_subscription\",\n USER_SIGNUP = \"user_signup\",\n USER_LOGIN = \"user_login\",\n CUSTOM = \"custom\",\n USER_ENGAGEMENT = \"user_engagement\",\n SESSION_START = \"session_start\",\n FIRST_VISIT = \"first_visit\",\n SCROLL = \"scroll\",\n FORM_START = \"form_start\",\n ADD_PAYMENT_INFO = \"add_payment_info\",\n CART_VIEWED = \"cart_viewed\",\n PAGES_SCREENS_PER_SESSION = \"pages_screens_per_session\",\n VIEW_CONTENT = \"view_content\",\n PURCHASE = \"purchase\",\n VIEW_SEARCH_RESULTS = \"view_search_results\",\n ORDER_PLACED = \"order_placed\",\n BEGIN_CHECKOUT = \"begin_checkout\",\n\n // MoEngage events\n ITEM_PURCHASED = \"item_purchased\",\n UPDATE_CART = \"update_cart\",\n CUSTOMER_REGISTERED = \"customer_registered\",\n CUSTOMER_LOGGED_IN = \"customer_logged_in\",\n SHOPIFY_CHECKOUT_UPDATED = \"shopify_checkout_updated\",\n SHOPIFY_ABANDONED_CHECKOUT = \"shopify_abandoned_checkout\",\n SHOPIFY_ORDER_FULFILLED = \"shopify_order_fulfilled\",\n SHOPIFY_CHECKOUT_STARTED = \"shopify_checkout_started\",\n SHOPIFY_ADD_TO_CART = \"shopify_add_to_cart\",\n SHOPIFY_REMOVED_FROM_CART = \"shopify_removed_from_cart\",\n SHOPIFY_UPDATE_CART = \"shopify_update_cart\",\n SPINFORM_RESULT = \"spinform_result\",\n COUPON_COPIED = \"coupon_copied\",\n STARTED_CHECKOUT_GK = \"started_checkout_gk\",\n MOBILE_ADDED_GK = \"mobile_added_gk\",\n ADDRESS_SELECTED_GK = \"address_selected_gk\",\n ADDRESS_COMPLETED_GK = \"address_completed_gk\",\n PAYMENT_METHOD_SELECTED_GK = \"payment_method_selected_gk\",\n PAYMENT_COMPLETED_GK = \"payment_completed_gk\",\n ORDER_SUCCESS = \"order_success\",\n ORDER_COMPLETED = \"order_completed\",\n PIN_CODE_ADDED_GK = \"pin_code_added_gk\",\n ADDRESS_ADDED_GK = \"address_added_gk\",\n KP_MP_PHONE_NUMBER_LOGGED_IN = \"kp_mp_phone_number_logged_in\",\n KP_PHONE_NUMBER_LOGGED_IN = \"kp_phone_number_logged_in\",\n KP_MP_SHOPIFY_LOGGED_IN = \"kp_mp_shopify_logged_in\",\n KP_MP_SUCCESSFULLY_LOGGED_OUT = \"kp_mp_successfully_logged_out\",\n KP_WHATSAPP_LOGGED_IN = \"kp_whatsapp_logged_in\",\n KP_MP_TRUECALLER_LOGGED_IN = \"kp_mp_truecaller_logged_in\",\n KP_MP_WHATSAPP_LOGGED_IN = \"kp_mp_whatsapp_logged_in\",\n KP_TRUECALLER_LOGGED_IN = \"kp_truecaller_logged_in\",\n KP_SHOPIFY_LOGGED_IN = \"kp_shopify_logged_in\",\n KP_SUCCESSFULLY_LOGGED_OUT = \"kp_successfully_logged_out\",\n}\n\n/**\n * Base event interface that all events should implement\n */\nexport interface BaseEvent {\n type: EventType;\n timestamp?: number;\n event_category?: string;\n description?: string;\n [key: string]: any;\n}\n\n/**\n * Page view event\n */\nexport interface IPageViewEvent extends BaseEvent {\n type: EventType.PAGE_VIEW;\n path: string;\n title: string;\n referrer?: string;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n campaign?: string;\n campaign_id?: string;\n content?: string;\n debug_mode?: boolean;\n engagement_time_msec?: number;\n entrances?: number;\n ga_session_id?: string;\n ga_session_number?: number;\n gclid?: string;\n ignore_referrer?: boolean;\n medium?: string;\n page_location?: string;\n page_path?: string;\n page_referrer?: string;\n page_title?: string;\n page_source?: string;\n page_term?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n}\n\n/**\n * User engagement event\n */\nexport interface IUserEngagementEvent extends BaseEvent {\n type: EventType.USER_ENGAGEMENT;\n engagementTime?: number; // in seconds\n pagePath?: string;\n pageTitle?: string;\n scrollDepth?: number; // in percentage\n formId?: string;\n formName?: string;\n formFields?: Array<{\n fieldName: string;\n fieldValue: string;\n }>;\n buttonId?: string;\n buttonText?: string;\n location?: string;\n customProperties?: Record<string, any>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n campaign?: string;\n ga_session_id?: string;\n ga_session_number?: number;\n gclid?: string;\n ignore_referrer?: boolean;\n medium?: string;\n page_location?: string;\n page_path?: string;\n page_referrer?: string;\n page_title?: string;\n source?: string;\n srsltid?: string;\n term?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n}\n\n/**\n * Session start event\n */\nexport interface ISessionStartEvent extends BaseEvent {\n type: EventType.SESSION_START;\n sessionId: string;\n userId?: string;\n userAgent?: string;\n referrer?: string;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * First visit event\n */\nexport interface IFirstVisitEvent extends BaseEvent {\n type: EventType.FIRST_VISIT;\n userId?: string;\n userAgent?: string;\n referrer?: string;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * Scroll event\n */\nexport interface IScrollEvent extends BaseEvent {\n type: EventType.SCROLL;\n scrollDepth: number; // in percentage\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n engagement_time_msec?: number;\n ga_session_id?: string;\n ga_session_number?: number;\n ignore_referrer?: boolean;\n page_location?: string;\n page_referrer?: string;\n page_title?: string;\n percent_scrolled?: number;\n}\n\n/**\n * Form start event\n */\nexport interface IFormStartEvent extends BaseEvent {\n type: EventType.FORM_START;\n formId: string;\n formName?: string;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * Form submission event\n */\nexport interface IFormSubmissionEvent extends BaseEvent {\n type: EventType.FORM_SUBMISSION;\n formId: string;\n formName?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * User signup event\n */\nexport interface IUserSignupEvent extends BaseEvent {\n type: EventType.USER_SIGNUP;\n userId?: string;\n method?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * User login event\n */\nexport interface IUserLoginEvent extends BaseEvent {\n type: EventType.USER_LOGIN;\n userId?: string;\n method?: string;\n success: boolean;\n pagePath: string;\n pageTitle: string;\n timestamp: number;\n customProperties?: Record<string, any>;\n}\n\n/**\n * Button click event\n */\nexport interface IButtonClickEvent extends BaseEvent {\n type: EventType.BUTTON_CLICK;\n buttonId?: string;\n buttonText?: string;\n location: string;\n}\n\n/**\n * View item event for e-commerce tracking\n */\nexport interface IViewItemEvent extends BaseEvent {\n type: EventType.VIEW_ITEM;\n currency: string;\n value: number;\n items: Array<{\n item_id: string;\n item_name: string;\n price: number;\n currency: string;\n }>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n campaign?: string;\n ecomm_pagetype?: string;\n ecomm_prodid?: string;\n ecomm_totalvalue?: number;\n engagement_time_msec?: number;\n ga_session_id?: string;\n ga_session_number?: number;\n gclid?: string;\n ignore_referrer?: boolean;\n medium?: string;\n page_location?: string;\n page_path?: string;\n page_referrer?: string;\n page_title?: string;\n source?: string;\n srsltid?: string;\n term?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n}\n\n/**\n * Checkout payment event\n */\nexport interface ICheckoutPaymentEvent extends BaseEvent {\n type: EventType.CHECKOUT_PAYMENT;\n cartValue: number;\n currency: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n }>;\n}\n\n/**\n * Viewed product event after 20 seconds\n */\nexport interface IViewedProductEvent extends BaseEvent {\n type: EventType.VIEWED_PRODUCT;\n productId: string;\n productName: string;\n price: number;\n currency: string;\n viewDuration: number;\n}\n\nexport interface IPCollectionViewEvent extends BaseEvent {\n type: EventType.COLLECTION_VIEW;\n productId: string;\n productName: string;\n price?: number;\n currency?: string;\n category?: string;\n}\n\n/**\n * Add to cart event\n */\nexport interface IAddToCartEvent extends BaseEvent {\n type: EventType.ADD_TO_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity?: number;\n variant?: string;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n ecomm_pagetype?: string;\n ecomm_prodid?: string;\n ecomm_totalvalue?: number;\n value?: number;\n engagement_time_msec?: number;\n ga_session_id?: string;\n ga_session_number?: number;\n ignore_referrer?: boolean;\n page_location?: string;\n page_referrer?: string;\n page_title?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n}\n\n/**\n * Remove from cart event\n */\nexport interface IRemoveFromCartEvent extends BaseEvent {\n type: EventType.REMOVE_FROM_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Checkout started event\n */\nexport interface ICheckoutStartedEvent extends BaseEvent {\n type: EventType.CHECKOUT_STARTED;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n coupon?: string;\n discount?: number | string;\n}\n\n/**\n * Checkout completed event\n */\nexport interface ICheckoutCompletedEvent extends BaseEvent {\n type: EventType.CHECKOUT_COMPLETED;\n orderId: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n/**\n * Cart viewed event\n */\nexport interface ICartViewedEvent extends BaseEvent {\n type: EventType.CART_VIEWED;\n cartId: string;\n products: Array<{\n variantId: string;\n price: number;\n quantity: number;\n }>;\n}\n\n/**\n * Search event\n */\nexport interface ISearchEvent extends BaseEvent {\n type: EventType.SEARCH;\n searchTerm: string;\n content_ids: string[];\n resultsCount?: number;\n}\n\n/**\n * Filter applied event\n */\nexport interface IFilterAppliedEvent extends BaseEvent {\n type: EventType.FILTER_APPLIED;\n filterType: string;\n filterValue: string | number | boolean;\n}\n\n/**\n * Newsletter subscription event\n */\nexport interface INewsletterSubscriptionEvent extends BaseEvent {\n type: EventType.NEWSLETTER_SUBSCRIPTION;\n email: string;\n success: boolean;\n}\n\n/**\n * View content event (for Facebook Pixel ViewContent)\n */\nexport interface IViewContentEvent extends BaseEvent {\n type: EventType.VIEW_CONTENT;\n content_type?: string;\n content_ids?: string[];\n content_name?: string;\n content_category?: string;\n value?: number;\n currency?: string;\n items?: Array<any>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n campaign?: string;\n ga_session_id?: string;\n engagement_time_msec?: number;\n session_engaged?: boolean;\n page_title?: string;\n page_location?: string;\n page_referrer?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n}\n\n/**\n * Purchase event (for Facebook Pixel Purchase)\n */\nexport interface IPurchaseEvent extends BaseEvent {\n type: EventType.PURCHASE;\n value: number;\n currency?: string;\n content_type?: string;\n content_ids?: string[];\n num_items?: number;\n contents?: Array<{\n id: string;\n quantity: number;\n item_price?: number;\n }>;\n transaction_id?: string;\n coupon?: string;\n shipping?: number;\n tax?: number;\n items?: Array<any>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n campaign?: string;\n ga_session_id?: string;\n engagement_time_msec?: number;\n session_engaged?: boolean;\n page_title?: string;\n page_location?: string;\n page_referrer?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n}\n\n/**\n * View search results event (for GA4)\n */\nexport interface IViewSearchResultsEvent extends BaseEvent {\n type: EventType.VIEW_SEARCH_RESULTS;\n search_term?: string;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n campaign?: string;\n campaign_id?: string;\n content?: string;\n ga_session_id?: string;\n ga_session_number?: number;\n gclid?: string;\n medium?: string;\n page_location?: string;\n page_path?: string;\n page_referrer?: string;\n page_title?: string;\n source?: string;\n srsltid?: string;\n term?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n engagement_time_msec?: number;\n}\n\n/**\n * Order placed event (for GA4)\n */\nexport interface IOrderPlacedEvent extends BaseEvent {\n type: EventType.ORDER_PLACED;\n transaction_id?: string;\n order_id?: string;\n total_amount?: number;\n value: number;\n currency?: string;\n items?: Array<any>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n coupon?: string;\n discount?: number;\n engagement_time_msec?: number;\n ga_session_id?: string;\n ga_session_number?: number;\n ignore_referrer?: boolean;\n page_location?: string;\n page_referrer?: string;\n page_title?: string;\n payment_type?: string;\n shipping?: number;\n shipping_name?: string;\n tax?: number;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n}\n\n/**\n * Begin checkout event (for GA4)\n */\nexport interface IBeginCheckoutEvent extends BaseEvent {\n type: EventType.BEGIN_CHECKOUT;\n currency?: string;\n value: number;\n coupon?: string;\n items?: Array<any>;\n // GA4 specific parameters\n batch_ordering_id?: string;\n batch_page_id?: string;\n ecomm_pagetype?: string;\n ecomm_prodid?: string;\n ecomm_totalvalue?: number;\n engagement_time_msec?: number;\n ga_session_id?: string;\n ga_session_number?: number;\n ignore_referrer?: boolean;\n page_location?: string;\n page_referrer?: string;\n page_title?: string;\n user_id?: string;\n user_properties?: Record<string, any>;\n session_engaged?: boolean;\n}\n\n/**\n * Custom event for any other tracking needs\n */\nexport interface ICustomEvent extends BaseEvent {\n type: EventType.CUSTOM;\n name: string;\n properties?: Record<string, any>;\n}\n\n/**\n * Add Payment Info event\n */\nexport interface IAddPaymentInfoEvent extends BaseEvent {\n type: EventType.ADD_PAYMENT_INFO;\n cartValue: number;\n currency?: string;\n itemCount: number;\n paymentType?: string;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n/**\n * Item purchased event\n */\nexport interface IItemPurchasedEvent extends BaseEvent {\n type: EventType.ITEM_PURCHASED;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n orderId?: string;\n}\n\n/**\n * Update cart event\n */\nexport interface IUpdateCartEvent extends BaseEvent {\n type: EventType.UPDATE_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Customer registered event\n */\nexport interface ICustomerRegisteredEvent extends BaseEvent {\n type: EventType.CUSTOMER_REGISTERED;\n userId: string;\n email?: string;\n phone?: string;\n firstName?: string;\n lastName?: string;\n}\n\n/**\n * Customer logged in event\n */\nexport interface ICustomerLoggedInEvent extends BaseEvent {\n type: EventType.CUSTOMER_LOGGED_IN;\n userId: string;\n email?: string;\n phone?: string;\n method?: string;\n}\n\n/**\n * Shopify checkout updated event\n */\nexport interface IShopifyCheckoutUpdatedEvent extends BaseEvent {\n type: EventType.SHOPIFY_CHECKOUT_UPDATED;\n checkoutId: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n/**\n * Shopify abandoned checkout event\n */\nexport interface IShopifyAbandonedCheckoutEvent extends BaseEvent {\n type: EventType.SHOPIFY_ABANDONED_CHECKOUT;\n checkoutId: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n/**\n * Shopify order fulfilled event\n */\nexport interface IShopifyOrderFulfilledEvent extends BaseEvent {\n type: EventType.SHOPIFY_ORDER_FULFILLED;\n orderId: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n/**\n * Shopify checkout started event\n */\nexport interface IShopifyCheckoutStartedEvent extends BaseEvent {\n type: EventType.SHOPIFY_CHECKOUT_STARTED;\n checkoutId: string;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n variant?: string;\n }>;\n}\n\n/**\n * Shopify add to cart event\n */\nexport interface IShopifyAddToCartEvent extends BaseEvent {\n type: EventType.SHOPIFY_ADD_TO_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Shopify remove from cart event\n */\nexport interface IShopifyRemoveFromCartEvent extends BaseEvent {\n type: EventType.SHOPIFY_REMOVED_FROM_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Shopify update cart event\n */\nexport interface IShopifyUpdateCartEvent extends BaseEvent {\n type: EventType.SHOPIFY_UPDATE_CART;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n quantity: number;\n variant?: string;\n}\n\n/**\n * Spinform result event\n */\nexport interface ISpinformResultEvent extends BaseEvent {\n type: EventType.SPINFORM_RESULT;\n result?: string;\n}\n\n/**\n * Coupon copied event\n */\nexport interface ICouponCopiedEvent extends BaseEvent {\n type: EventType.COUPON_COPIED;\n couponCode?: string;\n}\n\n/**\n * Started checkout GK event\n */\nexport interface IStartedCheckoutGKEvent extends BaseEvent {\n type: EventType.STARTED_CHECKOUT_GK;\n cartValue?: number;\n currency?: string;\n}\n\n/**\n * Mobile added GK event\n */\nexport interface IMobileAddedGKEvent extends BaseEvent {\n type: EventType.MOBILE_ADDED_GK;\n mobile?: string;\n}\n\n/**\n * Address selected GK event\n */\nexport interface IAddressSelectedGKEvent extends BaseEvent {\n type: EventType.ADDRESS_SELECTED_GK;\n addressId?: string;\n}\n\n/**\n * Address completed GK event\n */\nexport interface IAddressCompletedGKEvent extends BaseEvent {\n type: EventType.ADDRESS_COMPLETED_GK;\n addressId?: string;\n}\n\n/**\n * Payment method selected GK event\n */\nexport interface IPaymentMethodSelectedGKEvent extends BaseEvent {\n type: EventType.PAYMENT_METHOD_SELECTED_GK;\n paymentMethod?: string;\n}\n\n/**\n * Payment completed GK event\n */\nexport interface IPaymentCompletedGKEvent extends BaseEvent {\n type: EventType.PAYMENT_COMPLETED_GK;\n amount?: number;\n currency?: string;\n}\n\n/**\n * Order success event\n */\nexport interface IOrderSuccessEvent extends BaseEvent {\n type: EventType.ORDER_SUCCESS;\n orderId?: string;\n amount?: number;\n currency?: string;\n}\n\n/**\n * Order completed event\n */\nexport interface IOrderCompletedEvent extends BaseEvent {\n type: EventType.ORDER_COMPLETED;\n orderId?: string;\n amount?: number;\n currency?: string;\n}\n\n/**\n * Cart page land event\n */\nexport interface ICartPageLandEvent extends BaseEvent {\n type: EventType.CART_PAGE_LAND;\n event_category: string;\n description: string;\n}\n\n/**\n * Close cart event\n */\nexport interface ICloseCartEvent extends BaseEvent {\n type: EventType.CLOSE_CART;\n event_category: string;\n description: string;\n}\n\n/**\n * Quantity change event\n */\nexport interface IQuantityChangeEvent extends BaseEvent {\n type: EventType.QUANTITY_CHANGE;\n event_category: string;\n description: string;\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n}\n\n/**\n * PIN code added GK event\n */\nexport interface IPinCodeAddedGKEvent extends BaseEvent {\n type: EventType.PIN_CODE_ADDED_GK;\n pinCode?: string;\n}\n\n/**\n * Address added GK event\n */\nexport interface IAddressAddedGKEvent extends BaseEvent {\n type: EventType.ADDRESS_ADDED_GK;\n addressId?: string;\n}\n\n/**\n * KP MP phone number logged in event\n */\nexport interface IKPMPPhoneNumberLoggedInEvent extends BaseEvent {\n type: EventType.KP_MP_PHONE_NUMBER_LOGGED_IN;\n phone?: string;\n}\n\n/**\n * KP phone number logged in event\n */\nexport interface IKPPhoneNumberLoggedInEvent extends BaseEvent {\n type: EventType.KP_PHONE_NUMBER_LOGGED_IN;\n phone?: string;\n}\n\n/**\n * KP MP Shopify logged in event\n */\nexport interface IKPMPShopifyLoggedInEvent extends BaseEvent {\n type: EventType.KP_MP_SHOPIFY_LOGGED_IN;\n userId?: string;\n}\n\n/**\n * KP MP successfully logged out event\n */\nexport interface IKPMPSuccessfullyLoggedOutEvent extends BaseEvent {\n type: EventType.KP_MP_SUCCESSFULLY_LOGGED_OUT;\n userId?: string;\n}\n\n/**\n * KP WhatsApp logged in event\n */\nexport interface IKPWhatsAppLoggedInEvent extends BaseEvent {\n type: EventType.KP_WHATSAPP_LOGGED_IN;\n phone?: string;\n}\n\n/**\n * KP MP Truecaller logged in event\n */\nexport interface IKPMPTruecallerLoggedInEvent extends BaseEvent {\n type: EventType.KP_MP_TRUECALLER_LOGGED_IN;\n phone?: string;\n}\n\n/**\n * KP MP WhatsApp logged in event\n */\nexport interface IKPMPWhatsAppLoggedInEvent extends BaseEvent {\n type: EventType.KP_MP_WHATSAPP_LOGGED_IN;\n phone?: string;\n}\n\n/**\n * KP Truecaller logged in event\n */\nexport interface IKPTruecallerLoggedInEvent extends BaseEvent {\n type: EventType.KP_TRUECALLER_LOGGED_IN;\n phone?: string;\n}\n\n/**\n * KP Shopify logged in event\n */\nexport interface IKPShopifyLoggedInEvent extends BaseEvent {\n type: EventType.KP_SHOPIFY_LOGGED_IN;\n userId?: string;\n}\n\n/**\n * KP successfully logged out event\n */\nexport interface IKPSuccessfullyLoggedOutEvent extends BaseEvent {\n type: EventType.KP_SUCCESSFULLY_LOGGED_OUT;\n userId?: string;\n}\n\n/**\n * Pages screens per session event\n */\nexport interface IPagesScreensPerSessionEvent extends BaseEvent {\n type: EventType.PAGES_SCREENS_PER_SESSION;\n currency: string;\n firebase_conversion: boolean;\n ga_session_id: string;\n ga_session_number: number;\n synthetic_bundle: boolean;\n value: number;\n}\n\n/**\n * Started order event\n */\nexport interface IStartedOrderEvent extends BaseEvent {\n type: EventType.STARTED_ORDER;\n cartValue: number;\n currency?: string;\n itemCount: number;\n items: Array<{\n productId: string;\n productName: string;\n price: number;\n quantity: number;\n }>;\n event_category: string;\n description: string;\n}\n\n/**\n * Product view event\n */\nexport interface IProductViewEvent extends BaseEvent {\n type: EventType.PRODUCT_VIEW;\n event_category: string;\n description: string;\n productId: string;\n productName: string;\n price: number;\n currency?: string;\n category?: string;\n}\n\n/**\n * Union type of all possible events\n */\nexport type TEvent =\n | IProductViewEvent\n | IPageViewEvent\n | IButtonClickEvent\n | IFormSubmissionEvent\n | ICartPageLandEvent\n | ICloseCartEvent\n | IQuantityChangeEvent\n | IViewItemEvent\n | IPCollectionViewEvent\n | IAddToCartEvent\n | IRemoveFromCartEvent\n | ICheckoutStartedEvent\n | ICheckoutCompletedEvent\n | ICartViewedEvent\n | ISearchEvent\n | IFilterAppliedEvent\n | INewsletterSubscriptionEvent\n | IUserSignupEvent\n | IUserLoginEvent\n | IViewContentEvent\n | IPurchaseEvent\n | IViewSearchResultsEvent\n | IOrderPlacedEvent\n | IBeginCheckoutEvent\n | ICustomEvent\n | IUserEngagementEvent\n | ISessionStartEvent\n | IFirstVisitEvent\n | IScrollEvent\n | IFormStartEvent\n | IAddPaymentInfoEvent\n | IItemPurchasedEvent\n | IUpdateCartEvent\n | ICustomerRegisteredEvent\n | ICustomerLoggedInEvent\n | IShopifyCheckoutUpdatedEvent\n | IShopifyAbandonedCheckoutEvent\n | IShopifyOrderFulfilledEvent\n | IShopifyCheckoutStartedEvent\n | IShopifyAddToCartEvent\n | IShopifyRemoveFromCartEvent\n | IShopifyUpdateCartEvent\n | ISpinformResultEvent\n | ICouponCopiedEvent\n | IStartedCheckoutGKEvent\n | IMobileAddedGKEvent\n | IAddressSelectedGKEvent\n | IAddressCompletedGKEvent\n | IPaymentMethodSelectedGKEvent\n | IPaymentCompletedGKEvent\n | IOrderSuccessEvent\n | IOrderCompletedEvent\n | IPinCodeAddedGKEvent\n | IAddressAddedGKEvent\n | IKPMPPhoneNumberLoggedInEvent\n | IKPPhoneNumberLoggedInEvent\n | IKPMPShopifyLoggedInEvent\n | IKPMPSuccessfullyLoggedOutEvent\n | IKPWhatsAppLoggedInEvent\n | IKPMPTruecallerLoggedInEvent\n | IKPMPWhatsAppLoggedInEvent\n | IKPTruecallerLoggedInEvent\n | IKPShopifyLoggedInEvent\n | IKPSuccessfullyLoggedOutEvent\n | IPagesScreensPerSessionEvent\n | IViewedProductEvent\n | ICheckoutPaymentEvent\n | IStartedOrderEvent;\n"],"mappings":";;;AAIO,IAAK,YAAL,kBAAKA,eAAL;AACL,EAAAA,WAAA,kBAAe;AACf,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,kBAAe;AACf,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,oBAAiB;AACjB,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,wBAAqB;AACrB,EAAAA,WAAA,YAAS;AACT,EAAAA,WAAA,oBAAiB;AACjB,EAAAA,WAAA,gBAAa;AACb,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,oBAAiB;AACjB,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,gBAAa;AACb,EAAAA,WAAA,YAAS;AACT,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,YAAS;AACT,EAAAA,WAAA,gBAAa;AACb,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,+BAA4B;AAC5B,EAAAA,WAAA,kBAAe;AACf,EAAAA,WAAA,cAAW;AACX,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,kBAAe;AACf,EAAAA,WAAA,oBAAiB;AAGjB,EAAAA,WAAA,oBAAiB;AACjB,EAAAA,WAAA,iBAAc;AACd,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,wBAAqB;AACrB,EAAAA,WAAA,8BAA2B;AAC3B,EAAAA,WAAA,gCAA6B;AAC7B,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,8BAA2B;AAC3B,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,+BAA4B;AAC5B,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,0BAAuB;AACvB,EAAAA,WAAA,gCAA6B;AAC7B,EAAAA,WAAA,0BAAuB;AACvB,EAAAA,WAAA,mBAAgB;AAChB,EAAAA,WAAA,qBAAkB;AAClB,EAAAA,WAAA,uBAAoB;AACpB,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,kCAA+B;AAC/B,EAAAA,WAAA,+BAA4B;AAC5B,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,mCAAgC;AAChC,EAAAA,WAAA,2BAAwB;AACxB,EAAAA,WAAA,gCAA6B;AAC7B,EAAAA,WAAA,8BAA2B;AAC3B,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,0BAAuB;AACvB,EAAAA,WAAA,gCAA6B;AAtEnB,SAAAA;AAAA,GAAA;","names":["EventType"]}
|