UNPKG

@swrve/smarttv-sdk

Version:

Swrve marketing engagement platform SDK for SmartTV OTT devices

1,057 lines 50.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.SwrveInternal = void 0; const EventFactory_1 = require("./Events/EventFactory"); const ProfileManager_1 = require("./Profile/ProfileManager"); const PAL_1 = __importDefault(require("./utils/PAL")); const CampaignManager_1 = require("./Campaigns/CampaignManager"); const IPlatform_1 = require("./utils/platforms/IPlatform"); const ResourceManagerInternal_1 = require("./Resources/ResourceManagerInternal"); const SwrveConstants = __importStar(require("./utils/SwrveConstants")); const StorageManager_1 = require("./Storage/StorageManager"); const ISwrveInternalConfig_1 = require("./Config/ISwrveInternalConfig"); const SwrveLogger_1 = __importDefault(require("./utils/SwrveLogger")); const EventManager_1 = require("./Events/EventManager"); const SwrveRestClient_1 = require("./RestClient/SwrveRestClient"); const ISwrveConfig_1 = require("./Config/ISwrveConfig"); const DeviceProperties_1 = require("./utils/DeviceProperties"); const DateHelper_1 = __importDefault(require("./utils/DateHelper")); const TimeHelper_1 = require("./utils/TimeHelper"); const SwrveConstants_1 = require("./utils/SwrveConstants"); const TextTemplating_1 = require("./utils/TextTemplating"); const RealTimeUserPropertiesManager_1 = require("./UserProperties/RealTimeUserPropertiesManager"); const DictionaryHelper_1 = require("./utils/DictionaryHelper"); const uuid_1 = require("./utils/uuid"); class SwrveInternal { constructor(config, dependencies) { this.onResourcesLoadedCallback = null; this.onCampaignLoadedCallback = null; this.onCustomButtonClickedCallback = null; this.onIAMDismissedCallback = null; this.onIAMShownCallback = null; this.eventLoopTimer = 0; this.flushFrequency = 0; this._shutdown = false; this.autoShowEnabled = true; this.pauseSDK = false; this.installDate = ""; this.identifiedOnAnotherDevice = false; this.refreshAssets = true; dependencies = dependencies || {}; this.platform = config.customPlatform || dependencies.platform || PAL_1.default.getPlatform(config); if (PAL_1.default.platform !== undefined) { //in case it was custom, set the static instance in PAl, as asset /campaign /storage managers reference it. PAL_1.default.platform = this.platform; } this.loadInstallDate(); let lastUserId = StorageManager_1.StorageManager.getData(SwrveConstants.SWRVE_USER_ID); SwrveLogger_1.default.debug(`last user ID: ${lastUserId}`); if (lastUserId === null) { lastUserId = uuid_1.generateUuid().toString(); } this.config = ISwrveConfig_1.configWithDefaults(config, lastUserId); ISwrveInternalConfig_1.validateConfig(this.config); this.resourceManager = new ResourceManagerInternal_1.ResourceManagerInternal(); this.profileManager = dependencies.profileManager || new ProfileManager_1.ProfileManager(this.config.userId, this.config.appId, this.config.apiKey, this.config.newSessionInterval); this.realTimeUserPropertiesManager = new RealTimeUserPropertiesManager_1.RealTimeUserPropertiesManager(this.profileManager); this.campaignManager = dependencies.campaignManager || new CampaignManager_1.CampaignManager(this.profileManager, this.platform, this.config, this.getResourceManager()); this.campaignManager.onPageViewed((messageId, pageId, pageName) => { this.handlePageViewed(messageId, pageId, pageName); }); this.campaignManager.onButtonClicked((button, campaign, pageId, pageName) => { this.handleButtonClicked(button, campaign, pageId, pageName); }); this.campaignManager.onBackButtonClicked(() => { if (this.onIAMDismissedCallback) { this.onIAMDismissedCallback(); } }); this.restClient = dependencies.restClient || new SwrveRestClient_1.SwrveRestClient(this.config, this.profileManager, this.platform); this.evtManager = dependencies.eventManager || new EventManager_1.EventManager(this.restClient); this.eventFactory = new EventFactory_1.EventFactory(); if (this.config.embeddedMessageConfig && this.config.embeddedMessageConfig.embeddedCallback) { if (typeof this.config.embeddedMessageConfig.embeddedCallback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onEmbeddedMessage")); } this.campaignManager.onEmbeddedMessage(this.config.embeddedMessageConfig.embeddedCallback); } } init() { ProfileManager_1.ProfileManager.storeUserId(this.config.userId); window.onbeforeunload = () => { this.pageStateHandler(); this.shutdown(); }; window.onblur = () => { this.pageStateHandler(); }; this.platform.init(["language", "countryCode", "timezone", "firmware", "deviceHeight", "deviceWidth"]) .then(() => { if (!this._shutdown) { this.queueDeviceProperties(); } }); if (this.isIdentifyCallPending()) { const externalId = StorageManager_1.StorageManager.getData(SwrveConstants.IDENTIFY_CALL_PENDING_EXTERNAL_ID); const swrveId = StorageManager_1.StorageManager.getData(SwrveConstants.IDENTIFY_CALL_PENDING); this.makeIdentityCall(externalId, this.profileManager.currentUser.userId, swrveId, () => { }, () => this.initSDK()); } else if (this.config.managedMode) { SwrveLogger_1.default.debug("SwrveSDK: This application has started Swrve in MANAGED mode. Call start() to begin tracking"); this.stop(); } else { this.initSDK(); } } getConfig() { return this.config; } getUserInfo() { const { userId, firstUse, sessionStart, isQAUser } = this.profileManager.currentUser; return { userId, firstUse, sessionStart, isQAUser }; } getMessageCenterCampaigns(personalizationProperties) { if (personalizationProperties) { return this.campaignManager.getMessageCenterCampaigns(personalizationProperties); } else { return this.campaignManager.getMessageCenterCampaigns(); } } getPlatform() { return this.platform; } //******************************************** Embedded Campaigns ********************************************/ embeddedMessageWasShownToUser(message) { this.campaignManager.updateCampaignState(message); this.queueMessageImpressionEvent(message.id, { embedded: "true" }); } embeddedMessageButtonWasPressed(message, buttonName) { const nextSeqNum = this.profileManager.getNextSequenceNumber(); const evt = this.eventFactory.getButtonClickEvent(nextSeqNum, message.id, buttonName, "true", this.platform.os, 0, "", ""); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedNamedEvent(evt)); } } getPersonalizedEmbeddedMessageData(message, personalizationProperties) { if (message != null) { try { if (message.type === "json") { return TextTemplating_1.TextTemplating.applyTextTemplatingToJSON(message.data, personalizationProperties); } else { return TextTemplating_1.TextTemplating.applyTextTemplatingToString(message.data, personalizationProperties); } } catch (e) { SwrveLogger_1.default.error("Campaign id:%s Could not resolve, error with personalization", e); } } return null; } getPersonalizedText(text, personalizationProperties) { if (text != null) { try { return TextTemplating_1.TextTemplating.applyTextTemplatingToString(text, personalizationProperties); } catch (e) { SwrveLogger_1.default.error("Could not resolve, error with personalization", e); } } return null; } //************************************ EVENTS ********************************************************************/ sendEvent(keyName, payload) { if (this.pauseSDK) return; this.validateEventName(keyName); const evt = this.eventFactory.getNamedEvent(keyName, payload, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedNamedEvent(evt)); this.sendQueuedEvents(); } this.checkTriggers(keyName, payload); } sendUserUpdateWithDate(keyName, date) { if (this.pauseSDK) return; this.validateEventName(keyName); const evt = this.eventFactory.getUserUpdateWithDate(keyName, date, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedUserUpdateWithDate(evt)); this.sendQueuedEvents(); } } sendUserUpdate(attributes) { if (this.pauseSDK) return; const evt = this.eventFactory.getUserUpdate(attributes, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedUserUpdate(evt)); this.sendQueuedEvents(); } } sendPurchaseEvent(keyName, currency, cost, quantity) { if (this.pauseSDK) return; this.validateEventName(keyName); const evt = this.eventFactory.getPurchaseEvent(keyName, currency, cost, quantity, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedPurchaseEvent(evt)); } this.sendQueuedEvents(); } sendInAppPurchaseWithoutReceipt(quantity, productId, productPrice, currency, rewards) { if (this.pauseSDK) return; const evt = this.eventFactory.getInAppPurchaseEventWithoutReceipt(quantity, productId, productPrice, currency, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime(), rewards); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedInAppPurchaseEventWithoutReceipt(evt)); } this.sendQueuedEvents(); } sendCurrencyGiven(currencyGiven, amount) { if (this.pauseSDK) return; const evt = this.eventFactory.getCurrencyGivenEvent(currencyGiven, amount, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedCurrencyGivenEvent(evt)); this.sendQueuedEvents(); } } sendQueuedEvents(userId = this.profileManager.currentUser.userId, forceUpdate = false) { SwrveLogger_1.default.info("SWRVE INTERNAL: SEND QUEUED EVENTS"); if (this.pauseSDK) { return; } this.evtManager.sendQueue(userId).then(success => { if (success || forceUpdate) { this.updateCampaignsAndResources(forceUpdate); } }); } //******************************************** OTHER *********************************************************/ stop() { this.pauseSDK = true; clearInterval(this.eventLoopTimer); this.eventLoopTimer = 0; } updateCampaignsAndResources(forceUpdate = false) { SwrveLogger_1.default.info("updateCampaignsAndResources"); return this.restClient.getCampaignsAndResources() .then(response => { this.handleCampaignResponse(response); if (this.isCampaignCallPending()) { this.cleanUpCampaignCallPending(); } }) .catch((error) => { SwrveLogger_1.default.warn("getCampaigns failed ", error); if (!this.isCampaignCallPending()) { this.campaignNetworkMonitorHandle = this.platform.monitorNetwork((state) => { if (state === IPlatform_1.NETWORK_CONNECTED) { SwrveLogger_1.default.info("NETWORK RECONNECTED - RETRY CAMPAIGNS AND RESOURCES"); this.platform.stopMonitoringNetwork(this.campaignNetworkMonitorHandle); this.updateCampaignsAndResources(); } }); } StorageManager_1.StorageManager.saveData(SwrveConstants.CAMPAIGN_CALL_PENDING, this.profileManager.currentUser.userId); if (forceUpdate) { const userId = this.profileManager.currentUser.userId; this.realTimeUserPropertiesManager.loadStoredUserProperties(userId); this.campaignManager.loadStoredCampaigns(userId); this.resourceManager.getResources(userId).then(resources => { if (this.onResourcesLoadedCallback != null) { this.onResourcesLoadedCallback(resources || []); } }); this.autoShowMessages(); } }); } saveToStorage() { this.evtManager.saveEventsToStorage(this.profileManager.currentUser.userId); } identify(externalUserId, onIdentifySuccess, onIdentifyError) { if (this.config.managedMode) { SwrveLogger_1.default.error("SwrveSDK: identify() cannot be called when MANAGED mode is enabled. Use start() instead."); return; } this.sendQueuedEvents(); this.pauseSDK = true; const previousSwrveId = this.profileManager.currentUser.userId; if (externalUserId === "" || externalUserId == null) { this.pauseSDK = false; SwrveLogger_1.default.error("Swrve identify: External user id cannot be nil or empty"); if (onIdentifyError !== undefined) { onIdentifyError("External user id cannot be nil or empty"); } return; } const cachedSwrveUserId = this.profileManager.getSwrveIdByThirdPartyId(externalUserId); if (cachedSwrveUserId) { this.pauseSDK = false; SwrveLogger_1.default.info("Identity API call skipped, user loaded from cache: ", this.profileManager.currentUser.userId); if (cachedSwrveUserId !== this.profileManager.currentUser.userId) { this.verifyAndSwitchUser(cachedSwrveUserId); } if (onIdentifySuccess) { onIdentifySuccess("Identity API call skipped, user loaded from cache", this.profileManager.currentUser.userId); } } else { if (ProfileManager_1.ProfileManager.isUserIdVerified(this.profileManager.currentUser.userId) || (!this.profileManager.currentUser.isAnonymous)) { this.createAnonymousUser(); } const swrveId = this.profileManager.currentUser.userId; this.makeIdentityCall(externalUserId, previousSwrveId, swrveId, onIdentifySuccess, onIdentifyError); } } //******************************************** CALLBACKS *********************************************************/ queueMessageImpressionEvent(messageId, payload) { const nextSeqNum = this.profileManager.getNextSequenceNumber(); if (!payload) { payload = { embedded: "false" }; } payload['platform'] = this.platform.os; payload['deviceType'] = SwrveConstants_1.SWRVE_PAYLOAD_DEVICE_TYPE_TV; const evt = this.eventFactory.getImpressionEvent(messageId, nextSeqNum, payload); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedNamedEvent(evt)); } } onResourcesLoaded(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onResourcesLoaded")); return; } this.onResourcesLoadedCallback = callback; } onCampaignLoaded(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onCampaignLoaded")); return; } this.onCampaignLoadedCallback = callback; } onMessage(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onMessage")); return; } this.campaignManager.onMessage(callback); } onIAMDismissed(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onIAMDismissed")); return; } this.onIAMDismissedCallback = callback; } onCustomButtonClicked(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onCustomButtonClicked")); return; } this.onCustomButtonClickedCallback = callback; } onIAMShown(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "onIAMShown")); return; } this.onIAMShownCallback = callback; } //************************************* RESOURCES *****************************************************************/ getResources(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "getResources")); return; } this.resourceManager.getResources(this.profileManager.currentUser.userId) .then(resources => { if (resources) { SwrveLogger_1.default.info("RESOURCES READILY AVAILABLE"); if (callback) { callback(resources); } } else { SwrveLogger_1.default.info("NO RESOURCES AVAILABLE"); if (callback) { callback([]); } } }); } getResourceManager() { return this.resourceManager.getResourceManager(); } getUserResourcesDiff(callback) { if (typeof callback !== "function") { SwrveLogger_1.default.error(SwrveConstants.INVALID_FUNCTION.replace("$", "getResources")); return; } const resourcesDiffKey = "resourcesDiff" + this.profileManager.currentUser.userId; this.restClient.getUserResourcesDiff() .then(response => { return StorageManager_1.StorageManager.saveDataWithMD5Hash(resourcesDiffKey, JSON.stringify(response.json)) .then(() => response.json); }) .catch((error) => { SwrveLogger_1.default.warn("getUserResourcesDiff failed", error); return StorageManager_1.StorageManager.getDataWithMD5Hash(resourcesDiffKey) .then(data => data ? JSON.parse(data) : []); }) .then(json => { if (callback) { const diff = this.transformResourcesDiff(json); callback(diff[0], diff[1], json); } }); } //*****************************************************************************************************************/ showMessageCenterCampaign(campaign, personalizationProperties) { const properties = this.retrievePersonalizationProperties({}, personalizationProperties); return this.campaignManager.showCampaign(campaign, properties, (msg) => { this.queueMessageImpressionEvent(msg.id); if (this.onIAMShownCallback) { this.onIAMShownCallback(); } }); } markMessageCenterCampaignAsSeen(campaign) { this.campaignManager.markCampaignAsSeen(campaign); } removeMessageCenterCampaign(campaign) { this.campaignManager.removeMessageCenterCampaign(campaign); } getCampaignState(campaignId) { return this.campaignManager.getCampaignState(campaignId); } start(userId) { if (this.config.managedMode) { if (userId) { if (this.profileManager.currentUser.userId === userId) { if (this.pauseSDK) { this.pauseSDK = false; this.initSDK(); } else { SwrveLogger_1.default.info("SwrveSDK: Already running on userID: " + userId); } } else { this.stopAndSwitchUser(userId); } } else if (this.pauseSDK) { this.pauseSDK = false; this.initSDK(); } else { SwrveLogger_1.default.info("SwrveSDK: Already running on userID: " + this.profileManager.currentUser.userId); } } else { SwrveLogger_1.default.error("SwrveSDK: start() can only be called when managedMode in SwrveConfig is enabled"); } } stopAndSwitchUser(userId) { if (this.config.managedMode) { this.stop(); this.switchUser(userId); } else { SwrveLogger_1.default.error("SwrveSDK: switchUser() can only be called when managedMode in SwrveConfig is enabled"); } } isSDKStarted() { return !this.pauseSDK; } showCampaign(campaign, personalizationProperties) { const properties = this.retrievePersonalizationProperties({}, personalizationProperties); return this.campaignManager.showCampaign(campaign, properties, (msg) => { this.queueMessageImpressionEvent(msg.id); if (this.onIAMShownCallback) { this.onIAMShownCallback(); } }); } shutdown() { this._shutdown = true; this.evtManager.saveEventsToStorage(this.profileManager.currentUser.userId); clearTimeout(this.eventLoopTimer); const qa = this.profileManager.QAUser; if (qa && qa.reset_device_state === true) { SwrveLogger_1.default.info("SwrveSDK: Clearing campaign state for QA user: " + this.profileManager.currentUser.userId); this.campaignManager.resetCampaignState(); StorageManager_1.StorageManager.clearData(SwrveConstants_1.CAMPAIGN_STATE + this.profileManager.currentUser.userId); } } handleSendingQueue() { this.sendQueuedEvents(); } isIdentifyCallPending() { return Boolean(StorageManager_1.StorageManager.getData(SwrveConstants.IDENTIFY_CALL_PENDING)); } isCampaignCallPending() { return Boolean(StorageManager_1.StorageManager.getData(SwrveConstants.CAMPAIGN_CALL_PENDING)); } getRealTimeUserProperties() { return this.realTimeUserPropertiesManager.UserProperties; } retrievePersonalizationProperties(eventPayload, properties) { const processedRealTimeUserProperties = RealTimeUserPropertiesManager_1.RealTimeUserPropertiesManager.processForPersonalization(this.getRealTimeUserProperties()); let resultProperties = {}; if ((!properties || Object.keys(properties).length === 0) && this.config.personalizationProvider) { const providerResult = this.config.personalizationProvider(eventPayload || {}); resultProperties = DictionaryHelper_1.combineDictionaries(processedRealTimeUserProperties, providerResult); } else if (properties) { resultProperties = DictionaryHelper_1.combineDictionaries(processedRealTimeUserProperties, properties); } else { resultProperties = processedRealTimeUserProperties; } return resultProperties; } isMessageShowing() { var _a, _b; return (_b = (_a = this.campaignManager) === null || _a === void 0 ? void 0 : _a.isMessageShowing()) !== null && _b !== void 0 ? _b : false; } checkTriggers(triggerName, payload) { const qa = this.profileManager.isQAUser(); const personalization = this.retrievePersonalizationProperties(payload); const { globalStatus, campaignStatus, campaigns } = this.campaignManager.checkTriggers(triggerName, payload, (msg) => { this.queueMessageImpressionEvent(msg.id); if (this.onIAMShownCallback) { this.onIAMShownCallback(); } }, qa, personalization); if (qa && globalStatus.status !== SwrveConstants.CAMPAIGN_MATCH) { SwrveLogger_1.default.debug(globalStatus.message); const event = this.eventFactory.getCampaignTriggeredEvent(triggerName, payload, globalStatus.message, "false"); const nextQASeqNum = this.profileManager.getNextSequenceNumber(); const wrappedEvent = this.eventFactory.getWrappedCampaignTriggeredEvent(nextQASeqNum, event); this.queueEvent(wrappedEvent); } if (qa && campaignStatus) { SwrveLogger_1.default.debug(campaignStatus.message); const displayed = campaignStatus.status === SwrveConstants.CAMPAIGN_MATCH ? "true" : "false"; const event = this.eventFactory.getCampaignTriggeredEvent(triggerName, payload, campaignStatus.message, displayed, campaigns); const nextQASeqNum = this.profileManager.getNextSequenceNumber(); const wrappedEvent = this.eventFactory.getWrappedCampaignTriggeredEvent(nextQASeqNum, event); this.queueEvent(wrappedEvent); } } makeIdentityCall(thirdPartyLoginId, previousSwrveId, swrveId, onIdentifySuccess, onIdentifyError) { this.identifiedOnAnotherDevice = false; // reset the flag this.restClient.identify(thirdPartyLoginId, swrveId) .then((response) => { this.profileManager.cacheThirdPartyId(thirdPartyLoginId, response.swrve_id); if (response.status === SwrveConstants.NEW_EXTERNAL_ID || response.status === SwrveConstants.EXISTING_EXTERNAL_ID_MATCHES_SWRVE_ID) { this.pauseSDK = false; if (previousSwrveId !== response.swrve_id) { this.verifyAndSwitchUser(response.swrve_id); } } else if (response.status === SwrveConstants.EXISTING_EXTERNAL_ID) { this.identifiedOnAnotherDevice = true; this.verifyAndSwitchUser(response.swrve_id); } else { this.pauseSDK = false; } if (this.isIdentifyCallPending()) { this.cleanUpIdentifyCallPending(); } ProfileManager_1.ProfileManager.setUserIdAsVerified(this.profileManager.currentUser.userId); if (onIdentifySuccess) { onIdentifySuccess(response.status, response.swrve_id); } }) .catch(error => { SwrveLogger_1.default.info("Identify error" + error); this.handleIdentifyOffline(thirdPartyLoginId, previousSwrveId, swrveId, onIdentifySuccess, onIdentifyError); this.pauseSDK = false; if (onIdentifyError) { onIdentifyError(error); } }); } handleIdentifyOffline(thirdPartyLoginId, previousSwrveId, swrveId, onIdentifySuccess, onIdentifyError) { const existingThirdPartyLoginId = StorageManager_1.StorageManager.getData(SwrveConstants.IDENTIFY_CALL_PENDING_EXTERNAL_ID); if (existingThirdPartyLoginId && existingThirdPartyLoginId !== thirdPartyLoginId) { this.evtManager.clearQueueAndStorage(this.profileManager.currentUser.userId); } else { this.evtManager.saveEventsToStorage(this.profileManager.currentUser.userId); } if (!this.isIdentifyCallPending()) { this.identifyNetworkMonitorHandle = this.platform.monitorNetwork((state) => { if (state === IPlatform_1.NETWORK_CONNECTED) { SwrveLogger_1.default.info("connected"); this.makeIdentityCall(StorageManager_1.StorageManager.getData(SwrveConstants.IDENTIFY_CALL_PENDING_EXTERNAL_ID), previousSwrveId, swrveId, onIdentifySuccess, onIdentifyError); } }); } StorageManager_1.StorageManager.saveData(SwrveConstants.IDENTIFY_CALL_PENDING, swrveId); StorageManager_1.StorageManager.saveData(SwrveConstants.IDENTIFY_CALL_PENDING_EXTERNAL_ID, thirdPartyLoginId); } cleanUpCampaignCallPending() { if (this.campaignNetworkMonitorHandle !== undefined) { this.platform.stopMonitoringNetwork(this.campaignNetworkMonitorHandle); delete this.campaignNetworkMonitorHandle; } StorageManager_1.StorageManager.clearData(SwrveConstants.CAMPAIGN_CALL_PENDING); } cleanUpIdentifyCallPending() { if (this.identifyNetworkMonitorHandle !== undefined) { this.platform.stopMonitoringNetwork(this.identifyNetworkMonitorHandle); delete this.identifyNetworkMonitorHandle; } const anonId = StorageManager_1.StorageManager.getData(SwrveConstants.IDENTIFY_CALL_PENDING); if (anonId) { this.sendQueuedEvents(anonId); } StorageManager_1.StorageManager.clearData(SwrveConstants.IDENTIFY_CALL_PENDING); StorageManager_1.StorageManager.clearData(SwrveConstants.IDENTIFY_CALL_PENDING_EXTERNAL_ID); } createAnonymousUser() { this.profileManager.setCurrentUserAsNewAnonymousUser(); this.campaignManager.resetCampaignState(); } verifyAndSwitchUser(newUserId) { ProfileManager_1.ProfileManager.setUserIdAsVerified(newUserId); this.switchUser(newUserId); } switchUser(newUserId) { this.profileManager.setCurrentUser(newUserId); this.realTimeUserPropertiesManager.loadStoredUserProperties(newUserId); this.campaignManager.loadStoredCampaigns(newUserId); this.startNewSession(); } startNewSession() { SwrveLogger_1.default.info("Start new session"); this.pauseSDK = false; this.autoShowEnabled = true; //reset this as it may have timed out this.initSDK(); //send all init events this.queueDeviceProperties(); //send device props as at constuction time we wait for PAL to send this but PAL is ready in this case if (this.eventLoopTimer === 0) { this.updateTimer(this.flushFrequency); } } handlePageViewed(messageId, pageId, pageName) { const sentPageViewEvents = this.campaignManager.getSentPageViewEvents(); if (sentPageViewEvents.indexOf(pageId) > -1) { return; } const seqnum = this.profileManager.getNextSequenceNumber(); const id = messageId.toString(); const contextId = pageId.toString(); const payload = {}; if (pageName && pageName.length > 0) { payload['pageName'] = pageName; } payload['platform'] = this.platform.os; payload['deviceType'] = SwrveConstants_1.SWRVE_PAYLOAD_DEVICE_TYPE_TV; const event = this.eventFactory.getPageViewEvent(seqnum, id, contextId, payload); this.queueEvent(event); sentPageViewEvents.push(pageId); if (this.profileManager.isQAUser()) { const qaEvent = this.eventFactory.getWrappedGenericCampaignEvent(event); this.queueEvent(qaEvent); this.sendQueuedEvents(); } } handleButtonClicked(button, parentCampaign, pageId, pageName) { const type = String(button.type.value); const action = String(button.action.value); const campaignId = parentCampaign.id; const messageId = this.campaignManager.getCampaignVariantID(parentCampaign); const buttonName = button.name; const buttonId = button.button_id || 0; switch (type) { case SwrveConstants.DISMISS: this.dismissButtonClicked(messageId, pageId, pageName, buttonName, buttonId); break; case SwrveConstants.CUSTOM: this.customButtonClicked(campaignId, messageId, pageId, pageName, buttonName, buttonId, action); break; case SwrveConstants.PAGE_LINK: this.pageLinkButtonClicked(messageId, pageId, pageName, buttonName, buttonId, action); break; case SwrveConstants.COPY_TO_CLIPBOARD: this.copyToClipboard(action); break; } this.queueButtonEvents(button); this.queueButtonUserUpdates(button); } dismissButtonClicked(messageId, pageId, pageName, buttonName, buttonId) { const seqnum = this.profileManager.getNextSequenceNumber(); const id = messageId.toString(); const contextId = pageId.toString(); const payload = {}; if (pageName && pageName.length > 0) { payload['pageName'] = pageName; } if (buttonName && buttonName.length > 0) { payload['buttonName'] = buttonName; } if (buttonId > 0) { payload['buttonId'] = buttonId.toString(); } payload['platform'] = this.platform.os; payload['deviceType'] = SwrveConstants_1.SWRVE_PAYLOAD_DEVICE_TYPE_TV; const event = this.eventFactory.getDismissEvent(seqnum, id, contextId, payload); this.queueEvent(event); if (this.profileManager.isQAUser()) { const qaEvent = this.eventFactory.getWrappedGenericCampaignEvent(event); this.queueEvent(qaEvent); this.sendQueuedEvents(); } if (this.onIAMDismissedCallback) { this.onIAMDismissedCallback(); } } customButtonClicked(campaignId, messageId, pageId, pageName, buttonName, buttonId, action) { const seqnum = this.profileManager.getNextSequenceNumber(); const event = this.eventFactory.getButtonClickEvent(seqnum, messageId, buttonName, "false", this.platform.os, buttonId, pageId, pageName); this.queueEvent(event); if (this.profileManager.isQAUser()) { const qaSeqnum = this.profileManager.getNextSequenceNumber(); // const action = action || "No action"; // TODO: check if this is needed const qaEvent = this.eventFactory.getQAButtonClickEvent(campaignId, messageId, buttonName, "deeplink", action, qaSeqnum); this.queueEvent(qaEvent); this.sendQueuedEvents(); } if (this.onCustomButtonClickedCallback) { this.onCustomButtonClickedCallback(action); } else if (action.match(/^https?:\/\//)) { this.platform.openLink(action); } } copyToClipboard(text) { return __awaiter(this, void 0, void 0, function* () { if (navigator.clipboard) { try { yield navigator.clipboard.writeText(text); } catch (err) { SwrveLogger_1.default.error("Clipboard API error:", err); } } }); } pageLinkButtonClicked(messageId, pageId, pageName, buttonName, buttonId, pageToId) { const sentNavigationEvents = this.campaignManager.getSentNavigationEvents(); if (sentNavigationEvents.indexOf(buttonId) > -1) { return; } const seqnum = this.profileManager.getNextSequenceNumber(); const id = messageId.toString(); const contextId = pageId.toString(); const payload = {}; if (pageName && pageName.length > 0) { payload['pageName'] = pageName; } if (buttonName && buttonName.length > 0) { payload['buttonName'] = buttonName; } if (buttonId > 0) { payload['buttonId'] = buttonId.toString(); } payload['platform'] = this.platform.os; payload['deviceType'] = SwrveConstants_1.SWRVE_PAYLOAD_DEVICE_TYPE_TV; payload['to'] = pageToId; const event = this.eventFactory.getNavigationEvent(seqnum, id, contextId, payload); this.queueEvent(event); sentNavigationEvents.push(buttonId); if (this.profileManager.isQAUser()) { const qaEvent = this.eventFactory.getWrappedGenericCampaignEvent(event); this.queueEvent(qaEvent); this.sendQueuedEvents(); } } queueButtonEvents(button) { if (button.events) { button.events.forEach(event => { let personalizedPayload = {}; if (event.payload) { const personalizationProperties = this.retrievePersonalizationProperties(); event.payload.forEach(item => { let personalizedValue = item.value; if (typeof item.value === 'string') { personalizedValue = this.getPersonalizedText(item.value, personalizationProperties); } if (personalizedValue != null) { personalizedPayload = Object.assign(Object.assign({}, personalizedPayload), { [item.key]: personalizedValue }); } }); } const sendEvent = this.eventFactory.getNamedEvent(event.name, personalizedPayload, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(sendEvent); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedNamedEvent(sendEvent)); this.sendQueuedEvents(); } }); } } queueButtonUserUpdates(button) { if (button.user_updates) { const personalizationProperties = this.retrievePersonalizationProperties(); let personalizedAttributes = {}; button.user_updates.forEach(user_update => { let personalizedValue = user_update.value; if (typeof user_update.value === 'string') { personalizedValue = this.getPersonalizedText(user_update.value, personalizationProperties); } if (personalizedValue != null) { personalizedAttributes = Object.assign(Object.assign({}, personalizedAttributes), { [user_update.key]: personalizedValue }); } }); const userUpdateEvent = this.eventFactory.getUserUpdate(personalizedAttributes, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(userUpdateEvent); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedUserUpdate(userUpdateEvent)); this.sendQueuedEvents(); } } } autoShowMessages() { SwrveLogger_1.default.debug("AUTO SHOW MESSAGES " + this.autoShowEnabled); if (!this.autoShowEnabled) { return; } this.checkTriggers(SwrveConstants.SWRVE_AUTOSHOW_AT_SESSION_START_TRIGGER, {}); this.autoShowEnabled = false; } queueStartSessionEvent() { const event = this.eventFactory.getStartSessionEvent(this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(event); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedSessionStart(event)); } } handleCampaignResponse(response) { if (Object.keys(response.json).length !== 0) { this.handleRealTimeUserProperties(response.json); const personalizationProperties = this.retrievePersonalizationProperties(); //this will also download assets, pass in up todate personalizationProperties this.campaignManager.storeCampaigns(response.json, personalizationProperties, (error) => { SwrveLogger_1.default.debug("ON ASSETS LOADED"); this.refreshAssets = false; this.autoShowMessages(); if (this.onCampaignLoadedCallback) { this.onCampaignLoadedCallback(error); } }); this.handleQAUser(response.json); this.handleFlushRefresh(response.json); if (this.profileManager.isQAUser()) { this.sendCampaignsDownloadedEvent(); } } else { //if etag takes affect and no campaigns to update //then we still want to refresh assets just once on the first launch if (this.refreshAssets) { SwrveLogger_1.default.debug("Refresh Assets"); this.refreshAssets = false; const personalizationProperties = this.retrievePersonalizationProperties(); this.campaignManager.refreshAssets(personalizationProperties, (error) => { SwrveLogger_1.default.debug("ON ASSETS LOADED"); //campaigns wil have already been loaded from storage on init if (this.onCampaignLoadedCallback) { this.onCampaignLoadedCallback(error); } }); } } this.handleResources(response.json); if (response.etag != null) { this.profileManager.storeEtagHeader(response.etag); } } handleRealTimeUserProperties(response) { this.realTimeUserPropertiesManager.storeUserProperties(response); } sendCampaignsDownloadedEvent() { const ids = this.campaignManager.getCampaignIDs(); if (ids.length > 0) { const nextSeqNum = this.profileManager.getNextSequenceNumber(); this.queueEvent(this.eventFactory.getCampaignsDownloadedEvent(nextSeqNum, ids)); } } initSDK() { SwrveLogger_1.default.info("Initialising Swrve SDK"); this.autoShowEnabled = false; const isValid = this.profileManager.hasSessionRestored(); if (!isValid) { SwrveLogger_1.default.debug("Setting autoShowBack to true"); this.queueStartSessionEvent(); this.checkFirstUserInitiated(); this.autoShowEnabled = true; } this.disableAutoShowAfterDelay(); this.sendQueuedEvents(this.profileManager.currentUser.userId, true); SwrveLogger_1.default.info("Swrve Config: ", this.config); } disableAutoShowAfterDelay() { setTimeout(() => { SwrveLogger_1.default.debug("AUTO SHOW TIMED OUT " + this.config.autoShowMessagesMaxDelay); this.autoShowEnabled = false; }, this.config.autoShowMessagesMaxDelay); } queueEvent(event) { this.evtManager.queueEvent(event); if (this.evtManager.queueSize > this.evtManager.MAX_QUEUE_SIZE) { this.handleSendingQueue(); } } handleResources(response) { if (response.user_resources) { this.resourceManager.storeResources(response.user_resources, this.profileManager.currentUser.userId); const resources = this.resourceManager.getResourceManager().getResources(); if (this.onResourcesLoadedCallback != null) { this.onResourcesLoadedCallback(resources || []); } } else { this.resourceManager.getResources(this.profileManager.currentUser.userId).then(resources => { if (this.onResourcesLoadedCallback != null) { this.onResourcesLoadedCallback(resources || []); } }); } } handleUpdate() { if (this.evtManager.getQueue().length > 0) { this.handleSendingQueue(); } } handleQAUser(response) { if (response.qa) { this.profileManager.setAsQAUser(response.qa); } else { this.profileManager.clearQAUser(); } } handleFlushRefresh(response) { const flushFrequency = response.flush_frequency || 30000; this.updateTimer(flushFrequency); } updateTimer(flushFrequency) { if (this.eventLoopTimer === 0) { //first time this.flushFrequency = flushFrequency; this.eventLoopTimer = setInterval(() => this.handleUpdate(), flushFrequency); } else if (this.flushFrequency !== flushFrequency) { //only reset it if it different this.flushFrequency = flushFrequency; if (this.eventLoopTimer !== 0) { clearInterval(this.eventLoopTimer); } this.eventLoopTimer = setInterval(() => this.handleUpdate(), flushFrequency); } } validateEventName(name) { if (/[Ss]wrve/.exec(name)) { throw new Error(SwrveConstants.INVALID_EVENT_NAME); } } checkFirstUserInitiated() { const currentUser = this.profileManager.currentUser; if ((currentUser && currentUser.firstUse === 0) || currentUser.firstUse === undefined) { SwrveLogger_1.default.debug("First session on device detected. logging..."); currentUser.firstUse = DateHelper_1.default.nowInUtcTime(); if (this.identifiedOnAnotherDevice === false) { const evt = this.eventFactory.getFirstInstallEvent(currentUser.firstUse, this.profileManager.getNextSequenceNumber()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedFirstInstallEvent(evt)); } } } } loadInstallDate() { const storedInstallDate = StorageManager_1.StorageManager.getData("firstInstallDate"); if (storedInstallDate != null && storedInstallDate !== "") { this.installDate = storedInstallDate; } if (this.installDate.length < 1) { this.installDate = TimeHelper_1.getInstallDateFormat(DateHelper_1.default.nowInUtcTime()); StorageManager_1.StorageManager.saveData("firstInstallDate", String(this.installDate)); } } queueDeviceProperties() { const deviceProperties = DeviceProperties_1.queryDeviceProperties(this.platform, this.profileManager, this.installDate); const evt = this.eventFactory.getDeviceUpdate(deviceProperties, this.profileManager.getNextSequenceNumber(), DateHelper_1.default.nowInUtcTime()); this.queueEvent(evt); if (this.profileManager.isQAUser()) { this.queueEvent(this.eventFactory.getWrappedDeviceUpdate(evt)); } SwrveLogger_1.default.info("Swrve Device Properties: ", deviceProperties); } transformResourcesDiff(resources) { const mapOldResources = {}; const mapNewResources = {}; resources.forEach(resource => { const mapOldResourceValues = {}; const mapNewResourceValues = {}; for (const key in resource.diff) { if (resource.diff.hasOwnProperty(key)) { mapOldResourceVal