From 1ff6ecbe39fd5b8e5428efbcfda5c7f78805a183 Mon Sep 17 00:00:00 2001 From: Robert Ing Date: Fri, 22 Sep 2023 16:08:46 -0400 Subject: [PATCH 1/3] feat: Add Customer Configurable Standardization --- packages/GA4Client/src/common.js | 9 +++++++ packages/GA4Client/src/initialization.js | 11 +++++++- packages/GA4Client/test/src/tests.js | 32 ++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/packages/GA4Client/src/common.js b/packages/GA4Client/src/common.js index c99ff76..04eb308 100644 --- a/packages/GA4Client/src/common.js +++ b/packages/GA4Client/src/common.js @@ -132,6 +132,15 @@ Common.prototype.standardizeParameters = function (parameters) { }; Common.prototype.standardizeName = function (name) { + try { + name = window.GoogleAnalytics4Kit.setCustomNameStandardization(name); + } catch (e) { + console.warn( + 'Error calling setCustomNameStandardization callback. Check your callback. Data will still be sent without user-defined standardization', + e + ); + } + // names of events and parameters have the following requirements: // 1. They must only contain letters, numbers, and underscores function removeForbiddenCharacters(name) { diff --git a/packages/GA4Client/src/initialization.js b/packages/GA4Client/src/initialization.js index ac478de..a957a97 100644 --- a/packages/GA4Client/src/initialization.js +++ b/packages/GA4Client/src/initialization.js @@ -1,4 +1,6 @@ var initialization = { + // This name matches the mParticle database. This should not be changed unless the database name is being changed + // Changing this will also break the API for the cleansing data callback that a customer uses. name: 'GoogleAnalytics4', moduleId: 160, /* ****** Fill out initForwarder to load your SDK ****** @@ -21,6 +23,13 @@ var initialization = { ) { mParticle._setIntegrationDelay(this.moduleId, true); + // Due to current limitations, the API for allowing a customer to cleanse + // their data before our cleansing occurs must be placed on the + // window.GoogleAnalytics4Kit object. This exists when initializing MP + // SDK via snippet, but not via npm. If a customer uses npm, using the API + // requires window.GoogleAnalytics4Kit to exist on the page. + window.GoogleAnalytics4Kit = window.GoogleAnalytics4Kit || {}; + common.forwarderSettings = forwarderSettings; common.forwarderSettings.enableDataCleansing = common.forwarderSettings.enableDataCleansing === 'True'; @@ -29,7 +38,7 @@ var initialization = { var hashUserId = forwarderSettings.hashUserId; var configSettings = { - send_page_view: forwarderSettings.enablePageView === 'True' + send_page_view: forwarderSettings.enablePageView === 'True', }; window.dataLayer = window.dataLayer || []; diff --git a/packages/GA4Client/test/src/tests.js b/packages/GA4Client/test/src/tests.js index 758d82d..dc87cda 100644 --- a/packages/GA4Client/test/src/tests.js +++ b/packages/GA4Client/test/src/tests.js @@ -2021,6 +2021,38 @@ describe('Google Analytics 4 Event', function () { done(); }); + it('should standardize event names and attributes keys using user provided cleansing callback first, and then our standardization', function (done) { + window.GoogleAnalytics4Kit.setCustomNameStandardization = + function (str) { + return str.slice(0, str.length - 1); + }; + + mParticle.forwarder.process({ + EventDataType: MessageType.PageEvent, + EventCategory: EventType.Navigation, + EventName: '2?Test Event ?Standardization', + EventAttributes: { + foo: 'bar', + '1?test4ever!!!': 'tester', + }, + }); + + var expectedEventName = 'Test_Event__Standardizatio'; + + var expectedEventAttributes = { + fo: 'bar', + test4ever__: 'tester', + }; + + window.dataLayer[0][1].should.eql(expectedEventName); + window.dataLayer[0][2].should.eql(expectedEventAttributes); + + // remove this function so that it doesn't affect other tests + delete window.GoogleAnalytics4Kit.setCustomNameStandardization; + + done(); + }); + it('should remove forbidden prefixes', function (done) { mParticle.forwarder.process({ EventDataType: MessageType.PageEvent, From a0d4ecf8813924bce0543c4656eb6d2a7d7b5521 Mon Sep 17 00:00:00 2001 From: Robert Ing Date: Tue, 26 Sep 2023 14:35:07 -0400 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Alex S <49695018+alexs-mparticle@users.noreply.github.com> --- packages/GA4Client/src/common.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/GA4Client/src/common.js b/packages/GA4Client/src/common.js index 04eb308..a532ee4 100644 --- a/packages/GA4Client/src/common.js +++ b/packages/GA4Client/src/common.js @@ -135,7 +135,7 @@ Common.prototype.standardizeName = function (name) { try { name = window.GoogleAnalytics4Kit.setCustomNameStandardization(name); } catch (e) { - console.warn( + console.error( 'Error calling setCustomNameStandardization callback. Check your callback. Data will still be sent without user-defined standardization', e ); From 361036e44a82bb4b7136681083fa6df0856a1bd2 Mon Sep 17 00:00:00 2001 From: Robert Ing Date: Tue, 26 Sep 2023 14:44:55 -0400 Subject: [PATCH 3/3] update comments --- packages/GA4Client/src/common.js | 2 +- packages/GA4Client/src/initialization.js | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/GA4Client/src/common.js b/packages/GA4Client/src/common.js index a532ee4..bf8ff43 100644 --- a/packages/GA4Client/src/common.js +++ b/packages/GA4Client/src/common.js @@ -136,7 +136,7 @@ Common.prototype.standardizeName = function (name) { name = window.GoogleAnalytics4Kit.setCustomNameStandardization(name); } catch (e) { console.error( - 'Error calling setCustomNameStandardization callback. Check your callback. Data will still be sent without user-defined standardization', + 'Error calling setCustomNameStandardization callback. Check your callback. Data will still be sent without user-defined standardization. See our docs for proper use - https://docs.mparticle.com/integrations/google-analytics-4/event/', e ); } diff --git a/packages/GA4Client/src/initialization.js b/packages/GA4Client/src/initialization.js index a957a97..0b764e8 100644 --- a/packages/GA4Client/src/initialization.js +++ b/packages/GA4Client/src/initialization.js @@ -23,11 +23,11 @@ var initialization = { ) { mParticle._setIntegrationDelay(this.moduleId, true); - // Due to current limitations, the API for allowing a customer to cleanse - // their data before our cleansing occurs must be placed on the - // window.GoogleAnalytics4Kit object. This exists when initializing MP - // SDK via snippet, but not via npm. If a customer uses npm, using the API - // requires window.GoogleAnalytics4Kit to exist on the page. + // The API to allow a customer to provide the cleansing callback + // relies on window.GoogleAnalytics4Kit to exist. When MP is initialized + // via the snippet, the kit code adds it to the window automatically. + // However, when initialized via npm, it does not exist, and so we have + // to set it manually here. window.GoogleAnalytics4Kit = window.GoogleAnalytics4Kit || {}; common.forwarderSettings = forwarderSettings;