@deriv-com/analytics 1.32.6 → 1.34.0
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/dist/analytics.bundle.js +1 -1
- package/lib/analytics.d.ts +8 -2
- package/lib/analytics.js +56 -13
- package/lib/posthog.d.ts +63 -0
- package/lib/posthog.js +272 -0
- package/package.json +2 -1
package/lib/analytics.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Growthbook, GrowthbookConfigs } from './growthbook';
|
|
2
2
|
import { RudderStack } from './rudderstack';
|
|
3
|
+
import { PostHogAnalytics, PostHogConfig } from './posthog';
|
|
3
4
|
import { TCoreAttributes, TGrowthbookOptions, TAllEvents } from './types';
|
|
4
5
|
declare global {
|
|
5
6
|
interface Window {
|
|
@@ -10,11 +11,14 @@ type Options = {
|
|
|
10
11
|
growthbookKey?: string;
|
|
11
12
|
growthbookDecryptionKey?: string;
|
|
12
13
|
rudderstackKey: string;
|
|
14
|
+
posthogKey?: string;
|
|
15
|
+
posthogHost?: string;
|
|
16
|
+
posthogConfig?: PostHogConfig;
|
|
13
17
|
growthbookOptions?: TGrowthbookOptions;
|
|
14
18
|
disableRudderstackAMD?: boolean;
|
|
15
19
|
};
|
|
16
20
|
export declare function createAnalyticsInstance(options?: Options): {
|
|
17
|
-
initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
|
|
21
|
+
initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, posthogKey, posthogHost, posthogConfig, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
|
|
18
22
|
setAttributes: ({ country, user_language, device_language, device_type, account_type, user_id, anonymous_id, app_id, utm_source, utm_medium, utm_campaign, is_authorised, residence_country, url, domain, geo_location, loggedIn, network_downlink, network_rtt, network_type, account_currency, account_mode, }: TCoreAttributes) => void;
|
|
19
23
|
identifyEvent: (user_id?: string) => void;
|
|
20
24
|
getFeatureState: (id: string) => string | undefined;
|
|
@@ -30,12 +34,13 @@ export declare function createAnalyticsInstance(options?: Options): {
|
|
|
30
34
|
getInstances: () => {
|
|
31
35
|
ab: Growthbook;
|
|
32
36
|
tracking: RudderStack;
|
|
37
|
+
posthog: PostHogAnalytics;
|
|
33
38
|
};
|
|
34
39
|
pageView: (current_page: string, platform?: string, properties?: {}) => void;
|
|
35
40
|
reset: () => void;
|
|
36
41
|
};
|
|
37
42
|
export declare const Analytics: {
|
|
38
|
-
initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
|
|
43
|
+
initialise: ({ growthbookKey, growthbookDecryptionKey, rudderstackKey, posthogKey, posthogHost, posthogConfig, growthbookOptions, disableRudderstackAMD, }: Options) => Promise<void>;
|
|
39
44
|
setAttributes: ({ country, user_language, device_language, device_type, account_type, user_id, anonymous_id, app_id, utm_source, utm_medium, utm_campaign, is_authorised, residence_country, url, domain, geo_location, loggedIn, network_downlink, network_rtt, network_type, account_currency, account_mode, }: TCoreAttributes) => void;
|
|
40
45
|
identifyEvent: (user_id?: string) => void;
|
|
41
46
|
getFeatureState: (id: string) => string | undefined;
|
|
@@ -51,6 +56,7 @@ export declare const Analytics: {
|
|
|
51
56
|
getInstances: () => {
|
|
52
57
|
ab: Growthbook;
|
|
53
58
|
tracking: RudderStack;
|
|
59
|
+
posthog: PostHogAnalytics;
|
|
54
60
|
};
|
|
55
61
|
pageView: (current_page: string, platform?: string, properties?: {}) => void;
|
|
56
62
|
reset: () => void;
|
package/lib/analytics.js
CHANGED
|
@@ -53,11 +53,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
53
53
|
exports.Analytics = exports.createAnalyticsInstance = void 0;
|
|
54
54
|
var growthbook_1 = require("./growthbook");
|
|
55
55
|
var rudderstack_1 = require("./rudderstack");
|
|
56
|
+
var posthog_1 = require("./posthog");
|
|
56
57
|
var js_cookie_1 = __importDefault(require("js-cookie"));
|
|
57
58
|
var utils_1 = require("@deriv-com/utils");
|
|
58
59
|
function createAnalyticsInstance(options) {
|
|
59
60
|
var _this = this;
|
|
60
|
-
var _growthbook, _rudderstack, core_data = {}, tracking_config = {}, event_cache = [], _pending_identify_calls = [];
|
|
61
|
+
var _growthbook, _rudderstack, _posthog, core_data = {}, tracking_config = {}, event_cache = [], _pending_identify_calls = [];
|
|
61
62
|
var getClientCountry = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
62
63
|
var countryFromCloudflare, countryFromCookie, websiteStatus, countryFromWebsiteStatus;
|
|
63
64
|
var _a;
|
|
@@ -82,7 +83,7 @@ function createAnalyticsInstance(options) {
|
|
|
82
83
|
});
|
|
83
84
|
}); };
|
|
84
85
|
var initialise = function (_a) {
|
|
85
|
-
var growthbookKey = _a.growthbookKey, growthbookDecryptionKey = _a.growthbookDecryptionKey, rudderstackKey = _a.rudderstackKey, growthbookOptions = _a.growthbookOptions, _b = _a.disableRudderstackAMD, disableRudderstackAMD = _b === void 0 ? false : _b;
|
|
86
|
+
var growthbookKey = _a.growthbookKey, growthbookDecryptionKey = _a.growthbookDecryptionKey, rudderstackKey = _a.rudderstackKey, posthogKey = _a.posthogKey, posthogHost = _a.posthogHost, posthogConfig = _a.posthogConfig, growthbookOptions = _a.growthbookOptions, _b = _a.disableRudderstackAMD, disableRudderstackAMD = _b === void 0 ? false : _b;
|
|
86
87
|
return __awaiter(_this, void 0, void 0, function () {
|
|
87
88
|
var country, _c, interval_1, error_1;
|
|
88
89
|
var _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
@@ -99,16 +100,35 @@ function createAnalyticsInstance(options) {
|
|
|
99
100
|
_2.label = 2;
|
|
100
101
|
case 2:
|
|
101
102
|
country = _c;
|
|
103
|
+
// Initialize RudderStack
|
|
102
104
|
_rudderstack = rudderstack_1.RudderStack.getRudderStackInstance(rudderstackKey, disableRudderstackAMD, function () {
|
|
103
105
|
_pending_identify_calls.forEach(function (userId) {
|
|
104
106
|
if (userId) {
|
|
105
107
|
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.identifyEvent(userId, {
|
|
106
108
|
language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
|
|
107
109
|
});
|
|
110
|
+
// Also identify in PostHog if initialized
|
|
111
|
+
if (_posthog === null || _posthog === void 0 ? void 0 : _posthog.has_initialized) {
|
|
112
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.identifyEvent(userId, {
|
|
113
|
+
language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
108
116
|
}
|
|
109
117
|
});
|
|
110
118
|
_pending_identify_calls = [];
|
|
111
119
|
});
|
|
120
|
+
// Initialize PostHog only if key is provided
|
|
121
|
+
if (posthogKey) {
|
|
122
|
+
_posthog = posthog_1.PostHogAnalytics.getPostHogInstance(posthogKey, posthogHost || 'https://ph.deriv.com', disableRudderstackAMD, function () {
|
|
123
|
+
_pending_identify_calls.forEach(function (userId) {
|
|
124
|
+
if (userId) {
|
|
125
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.identifyEvent(userId, {
|
|
126
|
+
language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}, posthogConfig);
|
|
131
|
+
}
|
|
112
132
|
if ((growthbookOptions === null || growthbookOptions === void 0 ? void 0 : growthbookOptions.attributes) && Object.keys(growthbookOptions.attributes).length > 0)
|
|
113
133
|
core_data = __assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign(__assign({}, core_data), { country: country }), (((_e = growthbookOptions === null || growthbookOptions === void 0 ? void 0 : growthbookOptions.attributes) === null || _e === void 0 ? void 0 : _e.user_language) && {
|
|
114
134
|
user_language: growthbookOptions === null || growthbookOptions === void 0 ? void 0 : growthbookOptions.attributes.user_language,
|
|
@@ -192,23 +212,35 @@ function createAnalyticsInstance(options) {
|
|
|
192
212
|
return userId && !isUUID(userId) ? userId : '';
|
|
193
213
|
};
|
|
194
214
|
/**
|
|
195
|
-
* Pushes page view event to
|
|
215
|
+
* Pushes page view event to RudderStack and PostHog
|
|
196
216
|
*
|
|
197
|
-
* @param
|
|
217
|
+
* @param current_page The name or URL of the current page to track the page view event
|
|
198
218
|
*/
|
|
199
219
|
var pageView = function (current_page, platform, properties) {
|
|
200
220
|
if (platform === void 0) { platform = 'Deriv App'; }
|
|
201
221
|
if (!_rudderstack)
|
|
202
222
|
return;
|
|
203
223
|
var userId = getId();
|
|
224
|
+
// Send to RudderStack
|
|
204
225
|
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.pageView(current_page, platform, userId, properties);
|
|
226
|
+
// Send to PostHog (if initialized)
|
|
227
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.pageView(current_page, platform, userId, properties);
|
|
205
228
|
};
|
|
206
229
|
var identifyEvent = function (user_id) {
|
|
207
230
|
var stored_user_id = user_id || getId();
|
|
208
|
-
if ((_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.has_initialized) && stored_user_id) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
231
|
+
if (((_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.has_initialized) || (_posthog === null || _posthog === void 0 ? void 0 : _posthog.has_initialized)) && stored_user_id) {
|
|
232
|
+
// Identify in RudderStack
|
|
233
|
+
if (_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.has_initialized) {
|
|
234
|
+
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.identifyEvent(stored_user_id, {
|
|
235
|
+
language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
// Identify in PostHog (if initialized)
|
|
239
|
+
if (_posthog === null || _posthog === void 0 ? void 0 : _posthog.has_initialized) {
|
|
240
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.identifyEvent(stored_user_id, {
|
|
241
|
+
language: (core_data === null || core_data === void 0 ? void 0 : core_data.user_language) || 'en',
|
|
242
|
+
});
|
|
243
|
+
}
|
|
212
244
|
return;
|
|
213
245
|
}
|
|
214
246
|
if (stored_user_id) {
|
|
@@ -216,9 +248,12 @@ function createAnalyticsInstance(options) {
|
|
|
216
248
|
}
|
|
217
249
|
};
|
|
218
250
|
var reset = function () {
|
|
219
|
-
if (!_rudderstack)
|
|
251
|
+
if (!_rudderstack && !_posthog)
|
|
220
252
|
return;
|
|
253
|
+
// Reset RudderStack
|
|
221
254
|
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.reset();
|
|
255
|
+
// Reset PostHog (if initialized)
|
|
256
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.reset();
|
|
222
257
|
};
|
|
223
258
|
var isV2Payload = function (payload) {
|
|
224
259
|
return 'event_metadata' in payload || 'cta_information' in payload || 'error' in payload;
|
|
@@ -235,25 +270,33 @@ function createAnalyticsInstance(options) {
|
|
|
235
270
|
// --- V1 LOGIC: Flatten Core Data (Backward Compatible) ---
|
|
236
271
|
final_payload = __assign(__assign(__assign({}, core_data), analytics_data), (userId && { user_id: userId }));
|
|
237
272
|
}
|
|
238
|
-
if (navigator.onLine && _rudderstack) {
|
|
273
|
+
if (navigator.onLine && (_rudderstack || _posthog)) {
|
|
239
274
|
if (event_cache.length > 0) {
|
|
240
275
|
event_cache.forEach(function (cache, index) {
|
|
241
|
-
|
|
276
|
+
// Send cached events to both providers
|
|
277
|
+
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(cache.event, cache.payload);
|
|
278
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.track(cache.event, cache.payload);
|
|
242
279
|
delete event_cache[index];
|
|
243
280
|
});
|
|
244
281
|
}
|
|
245
282
|
if (event in tracking_config) {
|
|
246
|
-
tracking_config[event]
|
|
283
|
+
if (tracking_config[event]) {
|
|
284
|
+
// Send to both RudderStack and PostHog
|
|
285
|
+
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(event, final_payload);
|
|
286
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.track(event, final_payload);
|
|
287
|
+
}
|
|
247
288
|
}
|
|
248
289
|
else {
|
|
290
|
+
// Send to both RudderStack and PostHog
|
|
249
291
|
_rudderstack === null || _rudderstack === void 0 ? void 0 : _rudderstack.track(event, final_payload);
|
|
292
|
+
_posthog === null || _posthog === void 0 ? void 0 : _posthog.track(event, final_payload);
|
|
250
293
|
}
|
|
251
294
|
}
|
|
252
295
|
else {
|
|
253
296
|
event_cache.push({ event: event, payload: final_payload });
|
|
254
297
|
}
|
|
255
298
|
};
|
|
256
|
-
var getInstances = function () { return ({ ab: _growthbook, tracking: _rudderstack }); };
|
|
299
|
+
var getInstances = function () { return ({ ab: _growthbook, tracking: _rudderstack, posthog: _posthog }); };
|
|
257
300
|
var AnalyticsInstance = {
|
|
258
301
|
initialise: initialise,
|
|
259
302
|
setAttributes: setAttributes,
|
package/lib/posthog.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { PostHogConfig as PostHogInitConfig } from 'posthog-js';
|
|
2
|
+
import { TCoreAttributes, TAllEvents } from './types';
|
|
3
|
+
export type PostHogConfig = Omit<Partial<PostHogInitConfig>, 'api_host' | 'ui_host' | 'bootstrap' | 'loaded'> & {
|
|
4
|
+
capture_pageview?: boolean;
|
|
5
|
+
capture_pageleave?: boolean;
|
|
6
|
+
autocapture?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export declare class PostHogAnalytics {
|
|
9
|
+
has_identified: boolean;
|
|
10
|
+
has_initialized: boolean;
|
|
11
|
+
current_page: string;
|
|
12
|
+
rudderstack_anonymous_cookie_key: string;
|
|
13
|
+
private static _instance;
|
|
14
|
+
private onLoadedCallback?;
|
|
15
|
+
constructor(POSTHOG_KEY: string, POSTHOG_HOST?: string, disableAMD?: boolean, onLoaded?: () => void, config?: PostHogConfig);
|
|
16
|
+
static getPostHogInstance: (POSTHOG_KEY: string, POSTHOG_HOST?: string, disableAMD?: boolean, onLoaded?: () => void, config?: PostHogConfig) => PostHogAnalytics;
|
|
17
|
+
getAnonymousId: () => string | undefined;
|
|
18
|
+
setCookieIfNotExists: () => void;
|
|
19
|
+
/**
|
|
20
|
+
* @returns The user ID that was assigned to the user after calling identify event
|
|
21
|
+
*/
|
|
22
|
+
getUserId: () => string;
|
|
23
|
+
/** For caching mechanism, PostHog SDK, first page load */
|
|
24
|
+
handleCachedEvents: () => void;
|
|
25
|
+
/**
|
|
26
|
+
* Transform V2 event payload to PostHog flat structure
|
|
27
|
+
*/
|
|
28
|
+
private transformToPostHogPayload;
|
|
29
|
+
/**
|
|
30
|
+
* Initializes the PostHog SDK using proxy endpoint.
|
|
31
|
+
* For local/staging environment, ensure that `POSTHOG_STAGING_KEY` is set.
|
|
32
|
+
* For production environment, ensure that `POSTHOG_PRODUCTION_KEY` is set.
|
|
33
|
+
*
|
|
34
|
+
* Proxy Setup:
|
|
35
|
+
* - Using https://ph.deriv.com as proxy endpoint (same for staging and production)
|
|
36
|
+
* - Proxy forwards requests to PostHog Cloud
|
|
37
|
+
* - X-headers are configured on the proxy server (not client-side)
|
|
38
|
+
* - See: https://posthog.com/docs/advanced/proxy
|
|
39
|
+
*/
|
|
40
|
+
init: (POSTHOG_KEY: string, POSTHOG_HOST?: string, disableAMD?: boolean, config?: PostHogConfig) => void;
|
|
41
|
+
/**
|
|
42
|
+
*
|
|
43
|
+
* @param user_id The user ID of the user to identify and associate all events with that particular user ID
|
|
44
|
+
* @param payload Additional information passed to identify the user
|
|
45
|
+
*/
|
|
46
|
+
identifyEvent: (user_id: string, payload: {
|
|
47
|
+
language: string;
|
|
48
|
+
}) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Pushes page view event to PostHog
|
|
51
|
+
*
|
|
52
|
+
* @param current_page The name or URL of the current page to track the page view event
|
|
53
|
+
*/
|
|
54
|
+
pageView: (current_page: string, platform: string | undefined, user_id: string, properties?: {}) => void;
|
|
55
|
+
/**
|
|
56
|
+
* Pushes reset event to PostHog
|
|
57
|
+
*/
|
|
58
|
+
reset: () => void;
|
|
59
|
+
/**
|
|
60
|
+
* Pushes track events to PostHog with automatic payload transformation
|
|
61
|
+
*/
|
|
62
|
+
track: <T extends keyof import("./types").TEvents | "ce_get_start_page">(event: T, payload: TAllEvents[T] & Partial<TCoreAttributes>) => void;
|
|
63
|
+
}
|
package/lib/posthog.js
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.PostHogAnalytics = void 0;
|
|
18
|
+
var posthog_js_1 = __importDefault(require("posthog-js"));
|
|
19
|
+
var uuid_1 = require("uuid");
|
|
20
|
+
var js_cookie_1 = __importDefault(require("js-cookie"));
|
|
21
|
+
var PostHogAnalytics = /** @class */ (function () {
|
|
22
|
+
function PostHogAnalytics(POSTHOG_KEY, POSTHOG_HOST, disableAMD, onLoaded, config) {
|
|
23
|
+
if (disableAMD === void 0) { disableAMD = false; }
|
|
24
|
+
var _this = this;
|
|
25
|
+
this.has_identified = false;
|
|
26
|
+
this.has_initialized = false;
|
|
27
|
+
this.current_page = '';
|
|
28
|
+
// Share the same anonymous ID cookie with RudderStack
|
|
29
|
+
this.rudderstack_anonymous_cookie_key = 'rudder_anonymous_id';
|
|
30
|
+
this.getAnonymousId = function () {
|
|
31
|
+
var _a;
|
|
32
|
+
return (_a = document.cookie.match('(^|;)\\s*' + _this.rudderstack_anonymous_cookie_key + '\\s*=\\s*([^;]+)')) === null || _a === void 0 ? void 0 : _a.pop();
|
|
33
|
+
};
|
|
34
|
+
this.setCookieIfNotExists = function () {
|
|
35
|
+
var anonymous_id = _this.getAnonymousId();
|
|
36
|
+
if (!anonymous_id) {
|
|
37
|
+
var hostname_1 = window.location.hostname;
|
|
38
|
+
// List of external domains where we should use the full hostname
|
|
39
|
+
var external_domains = ['webflow.io'];
|
|
40
|
+
// Check if the hostname ends with any of the external domains
|
|
41
|
+
var is_external_domain = external_domains.some(function (domain) { return hostname_1.endsWith(domain); });
|
|
42
|
+
// If it's an external domain, use the full hostname, otherwise use the last two parts
|
|
43
|
+
var domain_name = is_external_domain ? hostname_1 : hostname_1.split('.').slice(-2).join('.');
|
|
44
|
+
// Set cookie to expire in 2 years
|
|
45
|
+
document.cookie = "".concat(_this.rudderstack_anonymous_cookie_key, "=").concat((0, uuid_1.v6)(), "; path=/; Domain=").concat(domain_name, "; max-age=").concat(2 * 365 * 24 * 60 * 60);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* @returns The user ID that was assigned to the user after calling identify event
|
|
50
|
+
*/
|
|
51
|
+
this.getUserId = function () { return posthog_js_1.default.get_distinct_id(); };
|
|
52
|
+
/** For caching mechanism, PostHog SDK, first page load */
|
|
53
|
+
this.handleCachedEvents = function () {
|
|
54
|
+
var allowedDomains = ['deriv.com', 'deriv.team', 'deriv.ae'];
|
|
55
|
+
var domain = allowedDomains.some(function (d) { return window.location.hostname.includes(d); })
|
|
56
|
+
? ".".concat(allowedDomains.find(function (d) { return window.location.hostname.includes(d); }))
|
|
57
|
+
: ".".concat(allowedDomains[0]);
|
|
58
|
+
var storedEventsString = js_cookie_1.default.get('cached_analytics_events');
|
|
59
|
+
var storedPagesString = js_cookie_1.default.get('cached_analytics_page_views');
|
|
60
|
+
try {
|
|
61
|
+
// Handle cached analytics events
|
|
62
|
+
if (storedEventsString) {
|
|
63
|
+
var storedEvents = JSON.parse(storedEventsString);
|
|
64
|
+
if (Array.isArray(storedEvents) && storedEvents.length > 0) {
|
|
65
|
+
storedEvents.forEach(function (event) {
|
|
66
|
+
posthog_js_1.default.capture(event.name, event.properties);
|
|
67
|
+
});
|
|
68
|
+
// Clear the stored events cookie
|
|
69
|
+
js_cookie_1.default.remove('cached_analytics_events', { domain: domain });
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Handle cached page views
|
|
73
|
+
if (storedPagesString) {
|
|
74
|
+
var storedPages = JSON.parse(storedPagesString);
|
|
75
|
+
if (Array.isArray(storedPages) && storedPages.length > 0) {
|
|
76
|
+
storedPages.forEach(function (page) {
|
|
77
|
+
posthog_js_1.default.capture('$pageview', __assign({ $current_url: window.location.href, page_name: page === null || page === void 0 ? void 0 : page.name }, page === null || page === void 0 ? void 0 : page.properties));
|
|
78
|
+
});
|
|
79
|
+
// Clear the stored page views cookie
|
|
80
|
+
js_cookie_1.default.remove('cached_analytics_page_views', { domain: domain });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
// eslint-disable-next-line no-console
|
|
86
|
+
console.log(error);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Transform V2 event payload to PostHog flat structure
|
|
91
|
+
*/
|
|
92
|
+
this.transformToPostHogPayload = function (payload) {
|
|
93
|
+
var transformed = {};
|
|
94
|
+
// Flatten event_metadata
|
|
95
|
+
if (payload.event_metadata) {
|
|
96
|
+
Object.keys(payload.event_metadata).forEach(function (key) {
|
|
97
|
+
// Handle nested marketing_data within event_metadata
|
|
98
|
+
if (key === 'marketing_data' && typeof payload.event_metadata[key] === 'object') {
|
|
99
|
+
var marketingData_1 = payload.event_metadata[key];
|
|
100
|
+
Object.keys(marketingData_1).forEach(function (marketingKey) {
|
|
101
|
+
// Flatten utm_data within marketing_data
|
|
102
|
+
if (marketingKey === 'utm_data') {
|
|
103
|
+
try {
|
|
104
|
+
// Parse utm_data if it's a JSON string
|
|
105
|
+
var utmData_1 = typeof marketingData_1[marketingKey] === 'string'
|
|
106
|
+
? JSON.parse(marketingData_1[marketingKey])
|
|
107
|
+
: marketingData_1[marketingKey];
|
|
108
|
+
// Flatten utm_data properties to root level
|
|
109
|
+
if (typeof utmData_1 === 'object' && utmData_1 !== null) {
|
|
110
|
+
Object.keys(utmData_1).forEach(function (utmKey) {
|
|
111
|
+
transformed[utmKey] = utmData_1[utmKey];
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
// If parsing fails, add the raw value
|
|
117
|
+
console.error('Failed to parse utm_data:', error);
|
|
118
|
+
transformed[marketingKey] = marketingData_1[marketingKey];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// Add other marketing_data properties directly
|
|
123
|
+
transformed[marketingKey] = marketingData_1[marketingKey];
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
transformed[key] = payload.event_metadata[key];
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
// Flatten cta_information
|
|
133
|
+
if (payload.cta_information) {
|
|
134
|
+
Object.keys(payload.cta_information).forEach(function (key) {
|
|
135
|
+
transformed[key] = payload.cta_information[key];
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
// Flatten error
|
|
139
|
+
if (payload.error) {
|
|
140
|
+
Object.keys(payload.error).forEach(function (key) {
|
|
141
|
+
transformed[key] = payload.error[key];
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// Add top-level properties (excluding nested objects)
|
|
145
|
+
Object.keys(payload).forEach(function (key) {
|
|
146
|
+
if (!['event_metadata', 'cta_information', 'error'].includes(key)) {
|
|
147
|
+
transformed[key] = payload[key];
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
return transformed;
|
|
151
|
+
};
|
|
152
|
+
/**
|
|
153
|
+
* Initializes the PostHog SDK using proxy endpoint.
|
|
154
|
+
* For local/staging environment, ensure that `POSTHOG_STAGING_KEY` is set.
|
|
155
|
+
* For production environment, ensure that `POSTHOG_PRODUCTION_KEY` is set.
|
|
156
|
+
*
|
|
157
|
+
* Proxy Setup:
|
|
158
|
+
* - Using https://ph.deriv.com as proxy endpoint (same for staging and production)
|
|
159
|
+
* - Proxy forwards requests to PostHog Cloud
|
|
160
|
+
* - X-headers are configured on the proxy server (not client-side)
|
|
161
|
+
* - See: https://posthog.com/docs/advanced/proxy
|
|
162
|
+
*/
|
|
163
|
+
this.init = function (POSTHOG_KEY, POSTHOG_HOST, disableAMD, config) {
|
|
164
|
+
if (disableAMD === void 0) { disableAMD = false; }
|
|
165
|
+
if (POSTHOG_KEY) {
|
|
166
|
+
var _define_1;
|
|
167
|
+
if (disableAMD) {
|
|
168
|
+
_define_1 = window.define;
|
|
169
|
+
window.define = undefined;
|
|
170
|
+
}
|
|
171
|
+
_this.setCookieIfNotExists();
|
|
172
|
+
// Get the shared anonymous ID from cookie
|
|
173
|
+
var anonymous_id_1 = _this.getAnonymousId();
|
|
174
|
+
posthog_js_1.default.init(POSTHOG_KEY, __assign(__assign({
|
|
175
|
+
// Use proxy endpoint for both staging and production
|
|
176
|
+
// Default to https://ph.deriv.com, can be overridden via POSTHOG_HOST parameter
|
|
177
|
+
api_host: POSTHOG_HOST || 'https://ph.deriv.com',
|
|
178
|
+
// UI host should point to PostHog Cloud for dashboard links
|
|
179
|
+
ui_host: 'https://us.posthog.com',
|
|
180
|
+
// Use the same anonymous ID as RudderStack
|
|
181
|
+
bootstrap: {
|
|
182
|
+
distinctID: anonymous_id_1,
|
|
183
|
+
},
|
|
184
|
+
// Default configurations
|
|
185
|
+
capture_pageview: false, capture_pageleave: false, autocapture: true }, config), { loaded: function (ph) {
|
|
186
|
+
var _a;
|
|
187
|
+
if (disableAMD) {
|
|
188
|
+
window.define = _define_1;
|
|
189
|
+
}
|
|
190
|
+
_this.has_initialized = true;
|
|
191
|
+
// Check if user is already identified
|
|
192
|
+
_this.has_identified = posthog_js_1.default.get_distinct_id() !== anonymous_id_1;
|
|
193
|
+
_this.handleCachedEvents();
|
|
194
|
+
(_a = _this.onLoadedCallback) === null || _a === void 0 ? void 0 : _a.call(_this);
|
|
195
|
+
} }));
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
/**
|
|
199
|
+
*
|
|
200
|
+
* @param user_id The user ID of the user to identify and associate all events with that particular user ID
|
|
201
|
+
* @param payload Additional information passed to identify the user
|
|
202
|
+
*/
|
|
203
|
+
this.identifyEvent = function (user_id, payload) {
|
|
204
|
+
var currentUserId = _this.getUserId();
|
|
205
|
+
var anonymousId = _this.getAnonymousId();
|
|
206
|
+
// Only identify if not already identified or if it's still using anonymous ID
|
|
207
|
+
if (!currentUserId || currentUserId === anonymousId) {
|
|
208
|
+
// CRITICAL: Use alias to link anonymous ID with user ID before identifying
|
|
209
|
+
// This preserves the pre-signup journey in PostHog
|
|
210
|
+
if (anonymousId && currentUserId === anonymousId) {
|
|
211
|
+
posthog_js_1.default.alias(user_id, anonymousId);
|
|
212
|
+
}
|
|
213
|
+
posthog_js_1.default.identify(user_id, payload);
|
|
214
|
+
}
|
|
215
|
+
_this.has_identified = true;
|
|
216
|
+
};
|
|
217
|
+
/**
|
|
218
|
+
* Pushes page view event to PostHog
|
|
219
|
+
*
|
|
220
|
+
* @param current_page The name or URL of the current page to track the page view event
|
|
221
|
+
*/
|
|
222
|
+
this.pageView = function (current_page, platform, user_id, properties) {
|
|
223
|
+
if (platform === void 0) { platform = 'Deriv App'; }
|
|
224
|
+
if (_this.has_initialized && current_page !== _this.current_page) {
|
|
225
|
+
var pageProperties = user_id ? __assign({ user_id: user_id, platform: platform }, properties) : __assign({ platform: platform }, properties);
|
|
226
|
+
posthog_js_1.default.capture('$pageview', __assign({ $current_url: window.location.href, page_name: current_page }, pageProperties));
|
|
227
|
+
_this.current_page = current_page;
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* Pushes reset event to PostHog
|
|
232
|
+
*/
|
|
233
|
+
this.reset = function () {
|
|
234
|
+
if (_this.has_initialized) {
|
|
235
|
+
posthog_js_1.default.reset();
|
|
236
|
+
_this.has_identified = false;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
/**
|
|
240
|
+
* Pushes track events to PostHog with automatic payload transformation
|
|
241
|
+
*/
|
|
242
|
+
this.track = function (event, payload) {
|
|
243
|
+
if (_this.has_initialized) {
|
|
244
|
+
try {
|
|
245
|
+
// Transform payload to flat structure for PostHog
|
|
246
|
+
var transformedPayload = _this.transformToPostHogPayload(payload);
|
|
247
|
+
// Clean undefined values
|
|
248
|
+
var clean_payload = Object.fromEntries(Object.entries(transformedPayload).filter(function (_a) {
|
|
249
|
+
var _ = _a[0], value = _a[1];
|
|
250
|
+
return value !== undefined;
|
|
251
|
+
}));
|
|
252
|
+
posthog_js_1.default.capture(event, clean_payload);
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
console.error(err);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
this.onLoadedCallback = onLoaded;
|
|
260
|
+
this.init(POSTHOG_KEY, POSTHOG_HOST, disableAMD, config);
|
|
261
|
+
}
|
|
262
|
+
PostHogAnalytics.getPostHogInstance = function (POSTHOG_KEY, POSTHOG_HOST, disableAMD, onLoaded, config) {
|
|
263
|
+
if (disableAMD === void 0) { disableAMD = false; }
|
|
264
|
+
if (!PostHogAnalytics._instance) {
|
|
265
|
+
PostHogAnalytics._instance = new PostHogAnalytics(POSTHOG_KEY, POSTHOG_HOST, disableAMD, onLoaded, config);
|
|
266
|
+
return PostHogAnalytics._instance;
|
|
267
|
+
}
|
|
268
|
+
return PostHogAnalytics._instance;
|
|
269
|
+
};
|
|
270
|
+
return PostHogAnalytics;
|
|
271
|
+
}());
|
|
272
|
+
exports.PostHogAnalytics = PostHogAnalytics;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deriv-com/analytics",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0",
|
|
4
4
|
"description": "The analytics package contains all the utility functions used for tracking user events and sending them to the respective platform such as Rudderstack.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rudderstack",
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"@growthbook/growthbook": "^1.1.0",
|
|
57
57
|
"@rudderstack/analytics-js": "^3.5.1",
|
|
58
58
|
"js-cookie": "^3.0.5",
|
|
59
|
+
"posthog-js": "^1.313.0",
|
|
59
60
|
"uuid": "^10.0.0"
|
|
60
61
|
},
|
|
61
62
|
"engines": {
|