@splendidlabz/tracking 0.2.11 → 0.2.12
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/lib/fb/node.js +100 -4
- package/lib/fb/web.js +64 -6
- package/lib/posthog/node.js +3 -3
- package/lib/posthog/readme.md +8 -0
- package/lib/posthog/web.js +5 -2
- package/package.json +1 -1
package/lib/fb/node.js
CHANGED
|
@@ -8,15 +8,36 @@ import {
|
|
|
8
8
|
} from './consts.js'
|
|
9
9
|
import { formatUserData } from './utils.js'
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Facebook Conversions API tracker for server-side tracking
|
|
13
|
+
* @param {Object} config - Configuration options
|
|
14
|
+
* @param {string} config.pixelID - Facebook Pixel ID
|
|
15
|
+
* @param {string} [config.testEventCode] - Test event code for debugging
|
|
16
|
+
* @param {string} config.accessToken - Facebook Access Token (required)
|
|
17
|
+
* @param {string} config.framework - Framework being used (astro, express, fastify, koa)
|
|
18
|
+
* @return {Object} FB tracking instance
|
|
19
|
+
* @property {Function} sendEvent - Send a pre-formatted event to CAPI
|
|
20
|
+
* @property {Function} createEvent - Create an event payload
|
|
21
|
+
* @property {Function} track - Track an event and send to CAPI
|
|
22
|
+
* @property {Function} sendCAPIRequest - Send raw request to CAPI
|
|
23
|
+
* @see https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/
|
|
24
|
+
*/
|
|
12
25
|
export default function FB({ pixelID, testEventCode, accessToken, framework }) {
|
|
13
26
|
framework = framework.toLowerCase()
|
|
14
27
|
|
|
15
28
|
if (!accessToken) throw new Error('Facebook Access Token required')
|
|
16
29
|
|
|
17
30
|
return {
|
|
18
|
-
|
|
19
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Sends a pre-formatted event to Facebook CAPI
|
|
33
|
+
* Used when frontend has already prepared the event data
|
|
34
|
+
* @param {Object} [props={}] - Event properties including pixel_id, test_event_code, user_data
|
|
35
|
+
* @param {Object} [options={}] - Additional options
|
|
36
|
+
* @param {Object} [options.context] - Framework-specific request context
|
|
37
|
+
* @param {boolean} [options.debug] - Enable debug logging
|
|
38
|
+
* @param {boolean} [options.dryRun] - Skip actual API call
|
|
39
|
+
* @return {Promise<Object>} CAPI response
|
|
40
|
+
*/
|
|
20
41
|
async sendEvent(props = {}, options = {}) {
|
|
21
42
|
const { pixel_id, test_event_code, user_data, ...rest } = props
|
|
22
43
|
const { context } = options
|
|
@@ -44,6 +65,14 @@ export default function FB({ pixelID, testEventCode, accessToken, framework }) {
|
|
|
44
65
|
return this.sendCAPIRequest(body, { ...options, pixel_id })
|
|
45
66
|
},
|
|
46
67
|
|
|
68
|
+
/**
|
|
69
|
+
* Creates a Facebook CAPI event payload
|
|
70
|
+
* @param {string} eventName - Name of the event to track
|
|
71
|
+
* @param {Object} [props={}] - Event properties and user data
|
|
72
|
+
* @param {Object} [props.context] - Framework-specific request context (required for auto-filled properties)
|
|
73
|
+
* @param {Object} [options={}] - Additional options
|
|
74
|
+
* @return {Promise<Object>} Event payload ready to send to CAPI
|
|
75
|
+
*/
|
|
47
76
|
async createEvent(eventName, props = {}, options = {}) {
|
|
48
77
|
const { context, ...p } = props
|
|
49
78
|
const { p: eventParams, o: r1 } = splitObject(p, SERVER_EVENT_PARAMS)
|
|
@@ -93,12 +122,32 @@ export default function FB({ pixelID, testEventCode, accessToken, framework }) {
|
|
|
93
122
|
return body
|
|
94
123
|
},
|
|
95
124
|
|
|
96
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Tracks an event and sends it to Facebook CAPI
|
|
127
|
+
* Combines createEvent and sendCAPIRequest
|
|
128
|
+
* @param {string} eventName - Name of the event to track
|
|
129
|
+
* @param {Object} [props={}] - Event properties and user data
|
|
130
|
+
* @param {Object} [props.context] - Framework-specific request context
|
|
131
|
+
* @param {Object} [options={}] - Additional options
|
|
132
|
+
* @param {boolean} [options.debug] - Enable debug logging
|
|
133
|
+
* @param {boolean} [options.dryRun] - Skip actual API call
|
|
134
|
+
* @param {string} [options.pixel_id] - Override default pixel ID
|
|
135
|
+
* @return {Promise<Object>} CAPI response
|
|
136
|
+
*/
|
|
97
137
|
async track(eventName, props = {}, options = {}) {
|
|
98
138
|
const body = await this.createEvent(eventName, props, options)
|
|
99
139
|
return this.sendCAPIRequest(body, options)
|
|
100
140
|
},
|
|
101
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Sends a raw request to Facebook Conversions API
|
|
144
|
+
* @param {Object} body - Request body containing event data
|
|
145
|
+
* @param {Object} [options={}] - Request options
|
|
146
|
+
* @param {boolean} [options.debug] - Log request body
|
|
147
|
+
* @param {boolean} [options.dryRun] - Skip actual API call
|
|
148
|
+
* @param {string} [options.pixel_id] - Override default pixel ID
|
|
149
|
+
* @return {Promise<Object>} CAPI response
|
|
150
|
+
*/
|
|
102
151
|
async sendCAPIRequest(body, options) {
|
|
103
152
|
const { debug = false, dryRun = false, pixel_id } = options
|
|
104
153
|
const pixel = pixel_id || pixelID
|
|
@@ -121,6 +170,17 @@ export default function FB({ pixelID, testEventCode, accessToken, framework }) {
|
|
|
121
170
|
// ========================
|
|
122
171
|
// Helper Functions
|
|
123
172
|
// ========================
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Gets default event parameters based on the framework and context
|
|
176
|
+
* @param {string} framework - Framework name (astro, express, fastify, koa)
|
|
177
|
+
* @param {Object} context - Framework-specific request context
|
|
178
|
+
* @return {Object} Default event parameters
|
|
179
|
+
* @property {string} event_id - Randomly generated event ID
|
|
180
|
+
* @property {string} action_source - Always set to 'website'
|
|
181
|
+
* @property {number} event_time - Unix timestamp in seconds
|
|
182
|
+
* @property {string} event_source_url - Full URL of the request
|
|
183
|
+
*/
|
|
124
184
|
function getEventParamDefaults(framework, context) {
|
|
125
185
|
return {
|
|
126
186
|
event_id: randomString(10),
|
|
@@ -130,6 +190,12 @@ function getEventParamDefaults(framework, context) {
|
|
|
130
190
|
}
|
|
131
191
|
}
|
|
132
192
|
|
|
193
|
+
/**
|
|
194
|
+
* Extracts the full URL from framework-specific context
|
|
195
|
+
* @param {string} framework - Framework name (astro, express, fastify, koa)
|
|
196
|
+
* @param {Object} context - Framework-specific request context
|
|
197
|
+
* @return {string} Full URL including protocol, host, and path
|
|
198
|
+
*/
|
|
133
199
|
function getUrl(framework, context) {
|
|
134
200
|
if (framework === 'astro') return context.url.href
|
|
135
201
|
if (framework === 'express') {
|
|
@@ -143,6 +209,12 @@ function getUrl(framework, context) {
|
|
|
143
209
|
}
|
|
144
210
|
}
|
|
145
211
|
|
|
212
|
+
/**
|
|
213
|
+
* Extracts client IP address from framework-specific context
|
|
214
|
+
* @param {string} framework - Framework name (astro, express, fastify, koa)
|
|
215
|
+
* @param {Object} context - Framework-specific request context
|
|
216
|
+
* @return {string} Client IP address
|
|
217
|
+
*/
|
|
146
218
|
function getIP(framework, context) {
|
|
147
219
|
if (framework === 'astro') return context.clientAddress
|
|
148
220
|
if (framework === 'express')
|
|
@@ -151,6 +223,12 @@ function getIP(framework, context) {
|
|
|
151
223
|
if (framework === 'koa') return context.ip
|
|
152
224
|
}
|
|
153
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Extracts user agent string from framework-specific context
|
|
228
|
+
* @param {string} framework - Framework name (astro, express, fastify, koa)
|
|
229
|
+
* @param {Object} context - Framework-specific request context
|
|
230
|
+
* @return {string} User agent string
|
|
231
|
+
*/
|
|
154
232
|
function getUserAgent(framework, context) {
|
|
155
233
|
if (framework === 'astro') return context.request.headers.get('user-agent')
|
|
156
234
|
if (framework === 'express') return context.get('user-agent')
|
|
@@ -158,6 +236,13 @@ function getUserAgent(framework, context) {
|
|
|
158
236
|
if (framework === 'koa') return context.get('user-agent')
|
|
159
237
|
}
|
|
160
238
|
|
|
239
|
+
/**
|
|
240
|
+
* Extracts cookie value from framework-specific context
|
|
241
|
+
* @param {string} framework - Framework name (astro, express, fastify, koa)
|
|
242
|
+
* @param {Object} context - Framework-specific request context
|
|
243
|
+
* @param {string} name - Cookie name
|
|
244
|
+
* @return {string} Cookie value
|
|
245
|
+
*/
|
|
161
246
|
function getCookie(framework, context, name) {
|
|
162
247
|
if (framework === 'astro') return context.cookies.get(name)?.value
|
|
163
248
|
if (framework === 'express') return context.cookies?.[name]
|
|
@@ -165,6 +250,17 @@ function getCookie(framework, context, name) {
|
|
|
165
250
|
if (framework === 'koa') return context.cookies?.get(name)
|
|
166
251
|
}
|
|
167
252
|
|
|
253
|
+
/**
|
|
254
|
+
* Normalizes and enriches user data for Facebook CAPI
|
|
255
|
+
* Hashes required properties and adds client information from request context
|
|
256
|
+
* @param {Object} params - Parameters object
|
|
257
|
+
* @param {Object} params.context - Framework-specific request context
|
|
258
|
+
* @param {string} params.framework - Framework name (astro, express, fastify, koa)
|
|
259
|
+
* @param {Object} params.userProps - User properties to normalize
|
|
260
|
+
* @param {string} [params.fbc] - Facebook click ID cookie
|
|
261
|
+
* @param {string} [params.fbp] - Facebook browser ID cookie
|
|
262
|
+
* @return {Promise<Object>} Normalized user data with hashed properties and client info
|
|
263
|
+
*/
|
|
168
264
|
async function normalizeUserData({ context, framework, userProps, fbc, fbp }) {
|
|
169
265
|
const { p: userPropsToHash, o: otherUserProps } = splitObject(
|
|
170
266
|
userProps,
|
package/lib/fb/web.js
CHANGED
|
@@ -8,10 +8,39 @@ import {
|
|
|
8
8
|
} from './consts.js'
|
|
9
9
|
import { formatUserData } from './utils.js'
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Facebook Pixel and CAPI tracker for client-side tracking
|
|
13
|
+
* @param {Object} config - Configuration options
|
|
14
|
+
* @param {string} config.pixelID - Facebook Pixel ID
|
|
15
|
+
* @param {string} [config.testEventCode] - Test event code for debugging
|
|
16
|
+
* @param {string} config.capiEndpoint - API endpoint for sending CAPI requests
|
|
17
|
+
* @return {Object} FB tracking instance
|
|
18
|
+
* @property {Function} init - Initialize Facebook Pixel
|
|
19
|
+
* @property {Function} createEvent - Create event data for both Pixel and CAPI
|
|
20
|
+
* @property {Function} track - Track event via both Pixel and CAPI
|
|
21
|
+
* @property {Function} sendPixelEvent - Send event to Facebook Pixel
|
|
22
|
+
* @property {Function} sendCAPIRequest - Send event to CAPI endpoint
|
|
23
|
+
*/
|
|
11
24
|
export default function FB({ pixelID, testEventCode, capiEndpoint }) {
|
|
12
25
|
return {
|
|
26
|
+
/**
|
|
27
|
+
* Initializes the Facebook Pixel on the page
|
|
28
|
+
* @return {void}
|
|
29
|
+
*/
|
|
13
30
|
init: _ => initPixel(pixelID),
|
|
14
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Creates event data for both Facebook Pixel and CAPI
|
|
34
|
+
* @param {string} event_name - Name of the event to track
|
|
35
|
+
* @param {Object} [props={}] - Event properties and user data
|
|
36
|
+
* @param {string} [props.eventURL] - Custom URL for the event (defaults to current page)
|
|
37
|
+
* @param {string} [props.actionSource] - Action source (defaults to 'website')
|
|
38
|
+
* @param {Object} [options={}] - Additional options
|
|
39
|
+
* @param {boolean} [options.debug] - Enable debug logging
|
|
40
|
+
* @return {Promise<Object>} Object containing pixelData and capiData
|
|
41
|
+
* @property {Object} pixelData - Data formatted for Facebook Pixel
|
|
42
|
+
* @property {Object} capiData - Data formatted for CAPI
|
|
43
|
+
*/
|
|
15
44
|
async createEvent(event_name, props = {}, options = {}) {
|
|
16
45
|
const { debug = false } = options
|
|
17
46
|
const { eventURL, actionSource, ...r } = props
|
|
@@ -60,6 +89,15 @@ export default function FB({ pixelID, testEventCode, capiEndpoint }) {
|
|
|
60
89
|
return { pixelData, capiData }
|
|
61
90
|
},
|
|
62
91
|
|
|
92
|
+
/**
|
|
93
|
+
* Tracks an event by sending to both Facebook Pixel and CAPI
|
|
94
|
+
* @param {string} event_name - Name of the event to track
|
|
95
|
+
* @param {Object} [props={}] - Event properties and user data
|
|
96
|
+
* @param {Object} [options={}] - Additional options
|
|
97
|
+
* @param {boolean} [options.debug] - Enable debug logging
|
|
98
|
+
* @param {boolean} [options.dryRun] - Skip actual tracking (for testing)
|
|
99
|
+
* @return {Promise<Object>} CAPI response body
|
|
100
|
+
*/
|
|
63
101
|
async track(event_name, props = {}, options = {}) {
|
|
64
102
|
const { debug = false, dryRun = false } = options
|
|
65
103
|
const { pixelData, capiData } = await this.createEvent(
|
|
@@ -77,11 +115,20 @@ export default function FB({ pixelID, testEventCode, capiEndpoint }) {
|
|
|
77
115
|
return response.body
|
|
78
116
|
},
|
|
79
117
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Sends an event to Facebook Pixel
|
|
120
|
+
* Supports standard events, custom events, and advanced matching
|
|
121
|
+
* @param {Object} data - Event data
|
|
122
|
+
* @param {string} data.pixelID - Pixel ID
|
|
123
|
+
* @param {string} data.eventID - Event ID for deduplication
|
|
124
|
+
* @param {string} data.event_name - Event name (use 'init' to initialize pixel)
|
|
125
|
+
* @param {Object} [data.user_data] - User data for advanced matching
|
|
126
|
+
* @param {Object} [options] - Options
|
|
127
|
+
* @param {boolean} [options.debug] - Enable debug logging
|
|
128
|
+
* @return {void}
|
|
129
|
+
* @see https://developers.facebook.com/docs/meta-pixel/reference#standard-events
|
|
130
|
+
* @see https://developers.facebook.com/docs/meta-pixel/advanced/advanced-matching/
|
|
131
|
+
*/
|
|
85
132
|
sendPixelEvent(data, { debug = false }) {
|
|
86
133
|
const { pixelID, eventID, event_name, user_data = {}, ...rest } = data
|
|
87
134
|
const hasUserData = notEmpty(user_data)
|
|
@@ -108,13 +155,24 @@ export default function FB({ pixelID, testEventCode, capiEndpoint }) {
|
|
|
108
155
|
}
|
|
109
156
|
},
|
|
110
157
|
|
|
111
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Sends a request to the CAPI endpoint
|
|
160
|
+
* @param {Object} data - CAPI event data
|
|
161
|
+
* @return {Promise<Object>} Response from CAPI endpoint
|
|
162
|
+
* @see https://developers.facebook.com/docs/marketing-api/conversions-api/parameters/customer-information-parameters
|
|
163
|
+
*/
|
|
112
164
|
sendCAPIRequest(data) {
|
|
113
165
|
return zlFetch.post(capiEndpoint, { body: data })
|
|
114
166
|
},
|
|
115
167
|
}
|
|
116
168
|
}
|
|
117
169
|
|
|
170
|
+
/**
|
|
171
|
+
* Initializes the Facebook Pixel by loading the fbevents.js script
|
|
172
|
+
* @param {string} pixelID - Facebook Pixel ID
|
|
173
|
+
* @return {void}
|
|
174
|
+
* @throws {Error} If called outside of browser environment
|
|
175
|
+
*/
|
|
118
176
|
function initPixel(pixelID) {
|
|
119
177
|
// eslint-disable-next-line
|
|
120
178
|
!(function (f, b, e, v, n, t, s) {
|
package/lib/posthog/node.js
CHANGED
|
@@ -72,7 +72,7 @@ export default function (config = {}) {
|
|
|
72
72
|
* @param {string} [properties.userId] - User ID (used for distinct ID)
|
|
73
73
|
* @param {Object} [properties.context] - Request context (for cookie access)
|
|
74
74
|
* @param {...*} properties.rest - Additional event properties
|
|
75
|
-
* @return {Promise|undefined} PostHog capture promise, or undefined if
|
|
75
|
+
* @return {Promise|undefined} PostHog capture promise, or undefined if trackEvents is false
|
|
76
76
|
*/
|
|
77
77
|
capture(event, properties = {}) {
|
|
78
78
|
if (!trackEvents) return
|
|
@@ -88,7 +88,7 @@ export default function (config = {}) {
|
|
|
88
88
|
* Sets person properties on the current user
|
|
89
89
|
* @param {Object} [set={}] - Properties to set (will overwrite existing values)
|
|
90
90
|
* @param {Object} [once={}] - Properties to set only once (won't overwrite existing values)
|
|
91
|
-
* @return {Promise|undefined} PostHog capture promise, or undefined if
|
|
91
|
+
* @return {Promise|undefined} PostHog capture promise, or undefined if trackEvents is false
|
|
92
92
|
*/
|
|
93
93
|
setPersonProperties(set = {}, once = {}) {
|
|
94
94
|
if (!trackEvents) return
|
|
@@ -104,7 +104,7 @@ export default function (config = {}) {
|
|
|
104
104
|
/**
|
|
105
105
|
* Removes person properties from the current user
|
|
106
106
|
* @param {string[]} properties - List of property names to remove
|
|
107
|
-
* @return {Promise|undefined} PostHog capture promise, or undefined if
|
|
107
|
+
* @return {Promise|undefined} PostHog capture promise, or undefined if trackEvents is false
|
|
108
108
|
*/
|
|
109
109
|
removePersonProperties(properties) {
|
|
110
110
|
if (!trackEvents) return
|
package/lib/posthog/readme.md
CHANGED
|
@@ -15,3 +15,11 @@ This package assumes you're using Posthog for both web and node.js.
|
|
|
15
15
|
|
|
16
16
|
- Get distinct_id from cookies on the backend automatically when using Astro — just provide context.
|
|
17
17
|
- Use `trackEvents:false` to disable tracking completely when developing.
|
|
18
|
+
|
|
19
|
+
## Filtering out local development environments
|
|
20
|
+
|
|
21
|
+
You can create filters which include more than one value by separating values with a comma. We use such a filter to exclude events from local development environments, for example:
|
|
22
|
+
|
|
23
|
+
Host ≠ (doesn’t equal) localhost:8000,localhost:5000,127.0.0.1:8000
|
|
24
|
+
|
|
25
|
+
You can also create filters based on pre-prepared cohorts of users, which is especially useful if you’re using cohorts with Feature Flags or to run Experiments. To do this, simply select the cohort you wish to add to your internal and test user list.
|
package/lib/posthog/web.js
CHANGED
|
@@ -41,7 +41,8 @@ export default function (config = {}) {
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Set properties for the current person
|
|
44
|
-
* @param {
|
|
44
|
+
* @param {object} [set={}] - Properties to set (will overwrite existing values)
|
|
45
|
+
* @param {object} [once={}] - Properties to set only once (won't overwrite existing values)
|
|
45
46
|
* @returns {void}
|
|
46
47
|
*/
|
|
47
48
|
setPersonProperties(set = {}, once = {}) {
|
|
@@ -50,8 +51,9 @@ export default function (config = {}) {
|
|
|
50
51
|
},
|
|
51
52
|
|
|
52
53
|
/**
|
|
54
|
+
* Identify a user with PostHog. If the distinctId differs from the existing cookie ID, creates a new identity; otherwise updates properties.
|
|
53
55
|
* @param {string} distinctId - New unique identifier for the user (email, userId, etc.)
|
|
54
|
-
* @param {object} properties - The properties to set for the user
|
|
56
|
+
* @param {object} [properties={}] - The properties to set for the user
|
|
55
57
|
* @returns {void}
|
|
56
58
|
*/
|
|
57
59
|
identify(distinctId, properties = {}) {
|
|
@@ -67,6 +69,7 @@ export default function (config = {}) {
|
|
|
67
69
|
},
|
|
68
70
|
|
|
69
71
|
/**
|
|
72
|
+
* Create an alias for a user, linking two distinct IDs together
|
|
70
73
|
* @param {string} distinctId - New unique identifier for the user
|
|
71
74
|
* @param {string} aliasId - Alias for the user
|
|
72
75
|
* @returns {void}
|