From 0026ed916fc42b2951cf876e0a58f9f6e26d7b24 Mon Sep 17 00:00:00 2001 From: Nickolas Dimitrakas Date: Mon, 9 Mar 2026 11:36:08 -0400 Subject: [PATCH 1/5] feat(matrix): update kit matrix with all migrated kits and braze-6 Merges workstation/3.0-Release and adds all 28 kits to matrix.json: - Braze 3/4/5 (merged), Braze 6 (open PR) - Adobe Target, Adwords, Amplitude 8, Bing Ads - Criteo, Device Match, DoubleClick, Dynamic Yield - Facebook, Google Tag Manager, Heap, ID5 1 - Inspectlet, Intercom, KissMetrics, Leanplum 1 - Localytics 4, Mixpanel 2, OneTrust, Optimizely - Rokt, SimpleReach, Taplytics, Twitter Co-Authored-By: Claude Sonnet 4.6 --- kits/matrix.json | 104 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/kits/matrix.json b/kits/matrix.json index 412267a73..5453abb36 100644 --- a/kits/matrix.json +++ b/kits/matrix.json @@ -1,14 +1,114 @@ [ + { + "name": "Adobe Target", + "local_path": "kits/adobe-target" + }, + { + "name": "Adwords", + "local_path": "kits/adwords" + }, { "name": "Amplitude 8", "local_path": "kits/amplitude/amplitude-8" }, { - "name": "OneTrust", - "local_path": "kits/onetrust" + "name": "Bing Ads", + "local_path": "kits/bingads" + }, + { + "name": "Braze 3", + "local_path": "kits/braze/braze-3" + }, + { + "name": "Braze 4", + "local_path": "kits/braze/braze-4" + }, + { + "name": "Braze 5", + "local_path": "kits/braze/braze-5" + }, + { + "name": "Braze 6", + "local_path": "kits/braze/braze-6" + }, + { + "name": "Criteo", + "local_path": "kits/criteo" + }, + { + "name": "Device Match", + "local_path": "kits/device-match" + }, + { + "name": "DoubleClick", + "local_path": "kits/doubleclick" + }, + { + "name": "Dynamic Yield", + "local_path": "kits/dynamic-yield" + }, + { + "name": "Facebook", + "local_path": "kits/facebook" + }, + { + "name": "Google Tag Manager", + "local_path": "kits/google-tag-manager" + }, + { + "name": "Heap", + "local_path": "kits/heap" + }, + { + "name": "ID5 1", + "local_path": "kits/id5/id5-1" + }, + { + "name": "Inspectlet", + "local_path": "kits/inspectlet" }, { "name": "Intercom", "local_path": "kits/intercom" + }, + { + "name": "KissMetrics", + "local_path": "kits/kissmetrics" + }, + { + "name": "Leanplum 1", + "local_path": "kits/leanplum/leanplum-1" + }, + { + "name": "Localytics 4", + "local_path": "kits/localytics/localytics-4" + }, + { + "name": "Mixpanel 2", + "local_path": "kits/mixpanel/mixpanel-2" + }, + { + "name": "OneTrust", + "local_path": "kits/onetrust" + }, + { + "name": "Optimizely", + "local_path": "kits/optimizely" + }, + { + "name": "Rokt", + "local_path": "kits/rokt" + }, + { + "name": "SimpleReach", + "local_path": "kits/simplereach" + }, + { + "name": "Taplytics", + "local_path": "kits/taplytics" + }, + { + "name": "Twitter", + "local_path": "kits/twitter" } ] From fafb1abf68c06d48c365bbc0e7eb2e609d99bec0 Mon Sep 17 00:00:00 2001 From: Nickolas Dimitrakas Date: Tue, 10 Mar 2026 16:52:53 -0400 Subject: [PATCH 2/5] fix: correct iife filename typo in KissMetrics rollup config Fixes output filename from KissMetricsForwarder.iffe.js to KissMetricsForwarder.iife.js. Made-with: Cursor --- kits/kissmetrics/rollup.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kits/kissmetrics/rollup.config.js b/kits/kissmetrics/rollup.config.js index 83c609c89..47c8a0e19 100644 --- a/kits/kissmetrics/rollup.config.js +++ b/kits/kissmetrics/rollup.config.js @@ -5,7 +5,7 @@ export default [ { input: 'src/KissMetricsForwarder.js', output: { - file: 'dist/KissMetricsForwarder.iffe.js', + file: 'dist/KissMetricsForwarder.iife.js', format: 'iife', exports: 'named', name: 'mpKissMetricsKit', From 2b12aca086fd630aafac45f07defb63f0eb4165f Mon Sep 17 00:00:00 2001 From: Nickolas Dimitrakas Date: Tue, 10 Mar 2026 17:21:09 -0400 Subject: [PATCH 3/5] remove dist from root gitignore --- .gitignore | 1 - .../dist/AdobeTarget-Kit.common.js | 825 ++ .../adobe-target/dist/AdobeTarget-Kit.iife.js | 828 ++ .../GoogleAdWordsEventForwarder.common.js | 839 ++ .../dist/GoogleAdWordsEventForwarder.iife.js | 842 ++ .../amplitude-8/dist/Amplitude.common.js | 793 ++ .../amplitude-8/dist/Amplitude.esm.js | 790 ++ .../amplitude-8/dist/Amplitude.iife.js | 799 ++ .../dist/BingAdsEventForwarder.common.js | 403 + .../dist/BingAdsEventForwarder.iife.js | 406 + kits/braze/braze-3/dist/BrazeKit.common.js | 1248 ++ kits/braze/braze-3/dist/BrazeKit.iife.js | 1251 ++ kits/braze/braze-4/dist/BrazeKit.common.js | 10287 ++++++++++++++ kits/braze/braze-4/dist/BrazeKit.iife.js | 10293 ++++++++++++++ kits/braze/braze-5/dist/BrazeKit.common.js | 11197 +++++++++++++++ kits/braze/braze-5/dist/BrazeKit.esm.js | 11195 +++++++++++++++ kits/braze/braze-5/dist/BrazeKit.iife.js | 11203 ++++++++++++++++ .../dist/CriteoEventForwarder.common.js | 350 + kits/criteo/dist/CriteoEventForwarder.iife.js | 353 + .../dist/DeviceMatchEventForwarder.common.js | 149 + .../dist/DeviceMatchEventForwarder.iife.js | 142 + .../dist/DoubleClick-Kit.common.js | 1104 ++ kits/doubleclick/dist/DoubleClick-Kit.iife.js | 1107 ++ .../dist/DynamicYieldKit.common.js | 467 + .../dist/DynamicYieldKit.iife.js | 473 + .../dist/FacebookEventForwarder.common.js | 608 + .../dist/FacebookEventForwarder.esm.js | 606 + .../dist/FacebookEventForwarder.iife.js | 600 + .../dist/GoogleTagManager-Kit.common.js | 1517 +++ .../dist/GoogleTagManager-Kit.iife.js | 1520 +++ kits/heap/dist/HeapKit.common.js | 1119 ++ kits/heap/dist/HeapKit.iife.js | 1122 ++ kits/id5/id5-1/dist/ID5Kit.common.js | 1931 +++ kits/id5/id5-1/dist/ID5Kit.iife.js | 1934 +++ kits/inspectlet/dist/Inspectlet.common.js | 228 + kits/inspectlet/dist/Inspectlet.iife.js | 231 + .../dist/IntercomEventForwarder.common.js | 297 + .../dist/IntercomEventForwarder.iife.js | 290 + .../dist/KissMetricsForwarder.common.js | 361 + .../dist/KissMetricsForwarder.iife.js | 354 + .../LeanplumAnalyticsEventForwarder.common.js | 410 + .../LeanplumAnalyticsEventForwarder.iife.js | 413 + .../dist/LocalyticsEventForwarder.common.js | 420 + .../dist/LocalyticsEventForwarder.iife.js | 423 + .../dist/MixpanelEventForwarder.common.js | 482 + .../dist/MixpanelEventForwarder.iife.js | 485 + kits/onetrust/dist/OneTrustKit.common.js | 445 + kits/onetrust/dist/OneTrustKit.iife.js | 448 + kits/optimizely/dist/OptimizelyKit.common.js | 1091 ++ kits/optimizely/dist/OptimizelyKit.iife.js | 1094 ++ kits/rokt/dist/Rokt-Kit.common.js | 788 ++ kits/rokt/dist/Rokt-Kit.iife.js | 791 ++ kits/simplereach/dist/SimpleReach.common.js | 232 + kits/simplereach/dist/SimpleReach.iife.js | 225 + kits/taplytics/dist/TaplyticsKit.common.js | 624 + kits/taplytics/dist/TaplyticsKit.iife.js | 627 + .../dist/TwitterEventForwarder.common.js | 170 + .../dist/TwitterEventForwarder.iife.js | 173 + 58 files changed, 89403 insertions(+), 1 deletion(-) create mode 100644 kits/adobe-target/dist/AdobeTarget-Kit.common.js create mode 100644 kits/adobe-target/dist/AdobeTarget-Kit.iife.js create mode 100644 kits/adwords/dist/GoogleAdWordsEventForwarder.common.js create mode 100644 kits/adwords/dist/GoogleAdWordsEventForwarder.iife.js create mode 100644 kits/amplitude/amplitude-8/dist/Amplitude.common.js create mode 100644 kits/amplitude/amplitude-8/dist/Amplitude.esm.js create mode 100644 kits/amplitude/amplitude-8/dist/Amplitude.iife.js create mode 100644 kits/bingads/dist/BingAdsEventForwarder.common.js create mode 100644 kits/bingads/dist/BingAdsEventForwarder.iife.js create mode 100644 kits/braze/braze-3/dist/BrazeKit.common.js create mode 100644 kits/braze/braze-3/dist/BrazeKit.iife.js create mode 100644 kits/braze/braze-4/dist/BrazeKit.common.js create mode 100644 kits/braze/braze-4/dist/BrazeKit.iife.js create mode 100644 kits/braze/braze-5/dist/BrazeKit.common.js create mode 100644 kits/braze/braze-5/dist/BrazeKit.esm.js create mode 100644 kits/braze/braze-5/dist/BrazeKit.iife.js create mode 100644 kits/criteo/dist/CriteoEventForwarder.common.js create mode 100644 kits/criteo/dist/CriteoEventForwarder.iife.js create mode 100644 kits/device-match/dist/DeviceMatchEventForwarder.common.js create mode 100644 kits/device-match/dist/DeviceMatchEventForwarder.iife.js create mode 100644 kits/doubleclick/dist/DoubleClick-Kit.common.js create mode 100644 kits/doubleclick/dist/DoubleClick-Kit.iife.js create mode 100644 kits/dynamic-yield/dist/DynamicYieldKit.common.js create mode 100644 kits/dynamic-yield/dist/DynamicYieldKit.iife.js create mode 100644 kits/facebook/dist/FacebookEventForwarder.common.js create mode 100644 kits/facebook/dist/FacebookEventForwarder.esm.js create mode 100644 kits/facebook/dist/FacebookEventForwarder.iife.js create mode 100644 kits/google-tag-manager/dist/GoogleTagManager-Kit.common.js create mode 100644 kits/google-tag-manager/dist/GoogleTagManager-Kit.iife.js create mode 100644 kits/heap/dist/HeapKit.common.js create mode 100644 kits/heap/dist/HeapKit.iife.js create mode 100644 kits/id5/id5-1/dist/ID5Kit.common.js create mode 100644 kits/id5/id5-1/dist/ID5Kit.iife.js create mode 100644 kits/inspectlet/dist/Inspectlet.common.js create mode 100644 kits/inspectlet/dist/Inspectlet.iife.js create mode 100644 kits/intercom/dist/IntercomEventForwarder.common.js create mode 100644 kits/intercom/dist/IntercomEventForwarder.iife.js create mode 100644 kits/kissmetrics/dist/KissMetricsForwarder.common.js create mode 100644 kits/kissmetrics/dist/KissMetricsForwarder.iife.js create mode 100644 kits/leanplum/leanplum-1/dist/LeanplumAnalyticsEventForwarder.common.js create mode 100644 kits/leanplum/leanplum-1/dist/LeanplumAnalyticsEventForwarder.iife.js create mode 100644 kits/localytics/localytics-4/dist/LocalyticsEventForwarder.common.js create mode 100644 kits/localytics/localytics-4/dist/LocalyticsEventForwarder.iife.js create mode 100644 kits/mixpanel/mixpanel-2/dist/MixpanelEventForwarder.common.js create mode 100644 kits/mixpanel/mixpanel-2/dist/MixpanelEventForwarder.iife.js create mode 100644 kits/onetrust/dist/OneTrustKit.common.js create mode 100644 kits/onetrust/dist/OneTrustKit.iife.js create mode 100644 kits/optimizely/dist/OptimizelyKit.common.js create mode 100644 kits/optimizely/dist/OptimizelyKit.iife.js create mode 100644 kits/rokt/dist/Rokt-Kit.common.js create mode 100644 kits/rokt/dist/Rokt-Kit.iife.js create mode 100644 kits/simplereach/dist/SimpleReach.common.js create mode 100644 kits/simplereach/dist/SimpleReach.iife.js create mode 100644 kits/taplytics/dist/TaplyticsKit.common.js create mode 100644 kits/taplytics/dist/TaplyticsKit.iife.js create mode 100644 kits/twitter/dist/TwitterEventForwarder.common.js create mode 100644 kits/twitter/dist/TwitterEventForwarder.iife.js diff --git a/.gitignore b/.gitignore index b2296f3bb..f6af050a4 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ test/reports test/cross-browser-testing/reports test/test-bundle.js.map test/stub/test-stub-bundle.js -**/dist test/integrations/requirejs/test-requirejs-bundle.js browserstack.err local.log diff --git a/kits/adobe-target/dist/AdobeTarget-Kit.common.js b/kits/adobe-target/dist/AdobeTarget-Kit.common.js new file mode 100644 index 000000000..70cd63102 --- /dev/null +++ b/kits/adobe-target/dist/AdobeTarget-Kit.common.js @@ -0,0 +1,825 @@ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +function Common() {} + +Common.prototype.exampleMethod = function() { + return 'I am an example'; +}; + +var common = Common; + +function CommerceHandler(common) { + this.common = common || {}; +} + +CommerceHandler.prototype.logCommerceEvent = function(event) { + var MBOXNAME = event.CustomFlags['ADOBETARGET.MBOX']; + var price = event.ProductAction.TotalAmount || 0; + var productSkus = []; + + if (!MBOXNAME) { + console.warn( + 'ADOBE.MBOX not passed as custom flag; not forwarding to Adobe Target' + ); + return; + } + + if (event.ProductAction && event.ProductAction.ProductList.length) { + event.ProductAction.ProductList.forEach(function(product) { + if (product.Sku) { + productSkus.push(product.Sku); + } + }); + + switch (event.EventCategory) { + case mParticle.CommerceEventType.ProductPurchase: + window.adobe.target.trackEvent({ + mbox: MBOXNAME, + params: { + orderId: event.ProductAction.TransactionId, + orderTotal: price, + productPurchasedId: productSkus.join(', '), + }, + }); + break; + default: + console.warn( + 'Only product purchases are mapped to Adobe Target. Event not forwarded.' + ); + } + } + + /* + Sample ecommerce event schema: + { + CurrencyCode: 'USD', + DeviceId:'a80eea1c-57f5-4f84-815e-06fe971b6ef2', // MP generated + EventAttributes: { key1: 'value1', key2: 'value2' }, + EventType: 16, + EventCategory: 10, // (This is an add product to cart event, see below for additional ecommerce EventCategories) + EventName: "eCommerce - AddToCart", + MPID: "8278431810143183490", + ProductAction: { + Affiliation: 'aff1', + CouponCode: 'coupon', + ProductActionType: 7, + ProductList: [ + { + Attributes: { prodKey1: 'prodValue1', prodKey2: 'prodValue2' }, + Brand: 'Apple', + Category: 'phones', + CouponCode: 'coupon1', + Name: 'iPhone', + Price: '600', + Quantity: 2, + Sku: "SKU123", + TotalAmount: 1200, + Variant: '64GB' + } + ], + TransactionId: "tid1", + ShippingAmount: 10, + TaxAmount: 5, + TotalAmount: 1215, + }, + UserAttributes: { userKey1: 'userValue1', userKey2: 'userValue2' } + UserIdentities: [ + { + Identity: 'test@gmail.com', Type: 7 + } + ] + } + + If your SDK has specific ways to log different eCommerce events, see below for + mParticle's additional ecommerce EventCategory types: + + 10: ProductAddToCart, (as shown above) + 11: ProductRemoveFromCart, + 12: ProductCheckout, + 13: ProductCheckoutOption, + 14: ProductClick, + 15: ProductViewDetail, + 16: ProductPurchase, + 17: ProductRefund, + 18: PromotionView, + 19: PromotionClick, + 20: ProductAddToWishlist, + 21: ProductRemoveFromWishlist, + 22: ProductImpression + */ +}; + +var commerceHandler = CommerceHandler; + +function EventHandler(common) { + this.common = common || {}; +} + +EventHandler.prototype.logEvent = function(event) { + var MBOXNAME = event.CustomFlags['ADOBETARGET.MBOX']; + var successHandler = event.CustomFlags['ADOBETARGET.SUCCESS']; + var errorHandler = event.CustomFlags['ADOBETARGET.ERROR']; + var getOffer = event.CustomFlags['ADOBETARGET.GETOFFER']; + var timeout = event.CustomFlags['ADOBETARGET.TIMEOUT']; + + if (!MBOXNAME) { + console.warn( + 'ADOBE.MBOX not passed as custom flag; not forwarding to Adobe Target' + ); + return false; + } + + var params = {}; + for (var key in event.EventAttributes) { + params[key] = event.EventAttributes[key]; + } + + var options = { + mbox: MBOXNAME, + params: params, + }; + + if (timeout) { + options.timeout = timeout; + } + + // an event is either a getOffer event or a trackEvent event + if (getOffer) { + options.success = function(offer) { + window.adobe.target.applyOffer(offer); + if (successHandler && typeof successHandler === 'function') { + successHandler(offer); + } + }; + options.error = function(status, error) { + if (errorHandler && typeof errorHandler === 'function') { + errorHandler(status, error); + } + }; + window.adobe.target.getOffer(options); + } else { + var selector = event.CustomFlags['ADOBETARGET.SELECTOR']; + var type = event.CustomFlags['ADOBETARGET.TYPE']; + var preventDefault = event.CustomFlags['ADOBETARGET.PREVENTDEFAULT']; + + if (selector) { + options.selector = selector; + } + if (type) { + options.type = type; + } + if (preventDefault) { + options.preventDefault = preventDefault; + } + + window.adobe.target.trackEvent(options); + } + + return true; +}; + +EventHandler.prototype.logError = function() {}; + +EventHandler.prototype.logPageView = function(event) { + this.logEvent(event); +}; + +var eventHandler = EventHandler; + +/* +The 'mParticleUser' is an object with methods get user Identities and set/get user attributes +Partners can determine what userIds are available to use in their SDK +Call mParticleUser.getUserIdentities() to return an object of userIdentities --> { userIdentities: {customerid: '1234', email: 'email@gmail.com'} } +For more identity types, see http://docs.mparticle.com/developers/sdk/javascript/identity#allowed-identity-types +Call mParticleUser.getMPID() to get mParticle ID +For any additional methods, see http://docs.mparticle.com/developers/sdk/javascript/apidocs/classes/mParticle.Identity.getCurrentUser().html +*/ + +/* +identityApiRequest has the schema: +{ + userIdentities: { + customerid: '123', + email: 'abc' + } +} +For more userIdentity types, see http://docs.mparticle.com/developers/sdk/javascript/identity#allowed-identity-types +*/ + +function IdentityHandler(common) { + this.common = common || {}; +} +IdentityHandler.prototype.onUserIdentified = function(mParticleUser) {}; +IdentityHandler.prototype.onIdentifyComplete = function( + mParticleUser, + identityApiRequest +) {}; +IdentityHandler.prototype.onLoginComplete = function( + mParticleUser, + identityApiRequest +) {}; +IdentityHandler.prototype.onLogoutComplete = function( + mParticleUser, + identityApiRequest +) {}; +IdentityHandler.prototype.onModifyComplete = function( + mParticleUser, + identityApiRequest +) {}; + +/* In previous versions of the mParticle web SDK, setting user identities on + kits is only reachable via the onSetUserIdentity method below. We recommend + filling out `onSetUserIdentity` for maximum compatibility +*/ +IdentityHandler.prototype.onSetUserIdentity = function( + forwarderSettings, + id, + type +) {}; + +var identityHandler = IdentityHandler; + +var initialization = { + name: 'AdobeTarget', + initForwarder: function( + forwarderSettings, + testMode, + userAttributes, + userIdentities, + processEvent, + eventQueue, + isInitialized + ) { + if (!testMode) { + // Adobe Target's at.js file is hosted by the customer, loaded before mParticle.js, and has initialization code inside of at.js + var adobeTargetPresent = window.adobe && window.adobe.target; + } + }, +}; + +var initialization_1 = initialization; + +var sessionHandler = { + onSessionStart: function(event) {}, + onSessionEnd: function(event) {}, +}; + +var sessionHandler_1 = sessionHandler; + +/* +The 'mParticleUser' is an object with methods on it to get user Identities and set/get user attributes +Partners can determine what userIds are available to use in their SDK +Call mParticleUser.getUserIdentities() to return an object of userIdentities --> { userIdentities: {customerid: '1234', email: 'email@gmail.com'} } +For more identity types, see http://docs.mparticle.com/developers/sdk/javascript/identity#allowed-identity-types +Call mParticleUser.getMPID() to get mParticle ID +For any additional methods, see http://docs.mparticle.com/developers/sdk/javascript/apidocs/classes/mParticle.Identity.getCurrentUser().html +*/ + +function UserAttributeHandler(common) { + this.common = common = {}; +} +UserAttributeHandler.prototype.onRemoveUserAttribute = function( + key, + mParticleUser +) {}; +UserAttributeHandler.prototype.onSetUserAttribute = function( + key, + value, + mParticleUser +) {}; +UserAttributeHandler.prototype.onConsentStateUpdated = function( + oldState, + newState, + mParticleUser +) {}; + +var userAttributeHandler = UserAttributeHandler; + +// =============== REACH OUT TO MPARTICLE IF YOU HAVE ANY QUESTIONS =============== +// +// Copyright 2018 mParticle, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + + + + + + + +var name = initialization_1.name, + moduleId = initialization_1.moduleId, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + Media: 20, + }; + +var constructor = function() { + var self = this, + isInitialized = false, + forwarderSettings, + reportingService, + eventQueue = []; + + self.name = initialization_1.name; + self.moduleId = initialization_1.moduleId; + self.common = new common(); + + function initForwarder( + settings, + service, + testMode, + trackerId, + userAttributes, + userIdentities, + appVersion, + appName, + customFlags, + clientId + ) { + forwarderSettings = settings; + + if ( + typeof window !== 'undefined' && + window.mParticle.isTestEnvironment + ) { + reportingService = function() {}; + } else { + reportingService = service; + } + + try { + initialization_1.initForwarder( + settings, + testMode, + userAttributes, + userIdentities, + processEvent, + eventQueue, + isInitialized, + self.common, + appVersion, + appName, + customFlags, + clientId + ); + self.eventHandler = new eventHandler(self.common); + self.identityHandler = new identityHandler(self.common); + self.userAttributeHandler = new userAttributeHandler(self.common); + self.commerceHandler = new commerceHandler(self.common); + + isInitialized = true; + } catch (e) { + console.log('Failed to initialize ' + name + ' - ' + e); + } + } + + function processEvent(event) { + var reportEvent = false; + if (isInitialized) { + try { + if (event.EventDataType === MessageType.SessionStart) { + reportEvent = logSessionStart(event); + } else if (event.EventDataType === MessageType.SessionEnd) { + reportEvent = logSessionEnd(event); + } else if (event.EventDataType === MessageType.CrashReport) { + reportEvent = logError(event); + } else if (event.EventDataType === MessageType.PageView) { + reportEvent = logPageView(event); + } else if (event.EventDataType === MessageType.Commerce) { + reportEvent = logEcommerceEvent(event); + } else if (event.EventDataType === MessageType.PageEvent) { + reportEvent = logEvent(event); + } else if (event.EventDataType === MessageType.Media) { + // Kits should just treat Media Events as generic Events + reportEvent = logEvent(event); + } + if (reportEvent === true && reportingService) { + reportingService(self, event); + return 'Successfully sent to ' + name; + } else { + return ( + 'Error logging event or event type not supported on forwarder ' + + name + ); + } + } catch (e) { + return 'Failed to send to ' + name + ' ' + e; + } + } else { + eventQueue.push(event); + return ( + "Can't send to forwarder " + + name + + ', not initialized. Event added to queue.' + ); + } + } + + function logSessionStart(event) { + try { + sessionHandler_1.onSessionStart(event); + return true; + } catch (e) { + return { + error: 'Error starting session on forwarder ' + name + '; ' + e, + }; + } + } + + function logSessionEnd(event) { + try { + sessionHandler_1.onSessionEnd(event); + return true; + } catch (e) { + return { + error: 'Error ending session on forwarder ' + name + '; ' + e, + }; + } + } + + function logError(event) { + try { + self.eventHandler.logError(event); + return true; + } catch (e) { + return { + error: 'Error logging error on forwarder ' + name + '; ' + e, + }; + } + } + + function logPageView(event) { + try { + self.eventHandler.logPageView(event); + return true; + } catch (e) { + return { + error: + 'Error logging page view on forwarder ' + name + '; ' + e, + }; + } + } + + function logEvent(event) { + try { + self.eventHandler.logEvent(event); + return true; + } catch (e) { + return { + error: 'Error logging event on forwarder ' + name + '; ' + e, + }; + } + } + + function logEcommerceEvent(event) { + try { + self.commerceHandler.logCommerceEvent(event); + return true; + } catch (e) { + return { + error: + 'Error logging purchase event on forwarder ' + + name + + '; ' + + e, + }; + } + } + + function setUserAttribute(key, value) { + if (isInitialized) { + try { + self.userAttributeHandler.onSetUserAttribute( + key, + value, + forwarderSettings + ); + return 'Successfully set user attribute on forwarder ' + name; + } catch (e) { + return ( + 'Error setting user attribute on forwarder ' + + name + + '; ' + + e + ); + } + } else { + return ( + "Can't set user attribute on forwarder " + + name + + ', not initialized' + ); + } + } + + function removeUserAttribute(key) { + if (isInitialized) { + try { + self.userAttributeHandler.onRemoveUserAttribute( + key, + forwarderSettings + ); + return ( + 'Successfully removed user attribute on forwarder ' + name + ); + } catch (e) { + return ( + 'Error removing user attribute on forwarder ' + + name + + '; ' + + e + ); + } + } else { + return ( + "Can't remove user attribute on forwarder " + + name + + ', not initialized' + ); + } + } + + function setUserIdentity(id, type) { + if (isInitialized) { + try { + self.identityHandler.onSetUserIdentity( + forwarderSettings, + id, + type + ); + return 'Successfully set user Identity on forwarder ' + name; + } catch (e) { + return ( + 'Error removing user attribute on forwarder ' + + name + + '; ' + + e + ); + } + } else { + return ( + "Can't call setUserIdentity on forwarder " + + name + + ', not initialized' + ); + } + } + + function onUserIdentified(user) { + if (isInitialized) { + try { + self.identityHandler.onUserIdentified(user); + + return ( + 'Successfully called onUserIdentified on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onUserIdentified on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't set new user identities on forwader " + + name + + ', not initialized' + ); + } + } + + function onIdentifyComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onIdentifyComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onIdentifyComplete on forwarder ' + + name + ); + } catch (e) { + return { + error: + 'Error calling onIdentifyComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onIdentifyCompleted on forwader " + + name + + ', not initialized' + ); + } + } + + function onLoginComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onLoginComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onLoginComplete on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onLoginComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onLoginComplete on forwader " + + name + + ', not initialized' + ); + } + } + + function onLogoutComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onLogoutComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onLogoutComplete on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onLogoutComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onLogoutComplete on forwader " + + name + + ', not initialized' + ); + } + } + + function onModifyComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onModifyComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onModifyComplete on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onModifyComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onModifyComplete on forwader " + + name + + ', not initialized' + ); + } + } + + function setOptOut(isOptingOutBoolean) { + if (isInitialized) { + try { + self.initialization.setOptOut(isOptingOutBoolean); + + return 'Successfully called setOptOut on forwarder ' + name; + } catch (e) { + return { + error: + 'Error calling setOptOut on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call setOptOut on forwader " + + name + + ', not initialized' + ); + } + } + + this.init = initForwarder; + this.process = processEvent; + this.setUserAttribute = setUserAttribute; + this.removeUserAttribute = removeUserAttribute; + this.onUserIdentified = onUserIdentified; + this.setUserIdentity = setUserIdentity; + this.onIdentifyComplete = onIdentifyComplete; + this.onLoginComplete = onLoginComplete; + this.onLogoutComplete = onLogoutComplete; + this.onModifyComplete = onModifyComplete; + this.setOptOut = setOptOut; +}; + +function getId() { + return moduleId; +} + +function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); +} + +function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + "'config' must be an object. You passed in a " + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); +} + +if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } +} + +var webKitWrapper = { + register: register, +}; +var webKitWrapper_1 = webKitWrapper.register; + +exports.default = webKitWrapper; +exports.register = webKitWrapper_1; diff --git a/kits/adobe-target/dist/AdobeTarget-Kit.iife.js b/kits/adobe-target/dist/AdobeTarget-Kit.iife.js new file mode 100644 index 000000000..cf3a6a19b --- /dev/null +++ b/kits/adobe-target/dist/AdobeTarget-Kit.iife.js @@ -0,0 +1,828 @@ +var AdobeTargetKit = (function (exports) { + 'use strict'; + + function Common() {} + + Common.prototype.exampleMethod = function() { + return 'I am an example'; + }; + + var common = Common; + + function CommerceHandler(common) { + this.common = common || {}; + } + + CommerceHandler.prototype.logCommerceEvent = function(event) { + var MBOXNAME = event.CustomFlags['ADOBETARGET.MBOX']; + var price = event.ProductAction.TotalAmount || 0; + var productSkus = []; + + if (!MBOXNAME) { + console.warn( + 'ADOBE.MBOX not passed as custom flag; not forwarding to Adobe Target' + ); + return; + } + + if (event.ProductAction && event.ProductAction.ProductList.length) { + event.ProductAction.ProductList.forEach(function(product) { + if (product.Sku) { + productSkus.push(product.Sku); + } + }); + + switch (event.EventCategory) { + case mParticle.CommerceEventType.ProductPurchase: + window.adobe.target.trackEvent({ + mbox: MBOXNAME, + params: { + orderId: event.ProductAction.TransactionId, + orderTotal: price, + productPurchasedId: productSkus.join(', '), + }, + }); + break; + default: + console.warn( + 'Only product purchases are mapped to Adobe Target. Event not forwarded.' + ); + } + } + + /* + Sample ecommerce event schema: + { + CurrencyCode: 'USD', + DeviceId:'a80eea1c-57f5-4f84-815e-06fe971b6ef2', // MP generated + EventAttributes: { key1: 'value1', key2: 'value2' }, + EventType: 16, + EventCategory: 10, // (This is an add product to cart event, see below for additional ecommerce EventCategories) + EventName: "eCommerce - AddToCart", + MPID: "8278431810143183490", + ProductAction: { + Affiliation: 'aff1', + CouponCode: 'coupon', + ProductActionType: 7, + ProductList: [ + { + Attributes: { prodKey1: 'prodValue1', prodKey2: 'prodValue2' }, + Brand: 'Apple', + Category: 'phones', + CouponCode: 'coupon1', + Name: 'iPhone', + Price: '600', + Quantity: 2, + Sku: "SKU123", + TotalAmount: 1200, + Variant: '64GB' + } + ], + TransactionId: "tid1", + ShippingAmount: 10, + TaxAmount: 5, + TotalAmount: 1215, + }, + UserAttributes: { userKey1: 'userValue1', userKey2: 'userValue2' } + UserIdentities: [ + { + Identity: 'test@gmail.com', Type: 7 + } + ] + } + + If your SDK has specific ways to log different eCommerce events, see below for + mParticle's additional ecommerce EventCategory types: + + 10: ProductAddToCart, (as shown above) + 11: ProductRemoveFromCart, + 12: ProductCheckout, + 13: ProductCheckoutOption, + 14: ProductClick, + 15: ProductViewDetail, + 16: ProductPurchase, + 17: ProductRefund, + 18: PromotionView, + 19: PromotionClick, + 20: ProductAddToWishlist, + 21: ProductRemoveFromWishlist, + 22: ProductImpression + */ + }; + + var commerceHandler = CommerceHandler; + + function EventHandler(common) { + this.common = common || {}; + } + + EventHandler.prototype.logEvent = function(event) { + var MBOXNAME = event.CustomFlags['ADOBETARGET.MBOX']; + var successHandler = event.CustomFlags['ADOBETARGET.SUCCESS']; + var errorHandler = event.CustomFlags['ADOBETARGET.ERROR']; + var getOffer = event.CustomFlags['ADOBETARGET.GETOFFER']; + var timeout = event.CustomFlags['ADOBETARGET.TIMEOUT']; + + if (!MBOXNAME) { + console.warn( + 'ADOBE.MBOX not passed as custom flag; not forwarding to Adobe Target' + ); + return false; + } + + var params = {}; + for (var key in event.EventAttributes) { + params[key] = event.EventAttributes[key]; + } + + var options = { + mbox: MBOXNAME, + params: params, + }; + + if (timeout) { + options.timeout = timeout; + } + + // an event is either a getOffer event or a trackEvent event + if (getOffer) { + options.success = function(offer) { + window.adobe.target.applyOffer(offer); + if (successHandler && typeof successHandler === 'function') { + successHandler(offer); + } + }; + options.error = function(status, error) { + if (errorHandler && typeof errorHandler === 'function') { + errorHandler(status, error); + } + }; + window.adobe.target.getOffer(options); + } else { + var selector = event.CustomFlags['ADOBETARGET.SELECTOR']; + var type = event.CustomFlags['ADOBETARGET.TYPE']; + var preventDefault = event.CustomFlags['ADOBETARGET.PREVENTDEFAULT']; + + if (selector) { + options.selector = selector; + } + if (type) { + options.type = type; + } + if (preventDefault) { + options.preventDefault = preventDefault; + } + + window.adobe.target.trackEvent(options); + } + + return true; + }; + + EventHandler.prototype.logError = function() {}; + + EventHandler.prototype.logPageView = function(event) { + this.logEvent(event); + }; + + var eventHandler = EventHandler; + + /* + The 'mParticleUser' is an object with methods get user Identities and set/get user attributes + Partners can determine what userIds are available to use in their SDK + Call mParticleUser.getUserIdentities() to return an object of userIdentities --> { userIdentities: {customerid: '1234', email: 'email@gmail.com'} } + For more identity types, see http://docs.mparticle.com/developers/sdk/javascript/identity#allowed-identity-types + Call mParticleUser.getMPID() to get mParticle ID + For any additional methods, see http://docs.mparticle.com/developers/sdk/javascript/apidocs/classes/mParticle.Identity.getCurrentUser().html + */ + + /* + identityApiRequest has the schema: + { + userIdentities: { + customerid: '123', + email: 'abc' + } + } + For more userIdentity types, see http://docs.mparticle.com/developers/sdk/javascript/identity#allowed-identity-types + */ + + function IdentityHandler(common) { + this.common = common || {}; + } + IdentityHandler.prototype.onUserIdentified = function(mParticleUser) {}; + IdentityHandler.prototype.onIdentifyComplete = function( + mParticleUser, + identityApiRequest + ) {}; + IdentityHandler.prototype.onLoginComplete = function( + mParticleUser, + identityApiRequest + ) {}; + IdentityHandler.prototype.onLogoutComplete = function( + mParticleUser, + identityApiRequest + ) {}; + IdentityHandler.prototype.onModifyComplete = function( + mParticleUser, + identityApiRequest + ) {}; + + /* In previous versions of the mParticle web SDK, setting user identities on + kits is only reachable via the onSetUserIdentity method below. We recommend + filling out `onSetUserIdentity` for maximum compatibility + */ + IdentityHandler.prototype.onSetUserIdentity = function( + forwarderSettings, + id, + type + ) {}; + + var identityHandler = IdentityHandler; + + var initialization = { + name: 'AdobeTarget', + initForwarder: function( + forwarderSettings, + testMode, + userAttributes, + userIdentities, + processEvent, + eventQueue, + isInitialized + ) { + if (!testMode) { + // Adobe Target's at.js file is hosted by the customer, loaded before mParticle.js, and has initialization code inside of at.js + var adobeTargetPresent = window.adobe && window.adobe.target; + } + }, + }; + + var initialization_1 = initialization; + + var sessionHandler = { + onSessionStart: function(event) {}, + onSessionEnd: function(event) {}, + }; + + var sessionHandler_1 = sessionHandler; + + /* + The 'mParticleUser' is an object with methods on it to get user Identities and set/get user attributes + Partners can determine what userIds are available to use in their SDK + Call mParticleUser.getUserIdentities() to return an object of userIdentities --> { userIdentities: {customerid: '1234', email: 'email@gmail.com'} } + For more identity types, see http://docs.mparticle.com/developers/sdk/javascript/identity#allowed-identity-types + Call mParticleUser.getMPID() to get mParticle ID + For any additional methods, see http://docs.mparticle.com/developers/sdk/javascript/apidocs/classes/mParticle.Identity.getCurrentUser().html + */ + + function UserAttributeHandler(common) { + this.common = common = {}; + } + UserAttributeHandler.prototype.onRemoveUserAttribute = function( + key, + mParticleUser + ) {}; + UserAttributeHandler.prototype.onSetUserAttribute = function( + key, + value, + mParticleUser + ) {}; + UserAttributeHandler.prototype.onConsentStateUpdated = function( + oldState, + newState, + mParticleUser + ) {}; + + var userAttributeHandler = UserAttributeHandler; + + // =============== REACH OUT TO MPARTICLE IF YOU HAVE ANY QUESTIONS =============== + // + // Copyright 2018 mParticle, Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + + + + + + + + + var name = initialization_1.name, + moduleId = initialization_1.moduleId, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + Media: 20, + }; + + var constructor = function() { + var self = this, + isInitialized = false, + forwarderSettings, + reportingService, + eventQueue = []; + + self.name = initialization_1.name; + self.moduleId = initialization_1.moduleId; + self.common = new common(); + + function initForwarder( + settings, + service, + testMode, + trackerId, + userAttributes, + userIdentities, + appVersion, + appName, + customFlags, + clientId + ) { + forwarderSettings = settings; + + if ( + typeof window !== 'undefined' && + window.mParticle.isTestEnvironment + ) { + reportingService = function() {}; + } else { + reportingService = service; + } + + try { + initialization_1.initForwarder( + settings, + testMode, + userAttributes, + userIdentities, + processEvent, + eventQueue, + isInitialized, + self.common, + appVersion, + appName, + customFlags, + clientId + ); + self.eventHandler = new eventHandler(self.common); + self.identityHandler = new identityHandler(self.common); + self.userAttributeHandler = new userAttributeHandler(self.common); + self.commerceHandler = new commerceHandler(self.common); + + isInitialized = true; + } catch (e) { + console.log('Failed to initialize ' + name + ' - ' + e); + } + } + + function processEvent(event) { + var reportEvent = false; + if (isInitialized) { + try { + if (event.EventDataType === MessageType.SessionStart) { + reportEvent = logSessionStart(event); + } else if (event.EventDataType === MessageType.SessionEnd) { + reportEvent = logSessionEnd(event); + } else if (event.EventDataType === MessageType.CrashReport) { + reportEvent = logError(event); + } else if (event.EventDataType === MessageType.PageView) { + reportEvent = logPageView(event); + } else if (event.EventDataType === MessageType.Commerce) { + reportEvent = logEcommerceEvent(event); + } else if (event.EventDataType === MessageType.PageEvent) { + reportEvent = logEvent(event); + } else if (event.EventDataType === MessageType.Media) { + // Kits should just treat Media Events as generic Events + reportEvent = logEvent(event); + } + if (reportEvent === true && reportingService) { + reportingService(self, event); + return 'Successfully sent to ' + name; + } else { + return ( + 'Error logging event or event type not supported on forwarder ' + + name + ); + } + } catch (e) { + return 'Failed to send to ' + name + ' ' + e; + } + } else { + eventQueue.push(event); + return ( + "Can't send to forwarder " + + name + + ', not initialized. Event added to queue.' + ); + } + } + + function logSessionStart(event) { + try { + sessionHandler_1.onSessionStart(event); + return true; + } catch (e) { + return { + error: 'Error starting session on forwarder ' + name + '; ' + e, + }; + } + } + + function logSessionEnd(event) { + try { + sessionHandler_1.onSessionEnd(event); + return true; + } catch (e) { + return { + error: 'Error ending session on forwarder ' + name + '; ' + e, + }; + } + } + + function logError(event) { + try { + self.eventHandler.logError(event); + return true; + } catch (e) { + return { + error: 'Error logging error on forwarder ' + name + '; ' + e, + }; + } + } + + function logPageView(event) { + try { + self.eventHandler.logPageView(event); + return true; + } catch (e) { + return { + error: + 'Error logging page view on forwarder ' + name + '; ' + e, + }; + } + } + + function logEvent(event) { + try { + self.eventHandler.logEvent(event); + return true; + } catch (e) { + return { + error: 'Error logging event on forwarder ' + name + '; ' + e, + }; + } + } + + function logEcommerceEvent(event) { + try { + self.commerceHandler.logCommerceEvent(event); + return true; + } catch (e) { + return { + error: + 'Error logging purchase event on forwarder ' + + name + + '; ' + + e, + }; + } + } + + function setUserAttribute(key, value) { + if (isInitialized) { + try { + self.userAttributeHandler.onSetUserAttribute( + key, + value, + forwarderSettings + ); + return 'Successfully set user attribute on forwarder ' + name; + } catch (e) { + return ( + 'Error setting user attribute on forwarder ' + + name + + '; ' + + e + ); + } + } else { + return ( + "Can't set user attribute on forwarder " + + name + + ', not initialized' + ); + } + } + + function removeUserAttribute(key) { + if (isInitialized) { + try { + self.userAttributeHandler.onRemoveUserAttribute( + key, + forwarderSettings + ); + return ( + 'Successfully removed user attribute on forwarder ' + name + ); + } catch (e) { + return ( + 'Error removing user attribute on forwarder ' + + name + + '; ' + + e + ); + } + } else { + return ( + "Can't remove user attribute on forwarder " + + name + + ', not initialized' + ); + } + } + + function setUserIdentity(id, type) { + if (isInitialized) { + try { + self.identityHandler.onSetUserIdentity( + forwarderSettings, + id, + type + ); + return 'Successfully set user Identity on forwarder ' + name; + } catch (e) { + return ( + 'Error removing user attribute on forwarder ' + + name + + '; ' + + e + ); + } + } else { + return ( + "Can't call setUserIdentity on forwarder " + + name + + ', not initialized' + ); + } + } + + function onUserIdentified(user) { + if (isInitialized) { + try { + self.identityHandler.onUserIdentified(user); + + return ( + 'Successfully called onUserIdentified on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onUserIdentified on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't set new user identities on forwader " + + name + + ', not initialized' + ); + } + } + + function onIdentifyComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onIdentifyComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onIdentifyComplete on forwarder ' + + name + ); + } catch (e) { + return { + error: + 'Error calling onIdentifyComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onIdentifyCompleted on forwader " + + name + + ', not initialized' + ); + } + } + + function onLoginComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onLoginComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onLoginComplete on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onLoginComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onLoginComplete on forwader " + + name + + ', not initialized' + ); + } + } + + function onLogoutComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onLogoutComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onLogoutComplete on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onLogoutComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onLogoutComplete on forwader " + + name + + ', not initialized' + ); + } + } + + function onModifyComplete(user, filteredIdentityRequest) { + if (isInitialized) { + try { + self.identityHandler.onModifyComplete( + user, + filteredIdentityRequest + ); + + return ( + 'Successfully called onModifyComplete on forwarder ' + name + ); + } catch (e) { + return { + error: + 'Error calling onModifyComplete on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call onModifyComplete on forwader " + + name + + ', not initialized' + ); + } + } + + function setOptOut(isOptingOutBoolean) { + if (isInitialized) { + try { + self.initialization.setOptOut(isOptingOutBoolean); + + return 'Successfully called setOptOut on forwarder ' + name; + } catch (e) { + return { + error: + 'Error calling setOptOut on forwarder ' + + name + + '; ' + + e, + }; + } + } else { + return ( + "Can't call setOptOut on forwader " + + name + + ', not initialized' + ); + } + } + + this.init = initForwarder; + this.process = processEvent; + this.setUserAttribute = setUserAttribute; + this.removeUserAttribute = removeUserAttribute; + this.onUserIdentified = onUserIdentified; + this.setUserIdentity = setUserIdentity; + this.onIdentifyComplete = onIdentifyComplete; + this.onLoginComplete = onLoginComplete; + this.onLogoutComplete = onLogoutComplete; + this.onModifyComplete = onModifyComplete; + this.setOptOut = setOptOut; + }; + + function getId() { + return moduleId; + } + + function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); + } + + function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + "'config' must be an object. You passed in a " + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); + } + + if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } + } + + var webKitWrapper = { + register: register, + }; + var webKitWrapper_1 = webKitWrapper.register; + + exports.default = webKitWrapper; + exports.register = webKitWrapper_1; + + return exports; + +}({})); diff --git a/kits/adwords/dist/GoogleAdWordsEventForwarder.common.js b/kits/adwords/dist/GoogleAdWordsEventForwarder.common.js new file mode 100644 index 000000000..0497e854d --- /dev/null +++ b/kits/adwords/dist/GoogleAdWordsEventForwarder.common.js @@ -0,0 +1,839 @@ +Object.defineProperty(exports, '__esModule', { value: true }); + +/* eslint-disable no-undef*/ + +// +// Copyright 2017 mParticle, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var name = 'GoogleAdWords', + moduleId = 82, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + }, + ENHANCED_CONVERSION_DATA = 'GoogleAds.ECData'; + +// Declares valid Google consent values +var googleConsentValues = { + // Server Integration uses 'Unspecified' as a value when the setting is 'not set'. + // However, this is not used by Google's Web SDK. We are referencing it here as a comment + // as a record of this distinction and for posterity. + // If Google ever adds this for web, the line can just be uncommented to support this. + // + // Docs: + // Web: https://developers.google.com/tag-platform/gtagjs/reference#consent + // S2S: https://developers.google.com/google-ads/api/reference/rpc/v15/ConsentStatusEnum.ConsentStatus + // + // Unspecified: 'unspecified', + Denied: 'denied', + Granted: 'granted', +}; + +// Declares list of valid Google Consent Properties +var googleConsentProperties = [ + 'ad_storage', + 'ad_user_data', + 'ad_personalization', + 'analytics_storage', +]; + +var constructor = function() { + var self = this, + isInitialized = false, + forwarderSettings, + labels, + customAttributeMappings, + consentMappings = [], + consentPayloadDefaults = {}, + consentPayloadAsString = '', + reportingService, + eventQueue = [], + gtagSiteId; + + self.name = name; + + function processEvent(event) { + var reportEvent = false; + var sendEventFunction = function() {}; + var generateEventFunction = function() {}; + var conversionLabel; + var eventPayload; + + if (isInitialized) { + // First, process anything in the queue + processQueue(eventQueue); + + try { + if (window.gtag && forwarderSettings.enableGtag == 'True') { + // If consent payload is empty, + // we never sent an initial default consent state + // so we shouldn't send an update. + var eventConsentState = getEventConsentState( + event.ConsentState + ); + maybeSendConsentUpdateToGoogle(eventConsentState); + + if ( + forwarderSettings.enableEnhancedConversions === + 'True' && + hasEnhancedConversionData(event.CustomFlags) + ) { + window.enhanced_conversion_data = parseEnhancedConversionData( + event.CustomFlags[ENHANCED_CONVERSION_DATA] + ); + } + + sendEventFunction = sendGtagEvent; + generateEventFunction = generateGtagEvent; + generateCommerceEvent = generateGtagCommerceEvent; + } else if (window.google_trackConversion) { + // window.google_trackConversion is a legacy API and will be deprecated + sendEventFunction = sendAdwordsEvent; + generateEventFunction = generateAdwordsEvent; + generateCommerceEvent = generateAdwordsCommerceEvent; + } else { + eventQueue.push({ + action: processEvent, + data: event, + }); + + return ( + "Can't send to forwarder " + + name + + ', not initialized. Event added to queue.' + ); + } + + // Get conversionLabel to be used for event generation + var conversionLabel = getConversionLabel(event); + var customProps = getCustomProps(event); + + if (conversionLabel) { + // Determines the proper event to fire + if ( + event.EventDataType == MessageType.PageView || + event.EventDataType == MessageType.PageEvent + ) { + eventPayload = generateEventFunction( + event, + conversionLabel, + customProps + ); + } else if ( + event.EventDataType == MessageType.Commerce && + event.ProductAction + ) { + eventPayload = generateCommerceEvent( + event, + conversionLabel, + customProps + ); + } + + if (eventPayload) { + reportEvent = sendEventFunction(eventPayload); + } + + if (reportEvent && reportingService) { + reportingService(self, event); + + return 'Successfully sent to ' + name; + } + } + + return ( + "Can't send to forwarder: " + name + '. Event not mapped' + ); + } catch (e) { + console.error('Can\t send to forwarder', e); + return "Can't send to forwarder: " + name + ' ' + e; + } + } else { + eventQueue.push({ + action: processEvent, + data: event, + }); + } + + return ( + "Can't send to forwarder " + + name + + ', not initialized. Event added to queue.' + ); + } + + function hasEnhancedConversionData(customFlags) { + return ( + customFlags && + Object.keys(customFlags).length && + customFlags[ENHANCED_CONVERSION_DATA] + ); + } + + function parseEnhancedConversionData(conversionData) { + // Checks if conversion data in custom flags is a stringified object + // Conversion data should only be a stringified object or a JS object + if (typeof conversionData === 'string') { + try { + return JSON.parse(conversionData); + } catch (error) { + console.warn( + 'Unrecognized Enhanced Conversion Data Format', + conversionData, + error + ); + return {}; + } + } else if (typeof conversionData === 'object') { + // Not a stringified object so it can be used as-is. However, + // we want to avoid mutating the original state, so we make a copy. + return cloneObject(conversionData); + } else { + console.warn( + 'Unrecognized Enhanced Conversion Data Format', + conversionData + ); + return {}; + } + } + + // Converts an mParticle Commerce Event into either Legacy or gtag Event + function generateCommerceEvent(mPEvent, conversionLabel, isPageEvent) { + if ( + mPEvent.ProductAction && + mPEvent.ProductAction.ProductList && + mPEvent.ProductAction.ProductActionType + ) { + if (window.gtag && forwarderSettings.enableGtag == 'True') { + return generateGtagCommerceEvent( + mPEvent, + conversionLabel, + isPageEvent + ); + } else if (window.google_trackConversion) { + return generateAdwordsCommerceEvent( + mPEvent, + conversionLabel, + isPageEvent + ); + } else { + console.error('Unrecognized Commerce Event', mPEvent); + return false; + } + } else { + return false; + } + } + + function getUserConsentState() { + var userConsentState = {}; + + if ( + window.mParticle && + window.mParticle.Identity && + window.mParticle.Identity.getCurrentUser + ) { + var currentUser = window.mParticle.Identity.getCurrentUser(); + + if (!currentUser) { + return {}; + } + + var consentState = window.mParticle.Identity.getCurrentUser().getConsentState(); + + if (consentState && consentState.getGDPRConsentState) { + userConsentState = consentState.getGDPRConsentState(); + } + } + + return userConsentState; + } + + function getEventConsentState(eventConsentState) { + return eventConsentState && eventConsentState.getGDPRConsentState + ? eventConsentState.getGDPRConsentState() + : {}; + } + + // ** Adwords Events + function getBaseAdWordEvent() { + var adWordEvent = {}; + adWordEvent.google_conversion_value = 0; + adWordEvent.google_conversion_language = 'en'; + adWordEvent.google_conversion_format = '3'; + adWordEvent.google_conversion_color = 'ffffff'; + adWordEvent.google_remarketing_only = + forwarderSettings.remarketingOnly == 'True'; + adWordEvent.google_conversion_id = forwarderSettings.conversionId; + return adWordEvent; + } + + function generateAdwordsEvent(mPEvent, conversionLabel, customProps) { + var adWordEvent = getBaseAdWordEvent(); + adWordEvent.google_conversion_label = conversionLabel; + adWordEvent.google_custom_params = customProps; + + return adWordEvent; + } + + function generateAdwordsCommerceEvent( + mPEvent, + conversionLabel, + customProps + ) { + var adWordEvent = getBaseAdWordEvent(); + adWordEvent.google_conversion_label = conversionLabel; + + if ( + mPEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase && + mPEvent.ProductAction.TransactionId + ) { + adWordEvent.google_conversion_order_id = + mPEvent.ProductAction.TransactionId; + } + + if (mPEvent.CurrencyCode) { + adWordEvent.google_conversion_currency = mPEvent.CurrencyCode; + } + + if (mPEvent.ProductAction.TotalAmount) { + adWordEvent.google_conversion_value = + mPEvent.ProductAction.TotalAmount; + } + + adWordEvent.google_custom_params = customProps; + return adWordEvent; + } + + function getConsentSettings() { + var consentSettings = {}; + + var googleToMpConsentSettingsMapping = { + // Inherited from S2S Integration Settings + ad_user_data: 'defaultAdUserDataConsent', + ad_personalization: 'defaultAdPersonalizationConsent', + + // Unique to Web Kits + ad_storage: 'defaultAdStorageConsentWeb', + analytics_storage: 'defaultAnalyticsStorageConsentWeb', + }; + + Object.keys(googleToMpConsentSettingsMapping).forEach(function( + googleConsentKey + ) { + var mpConsentSettingKey = + googleToMpConsentSettingsMapping[googleConsentKey]; + var googleConsentValuesKey = forwarderSettings[mpConsentSettingKey]; + + if (googleConsentValuesKey && mpConsentSettingKey) { + consentSettings[googleConsentKey] = + googleConsentValues[googleConsentValuesKey]; + } + }); + + return consentSettings; + } + + // gtag Events + function getBaseGtagEvent(conversionLabel) { + return { + send_to: gtagSiteId + '/' + conversionLabel, + value: 0, + language: 'en', + remarketing_only: forwarderSettings.remarketingOnly == 'True', + }; + } + + function generateGtagEvent(mPEvent, conversionLabel, customProps) { + if (!conversionLabel) { + return null; + } + + var conversionPayload = getBaseGtagEvent(conversionLabel); + conversionPayload.transaction_id = mPEvent.SourceMessageId; + return mergeObjects(conversionPayload, customProps); + } + + function generateGtagCommerceEvent(mPEvent, conversionLabel, customProps) { + if (!conversionLabel) { + return null; + } + + var conversionPayload = getBaseGtagEvent(conversionLabel); + + if ( + mPEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase && + mPEvent.ProductAction.TransactionId + ) { + conversionPayload.transaction_id = + mPEvent.ProductAction.TransactionId; + } else { + conversionPayload.transaction_id = mPEvent.SourceMessageId; + } + + if (mPEvent.CurrencyCode) { + conversionPayload.currency = mPEvent.CurrencyCode; + } + + if (mPEvent.ProductAction.TotalAmount) { + conversionPayload.value = mPEvent.ProductAction.TotalAmount; + } + + return mergeObjects(conversionPayload, customProps); + } + + function sendGtagEvent(payload) { + // https://go.mparticle.com/work/SQDSDKS-6165 + try { + gtag('event', 'conversion', payload); + } catch (e) { + console.error( + 'gtag is not available to send payload: ', + payload, + e + ); + return false; + } + return true; + } + + function maybeSendConsentUpdateToGoogle(consentState) { + if ( + consentPayloadAsString && + forwarderSettings.consentMappingWeb && + !isEmpty(consentState) + ) { + var updatedConsentPayload = generateConsentStatePayloadFromMappings( + consentState, + consentMappings + ); + + var eventConsentAsString = JSON.stringify(updatedConsentPayload); + + if (eventConsentAsString !== consentPayloadAsString) { + sendGtagConsentUpdate(updatedConsentPayload); + consentPayloadAsString = eventConsentAsString; + } + } + } + + function sendGtagConsentDefaults(payload) { + // https://go.mparticle.com/work/SQDSDKS-6165 + consentPayloadAsString = JSON.stringify(payload); + + try { + gtag('consent', 'default', payload); + } catch (e) { + console.error( + 'gtag is not available to send consent defaults: ', + payload, + e + ); + return false; + } + return true; + } + + function sendGtagConsentUpdate(payload) { + // https://go.mparticle.com/work/SQDSDKS-6165 + try { + gtag('consent', 'update', payload); + } catch (e) { + console.error( + 'gtag is not available to send consent update: ', + payload, + e + ); + return false; + } + return true; + } + + function sendAdwordsEvent(payload) { + try { + window.google_trackConversion(payload); + } catch (e) { + console.error( + 'google_trackConversion is not available to send payload: ', + payload, + e + ); + return false; + } + return true; + } + + // Creates a new Consent State Payload based on Consent State and Mapping + function generateConsentStatePayloadFromMappings(consentState, mappings) { + if (!mappings) return {}; + var payload = cloneObject(consentPayloadDefaults); + + for (var i = 0; i <= mappings.length - 1; i++) { + var mappingEntry = mappings[i]; + // Although consent purposes can be inputted into the UI in any casing + // the SDK will automatically lowercase them to prevent pseudo-duplicate + // consent purposes, so we call `toLowerCase` on the consentMapping purposes here + var mpMappedConsentName = mappingEntry.map.toLowerCase(); + // var mpMappedConsentName = mappingEntry.map; + var googleMappedConsentName = mappingEntry.value; + + if ( + consentState[mpMappedConsentName] && + googleConsentProperties.indexOf(googleMappedConsentName) !== -1 + ) { + payload[googleMappedConsentName] = consentState[ + mpMappedConsentName + ].Consented + ? googleConsentValues.Granted + : googleConsentValues.Denied; + } + } + + return payload; + } + + // Looks up an Event's conversionLabel from customAttributeMappings based on computed jsHash value + function getConversionLabel(event) { + var jsHash = calculateJSHash( + event.EventDataType, + event.EventCategory, + event.EventName + ); + var type = + event.EventDataType === MessageType.PageEvent + ? 'EventClass.Id' + : 'EventClassDetails.Id'; + var conversionLabel = null; + var mappingEntry = findValueInMapping(jsHash, type, labels); + + if (mappingEntry) { + conversionLabel = mappingEntry.value; + } + + return conversionLabel; + } + + // Filters Event.EventAttributes for attributes that are in customAttributeMappings + function getCustomProps(event) { + var customProps = {}; + var attributes = event.EventAttributes; + var type = + event.EventDataType === MessageType.PageEvent + ? 'EventAttributeClass.Id' + : 'EventAttributeClassDetails.Id'; + + if (attributes) { + for (var attributeKey in attributes) { + if (attributes.hasOwnProperty(attributeKey)) { + var jsHash = calculateJSHash( + event.EventDataType, + event.EventCategory, + attributeKey + ); + var mappingEntry = findValueInMapping( + jsHash, + type, + customAttributeMappings + ); + if (mappingEntry) { + customProps[mappingEntry.value] = + attributes[attributeKey]; + } + } + } + } + + return customProps; + } + + function findValueInMapping(jsHash, type, mapping) { + if (mapping) { + var filteredArray = mapping.filter(function(mappingEntry) { + if ( + mappingEntry.jsmap && + mappingEntry.maptype && + mappingEntry.value + ) { + return ( + mappingEntry.jsmap == jsHash && + mappingEntry.maptype == type + ); + } + + return false; + }); + + if (filteredArray && filteredArray.length > 0) { + return filteredArray[0]; + } + } + return null; + } + + function calculateJSHash(eventDataType, eventCategory, name) { + var preHash = [eventDataType, eventCategory, name].join(''); + + return mParticle.generateHash(preHash); + } + + function loadGtagSnippet() { + (function() { + window.dataLayer = window.dataLayer || []; + window.gtag = function() { + dataLayer.push(arguments); + }; + + var gTagScript = document.createElement('script'); + gTagScript.async = true; + gTagScript.onload = function() { + gtag('js', new Date()); + if (forwarderSettings.enableEnhancedConversions === 'True') { + gtag('config', gtagSiteId, { + allow_enhanced_conversions: true, + }); + } else { + gtag('config', gtagSiteId); + } + isInitialized = true; + processQueue(eventQueue); + }; + gTagScript.src = + 'https://www.googletagmanager.com/gtag/js?id=' + gtagSiteId; + document.getElementsByTagName('head')[0].appendChild(gTagScript); + })(); + } + + function loadLegacySnippet() { + (function() { + var googleAdwords = document.createElement('script'); + googleAdwords.type = 'text/javascript'; + googleAdwords.async = true; + googleAdwords.onload = function() { + isInitialized = true; + processQueue(eventQueue); + }; + googleAdwords.src = + ('https:' == document.location.protocol ? 'https' : 'http') + + '://www.googleadservices.com/pagead/conversion_async.js'; + document.getElementsByTagName('head')[0].appendChild(googleAdwords); + })(); + } + + // https://go.mparticle.com/work/SQDSDKS-6166 + function initForwarder(settings, service, testMode) { + window.enhanced_conversion_data = {}; + forwarderSettings = settings; + reportingService = service; + + try { + if (!forwarderSettings.conversionId) { + return ( + "Can't initialize forwarder: " + + name + + ', conversionId is not defined' + ); + } + + gtagSiteId = 'AW-' + forwarderSettings.conversionId; + + if (testMode !== true) { + if (forwarderSettings.enableGtag == 'True') { + loadGtagSnippet(); + } else { + loadLegacySnippet(); + } + } else { + isInitialized = true; + processQueue(eventQueue); + } + + if (!forwarderSettings.conversionId) { + return ( + "Can't initialize forwarder: " + + name + + ', conversionId is not defined' + ); + } + + // https://go.mparticle.com/work/SQDSDKS-6165 + if (window.gtag && forwarderSettings.enableGtag === 'True') { + if (forwarderSettings.consentMappingWeb) { + consentMappings = parseSettingsString( + forwarderSettings.consentMappingWeb + ); + } else { + // Ensures consent mappings is an empty array + // for future use + consentMappings = []; + } + + consentPayloadDefaults = getConsentSettings(); + var defaultConsentPayload = cloneObject(consentPayloadDefaults); + var updatedConsentState = getUserConsentState(); + var updatedDefaultConsentPayload = generateConsentStatePayloadFromMappings( + updatedConsentState, + consentMappings + ); + + if (!isEmpty(defaultConsentPayload)) { + sendGtagConsentDefaults(defaultConsentPayload); + } else if (!isEmpty(updatedDefaultConsentPayload)) { + sendGtagConsentDefaults(updatedDefaultConsentPayload); + } + + maybeSendConsentUpdateToGoogle(updatedConsentState); + } + + forwarderSettings.remarketingOnly = + forwarderSettings.remarketingOnly == 'True'; + + try { + if (forwarderSettings.labels) { + labels = JSON.parse( + forwarderSettings.labels.replace(/"/g, '"') + ); + } + + if (forwarderSettings.customParameters) { + customAttributeMappings = JSON.parse( + forwarderSettings.customParameters.replace( + /"/g, + '"' + ) + ); + } + } catch (e) { + return ( + "Can't initialize forwarder: " + + name + + ', Could not process event to label mapping' + ); + } + + return 'Successfully initialized: ' + name; + } catch (e) { + return 'Failed to initialize: ' + name; + } + } + + function processQueue(queue) { + var item; + + if ( + (window.gtag || window.google_trackConversion) && + queue.length > 0 + ) { + try { + while (queue.length > 0) { + item = queue.shift(); + item.action(item.data); + } + } catch (e) { + console.error('Error on mParticle Adwords Kit', e); + } + } + } + + this.init = initForwarder; + this.process = processEvent; + this.processQueue = processQueue; +}; + +function getId() { + return moduleId; +} + +function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + "'config' must be an object. You passed in a " + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); +} + +function parseSettingsString(settingsString) { + return JSON.parse(settingsString.replace(/"/g, '"')); +} + +function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); +} + +function isEmpty(value) { + return value == null || !(Object.keys(value) || value).length; +} + +function mergeObjects() { + var resObj = {}; + for (var i = 0; i < arguments.length; i += 1) { + var obj = arguments[i], + keys = Object.keys(obj); + for (var j = 0; j < keys.length; j += 1) { + resObj[keys[j]] = obj[keys[j]]; + } + } + return resObj; +} + +function cloneObject(obj) { + return JSON.parse(JSON.stringify(obj)); +} + +if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } +} + +var GoogleAdWordsEventForwarder = { + register: register, +}; + +exports.default = GoogleAdWordsEventForwarder; diff --git a/kits/adwords/dist/GoogleAdWordsEventForwarder.iife.js b/kits/adwords/dist/GoogleAdWordsEventForwarder.iife.js new file mode 100644 index 000000000..ff4265579 --- /dev/null +++ b/kits/adwords/dist/GoogleAdWordsEventForwarder.iife.js @@ -0,0 +1,842 @@ +var mpAdWordsKit = (function (exports) { + /* eslint-disable no-undef*/ + + // + // Copyright 2017 mParticle, Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + var name = 'GoogleAdWords', + moduleId = 82, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + }, + ENHANCED_CONVERSION_DATA = 'GoogleAds.ECData'; + + // Declares valid Google consent values + var googleConsentValues = { + // Server Integration uses 'Unspecified' as a value when the setting is 'not set'. + // However, this is not used by Google's Web SDK. We are referencing it here as a comment + // as a record of this distinction and for posterity. + // If Google ever adds this for web, the line can just be uncommented to support this. + // + // Docs: + // Web: https://developers.google.com/tag-platform/gtagjs/reference#consent + // S2S: https://developers.google.com/google-ads/api/reference/rpc/v15/ConsentStatusEnum.ConsentStatus + // + // Unspecified: 'unspecified', + Denied: 'denied', + Granted: 'granted', + }; + + // Declares list of valid Google Consent Properties + var googleConsentProperties = [ + 'ad_storage', + 'ad_user_data', + 'ad_personalization', + 'analytics_storage', + ]; + + var constructor = function() { + var self = this, + isInitialized = false, + forwarderSettings, + labels, + customAttributeMappings, + consentMappings = [], + consentPayloadDefaults = {}, + consentPayloadAsString = '', + reportingService, + eventQueue = [], + gtagSiteId; + + self.name = name; + + function processEvent(event) { + var reportEvent = false; + var sendEventFunction = function() {}; + var generateEventFunction = function() {}; + var conversionLabel; + var eventPayload; + + if (isInitialized) { + // First, process anything in the queue + processQueue(eventQueue); + + try { + if (window.gtag && forwarderSettings.enableGtag == 'True') { + // If consent payload is empty, + // we never sent an initial default consent state + // so we shouldn't send an update. + var eventConsentState = getEventConsentState( + event.ConsentState + ); + maybeSendConsentUpdateToGoogle(eventConsentState); + + if ( + forwarderSettings.enableEnhancedConversions === + 'True' && + hasEnhancedConversionData(event.CustomFlags) + ) { + window.enhanced_conversion_data = parseEnhancedConversionData( + event.CustomFlags[ENHANCED_CONVERSION_DATA] + ); + } + + sendEventFunction = sendGtagEvent; + generateEventFunction = generateGtagEvent; + generateCommerceEvent = generateGtagCommerceEvent; + } else if (window.google_trackConversion) { + // window.google_trackConversion is a legacy API and will be deprecated + sendEventFunction = sendAdwordsEvent; + generateEventFunction = generateAdwordsEvent; + generateCommerceEvent = generateAdwordsCommerceEvent; + } else { + eventQueue.push({ + action: processEvent, + data: event, + }); + + return ( + "Can't send to forwarder " + + name + + ', not initialized. Event added to queue.' + ); + } + + // Get conversionLabel to be used for event generation + var conversionLabel = getConversionLabel(event); + var customProps = getCustomProps(event); + + if (conversionLabel) { + // Determines the proper event to fire + if ( + event.EventDataType == MessageType.PageView || + event.EventDataType == MessageType.PageEvent + ) { + eventPayload = generateEventFunction( + event, + conversionLabel, + customProps + ); + } else if ( + event.EventDataType == MessageType.Commerce && + event.ProductAction + ) { + eventPayload = generateCommerceEvent( + event, + conversionLabel, + customProps + ); + } + + if (eventPayload) { + reportEvent = sendEventFunction(eventPayload); + } + + if (reportEvent && reportingService) { + reportingService(self, event); + + return 'Successfully sent to ' + name; + } + } + + return ( + "Can't send to forwarder: " + name + '. Event not mapped' + ); + } catch (e) { + console.error('Can\t send to forwarder', e); + return "Can't send to forwarder: " + name + ' ' + e; + } + } else { + eventQueue.push({ + action: processEvent, + data: event, + }); + } + + return ( + "Can't send to forwarder " + + name + + ', not initialized. Event added to queue.' + ); + } + + function hasEnhancedConversionData(customFlags) { + return ( + customFlags && + Object.keys(customFlags).length && + customFlags[ENHANCED_CONVERSION_DATA] + ); + } + + function parseEnhancedConversionData(conversionData) { + // Checks if conversion data in custom flags is a stringified object + // Conversion data should only be a stringified object or a JS object + if (typeof conversionData === 'string') { + try { + return JSON.parse(conversionData); + } catch (error) { + console.warn( + 'Unrecognized Enhanced Conversion Data Format', + conversionData, + error + ); + return {}; + } + } else if (typeof conversionData === 'object') { + // Not a stringified object so it can be used as-is. However, + // we want to avoid mutating the original state, so we make a copy. + return cloneObject(conversionData); + } else { + console.warn( + 'Unrecognized Enhanced Conversion Data Format', + conversionData + ); + return {}; + } + } + + // Converts an mParticle Commerce Event into either Legacy or gtag Event + function generateCommerceEvent(mPEvent, conversionLabel, isPageEvent) { + if ( + mPEvent.ProductAction && + mPEvent.ProductAction.ProductList && + mPEvent.ProductAction.ProductActionType + ) { + if (window.gtag && forwarderSettings.enableGtag == 'True') { + return generateGtagCommerceEvent( + mPEvent, + conversionLabel, + isPageEvent + ); + } else if (window.google_trackConversion) { + return generateAdwordsCommerceEvent( + mPEvent, + conversionLabel, + isPageEvent + ); + } else { + console.error('Unrecognized Commerce Event', mPEvent); + return false; + } + } else { + return false; + } + } + + function getUserConsentState() { + var userConsentState = {}; + + if ( + window.mParticle && + window.mParticle.Identity && + window.mParticle.Identity.getCurrentUser + ) { + var currentUser = window.mParticle.Identity.getCurrentUser(); + + if (!currentUser) { + return {}; + } + + var consentState = window.mParticle.Identity.getCurrentUser().getConsentState(); + + if (consentState && consentState.getGDPRConsentState) { + userConsentState = consentState.getGDPRConsentState(); + } + } + + return userConsentState; + } + + function getEventConsentState(eventConsentState) { + return eventConsentState && eventConsentState.getGDPRConsentState + ? eventConsentState.getGDPRConsentState() + : {}; + } + + // ** Adwords Events + function getBaseAdWordEvent() { + var adWordEvent = {}; + adWordEvent.google_conversion_value = 0; + adWordEvent.google_conversion_language = 'en'; + adWordEvent.google_conversion_format = '3'; + adWordEvent.google_conversion_color = 'ffffff'; + adWordEvent.google_remarketing_only = + forwarderSettings.remarketingOnly == 'True'; + adWordEvent.google_conversion_id = forwarderSettings.conversionId; + return adWordEvent; + } + + function generateAdwordsEvent(mPEvent, conversionLabel, customProps) { + var adWordEvent = getBaseAdWordEvent(); + adWordEvent.google_conversion_label = conversionLabel; + adWordEvent.google_custom_params = customProps; + + return adWordEvent; + } + + function generateAdwordsCommerceEvent( + mPEvent, + conversionLabel, + customProps + ) { + var adWordEvent = getBaseAdWordEvent(); + adWordEvent.google_conversion_label = conversionLabel; + + if ( + mPEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase && + mPEvent.ProductAction.TransactionId + ) { + adWordEvent.google_conversion_order_id = + mPEvent.ProductAction.TransactionId; + } + + if (mPEvent.CurrencyCode) { + adWordEvent.google_conversion_currency = mPEvent.CurrencyCode; + } + + if (mPEvent.ProductAction.TotalAmount) { + adWordEvent.google_conversion_value = + mPEvent.ProductAction.TotalAmount; + } + + adWordEvent.google_custom_params = customProps; + return adWordEvent; + } + + function getConsentSettings() { + var consentSettings = {}; + + var googleToMpConsentSettingsMapping = { + // Inherited from S2S Integration Settings + ad_user_data: 'defaultAdUserDataConsent', + ad_personalization: 'defaultAdPersonalizationConsent', + + // Unique to Web Kits + ad_storage: 'defaultAdStorageConsentWeb', + analytics_storage: 'defaultAnalyticsStorageConsentWeb', + }; + + Object.keys(googleToMpConsentSettingsMapping).forEach(function( + googleConsentKey + ) { + var mpConsentSettingKey = + googleToMpConsentSettingsMapping[googleConsentKey]; + var googleConsentValuesKey = forwarderSettings[mpConsentSettingKey]; + + if (googleConsentValuesKey && mpConsentSettingKey) { + consentSettings[googleConsentKey] = + googleConsentValues[googleConsentValuesKey]; + } + }); + + return consentSettings; + } + + // gtag Events + function getBaseGtagEvent(conversionLabel) { + return { + send_to: gtagSiteId + '/' + conversionLabel, + value: 0, + language: 'en', + remarketing_only: forwarderSettings.remarketingOnly == 'True', + }; + } + + function generateGtagEvent(mPEvent, conversionLabel, customProps) { + if (!conversionLabel) { + return null; + } + + var conversionPayload = getBaseGtagEvent(conversionLabel); + conversionPayload.transaction_id = mPEvent.SourceMessageId; + return mergeObjects(conversionPayload, customProps); + } + + function generateGtagCommerceEvent(mPEvent, conversionLabel, customProps) { + if (!conversionLabel) { + return null; + } + + var conversionPayload = getBaseGtagEvent(conversionLabel); + + if ( + mPEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase && + mPEvent.ProductAction.TransactionId + ) { + conversionPayload.transaction_id = + mPEvent.ProductAction.TransactionId; + } else { + conversionPayload.transaction_id = mPEvent.SourceMessageId; + } + + if (mPEvent.CurrencyCode) { + conversionPayload.currency = mPEvent.CurrencyCode; + } + + if (mPEvent.ProductAction.TotalAmount) { + conversionPayload.value = mPEvent.ProductAction.TotalAmount; + } + + return mergeObjects(conversionPayload, customProps); + } + + function sendGtagEvent(payload) { + // https://go.mparticle.com/work/SQDSDKS-6165 + try { + gtag('event', 'conversion', payload); + } catch (e) { + console.error( + 'gtag is not available to send payload: ', + payload, + e + ); + return false; + } + return true; + } + + function maybeSendConsentUpdateToGoogle(consentState) { + if ( + consentPayloadAsString && + forwarderSettings.consentMappingWeb && + !isEmpty(consentState) + ) { + var updatedConsentPayload = generateConsentStatePayloadFromMappings( + consentState, + consentMappings + ); + + var eventConsentAsString = JSON.stringify(updatedConsentPayload); + + if (eventConsentAsString !== consentPayloadAsString) { + sendGtagConsentUpdate(updatedConsentPayload); + consentPayloadAsString = eventConsentAsString; + } + } + } + + function sendGtagConsentDefaults(payload) { + // https://go.mparticle.com/work/SQDSDKS-6165 + consentPayloadAsString = JSON.stringify(payload); + + try { + gtag('consent', 'default', payload); + } catch (e) { + console.error( + 'gtag is not available to send consent defaults: ', + payload, + e + ); + return false; + } + return true; + } + + function sendGtagConsentUpdate(payload) { + // https://go.mparticle.com/work/SQDSDKS-6165 + try { + gtag('consent', 'update', payload); + } catch (e) { + console.error( + 'gtag is not available to send consent update: ', + payload, + e + ); + return false; + } + return true; + } + + function sendAdwordsEvent(payload) { + try { + window.google_trackConversion(payload); + } catch (e) { + console.error( + 'google_trackConversion is not available to send payload: ', + payload, + e + ); + return false; + } + return true; + } + + // Creates a new Consent State Payload based on Consent State and Mapping + function generateConsentStatePayloadFromMappings(consentState, mappings) { + if (!mappings) return {}; + var payload = cloneObject(consentPayloadDefaults); + + for (var i = 0; i <= mappings.length - 1; i++) { + var mappingEntry = mappings[i]; + // Although consent purposes can be inputted into the UI in any casing + // the SDK will automatically lowercase them to prevent pseudo-duplicate + // consent purposes, so we call `toLowerCase` on the consentMapping purposes here + var mpMappedConsentName = mappingEntry.map.toLowerCase(); + // var mpMappedConsentName = mappingEntry.map; + var googleMappedConsentName = mappingEntry.value; + + if ( + consentState[mpMappedConsentName] && + googleConsentProperties.indexOf(googleMappedConsentName) !== -1 + ) { + payload[googleMappedConsentName] = consentState[ + mpMappedConsentName + ].Consented + ? googleConsentValues.Granted + : googleConsentValues.Denied; + } + } + + return payload; + } + + // Looks up an Event's conversionLabel from customAttributeMappings based on computed jsHash value + function getConversionLabel(event) { + var jsHash = calculateJSHash( + event.EventDataType, + event.EventCategory, + event.EventName + ); + var type = + event.EventDataType === MessageType.PageEvent + ? 'EventClass.Id' + : 'EventClassDetails.Id'; + var conversionLabel = null; + var mappingEntry = findValueInMapping(jsHash, type, labels); + + if (mappingEntry) { + conversionLabel = mappingEntry.value; + } + + return conversionLabel; + } + + // Filters Event.EventAttributes for attributes that are in customAttributeMappings + function getCustomProps(event) { + var customProps = {}; + var attributes = event.EventAttributes; + var type = + event.EventDataType === MessageType.PageEvent + ? 'EventAttributeClass.Id' + : 'EventAttributeClassDetails.Id'; + + if (attributes) { + for (var attributeKey in attributes) { + if (attributes.hasOwnProperty(attributeKey)) { + var jsHash = calculateJSHash( + event.EventDataType, + event.EventCategory, + attributeKey + ); + var mappingEntry = findValueInMapping( + jsHash, + type, + customAttributeMappings + ); + if (mappingEntry) { + customProps[mappingEntry.value] = + attributes[attributeKey]; + } + } + } + } + + return customProps; + } + + function findValueInMapping(jsHash, type, mapping) { + if (mapping) { + var filteredArray = mapping.filter(function(mappingEntry) { + if ( + mappingEntry.jsmap && + mappingEntry.maptype && + mappingEntry.value + ) { + return ( + mappingEntry.jsmap == jsHash && + mappingEntry.maptype == type + ); + } + + return false; + }); + + if (filteredArray && filteredArray.length > 0) { + return filteredArray[0]; + } + } + return null; + } + + function calculateJSHash(eventDataType, eventCategory, name) { + var preHash = [eventDataType, eventCategory, name].join(''); + + return mParticle.generateHash(preHash); + } + + function loadGtagSnippet() { + (function() { + window.dataLayer = window.dataLayer || []; + window.gtag = function() { + dataLayer.push(arguments); + }; + + var gTagScript = document.createElement('script'); + gTagScript.async = true; + gTagScript.onload = function() { + gtag('js', new Date()); + if (forwarderSettings.enableEnhancedConversions === 'True') { + gtag('config', gtagSiteId, { + allow_enhanced_conversions: true, + }); + } else { + gtag('config', gtagSiteId); + } + isInitialized = true; + processQueue(eventQueue); + }; + gTagScript.src = + 'https://www.googletagmanager.com/gtag/js?id=' + gtagSiteId; + document.getElementsByTagName('head')[0].appendChild(gTagScript); + })(); + } + + function loadLegacySnippet() { + (function() { + var googleAdwords = document.createElement('script'); + googleAdwords.type = 'text/javascript'; + googleAdwords.async = true; + googleAdwords.onload = function() { + isInitialized = true; + processQueue(eventQueue); + }; + googleAdwords.src = + ('https:' == document.location.protocol ? 'https' : 'http') + + '://www.googleadservices.com/pagead/conversion_async.js'; + document.getElementsByTagName('head')[0].appendChild(googleAdwords); + })(); + } + + // https://go.mparticle.com/work/SQDSDKS-6166 + function initForwarder(settings, service, testMode) { + window.enhanced_conversion_data = {}; + forwarderSettings = settings; + reportingService = service; + + try { + if (!forwarderSettings.conversionId) { + return ( + "Can't initialize forwarder: " + + name + + ', conversionId is not defined' + ); + } + + gtagSiteId = 'AW-' + forwarderSettings.conversionId; + + if (testMode !== true) { + if (forwarderSettings.enableGtag == 'True') { + loadGtagSnippet(); + } else { + loadLegacySnippet(); + } + } else { + isInitialized = true; + processQueue(eventQueue); + } + + if (!forwarderSettings.conversionId) { + return ( + "Can't initialize forwarder: " + + name + + ', conversionId is not defined' + ); + } + + // https://go.mparticle.com/work/SQDSDKS-6165 + if (window.gtag && forwarderSettings.enableGtag === 'True') { + if (forwarderSettings.consentMappingWeb) { + consentMappings = parseSettingsString( + forwarderSettings.consentMappingWeb + ); + } else { + // Ensures consent mappings is an empty array + // for future use + consentMappings = []; + } + + consentPayloadDefaults = getConsentSettings(); + var defaultConsentPayload = cloneObject(consentPayloadDefaults); + var updatedConsentState = getUserConsentState(); + var updatedDefaultConsentPayload = generateConsentStatePayloadFromMappings( + updatedConsentState, + consentMappings + ); + + if (!isEmpty(defaultConsentPayload)) { + sendGtagConsentDefaults(defaultConsentPayload); + } else if (!isEmpty(updatedDefaultConsentPayload)) { + sendGtagConsentDefaults(updatedDefaultConsentPayload); + } + + maybeSendConsentUpdateToGoogle(updatedConsentState); + } + + forwarderSettings.remarketingOnly = + forwarderSettings.remarketingOnly == 'True'; + + try { + if (forwarderSettings.labels) { + labels = JSON.parse( + forwarderSettings.labels.replace(/"/g, '"') + ); + } + + if (forwarderSettings.customParameters) { + customAttributeMappings = JSON.parse( + forwarderSettings.customParameters.replace( + /"/g, + '"' + ) + ); + } + } catch (e) { + return ( + "Can't initialize forwarder: " + + name + + ', Could not process event to label mapping' + ); + } + + return 'Successfully initialized: ' + name; + } catch (e) { + return 'Failed to initialize: ' + name; + } + } + + function processQueue(queue) { + var item; + + if ( + (window.gtag || window.google_trackConversion) && + queue.length > 0 + ) { + try { + while (queue.length > 0) { + item = queue.shift(); + item.action(item.data); + } + } catch (e) { + console.error('Error on mParticle Adwords Kit', e); + } + } + } + + this.init = initForwarder; + this.process = processEvent; + this.processQueue = processQueue; + }; + + function getId() { + return moduleId; + } + + function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + "'config' must be an object. You passed in a " + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); + } + + function parseSettingsString(settingsString) { + return JSON.parse(settingsString.replace(/"/g, '"')); + } + + function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); + } + + function isEmpty(value) { + return value == null || !(Object.keys(value) || value).length; + } + + function mergeObjects() { + var resObj = {}; + for (var i = 0; i < arguments.length; i += 1) { + var obj = arguments[i], + keys = Object.keys(obj); + for (var j = 0; j < keys.length; j += 1) { + resObj[keys[j]] = obj[keys[j]]; + } + } + return resObj; + } + + function cloneObject(obj) { + return JSON.parse(JSON.stringify(obj)); + } + + if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } + } + + var GoogleAdWordsEventForwarder = { + register: register, + }; + + exports.default = GoogleAdWordsEventForwarder; + + return exports; + +}({})); diff --git a/kits/amplitude/amplitude-8/dist/Amplitude.common.js b/kits/amplitude/amplitude-8/dist/Amplitude.common.js new file mode 100644 index 000000000..12704582d --- /dev/null +++ b/kits/amplitude/amplitude-8/dist/Amplitude.common.js @@ -0,0 +1,793 @@ +Object.defineProperty(exports, '__esModule', { value: true }); + +/* eslint-disable no-undef*/ +// +// Copyright 2015 mParticle, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var name = 'Amplitude', + moduleId = 53, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + }; + +var constants = { + MPID: 'mpId', + customerId: 'customerId', + email: 'email', + other: 'other', + other2: 'other2', + other3: 'other3', + other4: 'other4', + other5: 'other5', + other6: 'other6', + other7: 'other7', + other8: 'other8', + other9: 'other9', + other10: 'other10', +}; + +var MP_AMP_SPLIT = 'mparticle_amplitude_should_split', + TOTAL_AMOUNT = 'Total Amount', + TOTAL = 'Total', + PRODUCTS = 'products', + REFUND = 'Refund', + PURCHASE = 'Purchase', + TOTAL_PRODUCT_AMOUNT = 'Total Product Amount'; + +var includeIndividualProductEvents, + shouldSendSeparateAmplitudeRevenueEvent, + enableTempAmplitudeEcommerce; + +/* eslint-disable */ +// prettier-ignore +var renderSnippet = function() { + (function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script"); + r.type="text/javascript"; + r.integrity="sha384-QahB0HKETlcqjneomU3Ohs+UgJTinhUNFIKJitEl2Vo7DjvphO2jei64ZP5J2GA5"; + r.crossOrigin="anonymous";r.async=true; + r.src="https://cdn.amplitude.com/libs/amplitude-8.21.8-min.gz.js"; + r.onload=function(){if(!e.amplitude.runQueuedFunctions){console.log( + "[Amplitude] Error: could not load SDK");}};var s=t.getElementsByTagName("script" + )[0];s.parentNode.insertBefore(r,s);function i(e,t){e.prototype[t]=function(){ + this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this};} + var o=function(){this._q=[];return this};var a=["add","append","clearAll", + "prepend","set","setOnce","unset","preInsert","postInsert","remove"];for( + var c=0;c -1 + ) { + var revenueAmount = + (expandedEvt.EventAttributes['Total Amount'] || 0) * + (isRefund ? -1 : 1); + var revenue = new window.amplitude.Revenue() + .setPrice(revenueAmount) + .setEventProperties(updatedAttributes); + getInstance().logRevenueV2(revenue); + } else { + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + } + }); + + return true; + } + } + + // if it is not a product action, it is an impression or promotion commerce event + if (isNotProductAction(event)) { + expandedEvents.forEach(function(expandedEvt) { + // Exclude Totals from the attributes as we log it in the revenue call + var updatedAttributes = createEcommerceAttributes( + expandedEvt.EventAttributes + ); + + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + }); + + return true; + } + + console.warn( + 'Commerce event does not conform to our expectations and was not forwarded to Amplitude. Please double-check your code.' + ); + + return false; + } + + /* + When we process a product action event, Amplitude has a very specific way of + sending events to them: + + 1. Send a summary event with event attributes from the MP event. + a. Add a key of `products` with a value of JSON.stringify(productArray). + b. Add a key of mparticle_amplitude_should_split with a value of `false`. + + 2. Determine if we send product level events or not. + a. If includeIndividualProductEvents === true, send product level events + b. If includeIndividualProductEvents === false, do not send product level events + + 3. Determine if we send an Amplitude revenue event or not. + a. If shouldSendSeparateAmplitudeRevenueEvent === true, send an Amplitude revenue event. + b. If shouldSendSeparateAmplitudeRevenueEvent === true, the summary event attribute should be `revenue`. + c. If shouldSendSeparateAmplitudeRevenueEvent === false, the summary event attribute should be `$revenue` + + See test/AmplitudeCommerceEvent.MD for examples of what the expectations of the payload are. + + */ + function processTemporaryProductAction( + unexpandedCommerceEvent, + expandedEvents + ) { + var summaryEvent, isRefund, isPurchase, isMPRevenueEvent; + + isRefund = + unexpandedCommerceEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Refund; + isPurchase = + unexpandedCommerceEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase; + isMPRevenueEvent = isRefund || isPurchase; + + // if the event is a revenue event, then we set it to the expanded `Total` event for backwards compatibility + if ( + isMPRevenueEvent && + expandedEvents[0].EventName.indexOf(TOTAL) > -1 + ) { + summaryEvent = expandedEvents[0]; + sendMPRevenueSummaryEvent( + summaryEvent, + unexpandedCommerceEvent.ProductAction.ProductList, + isRefund, + shouldSendSeparateAmplitudeRevenueEvent + ); + } + + if (!isMPRevenueEvent) { + sendSummaryEvent(unexpandedCommerceEvent); + } + + if (includeIndividualProductEvents) { + sendIndividualProductEvents( + expandedEvents, + isMPRevenueEvent, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ); + } + + return true; + } + + // If event.ProductAction does not exist, the commerce event is a promotion or impression event + function isNotProductAction(event) { + return ( + event.EventCategory === + mParticle.CommerceEventType.ProductImpression || + event.EventCategory === mParticle.CommerceEventType.PromotionView || + event.EventCategory === mParticle.CommerceEventType.PromotionClick + ); + } + + // this function does not use Amplitude's logRevenueV2, but rather sends custom event names + function sendMPRevenueSummaryEvent( + summaryEvent, + products, + isRefund, + shouldSendSeparateAmplitudeRevenueEvent + ) { + // send the ecommerce - purchase event + var updatedAttributes = createMPRevenueEcommerceAttributes( + summaryEvent.EventAttributes, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ); + updatedAttributes[MP_AMP_SPLIT] = false; + + updatedAttributes[PRODUCTS] = products; + var revenueEventLabel = isRefund ? REFUND : PURCHASE; + getInstance().logEvent( + 'eCommerce - ' + revenueEventLabel, + updatedAttributes + ); + } + + // revenue summary event will either have $price/price or $revenue/revenue depending on if + function createMPRevenueEcommerceAttributes( + attributes, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ) { + var updatedAttributes = {}; + for (var key in attributes) { + if (key === TOTAL_AMOUNT) { + // A purchase is a positive amount and a refund is negative + var revenueAmount = attributes[key] * (isRefund ? -1 : 1); + // If we send a separate Amplitude Revenue Event, Amplitude's + // SDK prefixes price/revenue with a $ for calculating things + // like LTV, so we do not want to prepend it as part of the + // summary event to avoid double counting + var revenueKey = shouldSendSeparateAmplitudeRevenueEvent + ? 'revenue' + : '$revenue'; + + updatedAttributes[revenueKey] = revenueAmount; + } else if (key !== TOTAL_AMOUNT) { + updatedAttributes[key] = attributes[key]; + } + } + + return convertJsonAttrs(updatedAttributes); + } + + function createAttrsForAmplitudeRevenueEvent(attributes) { + var updatedAttributes = {}; + for (var key in attributes) { + if (key !== TOTAL_AMOUNT) { + updatedAttributes[key] = attributes[key]; + } + } + + return convertJsonAttrs(updatedAttributes); + } + + function sendSummaryEvent(summaryEvent) { + var updatedAttributes = createEcommerceAttributes( + summaryEvent.EventAttributes + ); + updatedAttributes[MP_AMP_SPLIT] = false; + try { + updatedAttributes[PRODUCTS] = + summaryEvent.ProductAction.ProductList; + } catch (e) { + console.error('error adding Product List to summary event'); + } + + getInstance().logEvent(summaryEvent.EventName, updatedAttributes); + } + + function sendIndividualProductEvents( + expandedEvents, + isMPRevenueEvent, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ) { + expandedEvents.forEach(function(expandedEvt) { + var updatedAttributes; + // `Total` exists on an expanded event if it is part of a revenue/purchase event + // but not on other commerce events. This only needs to be fired if shouldSendSeparateAmplitudeRevenueEvent === True + if ( + isMPRevenueEvent && + // A purchase is a positive amount and a refund is negative + (expandedEvt.EventName.indexOf(TOTAL) > -1) & + shouldSendSeparateAmplitudeRevenueEvent + ) { + var revenueAmount = + // A purchase is a positive amount and a refund is negative + (expandedEvt.EventAttributes[TOTAL_AMOUNT] || 0) * + (isRefund ? -1 : 1); + updatedAttributes = createAttrsForAmplitudeRevenueEvent( + expandedEvt.EventAttributes + ); + + var revenue = new window.amplitude.Revenue() + .setPrice(revenueAmount) + .setEventProperties(updatedAttributes); + getInstance().logRevenueV2(revenue); + } else if (expandedEvt.EventName.indexOf(TOTAL) === -1) { + updatedAttributes = createEcommerceAttributes( + expandedEvt.EventAttributes + ); + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + } + }); + } + + function convertJsonAttrs(customAttributes) { + if (forwarderSettings.sendEventAttributesAsObjects === 'True') { + for (var key in customAttributes) { + if (typeof customAttributes[key] === 'string') { + try { + var parsed = JSON.parse(customAttributes[key]); + if (typeof parsed === 'object') { + customAttributes[key] = parsed; + } + } catch (e) { + // if parsing fails, don't update the customAttribute object + } + } + } + } + + return customAttributes; + } + + function initForwarder(settings, service, testMode) { + var ampSettings; + + forwarderSettings = settings; + reportingService = service; + + // Changing this setting from a negative action to a positive action for readability + includeIndividualProductEvents = + forwarderSettings.excludeIndividualProductEvents === 'False'; + // Only send separate amplitude revenue events when we includeIndividualProductEvents, + // so create this variable for clarity + shouldSendSeparateAmplitudeRevenueEvent = includeIndividualProductEvents; + + enableTempAmplitudeEcommerce = + forwarderSettings.enableTempAmplitudeEcommerce === 'True'; + try { + if (!window.amplitude) { + if (testMode !== true) { + renderSnippet(); + } + } + + ampSettings = {}; + + // allow the client to set custom amplitude init properties + if ( + typeof window.AmplitudeInitSettings === 'object' && + window.AmplitudeInitSettings !== null + ) { + ampSettings = window.AmplitudeInitSettings; + } + + if (forwarderSettings.saveEvents) { + ampSettings.saveEvents = + forwarderSettings.saveEvents === 'True'; + } + + if (forwarderSettings.savedMaxCount) { + ampSettings.savedMaxCount = parseInt( + forwarderSettings.savedMaxCount, + 10 + ); + } + + if (forwarderSettings.uploadBatchSize) { + ampSettings.uploadBatchSize = parseInt( + forwarderSettings.uploadBatchSize, + 10 + ); + } + + if (forwarderSettings.includeUtm) { + ampSettings.includeUtm = + forwarderSettings.includeUtm === 'True'; + } + + if (forwarderSettings.includeReferrer) { + ampSettings.includeReferrer = + forwarderSettings.includeReferrer === 'True'; + } + + if (forwarderSettings.forceHttps) { + ampSettings.forceHttps = + forwarderSettings.forceHttps === 'True'; + } + + if (forwarderSettings.baseUrl) { + ampSettings.apiEndpoint = forwarderSettings.baseUrl; + } + + isDefaultInstance = + !forwarderSettings.instanceName || + forwarderSettings.instanceName === 'default'; + + getInstance().init(forwarderSettings.apiKey, null, ampSettings); + isInitialized = true; + + if (forwarderSettings.userIdentification === constants.MPID) { + if (window.mParticle && window.mParticle.Identity) { + var user = window.mParticle.Identity.getCurrentUser(); + if (user) { + var userId = user.getMPID(); + getInstance().setUserId(userId); + } + } + } + + return 'Successfully initialized: ' + name; + } catch (e) { + return 'Failed to initialize: ' + name; + } + } + + this.init = initForwarder; + this.process = processEvent; + this.setUserIdentity = setUserIdentity; + this.onUserIdentified = onUserIdentified; + this.setUserAttribute = setUserAttribute; + this.setOptOut = setOptOut; + this.removeUserAttribute = removeUserAttribute; +}; + +function getId() { + return moduleId; +} + +function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); +} + +function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + 'The "config" must be an object. You passed in a ' + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); +} + +if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } +} + +var Amplitude = { + register: register, +}; +var Amplitude_1 = Amplitude.register; + +exports["default"] = Amplitude; +exports.register = Amplitude_1; diff --git a/kits/amplitude/amplitude-8/dist/Amplitude.esm.js b/kits/amplitude/amplitude-8/dist/Amplitude.esm.js new file mode 100644 index 000000000..ae6cb0496 --- /dev/null +++ b/kits/amplitude/amplitude-8/dist/Amplitude.esm.js @@ -0,0 +1,790 @@ +/* eslint-disable no-undef*/ +// +// Copyright 2015 mParticle, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var name = 'Amplitude', + moduleId = 53, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + }; + +var constants = { + MPID: 'mpId', + customerId: 'customerId', + email: 'email', + other: 'other', + other2: 'other2', + other3: 'other3', + other4: 'other4', + other5: 'other5', + other6: 'other6', + other7: 'other7', + other8: 'other8', + other9: 'other9', + other10: 'other10', +}; + +var MP_AMP_SPLIT = 'mparticle_amplitude_should_split', + TOTAL_AMOUNT = 'Total Amount', + TOTAL = 'Total', + PRODUCTS = 'products', + REFUND = 'Refund', + PURCHASE = 'Purchase', + TOTAL_PRODUCT_AMOUNT = 'Total Product Amount'; + +var includeIndividualProductEvents, + shouldSendSeparateAmplitudeRevenueEvent, + enableTempAmplitudeEcommerce; + +/* eslint-disable */ +// prettier-ignore +var renderSnippet = function() { + (function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script"); + r.type="text/javascript"; + r.integrity="sha384-QahB0HKETlcqjneomU3Ohs+UgJTinhUNFIKJitEl2Vo7DjvphO2jei64ZP5J2GA5"; + r.crossOrigin="anonymous";r.async=true; + r.src="https://cdn.amplitude.com/libs/amplitude-8.21.8-min.gz.js"; + r.onload=function(){if(!e.amplitude.runQueuedFunctions){console.log( + "[Amplitude] Error: could not load SDK");}};var s=t.getElementsByTagName("script" + )[0];s.parentNode.insertBefore(r,s);function i(e,t){e.prototype[t]=function(){ + this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this};} + var o=function(){this._q=[];return this};var a=["add","append","clearAll", + "prepend","set","setOnce","unset","preInsert","postInsert","remove"];for( + var c=0;c -1 + ) { + var revenueAmount = + (expandedEvt.EventAttributes['Total Amount'] || 0) * + (isRefund ? -1 : 1); + var revenue = new window.amplitude.Revenue() + .setPrice(revenueAmount) + .setEventProperties(updatedAttributes); + getInstance().logRevenueV2(revenue); + } else { + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + } + }); + + return true; + } + } + + // if it is not a product action, it is an impression or promotion commerce event + if (isNotProductAction(event)) { + expandedEvents.forEach(function(expandedEvt) { + // Exclude Totals from the attributes as we log it in the revenue call + var updatedAttributes = createEcommerceAttributes( + expandedEvt.EventAttributes + ); + + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + }); + + return true; + } + + console.warn( + 'Commerce event does not conform to our expectations and was not forwarded to Amplitude. Please double-check your code.' + ); + + return false; + } + + /* + When we process a product action event, Amplitude has a very specific way of + sending events to them: + + 1. Send a summary event with event attributes from the MP event. + a. Add a key of `products` with a value of JSON.stringify(productArray). + b. Add a key of mparticle_amplitude_should_split with a value of `false`. + + 2. Determine if we send product level events or not. + a. If includeIndividualProductEvents === true, send product level events + b. If includeIndividualProductEvents === false, do not send product level events + + 3. Determine if we send an Amplitude revenue event or not. + a. If shouldSendSeparateAmplitudeRevenueEvent === true, send an Amplitude revenue event. + b. If shouldSendSeparateAmplitudeRevenueEvent === true, the summary event attribute should be `revenue`. + c. If shouldSendSeparateAmplitudeRevenueEvent === false, the summary event attribute should be `$revenue` + + See test/AmplitudeCommerceEvent.MD for examples of what the expectations of the payload are. + + */ + function processTemporaryProductAction( + unexpandedCommerceEvent, + expandedEvents + ) { + var summaryEvent, isRefund, isPurchase, isMPRevenueEvent; + + isRefund = + unexpandedCommerceEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Refund; + isPurchase = + unexpandedCommerceEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase; + isMPRevenueEvent = isRefund || isPurchase; + + // if the event is a revenue event, then we set it to the expanded `Total` event for backwards compatibility + if ( + isMPRevenueEvent && + expandedEvents[0].EventName.indexOf(TOTAL) > -1 + ) { + summaryEvent = expandedEvents[0]; + sendMPRevenueSummaryEvent( + summaryEvent, + unexpandedCommerceEvent.ProductAction.ProductList, + isRefund, + shouldSendSeparateAmplitudeRevenueEvent + ); + } + + if (!isMPRevenueEvent) { + sendSummaryEvent(unexpandedCommerceEvent); + } + + if (includeIndividualProductEvents) { + sendIndividualProductEvents( + expandedEvents, + isMPRevenueEvent, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ); + } + + return true; + } + + // If event.ProductAction does not exist, the commerce event is a promotion or impression event + function isNotProductAction(event) { + return ( + event.EventCategory === + mParticle.CommerceEventType.ProductImpression || + event.EventCategory === mParticle.CommerceEventType.PromotionView || + event.EventCategory === mParticle.CommerceEventType.PromotionClick + ); + } + + // this function does not use Amplitude's logRevenueV2, but rather sends custom event names + function sendMPRevenueSummaryEvent( + summaryEvent, + products, + isRefund, + shouldSendSeparateAmplitudeRevenueEvent + ) { + // send the ecommerce - purchase event + var updatedAttributes = createMPRevenueEcommerceAttributes( + summaryEvent.EventAttributes, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ); + updatedAttributes[MP_AMP_SPLIT] = false; + + updatedAttributes[PRODUCTS] = products; + var revenueEventLabel = isRefund ? REFUND : PURCHASE; + getInstance().logEvent( + 'eCommerce - ' + revenueEventLabel, + updatedAttributes + ); + } + + // revenue summary event will either have $price/price or $revenue/revenue depending on if + function createMPRevenueEcommerceAttributes( + attributes, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ) { + var updatedAttributes = {}; + for (var key in attributes) { + if (key === TOTAL_AMOUNT) { + // A purchase is a positive amount and a refund is negative + var revenueAmount = attributes[key] * (isRefund ? -1 : 1); + // If we send a separate Amplitude Revenue Event, Amplitude's + // SDK prefixes price/revenue with a $ for calculating things + // like LTV, so we do not want to prepend it as part of the + // summary event to avoid double counting + var revenueKey = shouldSendSeparateAmplitudeRevenueEvent + ? 'revenue' + : '$revenue'; + + updatedAttributes[revenueKey] = revenueAmount; + } else if (key !== TOTAL_AMOUNT) { + updatedAttributes[key] = attributes[key]; + } + } + + return convertJsonAttrs(updatedAttributes); + } + + function createAttrsForAmplitudeRevenueEvent(attributes) { + var updatedAttributes = {}; + for (var key in attributes) { + if (key !== TOTAL_AMOUNT) { + updatedAttributes[key] = attributes[key]; + } + } + + return convertJsonAttrs(updatedAttributes); + } + + function sendSummaryEvent(summaryEvent) { + var updatedAttributes = createEcommerceAttributes( + summaryEvent.EventAttributes + ); + updatedAttributes[MP_AMP_SPLIT] = false; + try { + updatedAttributes[PRODUCTS] = + summaryEvent.ProductAction.ProductList; + } catch (e) { + console.error('error adding Product List to summary event'); + } + + getInstance().logEvent(summaryEvent.EventName, updatedAttributes); + } + + function sendIndividualProductEvents( + expandedEvents, + isMPRevenueEvent, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ) { + expandedEvents.forEach(function(expandedEvt) { + var updatedAttributes; + // `Total` exists on an expanded event if it is part of a revenue/purchase event + // but not on other commerce events. This only needs to be fired if shouldSendSeparateAmplitudeRevenueEvent === True + if ( + isMPRevenueEvent && + // A purchase is a positive amount and a refund is negative + (expandedEvt.EventName.indexOf(TOTAL) > -1) & + shouldSendSeparateAmplitudeRevenueEvent + ) { + var revenueAmount = + // A purchase is a positive amount and a refund is negative + (expandedEvt.EventAttributes[TOTAL_AMOUNT] || 0) * + (isRefund ? -1 : 1); + updatedAttributes = createAttrsForAmplitudeRevenueEvent( + expandedEvt.EventAttributes + ); + + var revenue = new window.amplitude.Revenue() + .setPrice(revenueAmount) + .setEventProperties(updatedAttributes); + getInstance().logRevenueV2(revenue); + } else if (expandedEvt.EventName.indexOf(TOTAL) === -1) { + updatedAttributes = createEcommerceAttributes( + expandedEvt.EventAttributes + ); + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + } + }); + } + + function convertJsonAttrs(customAttributes) { + if (forwarderSettings.sendEventAttributesAsObjects === 'True') { + for (var key in customAttributes) { + if (typeof customAttributes[key] === 'string') { + try { + var parsed = JSON.parse(customAttributes[key]); + if (typeof parsed === 'object') { + customAttributes[key] = parsed; + } + } catch (e) { + // if parsing fails, don't update the customAttribute object + } + } + } + } + + return customAttributes; + } + + function initForwarder(settings, service, testMode) { + var ampSettings; + + forwarderSettings = settings; + reportingService = service; + + // Changing this setting from a negative action to a positive action for readability + includeIndividualProductEvents = + forwarderSettings.excludeIndividualProductEvents === 'False'; + // Only send separate amplitude revenue events when we includeIndividualProductEvents, + // so create this variable for clarity + shouldSendSeparateAmplitudeRevenueEvent = includeIndividualProductEvents; + + enableTempAmplitudeEcommerce = + forwarderSettings.enableTempAmplitudeEcommerce === 'True'; + try { + if (!window.amplitude) { + if (testMode !== true) { + renderSnippet(); + } + } + + ampSettings = {}; + + // allow the client to set custom amplitude init properties + if ( + typeof window.AmplitudeInitSettings === 'object' && + window.AmplitudeInitSettings !== null + ) { + ampSettings = window.AmplitudeInitSettings; + } + + if (forwarderSettings.saveEvents) { + ampSettings.saveEvents = + forwarderSettings.saveEvents === 'True'; + } + + if (forwarderSettings.savedMaxCount) { + ampSettings.savedMaxCount = parseInt( + forwarderSettings.savedMaxCount, + 10 + ); + } + + if (forwarderSettings.uploadBatchSize) { + ampSettings.uploadBatchSize = parseInt( + forwarderSettings.uploadBatchSize, + 10 + ); + } + + if (forwarderSettings.includeUtm) { + ampSettings.includeUtm = + forwarderSettings.includeUtm === 'True'; + } + + if (forwarderSettings.includeReferrer) { + ampSettings.includeReferrer = + forwarderSettings.includeReferrer === 'True'; + } + + if (forwarderSettings.forceHttps) { + ampSettings.forceHttps = + forwarderSettings.forceHttps === 'True'; + } + + if (forwarderSettings.baseUrl) { + ampSettings.apiEndpoint = forwarderSettings.baseUrl; + } + + isDefaultInstance = + !forwarderSettings.instanceName || + forwarderSettings.instanceName === 'default'; + + getInstance().init(forwarderSettings.apiKey, null, ampSettings); + isInitialized = true; + + if (forwarderSettings.userIdentification === constants.MPID) { + if (window.mParticle && window.mParticle.Identity) { + var user = window.mParticle.Identity.getCurrentUser(); + if (user) { + var userId = user.getMPID(); + getInstance().setUserId(userId); + } + } + } + + return 'Successfully initialized: ' + name; + } catch (e) { + return 'Failed to initialize: ' + name; + } + } + + this.init = initForwarder; + this.process = processEvent; + this.setUserIdentity = setUserIdentity; + this.onUserIdentified = onUserIdentified; + this.setUserAttribute = setUserAttribute; + this.setOptOut = setOptOut; + this.removeUserAttribute = removeUserAttribute; +}; + +function getId() { + return moduleId; +} + +function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); +} + +function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + 'The "config" must be an object. You passed in a ' + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); +} + +if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } +} + +var Amplitude = { + register: register, +}; +var Amplitude_1 = Amplitude.register; + +export { Amplitude as default, Amplitude_1 as register }; diff --git a/kits/amplitude/amplitude-8/dist/Amplitude.iife.js b/kits/amplitude/amplitude-8/dist/Amplitude.iife.js new file mode 100644 index 000000000..9713de92b --- /dev/null +++ b/kits/amplitude/amplitude-8/dist/Amplitude.iife.js @@ -0,0 +1,799 @@ +var mpAmplitudeKit = (function (exports) { + + /* eslint-disable no-undef*/ + // + // Copyright 2015 mParticle, Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + var name = 'Amplitude', + moduleId = 53, + MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Commerce: 16, + }; + + var constants = { + MPID: 'mpId', + customerId: 'customerId', + email: 'email', + other: 'other', + other2: 'other2', + other3: 'other3', + other4: 'other4', + other5: 'other5', + other6: 'other6', + other7: 'other7', + other8: 'other8', + other9: 'other9', + other10: 'other10', + }; + + var MP_AMP_SPLIT = 'mparticle_amplitude_should_split', + TOTAL_AMOUNT = 'Total Amount', + TOTAL = 'Total', + PRODUCTS = 'products', + REFUND = 'Refund', + PURCHASE = 'Purchase', + TOTAL_PRODUCT_AMOUNT = 'Total Product Amount'; + + var includeIndividualProductEvents, + shouldSendSeparateAmplitudeRevenueEvent, + enableTempAmplitudeEcommerce; + + /* eslint-disable */ + // prettier-ignore + var renderSnippet = function() { + (function(e,t){var n=e.amplitude||{_q:[],_iq:{}};var r=t.createElement("script"); + r.type="text/javascript"; + r.integrity="sha384-QahB0HKETlcqjneomU3Ohs+UgJTinhUNFIKJitEl2Vo7DjvphO2jei64ZP5J2GA5"; + r.crossOrigin="anonymous";r.async=true; + r.src="https://cdn.amplitude.com/libs/amplitude-8.21.8-min.gz.js"; + r.onload=function(){if(!e.amplitude.runQueuedFunctions){console.log( + "[Amplitude] Error: could not load SDK");}};var s=t.getElementsByTagName("script" + )[0];s.parentNode.insertBefore(r,s);function i(e,t){e.prototype[t]=function(){ + this._q.push([t].concat(Array.prototype.slice.call(arguments,0)));return this};} + var o=function(){this._q=[];return this};var a=["add","append","clearAll", + "prepend","set","setOnce","unset","preInsert","postInsert","remove"];for( + var c=0;c -1 + ) { + var revenueAmount = + (expandedEvt.EventAttributes['Total Amount'] || 0) * + (isRefund ? -1 : 1); + var revenue = new window.amplitude.Revenue() + .setPrice(revenueAmount) + .setEventProperties(updatedAttributes); + getInstance().logRevenueV2(revenue); + } else { + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + } + }); + + return true; + } + } + + // if it is not a product action, it is an impression or promotion commerce event + if (isNotProductAction(event)) { + expandedEvents.forEach(function(expandedEvt) { + // Exclude Totals from the attributes as we log it in the revenue call + var updatedAttributes = createEcommerceAttributes( + expandedEvt.EventAttributes + ); + + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + }); + + return true; + } + + console.warn( + 'Commerce event does not conform to our expectations and was not forwarded to Amplitude. Please double-check your code.' + ); + + return false; + } + + /* + When we process a product action event, Amplitude has a very specific way of + sending events to them: + + 1. Send a summary event with event attributes from the MP event. + a. Add a key of `products` with a value of JSON.stringify(productArray). + b. Add a key of mparticle_amplitude_should_split with a value of `false`. + + 2. Determine if we send product level events or not. + a. If includeIndividualProductEvents === true, send product level events + b. If includeIndividualProductEvents === false, do not send product level events + + 3. Determine if we send an Amplitude revenue event or not. + a. If shouldSendSeparateAmplitudeRevenueEvent === true, send an Amplitude revenue event. + b. If shouldSendSeparateAmplitudeRevenueEvent === true, the summary event attribute should be `revenue`. + c. If shouldSendSeparateAmplitudeRevenueEvent === false, the summary event attribute should be `$revenue` + + See test/AmplitudeCommerceEvent.MD for examples of what the expectations of the payload are. + + */ + function processTemporaryProductAction( + unexpandedCommerceEvent, + expandedEvents + ) { + var summaryEvent, isRefund, isPurchase, isMPRevenueEvent; + + isRefund = + unexpandedCommerceEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Refund; + isPurchase = + unexpandedCommerceEvent.ProductAction.ProductActionType === + mParticle.ProductActionType.Purchase; + isMPRevenueEvent = isRefund || isPurchase; + + // if the event is a revenue event, then we set it to the expanded `Total` event for backwards compatibility + if ( + isMPRevenueEvent && + expandedEvents[0].EventName.indexOf(TOTAL) > -1 + ) { + summaryEvent = expandedEvents[0]; + sendMPRevenueSummaryEvent( + summaryEvent, + unexpandedCommerceEvent.ProductAction.ProductList, + isRefund, + shouldSendSeparateAmplitudeRevenueEvent + ); + } + + if (!isMPRevenueEvent) { + sendSummaryEvent(unexpandedCommerceEvent); + } + + if (includeIndividualProductEvents) { + sendIndividualProductEvents( + expandedEvents, + isMPRevenueEvent, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ); + } + + return true; + } + + // If event.ProductAction does not exist, the commerce event is a promotion or impression event + function isNotProductAction(event) { + return ( + event.EventCategory === + mParticle.CommerceEventType.ProductImpression || + event.EventCategory === mParticle.CommerceEventType.PromotionView || + event.EventCategory === mParticle.CommerceEventType.PromotionClick + ); + } + + // this function does not use Amplitude's logRevenueV2, but rather sends custom event names + function sendMPRevenueSummaryEvent( + summaryEvent, + products, + isRefund, + shouldSendSeparateAmplitudeRevenueEvent + ) { + // send the ecommerce - purchase event + var updatedAttributes = createMPRevenueEcommerceAttributes( + summaryEvent.EventAttributes, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ); + updatedAttributes[MP_AMP_SPLIT] = false; + + updatedAttributes[PRODUCTS] = products; + var revenueEventLabel = isRefund ? REFUND : PURCHASE; + getInstance().logEvent( + 'eCommerce - ' + revenueEventLabel, + updatedAttributes + ); + } + + // revenue summary event will either have $price/price or $revenue/revenue depending on if + function createMPRevenueEcommerceAttributes( + attributes, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ) { + var updatedAttributes = {}; + for (var key in attributes) { + if (key === TOTAL_AMOUNT) { + // A purchase is a positive amount and a refund is negative + var revenueAmount = attributes[key] * (isRefund ? -1 : 1); + // If we send a separate Amplitude Revenue Event, Amplitude's + // SDK prefixes price/revenue with a $ for calculating things + // like LTV, so we do not want to prepend it as part of the + // summary event to avoid double counting + var revenueKey = shouldSendSeparateAmplitudeRevenueEvent + ? 'revenue' + : '$revenue'; + + updatedAttributes[revenueKey] = revenueAmount; + } else if (key !== TOTAL_AMOUNT) { + updatedAttributes[key] = attributes[key]; + } + } + + return convertJsonAttrs(updatedAttributes); + } + + function createAttrsForAmplitudeRevenueEvent(attributes) { + var updatedAttributes = {}; + for (var key in attributes) { + if (key !== TOTAL_AMOUNT) { + updatedAttributes[key] = attributes[key]; + } + } + + return convertJsonAttrs(updatedAttributes); + } + + function sendSummaryEvent(summaryEvent) { + var updatedAttributes = createEcommerceAttributes( + summaryEvent.EventAttributes + ); + updatedAttributes[MP_AMP_SPLIT] = false; + try { + updatedAttributes[PRODUCTS] = + summaryEvent.ProductAction.ProductList; + } catch (e) { + console.error('error adding Product List to summary event'); + } + + getInstance().logEvent(summaryEvent.EventName, updatedAttributes); + } + + function sendIndividualProductEvents( + expandedEvents, + isMPRevenueEvent, + shouldSendSeparateAmplitudeRevenueEvent, + isRefund + ) { + expandedEvents.forEach(function(expandedEvt) { + var updatedAttributes; + // `Total` exists on an expanded event if it is part of a revenue/purchase event + // but not on other commerce events. This only needs to be fired if shouldSendSeparateAmplitudeRevenueEvent === True + if ( + isMPRevenueEvent && + // A purchase is a positive amount and a refund is negative + (expandedEvt.EventName.indexOf(TOTAL) > -1) & + shouldSendSeparateAmplitudeRevenueEvent + ) { + var revenueAmount = + // A purchase is a positive amount and a refund is negative + (expandedEvt.EventAttributes[TOTAL_AMOUNT] || 0) * + (isRefund ? -1 : 1); + updatedAttributes = createAttrsForAmplitudeRevenueEvent( + expandedEvt.EventAttributes + ); + + var revenue = new window.amplitude.Revenue() + .setPrice(revenueAmount) + .setEventProperties(updatedAttributes); + getInstance().logRevenueV2(revenue); + } else if (expandedEvt.EventName.indexOf(TOTAL) === -1) { + updatedAttributes = createEcommerceAttributes( + expandedEvt.EventAttributes + ); + getInstance().logEvent( + expandedEvt.EventName, + updatedAttributes + ); + } + }); + } + + function convertJsonAttrs(customAttributes) { + if (forwarderSettings.sendEventAttributesAsObjects === 'True') { + for (var key in customAttributes) { + if (typeof customAttributes[key] === 'string') { + try { + var parsed = JSON.parse(customAttributes[key]); + if (typeof parsed === 'object') { + customAttributes[key] = parsed; + } + } catch (e) { + // if parsing fails, don't update the customAttribute object + } + } + } + } + + return customAttributes; + } + + function initForwarder(settings, service, testMode) { + var ampSettings; + + forwarderSettings = settings; + reportingService = service; + + // Changing this setting from a negative action to a positive action for readability + includeIndividualProductEvents = + forwarderSettings.excludeIndividualProductEvents === 'False'; + // Only send separate amplitude revenue events when we includeIndividualProductEvents, + // so create this variable for clarity + shouldSendSeparateAmplitudeRevenueEvent = includeIndividualProductEvents; + + enableTempAmplitudeEcommerce = + forwarderSettings.enableTempAmplitudeEcommerce === 'True'; + try { + if (!window.amplitude) { + if (testMode !== true) { + renderSnippet(); + } + } + + ampSettings = {}; + + // allow the client to set custom amplitude init properties + if ( + typeof window.AmplitudeInitSettings === 'object' && + window.AmplitudeInitSettings !== null + ) { + ampSettings = window.AmplitudeInitSettings; + } + + if (forwarderSettings.saveEvents) { + ampSettings.saveEvents = + forwarderSettings.saveEvents === 'True'; + } + + if (forwarderSettings.savedMaxCount) { + ampSettings.savedMaxCount = parseInt( + forwarderSettings.savedMaxCount, + 10 + ); + } + + if (forwarderSettings.uploadBatchSize) { + ampSettings.uploadBatchSize = parseInt( + forwarderSettings.uploadBatchSize, + 10 + ); + } + + if (forwarderSettings.includeUtm) { + ampSettings.includeUtm = + forwarderSettings.includeUtm === 'True'; + } + + if (forwarderSettings.includeReferrer) { + ampSettings.includeReferrer = + forwarderSettings.includeReferrer === 'True'; + } + + if (forwarderSettings.forceHttps) { + ampSettings.forceHttps = + forwarderSettings.forceHttps === 'True'; + } + + if (forwarderSettings.baseUrl) { + ampSettings.apiEndpoint = forwarderSettings.baseUrl; + } + + isDefaultInstance = + !forwarderSettings.instanceName || + forwarderSettings.instanceName === 'default'; + + getInstance().init(forwarderSettings.apiKey, null, ampSettings); + isInitialized = true; + + if (forwarderSettings.userIdentification === constants.MPID) { + if (window.mParticle && window.mParticle.Identity) { + var user = window.mParticle.Identity.getCurrentUser(); + if (user) { + var userId = user.getMPID(); + getInstance().setUserId(userId); + } + } + } + + return 'Successfully initialized: ' + name; + } catch (e) { + return 'Failed to initialize: ' + name; + } + } + + this.init = initForwarder; + this.process = processEvent; + this.setUserIdentity = setUserIdentity; + this.onUserIdentified = onUserIdentified; + this.setUserAttribute = setUserAttribute; + this.setOptOut = setOptOut; + this.removeUserAttribute = removeUserAttribute; + }; + + function getId() { + return moduleId; + } + + function isObject(val) { + return ( + val != null && typeof val === 'object' && Array.isArray(val) === false + ); + } + + function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + 'The "config" must be an object. You passed in a ' + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); + } + + if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } + } + + var Amplitude = { + register: register, + }; + var Amplitude_1 = Amplitude.register; + + exports["default"] = Amplitude; + exports.register = Amplitude_1; + + Object.defineProperty(exports, '__esModule', { value: true }); + + return exports; + +})({}); diff --git a/kits/bingads/dist/BingAdsEventForwarder.common.js b/kits/bingads/dist/BingAdsEventForwarder.common.js new file mode 100644 index 000000000..dbbc008a8 --- /dev/null +++ b/kits/bingads/dist/BingAdsEventForwarder.common.js @@ -0,0 +1,403 @@ +Object.defineProperty(exports, '__esModule', { value: true }); + +/*! + * isobject + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +function isObject(val) { + return val != null && typeof val === 'object' && Array.isArray(val) === false; +} + +// Copyright 2016 mParticle, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + + +var name = 'Bing'; +var moduleId = 107; +var MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Profile: 14, + Commerce: 16, +}; + +var bingConsentValues = { Denied: 'denied', Granted: 'granted' }; +var bingConsentProperties = ['ad_storage']; +var bingToMpConsentSettingsMapping = { + ad_storage: 'defaultAdStorageConsentWeb', +}; + +var constructor = function() { + var self = this; + var isInitialized = false; + var forwarderSettings = null; + var reportingService = null; + + self.consentMappings = []; + self.consentPayloadAsString = ''; + self.consentPayloadDefaults = {}; + + self.name = name; + + function initForwarder(settings, service, testMode) { + forwarderSettings = settings; + reportingService = service; + + if (forwarderSettings.consentMappingWeb) { + self.consentMappings = parseSettingsString( + forwarderSettings.consentMappingWeb + ); + } + self.consentPayloadDefaults = getConsentSettings(forwarderSettings); + + var initialConsentPayload = cloneObject(self.consentPayloadDefaults); + var userConsentState = getUserConsentState(); + + var updatedConsentPayload = generateConsentPayload( + userConsentState, + self.consentMappings + ); + + try { + if (!testMode) { + (function(window, document, tag, url, queue) { + var f; + var n; + var i; + (window[queue] = window[queue] || []), + (window.uetq = window.uetq || []), + sendConsentDefaultToBing(initialConsentPayload), + (f = function() { + var obj = { + ti: forwarderSettings.tagId, + q: window.uetq, + }; + (obj.q = window[queue]), + (window[queue] = new UET(obj)), + maybeSendConsentUpdateToBing( + updatedConsentPayload + ); + window[queue].push('pageLoad'); + }), + (n = document.createElement(tag)), + (n.src = url), + (n.async = 1), + (n.onload = n.onreadystatechange = function() { + var state = this.readyState; + (state && + state !== 'loaded' && + state !== 'complete') || + (f(), (n.onload = n.onreadystatechange = null)); + }), + (i = document.getElementsByTagName(tag)[0]), + i.parentNode.insertBefore(n, i); + })(window, document, 'script', '//bat.bing.com/bat.js', 'uetq'); + + if (window.uetq && window.queue && window.queue.length > 0) { + for ( + var i = 0, length = window.queue.length; + i < length; + i++ + ) { + processEvent(window.queue[i]); + } + + window.queue.length = 0; + } + } + + isInitialized = true; + return 'Successfully initialized: ' + name; + } catch (e) { + return "Can't initialize forwarder: " + name + ': ' + e; + } + } + + function processEvent(event) { + if (!isInitialized) { + return "Can't send to forwarder: " + name + ', not initialized'; + } + + var reportEvent = false; + try { + if ( + event.EventDataType == MessageType.PageEvent || + event.EventDataType == MessageType.PageView + ) { + reportEvent = true; + logEvent(event); + } else if ( + event.EventDataType == MessageType.Commerce && + event.ProductAction && + event.ProductAction.ProductActionType == + mParticle.ProductActionType.Purchase + ) { + reportEvent = true; + logPurchaseEvent(event); + } + + if (reportEvent && reportingService) { + reportingService(self, event); + return 'Successfully sent to forwarder: ' + name; + } + } catch (e) { + return "Can't send to forwarder: " + name + ' ' + e; + } + } + + function logEvent(event) { + if (!isInitialized) { + return ( + "Can't log event on forwarder: " + name + ', not initialized' + ); + } + try { + var obj = createUetObject(event, 'pageLoad'); + + var eventConsentState = getEventConsentState(event.ConsentState); + + maybeSendConsentUpdateToBing(eventConsentState); + + window.uetq.push(obj); + } catch (e) { + return "Can't log event on forwarder: " + name + ': ' + e; + } + + return 'Successfully logged event from forwarder: ' + name; + } + + function logPurchaseEvent(event) { + if (!isInitialized) { + return ( + "Can't log purchase event on forwarder: " + + name + + ', not initialized' + ); + } + + if ( + event.ProductAction.TotalAmount === undefined || + event.ProductAction.TotalAmount === null + ) { + return "Can't log purchase event without a total amount on product action"; + } + + try { + var obj = createUetObject(event, 'eCommerce'); + obj.gv = event.ProductAction.TotalAmount; + + window.uetq.push(obj); + } catch (e) { + return "Can't log commerce event on forwarder: " + name + ': ' + e; + } + } + + function createUetObject(event, action) { + var obj = { + ea: action, + ec: window.mParticle.EventType.getName(event.EventCategory), + el: event.EventName, + }; + + if (event.CustomFlags && event.CustomFlags['Bing.EventValue']) { + obj.ev = event.CustomFlags['Bing.EventValue']; + } + + return obj; + } + + function getEventConsentState(eventConsentState) { + return eventConsentState && eventConsentState.getGDPRConsentState + ? eventConsentState.getGDPRConsentState() + : {}; + } + + function generateConsentPayload(consentState, mappings) { + if (!mappings) { + return {}; + } + + var payload = cloneObject(self.consentPayloadDefaults); + if (mappings && mappings.length > 0) { + for (var i = 0; i < mappings.length; i++) { + var mappingEntry = mappings[i]; + var mpMappedConsentName = mappingEntry.map.toLowerCase(); + var bingMappedConsentName = mappingEntry.value; + + if ( + consentState[mpMappedConsentName] && + bingConsentProperties.indexOf(bingMappedConsentName) !== -1 + ) { + payload[bingMappedConsentName] = consentState[ + mpMappedConsentName + ].Consented + ? bingConsentValues.Granted + : bingConsentValues.Denied; + } + } + } + + return payload; + } + + function maybeSendConsentUpdateToBing(consentState) { + if ( + self.consentPayloadAsString && + self.consentMappings && + !isEmpty(consentState) + ) { + var updatedConsentPayload = generateConsentPayload( + consentState, + self.consentMappings + ); + + var eventConsentAsString = JSON.stringify(updatedConsentPayload); + + if (eventConsentAsString !== self.consentPayloadAsString) { + window.uetq.push('consent', 'update', updatedConsentPayload); + self.consentPayloadAsString = JSON.stringify( + updatedConsentPayload + ); + } + } + } + + function sendConsentDefaultToBing(consentPayload) { + self.consentPayloadAsString = JSON.stringify(consentPayload); + + window.uetq.push('consent', 'default', consentPayload); + } + + this.init = initForwarder; + this.process = processEvent; +}; + +function getUserConsentState() { + var userConsentState = {}; + + if (mParticle.Identity && mParticle.Identity.getCurrentUser) { + var currentUser = mParticle.Identity.getCurrentUser(); + + if (!currentUser) { + return {}; + } + + var consentState = mParticle.Identity.getCurrentUser().getConsentState(); + + if (consentState && consentState.getGDPRConsentState) { + userConsentState = consentState.getGDPRConsentState(); + } + } + + return userConsentState; +} + +function getConsentSettings(settings) { + var consentSettings = {}; + + Object.keys(bingToMpConsentSettingsMapping).forEach(function( + bingConsentKey + ) { + var mpConsentSettingKey = + bingToMpConsentSettingsMapping[bingConsentKey]; + var bingConsentValuesKey = settings[mpConsentSettingKey]; + + // Microsoft recommends that for most countries, we should default to 'Granted' + // if a default value is not provided + // https://help.ads.microsoft.com/apex/index/3/en/60119 + if (bingConsentValuesKey && mpConsentSettingKey) { + consentSettings[bingConsentKey] = bingConsentValues[ + bingConsentValuesKey + ] + ? bingConsentValues[bingConsentValuesKey] + : bingConsentValues.Granted; + } else { + consentSettings[bingConsentKey] = bingConsentValues.Granted; + } + }); + + return consentSettings; +} + +function parseSettingsString(settingsString) { + return JSON.parse(settingsString.replace(/"/g, '"')); +} + +function getId() { + return moduleId; +} + +function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + "'config' must be an object. You passed in a " + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); +} + +if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } +} + +function isEmpty(value) { + return value == null || !(Object.keys(value) || value).length; +} + +function cloneObject(obj) { + return JSON.parse(JSON.stringify(obj)); +} + +var BingAdsEventForwarder = { + register: register, +}; +var BingAdsEventForwarder_1 = BingAdsEventForwarder.register; + +exports.default = BingAdsEventForwarder; +exports.register = BingAdsEventForwarder_1; diff --git a/kits/bingads/dist/BingAdsEventForwarder.iife.js b/kits/bingads/dist/BingAdsEventForwarder.iife.js new file mode 100644 index 000000000..1c821d88b --- /dev/null +++ b/kits/bingads/dist/BingAdsEventForwarder.iife.js @@ -0,0 +1,406 @@ +var mpBingAdsKit = (function (exports) { + /*! + * isobject + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + + function isObject(val) { + return val != null && typeof val === 'object' && Array.isArray(val) === false; + } + + // Copyright 2016 mParticle, Inc. + // + // Licensed under the Apache License, Version 2.0 (the "License"); + // you may not use this file except in compliance with the License. + // You may obtain a copy of the License at + // + // http://www.apache.org/licenses/LICENSE-2.0 + // + // Unless required by applicable law or agreed to in writing, software + // distributed under the License is distributed on an "AS IS" BASIS, + // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + // See the License for the specific language governing permissions and + // limitations under the License. + + + + var name = 'Bing'; + var moduleId = 107; + var MessageType = { + SessionStart: 1, + SessionEnd: 2, + PageView: 3, + PageEvent: 4, + CrashReport: 5, + OptOut: 6, + Profile: 14, + Commerce: 16, + }; + + var bingConsentValues = { Denied: 'denied', Granted: 'granted' }; + var bingConsentProperties = ['ad_storage']; + var bingToMpConsentSettingsMapping = { + ad_storage: 'defaultAdStorageConsentWeb', + }; + + var constructor = function() { + var self = this; + var isInitialized = false; + var forwarderSettings = null; + var reportingService = null; + + self.consentMappings = []; + self.consentPayloadAsString = ''; + self.consentPayloadDefaults = {}; + + self.name = name; + + function initForwarder(settings, service, testMode) { + forwarderSettings = settings; + reportingService = service; + + if (forwarderSettings.consentMappingWeb) { + self.consentMappings = parseSettingsString( + forwarderSettings.consentMappingWeb + ); + } + self.consentPayloadDefaults = getConsentSettings(forwarderSettings); + + var initialConsentPayload = cloneObject(self.consentPayloadDefaults); + var userConsentState = getUserConsentState(); + + var updatedConsentPayload = generateConsentPayload( + userConsentState, + self.consentMappings + ); + + try { + if (!testMode) { + (function(window, document, tag, url, queue) { + var f; + var n; + var i; + (window[queue] = window[queue] || []), + (window.uetq = window.uetq || []), + sendConsentDefaultToBing(initialConsentPayload), + (f = function() { + var obj = { + ti: forwarderSettings.tagId, + q: window.uetq, + }; + (obj.q = window[queue]), + (window[queue] = new UET(obj)), + maybeSendConsentUpdateToBing( + updatedConsentPayload + ); + window[queue].push('pageLoad'); + }), + (n = document.createElement(tag)), + (n.src = url), + (n.async = 1), + (n.onload = n.onreadystatechange = function() { + var state = this.readyState; + (state && + state !== 'loaded' && + state !== 'complete') || + (f(), (n.onload = n.onreadystatechange = null)); + }), + (i = document.getElementsByTagName(tag)[0]), + i.parentNode.insertBefore(n, i); + })(window, document, 'script', '//bat.bing.com/bat.js', 'uetq'); + + if (window.uetq && window.queue && window.queue.length > 0) { + for ( + var i = 0, length = window.queue.length; + i < length; + i++ + ) { + processEvent(window.queue[i]); + } + + window.queue.length = 0; + } + } + + isInitialized = true; + return 'Successfully initialized: ' + name; + } catch (e) { + return "Can't initialize forwarder: " + name + ': ' + e; + } + } + + function processEvent(event) { + if (!isInitialized) { + return "Can't send to forwarder: " + name + ', not initialized'; + } + + var reportEvent = false; + try { + if ( + event.EventDataType == MessageType.PageEvent || + event.EventDataType == MessageType.PageView + ) { + reportEvent = true; + logEvent(event); + } else if ( + event.EventDataType == MessageType.Commerce && + event.ProductAction && + event.ProductAction.ProductActionType == + mParticle.ProductActionType.Purchase + ) { + reportEvent = true; + logPurchaseEvent(event); + } + + if (reportEvent && reportingService) { + reportingService(self, event); + return 'Successfully sent to forwarder: ' + name; + } + } catch (e) { + return "Can't send to forwarder: " + name + ' ' + e; + } + } + + function logEvent(event) { + if (!isInitialized) { + return ( + "Can't log event on forwarder: " + name + ', not initialized' + ); + } + try { + var obj = createUetObject(event, 'pageLoad'); + + var eventConsentState = getEventConsentState(event.ConsentState); + + maybeSendConsentUpdateToBing(eventConsentState); + + window.uetq.push(obj); + } catch (e) { + return "Can't log event on forwarder: " + name + ': ' + e; + } + + return 'Successfully logged event from forwarder: ' + name; + } + + function logPurchaseEvent(event) { + if (!isInitialized) { + return ( + "Can't log purchase event on forwarder: " + + name + + ', not initialized' + ); + } + + if ( + event.ProductAction.TotalAmount === undefined || + event.ProductAction.TotalAmount === null + ) { + return "Can't log purchase event without a total amount on product action"; + } + + try { + var obj = createUetObject(event, 'eCommerce'); + obj.gv = event.ProductAction.TotalAmount; + + window.uetq.push(obj); + } catch (e) { + return "Can't log commerce event on forwarder: " + name + ': ' + e; + } + } + + function createUetObject(event, action) { + var obj = { + ea: action, + ec: window.mParticle.EventType.getName(event.EventCategory), + el: event.EventName, + }; + + if (event.CustomFlags && event.CustomFlags['Bing.EventValue']) { + obj.ev = event.CustomFlags['Bing.EventValue']; + } + + return obj; + } + + function getEventConsentState(eventConsentState) { + return eventConsentState && eventConsentState.getGDPRConsentState + ? eventConsentState.getGDPRConsentState() + : {}; + } + + function generateConsentPayload(consentState, mappings) { + if (!mappings) { + return {}; + } + + var payload = cloneObject(self.consentPayloadDefaults); + if (mappings && mappings.length > 0) { + for (var i = 0; i < mappings.length; i++) { + var mappingEntry = mappings[i]; + var mpMappedConsentName = mappingEntry.map.toLowerCase(); + var bingMappedConsentName = mappingEntry.value; + + if ( + consentState[mpMappedConsentName] && + bingConsentProperties.indexOf(bingMappedConsentName) !== -1 + ) { + payload[bingMappedConsentName] = consentState[ + mpMappedConsentName + ].Consented + ? bingConsentValues.Granted + : bingConsentValues.Denied; + } + } + } + + return payload; + } + + function maybeSendConsentUpdateToBing(consentState) { + if ( + self.consentPayloadAsString && + self.consentMappings && + !isEmpty(consentState) + ) { + var updatedConsentPayload = generateConsentPayload( + consentState, + self.consentMappings + ); + + var eventConsentAsString = JSON.stringify(updatedConsentPayload); + + if (eventConsentAsString !== self.consentPayloadAsString) { + window.uetq.push('consent', 'update', updatedConsentPayload); + self.consentPayloadAsString = JSON.stringify( + updatedConsentPayload + ); + } + } + } + + function sendConsentDefaultToBing(consentPayload) { + self.consentPayloadAsString = JSON.stringify(consentPayload); + + window.uetq.push('consent', 'default', consentPayload); + } + + this.init = initForwarder; + this.process = processEvent; + }; + + function getUserConsentState() { + var userConsentState = {}; + + if (mParticle.Identity && mParticle.Identity.getCurrentUser) { + var currentUser = mParticle.Identity.getCurrentUser(); + + if (!currentUser) { + return {}; + } + + var consentState = mParticle.Identity.getCurrentUser().getConsentState(); + + if (consentState && consentState.getGDPRConsentState) { + userConsentState = consentState.getGDPRConsentState(); + } + } + + return userConsentState; + } + + function getConsentSettings(settings) { + var consentSettings = {}; + + Object.keys(bingToMpConsentSettingsMapping).forEach(function( + bingConsentKey + ) { + var mpConsentSettingKey = + bingToMpConsentSettingsMapping[bingConsentKey]; + var bingConsentValuesKey = settings[mpConsentSettingKey]; + + // Microsoft recommends that for most countries, we should default to 'Granted' + // if a default value is not provided + // https://help.ads.microsoft.com/apex/index/3/en/60119 + if (bingConsentValuesKey && mpConsentSettingKey) { + consentSettings[bingConsentKey] = bingConsentValues[ + bingConsentValuesKey + ] + ? bingConsentValues[bingConsentValuesKey] + : bingConsentValues.Granted; + } else { + consentSettings[bingConsentKey] = bingConsentValues.Granted; + } + }); + + return consentSettings; + } + + function parseSettingsString(settingsString) { + return JSON.parse(settingsString.replace(/"/g, '"')); + } + + function getId() { + return moduleId; + } + + function register(config) { + if (!config) { + console.log( + 'You must pass a config object to register the kit ' + name + ); + return; + } + + if (!isObject(config)) { + console.log( + "'config' must be an object. You passed in a " + typeof config + ); + return; + } + + if (isObject(config.kits)) { + config.kits[name] = { + constructor: constructor, + }; + } else { + config.kits = {}; + config.kits[name] = { + constructor: constructor, + }; + } + console.log( + 'Successfully registered ' + name + ' to your mParticle configuration' + ); + } + + if (typeof window !== 'undefined') { + if (window && window.mParticle && window.mParticle.addForwarder) { + window.mParticle.addForwarder({ + name: name, + constructor: constructor, + getId: getId, + }); + } + } + + function isEmpty(value) { + return value == null || !(Object.keys(value) || value).length; + } + + function cloneObject(obj) { + return JSON.parse(JSON.stringify(obj)); + } + + var BingAdsEventForwarder = { + register: register, + }; + var BingAdsEventForwarder_1 = BingAdsEventForwarder.register; + + exports.default = BingAdsEventForwarder; + exports.register = BingAdsEventForwarder_1; + + return exports; + +}({})); diff --git a/kits/braze/braze-3/dist/BrazeKit.common.js b/kits/braze/braze-3/dist/BrazeKit.common.js new file mode 100644 index 000000000..451974183 --- /dev/null +++ b/kits/braze/braze-3/dist/BrazeKit.common.js @@ -0,0 +1,1248 @@ +Object.defineProperty(exports, '__esModule', { value: true }); + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +var appboy_min = createCommonjsModule(function (module) { +/* +* Braze Web SDK v3.5.0 +* (c) Braze, Inc. 2022 - http://braze.com +* License available at https://github.com/Appboy/appboy-web-sdk/blob/master/LICENSE +* Compiled on 2022-02-02 +*/ +(function(){(function(b,a){if(module.exports){var e = a();module.exports=e;module.exports.default=e;}else if(b.appboy){var d=a(),c;for(c in d)b.appboy[c]=d[c];}else b.appboy=a();})("undefined"!==typeof self?self:this,function(){var appboyInterface={};var p;function aa(a){var b=0;return function(){return bb||1342177279>>=1)c+=c;return d}}); +ha("Promise",function(a){function b(g){this.Ub=0;this.Rd=void 0;this.sb=[];var h=this.Ad();try{g(h.resolve,h.reject);}catch(l){h.reject(l);}}function c(){this.Ha=null;}function d(g){return g instanceof b?g:new b(function(h){h(g);})}if(a)return a;c.prototype.Te=function(g){if(null==this.Ha){this.Ha=[];var h=this;this.Ue(function(){h.eh();});}this.Ha.push(g);};var e=fa.setTimeout;c.prototype.Ue=function(g){e(g,0);};c.prototype.eh=function(){for(;this.Ha&&this.Ha.length;){var g=this.Ha;this.Ha=[];for(var h= +0;h=d?b++:2047=d&&(b+=2);56320<=d&&57343>=d&&c--;}return b}function Qa(a,b,c,d){(d="string"===typeof a||null===a&&d)||x.error("Cannot "+b+" because "+c+' "'+a+'" is invalid.');return d}function Ra(a,b,c){var d=null!=a&&"string"===typeof a&&(""===a||a.match(Sa));d||x.error("Cannot "+b+" because "+c+' "'+a+'" is invalid.');return d} +function Ta(a,b,c,d,e){null==a&&(a={});if("object"!==typeof a||Ca(a))return x.error(b+" requires that "+c+" be an object. Ignoring "+e+"."),[!1,null];b=JSON.stringify(a);if(Pa(b)>Ua)return x.error("Could not "+d+" because "+c+" was greater than the max size of "+Va+"."),[!1,null];try{var f=JSON.parse(b);}catch(k){return x.error("Could not "+d+" because "+c+" did not contain valid JSON."),[!1,null]}for(var g in a){if(!Ra(g,d,"the "+e+" property name"))return [!1,null];c=a[g];if(null==c)delete a[g],delete f[g]; +else{Da(c)&&(f[g]=Ka(c));var h=d,l="the "+e+' property "'+g+'"';(b=Ea(c)||Ca(c)?Wa(c,f[g]):Ya(c))||x.error("Cannot "+h+" because "+l+' "'+c+'" is invalid.');if(!b)return [!1,null]}}return [!0,f]}function Wa(a,b){if(Ca(a)&&Ca(b))for(var c=0;c=a.length)return x.error("addAlias requires a non-empty alias"),!1;if(!Qa(b,"add alias","the label",!1)||0>=b.length)return x.error("addAlias requires a non-empty label"),!1;var c=this.H,d=new $a,e=ab(c.D),f=z.Df;d.j.push(new E(c.f.o(),f,(new Date).valueOf(),e,{a:a,l:b}));d.h=bb(c.b,d.j);return d.h};p.Eh=function(a){return Qa(a,"set first name","the firstName",!0)?cb(this.f,"first_name",a):!1}; +p.Ih=function(a){return Qa(a,"set last name","the lastName",!0)?cb(this.f,"last_name",a):!1};p.Ch=function(a){return null===a||"string"===typeof a&&null!=a.toLowerCase().match(Za)?cb(this.f,"email",a):(x.error('Cannot set email address - "'+a+'" did not pass RFC-5322 validation.'),!1)};p.Fh=function(a){"string"===typeof a&&(a=a.toLowerCase());return null===a||Aa(db,a,'Gender "'+a+'" is not a valid gender.',"User.Genders")?cb(this.f,"gender",a):!1}; +p.Bh=function(a,b,c){if(null===a&&null===b&&null===c)return cb(this.f,"dob",null);a=parseInt(a);b=parseInt(b);c=parseInt(c);return isNaN(a)||isNaN(b)||isNaN(c)||12b||31c?(x.error("Cannot set date of birth - parameters should comprise a valid date e.g. setDateOfBirth(1776, 7, 4);"),!1):cb(this.f,"dob",""+a+"-"+b+"-"+c)};p.yh=function(a){return Qa(a,"set country","the country",!0)?cb(this.f,"country",a):!1}; +p.Gh=function(a){return Qa(a,"set home city","the homeCity",!0)?cb(this.f,"home_city",a):!1};p.Hh=function(a){return Qa(a,"set language","the language",!0)?cb(this.f,"language",a):!1};p.Dh=function(a){return Aa(eb,a,'Email notification setting "'+a+'" is not a valid subscription type.',"User.NotificationSubscriptionTypes")?cb(this.f,"email_subscribe",a):!1}; +p.Ud=function(a){return Aa(eb,a,'Push notification setting "'+a+'" is not a valid subscription type.',"User.NotificationSubscriptionTypes")?cb(this.f,"push_subscribe",a):!1};p.Jh=function(a){return Qa(a,"set phone number","the phoneNumber",!0)?null===a||a.match(fb)?cb(this.f,"phone",a):(x.error('Cannot set phone number - "'+a+'" did not pass validation.'),!1):!1};p.xh=function(a){return cb(this.f,"image_url",a)}; +p.Oc=function(a,b,c,d,e){if(null==a||null==b)return x.error("Cannot set last-known location - latitude and longitude are required."),!1;a=parseFloat(a);b=parseFloat(b);null!=c&&(c=parseFloat(c));null!=d&&(d=parseFloat(d));null!=e&&(e=parseFloat(e));return isNaN(a)||isNaN(b)||null!=c&&isNaN(c)||null!=d&&isNaN(d)||null!=e&&isNaN(e)?(x.error("Cannot set last-known location - all supplied parameters must be numeric."),!1):90a||180b?(x.error("Cannot set last-known location - latitude and longitude are bounded by \u00b190 and \u00b1180 respectively."), +!1):null!=c&&0>c||null!=e&&0>e?(x.error("Cannot set last-known location - accuracy and altitudeAccuracy may not be negative."),!1):this.H.Oc(this.f.o(),a,b,d,c,e).h}; +p.Sd=function(a,b){if(!Ra(a,"set custom user attribute","the given key"))return !1;var c=typeof b,d=Da(b),e=Ca(b);if("number"!==c&&"boolean"!==c&&!d&&!e&&null!==b&&!Ra(b,'set custom user attribute "'+a+'"',"the given value"))return !1;d&&(b=Ka(b));if(e){for(c=0;cb||isNaN(c)||180c)return x.error("Received invalid values for latitude and/or longitude. Latitude and longitude are bounded by \u00b190 and \u00b1180 respectively, or must both be null for removal."),!1;var d=this.H,e=c;c=new $a;if(ib(d.J,a))x.info('Custom Attribute "'+a+'" is blocklisted, ignoring.'),c.h=!1;else{var f=ab(d.D); +if(null===b&&null===e){var g=z.kg;a={key:a};}else g=z.jg,a={key:a,latitude:b,longitude:e};c.j.push(new E(d.f.o(),g,(new Date).valueOf(),f,a));c.h=bb(d.b,c.j);}return c.h};p.Rg=function(a){return !Qa(a,"add user to subscription group","subscription group ID",!1)||0>=a.length?(x.error("addToSubscriptionGroup requires a non-empty subscription group ID"),!1):jb(this.H,a,kb).h}; +p.rh=function(a){return !Qa(a,"remove user from subscription group","subscription group ID",!1)||0>=a.length?(x.error("removeFromSubscriptionGroup requires a non-empty subscription group ID"),!1):jb(this.H,a,lb).h};var fb=/^[0-9 .\\(\\)\\+\\-]+$/,db={MALE:"m",FEMALE:"f",OTHER:"o",UNKNOWN:"u",NOT_APPLICABLE:"n",PREFER_NOT_TO_SAY:"p"},eb={OPTED_IN:"opted_in",SUBSCRIBED:"subscribed",UNSUBSCRIBED:"unsubscribed"},kb="subscribed",lb="unsubscribed";J.User=K;J.User.Genders=db; +J.User.NotificationSubscriptionTypes=eb;J.User.prototype.getUserId=K.prototype.o;J.User.prototype.setFirstName=K.prototype.Eh;J.User.prototype.setLastName=K.prototype.Ih;J.User.prototype.setEmail=K.prototype.Ch;J.User.prototype.setGender=K.prototype.Fh;J.User.prototype.setDateOfBirth=K.prototype.Bh;J.User.prototype.setCountry=K.prototype.yh;J.User.prototype.setHomeCity=K.prototype.Gh;J.User.prototype.setLanguage=K.prototype.Hh;J.User.prototype.setEmailNotificationSubscriptionType=K.prototype.Dh; +J.User.prototype.setPushNotificationSubscriptionType=K.prototype.Ud;J.User.prototype.setPhoneNumber=K.prototype.Jh;J.User.prototype.setAvatarImageUrl=K.prototype.xh;J.User.prototype.setLastKnownLocation=K.prototype.Oc;J.User.prototype.setCustomUserAttribute=K.prototype.Sd;J.User.prototype.addToCustomAttributeArray=K.prototype.Qg;J.User.prototype.removeFromCustomAttributeArray=K.prototype.qh;J.User.prototype.incrementCustomUserAttribute=K.prototype.kh;J.User.prototype.addAlias=K.prototype.Pg; +J.User.prototype.setCustomLocationAttribute=K.prototype.Ah;J.User.prototype.addToSubscriptionGroup=K.prototype.Rg;J.User.prototype.removeFromSubscriptionGroup=K.prototype.rh;function mb(){}mb.prototype.Ed=function(){};mb.prototype.Fd=function(){};mb.prototype.qb=function(){};function nb(a,b){if(a&&b)if(a=a.toLowerCase(),Ca(b.O))for(var c=0;cthis.Ke)return x.info("Storage failure: object is \u2248"+d+" bytes which is greater than the max of "+this.Ke),!1;this.ud[a]=c;return !0};Lb.prototype.Z=function(a){a=this.ud[a];return null==a?null:a.value}; +Lb.prototype.remove=function(a){this.ud[a]=null;};function Mb(a,b,c){this.ma=[];b&&this.ma.push(new Ib(a));c&&this.ma.push(new Hb(a));this.ma.push(new Lb);}Mb.prototype.store=function(a,b){for(var c=!0,d=0;dMath.abs(h)&&25<=Math.abs(g)?(0g&&b===Xb&&c(f),e=d=null):25<=Math.abs(h)&&(0h&&b===Zb&&0===a.scrollTop&&c(f),e=d=null);}});} +function $b(a,b,c){var d=document.createElementNS("http://www.w3.org/2000/svg","svg");d.setAttribute("viewBox",a);d.setAttribute("xmlns","http://www.w3.org/2000/svg");a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("d",b);null!=c&&a.setAttribute("fill",c);d.appendChild(a);return d}var Rb=null,Yb="up",Zb="down",Wb="left",Xb="right";function ac(a,b,c){var d=document.createElement("button");d.setAttribute("aria-label",a);d.setAttribute("tabindex","0");d.setAttribute("role","button");Sb(d,"touchstart",function(){});d.className="ab-close-button";a=$b("0 0 15 15","M15 1.5L13.5 0l-6 6-6-6L0 1.5l6 6-6 6L1.5 15l6-6 6 6 1.5-1.5-6-6 6-6z",b);d.appendChild(a);d.addEventListener("keydown",function(e){if(32===e.keyCode||13===e.keyCode)c(),e.stopPropagation();});d.onclick=function(e){c();e.stopPropagation();};return d}var bc={nh:function(){return 600>=screen.width},hh:function(){if("orientation"in window)return 90===Math.abs(window.orientation)||270===window.orientation?bc.Sa.Zc:bc.Sa.jc;if("screen"in window){var a=window.screen.orientation||screen.ci||screen.ei;null!=a&&"object"===typeof a&&(a=a.type);if("landscape-primary"===a||"landscape-secondary"===a)return bc.Sa.Zc}return bc.Sa.jc},oh:function(a,b,c){c||null!=b&&b.metaKey?window.open(a):window.location=a;},Sa:{jc:0,Zc:1}};J.WindowUtils=bc; +J.WindowUtils.openUri=bc.oh;function cc(a,b,c,d,e,f,g,h,l,k,m,q,v,t,w,r){this.id=a;this.viewed=b||!1;this.title=c||"";this.imageUrl=d;this.description=e||"";this.created=f||null;this.updated=g||null;this.categories=h||[];this.expiresAt=l||null;this.url=k;this.linkText=m;q=parseFloat(q);this.aspectRatio=isNaN(q)?null:q;this.extras=v;this.pinned=t||!1;this.dismissible=w||!1;this.dismissed=!1;this.clicked=r||!1;this.test=!1;this.pd=this.X=null;}function dc(a){null==a.X&&(a.X=new Nb);return a.X} +function ec(a){null==a.pd&&(a.pd=new Nb);return a.pd}p=cc.prototype;p.Vb=function(a){return Ob(dc(this),a)};p.Wd=function(a){return Ob(ec(this),a)};p.N=function(a){dc(this).N(a);ec(this).N(a);};p.K=function(){dc(this).K();ec(this).K();};p.Od=function(){this.viewed=!0;};p.fb=function(){this.clicked=this.viewed=!0;Pb(dc(this));};p.Nd=function(){return this.dismissible&&!this.dismissed?(this.dismissed=!0,Pb(ec(this)),!0):!1}; +function fc(a,b){if(null==b||b[T.wa]!==a.id)return !0;if(b[T.pe])return !1;if(null!=b[T.ea]&&null!=a.updated&&b[T.ea]>>24}function sc(a){a=parseInt(a);if(isNaN(a))return "";var b=parseFloat(b);isNaN(b)&&(b=1);a>>>=0;var c=a&255,d=(a&65280)>>>8,e=(a&16711680)>>>16;return (vb.Ya===ob.dc?8>>24)/255*b].join()+")":"rgb("+[e,d,c].join()+")"}function W(a,b,c,d,e,f,g,h,l,k,m,q,v,t,w,r,F,D,G,H,A,N,L,I,V,Q,n,u,y,B,P){this.message=a;this.messageAlignment=b||tc;this.duration=q||5E3;this.slideFrom=c||uc;this.extras=d||{};this.campaignId=e;this.cardId=f;this.triggerId=g;this.clickAction=h||vc;this.uri=l;this.openTarget=k||wc;this.dismissType=m||xc;this.icon=v;this.imageUrl=t;this.imageStyle=w||yc;this.iconColor=r||zc.nd;this.iconBackgroundColor=F||zc.$d;this.backgroundColor=D||zc.nd;this.textColor=G||zc.ce;this.closeButtonColor=H||zc.Sf;this.animateIn= +A;null==this.animateIn&&(this.animateIn=!0);this.animateOut=N;null==this.animateOut&&(this.animateOut=!0);this.header=L;this.headerAlignment=I||tc;this.headerTextColor=V||zc.ce;this.frameColor=Q||zc.vg;this.buttons=n||[];this.cropType=u||Ac;this.orientation=y;this.htmlId=B;this.css=P;this.Fe=this.Wa=this.Ge=!1;this.X=new Nb;this.nc=new Nb;}p=W.prototype;p.Ja=function(){return !0};p.xf=function(){return this.Ja()};function Bc(a){return null!=a.htmlId&&4a.target.clientHeight||document.querySelector("."+Sc)&&a.preventDefault();} +p.Kc=function(a){this.Ja()&&null!=a.parentNode&&this.orientation!==Zc&&(null!=a.parentNode.classList&&a.parentNode.classList.add(Sc),document.body.addEventListener("touchmove",Tc,Qb()?{passive:!1}:!1));a.className+=" "+Uc;};p.oa=function(){var a="";this.animateIn&&(a+=" ab-animate-in");this.animateOut&&(a+=" ab-animate-out");return a}; +var zc={ce:4281545523,nd:4294967295,$d:4278219733,Tf:4293914607,Uf:4283782485,vg:3224580915,Sf:4288387995},dd={ge:"hd",Bf:"ias",rg:"of",Vf:"do",Ab:"umt",yb:"tf",ie:"te"},uc="BOTTOM",ed={TOP:"TOP",BOTTOM:uc},bd="NEWS_FEED",$c="URI",vc="NONE",fd={NEWS_FEED:bd,URI:$c,NONE:vc},xc="AUTO_DISMISS",gd={AUTO_DISMISS:xc,MANUAL:"SWIPE"},wc="NONE",ad="BLANK",hd={NONE:wc,BLANK:ad},yc="TOP",Yc="GRAPHIC",id={TOP:yc,GRAPHIC:Yc},Zc="LANDSCAPE",jd={PORTRAIT:"PORTRAIT",LANDSCAPE:Zc},tc="CENTER",kd={START:"START",CENTER:tc, +END:"END"},cd="CENTER_CROP",Ac="FIT_CENTER",ld={CENTER_CROP:cd,FIT_CENTER:Ac},Mc="SLIDEUP",Hc="MODAL",Ic="MODAL_STYLED",Kc="FULL",Oc="WEB_HTML",Pc="HTML",Xc=500,Uc="ab-show",Vc="ab-hide",Sc="ab-pause-scrolling";J.InAppMessage=W;J.InAppMessage.SlideFrom=ed;J.InAppMessage.ClickAction=fd;J.InAppMessage.DismissType=gd;J.InAppMessage.OpenTarget=hd;J.InAppMessage.ImageStyle=id;J.InAppMessage.TextAlignment=kd;J.InAppMessage.Orientation=jd;J.InAppMessage.CropType=ld;J.InAppMessage.fromJson=Ec; +J.InAppMessage.prototype.subscribeToClickedEvent=W.prototype.Vb;J.InAppMessage.prototype.subscribeToDismissedEvent=W.prototype.Wd;J.InAppMessage.prototype.removeSubscription=W.prototype.N;J.InAppMessage.prototype.removeAllSubscriptions=W.prototype.K;J.InAppMessage.prototype.closeMessage=W.prototype.Ye;function Gc(a,b,c,d,e,f,g){this.text=a||"";this.backgroundColor=b||zc.$d;this.textColor=c||zc.nd;this.borderColor=d||this.backgroundColor;this.clickAction=e||vc;this.uri=f;null==g&&(g=md);this.id=g;this.Wa=!1;this.X=new Nb;}Gc.prototype.Vb=function(a){return Ob(this.X,a)};Gc.prototype.N=function(a){this.X.N(a);};Gc.prototype.K=function(){this.X.K();};Gc.prototype.fb=function(){return this.Wa?!1:(this.Wa=!0,Pb(this.X),!0)};var md=-1;J.InAppMessageButton=Gc; +J.InAppMessageButton.prototype.subscribeToClickedEvent=Gc.prototype.Vb;J.InAppMessageButton.prototype.removeSubscription=Gc.prototype.N;J.InAppMessageButton.prototype.removeAllSubscriptions=Gc.prototype.K;function Fc(a){this.triggerId=a;}J.ControlMessage=Fc;function nd(a){for(var b=a.querySelectorAll(".ab-close-button, .ab-message-text, .ab-message-button"),c=0;c/g,"