@mparticle/web-google-tag-manager-kit 2.0.3 → 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,125 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var googleConsentValues = {
6
+ // Server Integration uses 'Unspecified' as a value when the setting is 'not set'.
7
+ // However, this is not used by Google's Web SDK. We are referencing it here as a comment
8
+ // as a record of this distinction and for posterity.
9
+ // If Google ever adds this for web, the line can just be uncommented to support this.
10
+ //
11
+ // Docs:
12
+ // Web: https://developers.google.com/tag-platform/gtagjs/reference#consent
13
+ // S2S: https://developers.google.com/google-ads/api/reference/rpc/v15/ConsentStatusEnum.ConsentStatus
14
+ //
15
+ // Unspecified: 'unspecified',
16
+ Denied: 'denied',
17
+ Granted: 'granted',
18
+ };
19
+
20
+ // Declares list of valid Google Consent Properties
21
+ var googleConsentProperties = [
22
+ 'ad_storage',
23
+ 'ad_user_data',
24
+ 'ad_personalization',
25
+ 'analytics_storage',
26
+ ];
27
+
28
+ function ConsentHandler(common) {
29
+ this.common = common || {};
30
+ }
31
+
32
+ ConsentHandler.prototype.getUserConsentState = function () {
33
+ var userConsentState = {};
34
+
35
+ if (mParticle.Identity && mParticle.Identity.getCurrentUser) {
36
+ var currentUser = mParticle.Identity.getCurrentUser();
37
+
38
+ if (!currentUser) {
39
+ return {};
40
+ }
41
+
42
+ var consentState =
43
+ mParticle.Identity.getCurrentUser().getConsentState();
44
+
45
+ if (consentState && consentState.getGDPRConsentState) {
46
+ userConsentState = consentState.getGDPRConsentState();
47
+ }
48
+ }
49
+
50
+ return userConsentState;
51
+ };
52
+
53
+ ConsentHandler.prototype.getEventConsentState = function (eventConsentState) {
54
+ return eventConsentState && eventConsentState.getGDPRConsentState
55
+ ? eventConsentState.getGDPRConsentState()
56
+ : {};
57
+ };
58
+
59
+ ConsentHandler.prototype.getConsentSettings = function () {
60
+ var consentSettings = {};
61
+
62
+ var googleToMpConsentSettingsMapping = {
63
+ ad_user_data: 'defaultAdUserDataConsentWeb',
64
+ ad_personalization: 'defaultAdPersonalizationConsentWeb',
65
+ ad_storage: 'defaultAdStorageConsentWeb',
66
+ analytics_storage: 'defaultAnalyticsStorageConsentWeb',
67
+ };
68
+
69
+ var settings = this.common.settings;
70
+
71
+ Object.keys(googleToMpConsentSettingsMapping).forEach(function (
72
+ googleConsentKey
73
+ ) {
74
+ var mpConsentSettingKey =
75
+ googleToMpConsentSettingsMapping[googleConsentKey];
76
+ var googleConsentValuesKey = settings[mpConsentSettingKey];
77
+
78
+ if (googleConsentValuesKey && mpConsentSettingKey) {
79
+ consentSettings[googleConsentKey] =
80
+ googleConsentValues[googleConsentValuesKey];
81
+ }
82
+ });
83
+
84
+ return consentSettings;
85
+ };
86
+
87
+ ConsentHandler.prototype.generateConsentStatePayloadFromMappings = function (
88
+ consentState,
89
+ mappings
90
+ ) {
91
+ if (!mappings) return {};
92
+
93
+ var payload = this.common.cloneObject(this.common.consentPayloadDefaults);
94
+
95
+ for (var i = 0; i <= mappings.length - 1; i++) {
96
+ var mappingEntry = mappings[i];
97
+ var mpMappedConsentName = mappingEntry.map.toLowerCase();
98
+ var googleMappedConsentName = mappingEntry.value;
99
+
100
+ if (
101
+ consentState[mpMappedConsentName] &&
102
+ googleConsentProperties.indexOf(googleMappedConsentName) !== -1
103
+ ) {
104
+ payload[googleMappedConsentName] = consentState[mpMappedConsentName]
105
+ .Consented
106
+ ? googleConsentValues.Granted
107
+ : googleConsentValues.Denied;
108
+ }
109
+ }
110
+
111
+ return payload;
112
+ };
113
+
114
+ var consent = ConsentHandler;
115
+
5
116
  function Common() {
6
117
  this.customDataLayerName = null;
118
+
119
+ this.consentMappings = [];
120
+ this.consentPayloadDefaults = {};
121
+ this.consentPayloadAsString = '';
122
+
123
+ this.consentHandler = new consent(this);
7
124
  }
8
125
 
