@ezbot-ai/javascript-sdk
Version:
The easiest way to interact with ezbot via JS (node and browser)
278 lines • 22.1 kB
JavaScript
;
/* eslint-disable functional/immutable-data */
Object.defineProperty(exports, "__esModule", { value: true });
exports.setUserIdFromCookie = exports.setUserId = exports.trackPageView = exports.trackLinkClick = exports.startActivityTracking = exports.makeVisualChanges = exports.makeVisualChange = exports.initEzbotWithServerSidePredictions = exports.initEzbot = exports.trackRewardEvent = void 0;
/*
* This package uses source code from Snowplow Analytics Ltd
* Copyright (c) 2022 Snowplow Analytics Ltd, 2010 Anthon Pang
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
const browser_plugin_button_click_tracking_1 = require("@snowplow/browser-plugin-button-click-tracking");
const browser_plugin_link_click_tracking_1 = require("@snowplow/browser-plugin-link-click-tracking");
const browser_tracker_1 = require("@snowplow/browser-tracker");
const constants_1 = require("./constants");
const predictions_1 = require("./predictions");
const tracking_1 = require("./tracking");
Object.defineProperty(exports, "setUserId", { enumerable: true, get: function () { return tracking_1.setUserId; } });
Object.defineProperty(exports, "setUserIdFromCookie", { enumerable: true, get: function () { return tracking_1.setUserIdFromCookie; } });
Object.defineProperty(exports, "startActivityTracking", { enumerable: true, get: function () { return tracking_1.startActivityTracking; } });
Object.defineProperty(exports, "trackLinkClick", { enumerable: true, get: function () { return tracking_1.trackLinkClick; } });
Object.defineProperty(exports, "trackPageView", { enumerable: true, get: function () { return tracking_1.trackPageView; } });
Object.defineProperty(exports, "trackRewardEvent", { enumerable: true, get: function () { return tracking_1.trackRewardEvent; } });
const crossDomainLinker_1 = require("./utils/crossDomainLinker");
const visualChanges_1 = require("./visualChanges");
Object.defineProperty(exports, "makeVisualChange", { enumerable: true, get: function () { return visualChanges_1.makeVisualChange; } });
Object.defineProperty(exports, "makeVisualChanges", { enumerable: true, get: function () { return visualChanges_1.makeVisualChanges; } });
const ezbotTrackerId = 'ezbot';
async function initEzbot(projectId, userId, _config = constants_1.defaultWebConfiguration) {
var _a, _b;
const existingTracker = (_a = window.ezbot) === null || _a === void 0 ? void 0 : _a.tracker;
if (existingTracker) {
existingTracker.setUserId(userId);
return existingTracker;
}
// Prepare tracker configuration
const trackerConfig = {
appId: projectId.toString(),
plugins: constants_1.plugins,
stateStorageStrategy: 'localStorage',
discoverRootDomain: true,
};
// Handle cross-domain tracking if enabled
if ((_b = _config === null || _config === void 0 ? void 0 : _config.crossDomain) === null || _b === void 0 ? void 0 : _b.enabled) {
if (!(_config === null || _config === void 0 ? void 0 : _config.crossDomain.domains.length)) {
throw new Error('Cross-domain tracking enabled but no domains provided');
}
const extendedCrossDomainLinkerOptions = {
userId: true,
sessionId: true,
};
trackerConfig.useExtendedCrossDomainLinker =
extendedCrossDomainLinkerOptions;
const crossDomainLinkerFunction = (0, crossDomainLinker_1.createCrossDomainLinkChecker)(_config.crossDomain.domains);
trackerConfig.crossDomainLinker = crossDomainLinkerFunction;
}
const tracker = (0, browser_tracker_1.newTracker)(ezbotTrackerId, (0, constants_1.ezbotTrackerDomain)(projectId), trackerConfig);
if (!tracker) {
throw new Error('Failed to initialize tracker');
}
if (userId) {
tracker.setUserId(userId);
}
tracker.setUserIdFromReferrer('_sp');
const domainUserInfo = tracker.getDomainUserInfo();
// eslint-disable-next-line functional/no-let
let sessionId = domainUserInfo[6];
// TODO: this should happen automatically somehow
if (window.location.href.includes('_sp=')) {
// get sessionId for cross-domain linking
const urlParams = new URLSearchParams(window.location.search);
const snowPlowParams = urlParams.get('_sp');
if (snowPlowParams != null) {
sessionId = snowPlowParams.split('.')[2];
}
}
// eslint-disable-next-line functional/no-let
let predictions = [];
try {
predictions = await (0, predictions_1.getPredictions)(projectId, sessionId, tracker);
}
catch (error) {
if (error && typeof error === 'object' && 'name' in error && error.name === 'EzbotPaymentError') {
const paymentError = error;
// Payment or subscription issue - disable the SDK
console.error('SDK disabled due to payment/subscription issue:', paymentError.message);
window.ezbot = {
trackerConfig: trackerConfig,
userId: userId,
tracker: tracker,
predictions: [],
sessionId: sessionId,
disabled: true,
disabledReason: paymentError.message,
trackPageView: () => {
console.warn('Ezbot SDK is disabled due to payment/subscription issue');
return undefined;
},
trackRewardEvent: () => {
console.warn('Ezbot SDK is disabled due to payment/subscription issue');
return undefined;
},
startActivityTracking: () => {
console.warn('Ezbot SDK is disabled due to payment/subscription issue');
return undefined;
},
setUserId: () => {
console.warn('Ezbot SDK is disabled due to payment/subscription issue');
return undefined;
},
setUserIdFromCookie: () => {
console.warn('Ezbot SDK is disabled due to payment/subscription issue');
return undefined;
},
makeVisualChanges: () => {
console.warn('Ezbot SDK is disabled due to payment/subscription issue');
return undefined;
},
utils: {
visual: visualChanges_1.visualUtils,
},
actions: {
visual: visualChanges_1.visualChanges,
},
intervals: [],
mode: 'ezbot',
};
throw error; // Re-throw to let the caller know the SDK is disabled
}
console.error('Failed to get predictions', error);
}
const predictionsContext = {
schema: constants_1.ezbotPredictionsContextSchemaPath,
data: {
predictions: predictions.map((pred) => ({
variable: pred.key,
value: pred.value,
})),
},
};
(0, browser_tracker_1.addGlobalContexts)([predictionsContext], [tracker.id]);
window.ezbot = {
trackerConfig: trackerConfig,
userId: userId,
tracker: tracker,
predictions: [...predictions],
sessionId: sessionId,
trackPageView: tracking_1.trackPageView, // only send to ezbot tracker
trackRewardEvent: tracking_1.trackRewardEvent,
startActivityTracking: tracking_1.startActivityTracking,
makeVisualChanges: visualChanges_1.makeVisualChanges,
setUserId: tracking_1.setUserId,
setUserIdFromCookie: tracking_1.setUserIdFromCookie,
utils: {
visual: visualChanges_1.visualUtils,
},
actions: {
visual: visualChanges_1.visualChanges,
},
intervals: [],
mode: 'ezbot',
};
try {
(0, browser_plugin_link_click_tracking_1.enableLinkClickTracking)();
(0, browser_plugin_button_click_tracking_1.enableButtonClickTracking)();
}
catch (error) {
console.error('Failed to enable click tracking', error);
}
return tracker;
}
exports.initEzbot = initEzbot;
async function initEzbotWithServerSidePredictions(projectId, predictions, userId, _config = constants_1.defaultWebConfiguration) {
var _a, _b;
const existingTracker = (_a = window.ezbot) === null || _a === void 0 ? void 0 : _a.tracker;
if (existingTracker) {
existingTracker.setUserId(userId);
return existingTracker;
}
// Prepare tracker configuration
const trackerConfig = {
appId: projectId.toString(),
plugins: constants_1.plugins,
stateStorageStrategy: 'localStorage',
discoverRootDomain: true,
};
// Handle cross-domain tracking if enabled
if ((_b = _config === null || _config === void 0 ? void 0 : _config.crossDomain) === null || _b === void 0 ? void 0 : _b.enabled) {
if (!(_config === null || _config === void 0 ? void 0 : _config.crossDomain.domains.length)) {
throw new Error('Cross-domain tracking enabled but no domains provided');
}
const extendedCrossDomainLinkerOptions = {
userId: true,
sessionId: true,
};
trackerConfig.useExtendedCrossDomainLinker =
extendedCrossDomainLinkerOptions;
const crossDomainLinkerFunction = (0, crossDomainLinker_1.createCrossDomainLinkChecker)(_config.crossDomain.domains);
trackerConfig.crossDomainLinker = crossDomainLinkerFunction;
}
const tracker = (0, browser_tracker_1.newTracker)(ezbotTrackerId, (0, constants_1.ezbotTrackerDomain)(projectId), trackerConfig);
if (!tracker) {
throw new Error('Failed to initialize tracker');
}
if (userId) {
tracker.setUserId(userId);
}
tracker.setUserIdFromReferrer('_sp');
const domainUserInfo = tracker.getDomainUserInfo();
const sessionId = domainUserInfo[6];
// Use provided predictions instead of fetching them
const predictionsContext = {
schema: constants_1.ezbotPredictionsContextSchemaPath,
data: {
predictions: predictions.map((pred) => ({
variable: pred.key,
value: pred.value,
})),
},
};
(0, browser_tracker_1.addGlobalContexts)([predictionsContext], [tracker.id]);
window.ezbot = {
trackerConfig: trackerConfig,
userId: userId,
tracker: tracker,
predictions: [...predictions],
sessionId: sessionId,
disabled: false,
disabledReason: undefined,
trackPageView: tracking_1.trackPageView, // only send to ezbot tracker
trackRewardEvent: tracking_1.trackRewardEvent,
startActivityTracking: tracking_1.startActivityTracking,
makeVisualChanges: visualChanges_1.makeVisualChanges,
setUserId: tracking_1.setUserId,
setUserIdFromCookie: tracking_1.setUserIdFromCookie,
utils: {
visual: visualChanges_1.visualUtils,
},
actions: {
visual: visualChanges_1.visualChanges,
},
intervals: [],
mode: 'ezbot',
};
try {
(0, browser_plugin_link_click_tracking_1.enableLinkClickTracking)();
(0, browser_plugin_button_click_tracking_1.enableButtonClickTracking)();
}
catch (error) {
console.error('Failed to enable click tracking', error);
}
return tracker;
}
exports.initEzbotWithServerSidePredictions = initEzbotWithServerSidePredictions;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXpib3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2V6Ym90LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSw4Q0FBOEM7OztBQUU5Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFFSCx5R0FBMkY7QUFDM0YscUdBQXVGO0FBQ3ZGLCtEQU1tQztBQUVuQywyQ0FLcUI7QUFDckIsK0NBQStDO0FBQy9DLHlDQU9vQjtBQXFTbEIsMEZBM1NBLG9CQUFTLE9BMlNBO0FBQ1Qsb0dBM1NBLDhCQUFtQixPQTJTQTtBQUpuQixzR0F0U0EsZ0NBQXFCLE9Bc1NBO0FBQ3JCLCtGQXRTQSx5QkFBYyxPQXNTQTtBQUNkLDhGQXRTQSx3QkFBYSxPQXNTQTtBQVBiLGlHQTlSQSwyQkFBZ0IsT0E4UkE7QUFoUmxCLGlFQUF5RTtBQUN6RSxtREFLeUI7QUE2UXZCLGlHQWpSQSxnQ0FBZ0IsT0FpUkE7QUFDaEIsa0dBalJBLGlDQUFpQixPQWlSQTtBQTVRbkIsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDO0FBRS9CLEtBQUssVUFBVSxTQUFTLENBQ3RCLFNBQWlCLEVBQ2pCLE1BQXNCLEVBQ3RCLFVBQThCLG1DQUE2Qzs7SUFFM0UsTUFBTSxlQUFlLEdBQUcsTUFBQSxNQUFNLENBQUMsS0FBSywwQ0FBRSxPQUFPLENBQUM7SUFDOUMsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNwQixlQUFlLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xDLE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxnQ0FBZ0M7SUFDaEMsTUFBTSxhQUFhLEdBQXlCO1FBQzFDLEtBQUssRUFBRSxTQUFTLENBQUMsUUFBUSxFQUFFO1FBQzNCLE9BQU8sRUFBRSxtQkFBTztRQUNoQixvQkFBb0IsRUFBRSxjQUFjO1FBQ3BDLGtCQUFrQixFQUFFLElBQUk7S0FDekIsQ0FBQztJQUVGLDBDQUEwQztJQUMxQyxJQUFJLE1B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