9
126
  Common.prototype.buildMPID = function(event, user) {
@@ -122,6 +239,26 @@ Common.prototype.send = function(_attributes) {
122
239
  window[this.customDataLayerName].push(payload);
123
240
  };
124
241
 
242
+ Common.prototype.sendConsent = function (type, payload) {
243
+ // Google Tag Manager doesn't directly use the gtag function
244
+ // but recommends pushing directly into the dataLayer
245
+ // https://developers.google.com/tag-manager/devguide
246
+ var customDataLayerName = this.customDataLayerName;
247
+ function customDataLayer() {
248
+ window[customDataLayerName].push(arguments);
249
+ }
250
+
251
+ customDataLayer('consent', type, payload);
252
+ };
253
+
254
+ Common.prototype.cloneObject = function (obj) {
255
+ return JSON.parse(JSON.stringify(obj));
256
+ };
257
+
258
+ Common.prototype.isEmpty = function isEmpty(value) {
259
+ return value == null || !(Object.keys(value) || value).length;
260
+ };
261
+
125
262
  var common = Common;
126
263
 
127
264
  var ProductActionTypes = {
@@ -439,9 +576,36 @@ function EventHandler(common) {
439
576
  this.common = common || {};
440
577
  }
441
578
 
442
- EventHandler.prototype.logEvent = function(event) {
579
+ EventHandler.prototype.maybeSendConsentUpdateToGoogle = function (event) {
580
+ // If consent payload is empty,
581
+ // we never sent an initial default consent state
582
+ // so we shouldn't send an update.
583
+ if (this.common.consentPayloadAsString && this.common.consentMappings) {
584
+ var eventConsentState = this.common.consentHandler.getEventConsentState(
585
+ event.ConsentState
586
+ );
587
+
588
+ if (!this.common.isEmpty(eventConsentState)) {
589
+ var updatedConsentPayload =
590
+ this.common.consentHandler.generateConsentStatePayloadFromMappings(
591
+ eventConsentState,
592
+ this.common.consentMappings
593
+ );
594
+
595
+ var eventConsentAsString = JSON.stringify(updatedConsentPayload);
596
+
597
+ if (eventConsentAsString !== this.common.consentPayloadAsString) {
598
+ this.common.sendConsent('update', updatedConsentPayload);
599
+ this.common.consentPayloadAsString = eventConsentAsString;
600
+ }
601
+ }
602
+ }
603
+ };
604
+
605
+ EventHandler.prototype.logEvent = function (event) {
606
+ this.maybeSendConsentUpdateToGoogle(event);
443
607
  this.common.send({
444
- event: event
608
+ event: event,
445
609
  });
446
610
 
447
611
  return true;
@@ -449,7 +613,8 @@ EventHandler.prototype.logEvent = function(event) {
449
613
 
450
614
  EventHandler.prototype.logError = function() {};
451
615
 
452
- EventHandler.prototype.logPageView = function(event) {
616
+ EventHandler.prototype.logPageView = function (event) {
617
+ this.maybeSendConsentUpdateToGoogle(event);
453
618
  this.common.send({
454
619
  event: event,
455
620
  eventType: 'screen_view'
@@ -562,6 +727,20 @@ var initialization = {
562
727
  isInitialized,
563
728
  common
564
729
  ) {
730
+ common.settings = settings;
731
+
732
+ if (common.settings.consentMappingWeb) {
733
+ common.consentMappings = parseSettingsString(
734
+ common.settings.consentMappingWeb
735
+ );
736
+ } else {
737
+ // Ensures consent mappings is an empty array
738
+ // for future use
739
+ common.consentMappings = [];
740
+ common.consentPayloadDefaults = {};
741
+ common.consentPayloadAsString = '';
742
+ }
743
+
565
744
  var containerId = sanitizeContainerId(settings.containerId);
566
745
 
567
746
  if (!containerId) {
@@ -596,15 +775,32 @@ var initialization = {
596
775
 
597
776
  if (testMode || !includeContainer) {
598
777
  isInitialized = true;
599
- return;
778
+ } else {
779
+ isInitialized = initializeContainer(
780
+ containerId,
781
+ common.customDataLayerName,
782
+ previewUrl
783
+ );
600
784
  }
601
785
 
602
- isInitialized = initializeContainer(
603
- containerId,
604
- common.customDataLayerName,
605
- previewUrl
606
- );
607
- }
786
+ common.consentPayloadDefaults =
787
+ common.consentHandler.getConsentSettings();
788
+ var initialConsentState = common.consentHandler.getUserConsentState();
789
+
790
+ var defaultConsentPayload =
791
+ common.consentHandler.generateConsentStatePayloadFromMappings(
792
+ initialConsentState,
793
+ common.consentMappings
794
+ );
795
+
796
+ if (!common.isEmpty(defaultConsentPayload)) {
797
+ common.consentPayloadAsString = JSON.stringify(
798
+ defaultConsentPayload
799
+ );
800
+
801
+ common.sendConsent('default', defaultConsentPayload);
802
+ }
803
+ },
608
804
  };
609
805
 
610
806
  function initializeContainer(containerId, dataLayerName, previewUrl) {
@@ -680,10 +876,15 @@ function sanitizeDataLayerName(_dataLayerName) {
680
876
 
681
877
  function sanitizePreviewUrl(_previewUrl) {
682
878
  var previewUrl = _previewUrl || '';
683
- var regex = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/gm;
879
+ var regex =
880
+ /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\(\)\*\+,;=.]+$/gm;
684
881
  return previewUrl.trim().match(regex) ? previewUrl.trim() : '';
685
882
  }
686
883
 
884
+ function parseSettingsString(settingsString) {
885
+ return JSON.parse(settingsString.replace(/&quot;/g, '"'));
886
+ }
887
+
687
888
  var initialization_1 = initialization;
688
889
 
689
890
  var sessionHandler = {
@@ -892,8 +1093,7 @@ var constructor = function() {
892
1093
 
893
1094
  function logSessionStart(event) {
894
1095
  try {
895
- sessionHandler_1.onSessionStart(event);
896
- return true;
1096
+ return sessionHandler_1.onSessionStart(event);
897
1097
  } catch (e) {
898
1098
  return {
899
1099
  error: 'Error starting session on forwarder ' + name + '; ' + e,
@@ -903,8 +1103,7 @@ var constructor = function() {
903
1103
 
904
1104
  function logSessionEnd(event) {
905
1105
  try {
906
- sessionHandler_1.onSessionEnd(event);
907
- return true;
1106
+ return sessionHandler_1.onSessionEnd(event);
908
1107
  } catch (e) {
909
1108
  return {
910
1109
  error: 'Error ending session on forwarder ' + name + '; ' + e,
@@ -914,8 +1113,7 @@ var constructor = function() {
914
1113
 
915
1114
  function logError(event) {
916
1115
  try {
917
- self.eventHandler.logError(event);
918
- return true;
1116
+ return self.eventHandler.logError(event);
919
1117
  } catch (e) {
920
1118
  return {
921
1119
  error: 'Error logging error on forwarder ' + name + '; ' + e,
@@ -925,8 +1123,7 @@ var constructor = function() {
925
1123
 
926
1124
  function logPageView(event) {
927
1125
  try {
928
- self.eventHandler.logPageView(event);
929
- return true;
1126
+ return self.eventHandler.logPageView(event);
930
1127
  } catch (e) {
931
1128
  return {
932
1129
  error:
@@ -937,8 +1134,7 @@ var constructor = function() {
937
1134
 
938
1135
  function logEvent(event) {
939
1136
  try {
940
- self.eventHandler.logEvent(event);
941
- return true;
1137
+ return self.eventHandler.logEvent(event);
942
1138
  } catch (e) {
943
1139
  return {
944
1140
  error: 'Error logging event on forwarder ' + name + '; ' + e,
@@ -948,8 +1144,7 @@ var constructor = function() {
948
1144
 
949
1145
  function logEcommerceEvent(event) {
950
1146
  try {
951
- self.commerceHandler.logCommerceEvent(event);
952
- return true;
1147
+ return self.commerceHandler.logCommerceEvent(event);
953
1148
  } catch (e) {
954
1149
  return {
955
1150
  error:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-google-tag-manager-kit",
3
- "version": "2.0.3",
3
+ "version": "2.1.1",
4
4
  "repository": "https://github.com/mparticle-integrations/mparticle-javascript-integration-google-tag-manager",
5
5
  "main": "dist/GoogleTagManager-Kit.common.js",
6
6
  "browser": "dist/GoogleTagManager-Kit.common.js",
@@ -8,7 +8,8 @@
8
8
  "dist/GoogleTagManager-Kit.common.js"
9
9
  ],
10
10
  "scripts": {
11
- "testKarma": "node test/boilerplate/test-karma.js",
11
+ "test": "npm run build && npm run test:karma",
12
+ "test:karma": "node test/test-karma.js",
12
13
  "build": "ENVIRONMENT=production rollup --config rollup.config.js",
13
14
  "watch": "ENVIRONMENT=production rollup --config rollup.config.js -w",
14
15
  "testEndToEnd": "browserify node_modules/@mparticle/web-kit-wrapper/end-to-end-testapp/index.js -v -o test/end-to-end-testapp/build/compilation.js && open http://localhost:8082/node_modules/@mparticle/web-kit-wrapper/end-to-end-testapp/index.html && node node_modules/@mparticle/web-kit-wrapper/end-to-end-testapp/server"
@@ -18,8 +19,11 @@
18
19
  },
19
20
  "devDependencies": {
20
21
  "@mparticle/web-kit-wrapper": "^1.0.5",
22
+ "@semantic-release/changelog": "^5.0.1",
23
+ "@semantic-release/exec": "^5.0.0",
24
+ "@semantic-release/git": "^9.0.0",
21
25
  "chai": "^4.3.4",
22
- "karma": "^3.1.1",
26
+ "karma": "^5.1.0",
23
27
  "karma-chai": "^0.1.0",
24
28
  "karma-chrome-launcher": "^2.2.0",
25
29
  "karma-edge-launcher": "^0.4.2",