@mparticle/web-facebook-kit 2.3.0 → 3.1.0

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.
@@ -22,486 +22,585 @@ function getCjsExportFromNamespace (n) {
22
22
 
23
23
  var isobject$1 = getCjsExportFromNamespace(isobject);
24
24
 
25
- /* eslint-disable no-undef */
26
- // Copyright 2015 mParticle, Inc.
27
- //
28
- // Licensed under the Apache License, Version 2.0 (the "License");
29
- // you may not use this file except in compliance with the License.
30
- // You may obtain a copy of the License at
31
- //
32
- // http://www.apache.org/licenses/LICENSE-2.0
33
- //
34
- // Unless required by applicable law or agreed to in writing, software
35
- // distributed under the License is distributed on an "AS IS" BASIS,
36
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37
- // See the License for the specific language governing permissions and
38
- // limitations under the License.
39
-
40
-
41
- var name = 'Facebook',
42
- moduleId = 45,
43
- MessageType = {
44
- SessionStart: 1,
45
- SessionEnd: 2,
46
- PageView: 3,
47
- PageEvent: 4,
48
- CrashReport: 5,
49
- OptOut: 6,
50
- Commerce: 16,
51
- },
52
- IdentityType = {
53
- Other: 0,
54
- CustomerId: 1,
55
- Facebook: 2,
56
- Twitter: 3,
57
- Google: 4,
58
- Microsoft: 5,
59
- Yahoo: 6,
60
- Email: 7,
61
- FacebookCustomAudienceId: 9,
62
- Other2: 10,
63
- Other3: 11,
64
- Other4: 12,
65
- Other5: 13,
66
- Other6: 14,
67
- Other7: 15,
68
- Other8: 16,
69
- Other9: 17,
70
- Other10: 18,
71
- MobileNumber: 19,
72
- PhoneNumber2: 20,
73
- PhoneNumber3: 21,
74
- },
75
- SupportedCommerceTypes = [],
76
- // Standard FB Event Names from https://developers.facebook.com/docs/facebook-pixel/reference#standard-events
77
- ADD_TO_CART_EVENT_NAME = 'AddToCart',
78
- ADD_TO_WISHLIST_EVENT_NAME = 'AddToWishlist',
79
- CHECKOUT_EVENT_NAME = 'InitiateCheckout',
80
- PAGE_VIEW_EVENT_NAME = 'PageView',
81
- PURCHASE_EVENT_NAME = 'Purchase',
82
- REMOVE_FROM_CART_EVENT_NAME = 'RemoveFromCart',
83
- VIEW_CONTENT_EVENT_NAME = 'ViewContent',
84
- constructor = function () {
85
- var self = this,
86
- isInitialized = false,
87
- reportingService = null,
88
- settings,
89
- productAttributeMapping;
90
-
91
- self.name = name;
92
-
93
- function initForwarder(forwarderSettings, service, testMode, trackerId, userAttributes, userIdentities) {
94
- settings = forwarderSettings;
95
- reportingService = service;
96
-
97
- SupportedCommerceTypes = [
98
- mParticle.ProductActionType.Checkout,
99
- mParticle.ProductActionType.Purchase,
100
- mParticle.ProductActionType.AddToCart,
101
- mParticle.ProductActionType.RemoveFromCart,
102
- mParticle.ProductActionType.AddToWishlist,
103
- mParticle.ProductActionType.ViewDetail
104
- ];
105
-
106
- try {
107
- if (!testMode) {
108
- !function (f, b, e, v, n, t, s) {
109
- if (f.fbq) return; n = f.fbq = function () { n.callMethod ? n.callMethod.apply(n, arguments) : n.queue.push(arguments); }; if (!f._fbq) f._fbq = n;
110
- n.push = n; n.loaded = !0; n.version = '2.0'; n.queue = []; t = b.createElement(e); t.async = !0; t.src = v; s = b.getElementsByTagName(e)[0];
111
- s.parentNode.insertBefore(t, s);
112
- } (window, document, 'script', 'https://connect.facebook.net/en_US/fbevents.js');
113
-
114
- var visitorData = {};
115
-
116
- if(settings.externalUserIdentityType && userIdentities && userIdentities.length > 0) {
117
- var selectedType = IdentityType[settings.externalUserIdentityType];
118
- var selectedIdentity = userIdentities.filter(function (identityElement) {
119
- if (identityElement.Type === selectedType) {
120
- return identityElement.Identity;
121
- }
122
- });
123
-
124
- if (selectedIdentity.length > 0) {
125
- visitorData['external_id'] = selectedIdentity[0].Identity;
126
- }
127
- }
128
- }
129
-
130
- if (settings.disablePushState === 'True') {
131
- // Facebook will automatically track page views whenever a new state is pushed to the HTML 5 History State API
132
- // this option can be disabled to prevent duplicate page views
133
- // https://developers.facebook.com/docs/facebook-pixel/implementation/tag_spa/#tagging-single-page-applications
134
- fbq.disablePushState = true;
135
- }
136
- fbq('init', settings.pixelId, visitorData);
137
-
138
- loadMappings();
139
-
140
- isInitialized = true;
141
-
142
- return 'Successfully initialized: ' + name;
143
-
144
- }
145
- catch (e) {
146
- return 'Can\'t initialize forwarder: ' + name + ':' + e;
147
- }
148
- }
149
-
150
- function loadMappings() {
151
- productAttributeMapping = settings.productAttributeMapping
152
- ? JSON.parse(settings.productAttributeMapping.replace(/"/g, '"'))
153
- : [];
154
- }
155
-
156
- function processEvent(event) {
157
- var reportEvent = false;
158
-
159
- if (!isInitialized) {
160
- return 'Can\'t send forwarder ' + name + ', not initialized';
161
- }
162
-
163
- try {
164
- if (event.EventDataType == MessageType.PageView) {
165
- reportEvent = true;
166
- logPageView(event);
167
- }
168
- else if (event.EventDataType == MessageType.PageEvent) {
169
- reportEvent = true;
170
- logPageEvent(event);
171
- }
172
- else if (event.EventDataType == MessageType.Commerce) {
173
- reportEvent = logCommerceEvent(event);
174
- }
175
-
176
- if (reportEvent && reportingService) {
177
- reportingService(self, event);
178
- }
179
-
180
- return 'Successfully sent to forwarder ' + name;
181
- }
182
- catch (error) {
183
- return 'Can\'t send to forwarder: ' + name + ' ' + error;
184
- }
185
- }
186
-
187
- function logCommerceEvent(event) {
188
- if (event.ProductAction &&
189
- event.ProductAction.ProductList &&
190
- event.ProductAction.ProductActionType &&
191
- SupportedCommerceTypes.indexOf(event.ProductAction.ProductActionType) > -1) {
192
- var eventName,
193
- totalValue,
194
- params = cloneEventAttributes(event),
195
- eventID = createEventId(event),
196
- sendProductNamesAsContents = settings.sendProductNamesasContents || false;
197
-
198
- params['currency'] = event.CurrencyCode || 'USD';
199
-
200
- if (event.EventName) {
201
- params['content_name'] = event.EventName;
202
- }
203
-
204
- var productSkus = event.ProductAction.ProductList.reduce(function (arr, curr) {
205
- if (curr.Sku) {
206
- arr.push(curr.Sku);
207
- }
208
- return arr;
209
- }, []);
210
-
211
- if (productSkus && productSkus.length > 0) {
212
- params['content_ids'] = productSkus;
213
- }
214
-
215
- // Override content_name with product names array if setting enabled
216
- if (sendProductNamesAsContents) {
217
- var productNames = buildProductNames(event.ProductAction.ProductList);
218
- if (productNames && productNames.length > 0) {
219
- params['content_name'] = productNames;
220
- }
221
- }
222
-
223
- // Set order_id if TransactionId exists
224
- if (event.ProductAction.TransactionId) {
225
- params['order_id'] = event.ProductAction.TransactionId;
226
- }
227
-
228
- // Build contents array
229
- var contents = buildProductContents(event.ProductAction.ProductList);
230
- if (contents && contents.length > 0) {
231
- params['contents'] = contents;
232
- }
233
-
234
- if (event.ProductAction.ProductActionType == mParticle.ProductActionType.AddToWishlist ||
235
- event.ProductAction.ProductActionType == mParticle.ProductActionType.Checkout) {
236
- var eventCategory = getEventCategoryString(event);
237
- if (eventCategory) {
238
- params['content_category'] = eventCategory;
239
- }
240
- if (event.ProductAction.ProductActionType == mParticle.ProductActionType.Checkout && event.ProductAction.CheckoutStep) {
241
- params['checkout_step'] = event.ProductAction.CheckoutStep;
242
- }
243
- }
244
-
245
- if (event.ProductAction.ProductActionType == mParticle.ProductActionType.AddToCart ||
246
- event.ProductAction.ProductActionType == mParticle.ProductActionType.AddToWishlist ||
247
- event.ProductAction.ProductActionType == mParticle.ProductActionType.ViewDetail) {
248
-
249
- totalValue = event.ProductAction.ProductList.reduce(function(sum, product){
250
- if (isNumeric(product.Price) && isNumeric(product.Quantity)) {
251
- sum += product.Price * product.Quantity;
252
- }
253
- return sum;
254
- }, 0);
255
-
256
- params['value'] = totalValue;
257
-
258
- if (event.ProductAction.ProductActionType == mParticle.ProductActionType.AddToWishlist){
259
- eventName = ADD_TO_WISHLIST_EVENT_NAME;
260
- }
261
- else if (event.ProductAction.ProductActionType == mParticle.ProductActionType.AddToCart){
262
- eventName = ADD_TO_CART_EVENT_NAME;
263
- }
264
- else {
265
- eventName = VIEW_CONTENT_EVENT_NAME;
266
- }
267
-
268
- }
269
- else if (event.ProductAction.ProductActionType == mParticle.ProductActionType.Checkout ||
270
- event.ProductAction.ProductActionType == mParticle.ProductActionType.Purchase) {
271
-
272
- eventName = event.ProductAction.ProductActionType == mParticle.ProductActionType.Checkout ? CHECKOUT_EVENT_NAME : PURCHASE_EVENT_NAME;
273
-
274
- if (event.ProductAction.TotalAmount) {
275
- params['value'] = event.ProductAction.TotalAmount;
276
- }
277
-
278
- var num_items = event.ProductAction.ProductList.reduce(function(sum, product){
279
- if (isNumeric(product.Quantity)) {
280
- sum += product.Quantity;
281
- }
282
- return sum;
283
- }, 0);
284
- params['num_items'] = num_items;
285
- }
286
- else if (event.ProductAction.ProductActionType == mParticle.ProductActionType.RemoveFromCart) {
287
- eventName = REMOVE_FROM_CART_EVENT_NAME;
288
-
289
- // remove from cart can be performed in 1 of 2 ways:
290
- // 1. mParticle.eCommerce.logProductEvent(), which contains event.ProductAction.TotalAmount
291
- // 2. mParticle.eCommerce.Cart.remove(), which does not contain event.ProductAction.TotalAmount
292
- // when there is no TotalAmount, a manual calculation must be done
293
- if (event.ProductAction.TotalAmount) {
294
- totalValue = event.ProductAction.TotalAmount;
295
- } else {
296
- totalValue = event.ProductAction.ProductList.reduce(function(sum, product) {
297
- if (isNumeric(product.TotalAmount)) {
298
- sum += product.TotalAmount;
299
- }
300
- return sum;
301
- }, 0);
302
- }
303
-
304
- params['value'] = totalValue;
305
-
306
- fbq('trackCustom', eventName || 'customEvent', params, eventID);
307
- return true;
308
- }
309
-
310
- if (eventName) {
311
- fbq('track', eventName, params, eventID);
312
- }
313
- else {
314
- return false;
315
- }
316
-
317
- return true;
318
- }
319
-
320
- return false;
321
- }
322
-
323
- function logPageView(event) {
324
- logPageEvent(event, PAGE_VIEW_EVENT_NAME);
325
- }
326
-
327
- function logPageEvent(event, eventName) {
328
- var params = cloneEventAttributes(event);
329
- var eventID = createEventId(event);
330
-
331
- eventName = eventName || event.EventName;
332
- if (event.EventName) {
333
- params['content_name'] = event.EventName;
334
- }
335
-
336
- fbq('trackCustom', eventName || 'customEvent', params, eventID);
337
- }
338
-
339
- function cloneEventAttributes(event) {
340
- var attr = {};
341
- if (event && event.EventAttributes) {
342
- try {
343
- attr = JSON.parse(JSON.stringify(event.EventAttributes));
344
- }
345
- catch (e) {
346
- //
347
- }
348
- }
349
- return attr;
350
- }
351
-
352
- function isNumeric(n) {
353
- return !isNaN(parseFloat(n)) && isFinite(n);
354
- }
355
-
356
- function getEventCategoryString(event) {
357
-
358
- var enumTypeValues;
359
- var enumValue;
360
- if (event.EventDataType == MessageType.Commerce) {
361
- enumTypeValues = event.EventCategory ? mParticle.CommerceEventType : mParticle.ProductActionType;
362
- enumValue = event.EventCategory || event.ProductAction.ProductActionType;
363
- }
364
- else {
365
- enumTypeValues = mParticle.EventType;
366
- enumValue = event.EventCategory;
367
- }
368
-
369
- if (enumTypeValues && enumValue) {
370
-
371
- for (var category in enumTypeValues) {
372
- if (enumValue == enumTypeValues[category]) {
373
- return category;
374
- }
375
- }
376
- }
377
-
378
- return null;
379
- }
380
-
381
- /**
382
- * Builds contents array for Facebook Pixel commerce events.
383
- * Creates a nested array of content items with product details.
384
- *
385
- * @param {Array} productList - Array of products from event.ProductAction.ProductList
386
- * @returns {Array} Array of content objects for Facebook Pixel
387
- */
388
- function buildProductContents(productList) {
389
- if (!productList || productList.length === 0) {
390
- return [];
391
- }
392
-
393
- return productList
394
- .filter(function(product) {
395
- return product && product.Sku;
396
- })
397
- .map(function(product) {
398
- var contentItem = {
399
- id: product.Sku,
400
- quantity: isNumeric(product.Quantity) ? product.Quantity : 1,
401
- name: product.Name,
402
- brand: product.Brand,
403
- category: product.Category,
404
- variant: product.Variant,
405
- item_price: isNumeric(product.Price) ? product.Price : null
406
- };
407
-
408
- // Apply configured mappings to custom attributes
409
- productAttributeMapping.forEach(function(productMapping) {
410
- if (!isobject$1(productMapping) || !productMapping.map || !productMapping.value) {
411
- return;
412
- }
413
-
414
- var sourceField = productMapping.map;
415
- var facebookFieldName = productMapping.value;
416
- var value = null;
417
-
418
- // Check for Product level field first
419
- if (product.hasOwnProperty(sourceField)) {
420
- value = product[sourceField];
421
- }
422
- // then check for Product.Attributes level field
423
- else if (product.Attributes && product.Attributes[sourceField]) {
424
- value = product.Attributes[sourceField];
425
- }
426
-
427
- if (value !== null && value !== undefined) {
428
- contentItem[facebookFieldName] = value;
429
- }
430
- });
431
- return contentItem;
432
- });
433
- }
434
-
435
- // https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events#event-deduplication-options
436
- function createEventId(event) {
437
- return {
438
- eventID: event.SourceMessageId || null
439
- }
440
- }
441
-
442
- /**
443
- * Builds array of product names from product list
444
- * @param {Array} productList - Array of products
445
- * @returns {Array} Array of product names
446
- */
447
- function buildProductNames(productList) {
448
- if (!productList || productList.length === 0) {
449
- return [];
450
- }
451
-
452
- return productList
453
- .filter(function(product) {
454
- return product && product.Name;
455
- })
456
- .map(function(product) {
457
- return product.Name;
458
- });
459
- }
460
-
461
- this.init = initForwarder;
462
- this.process = processEvent;
463
- };
464
-
465
- function getId() {
466
- return moduleId;
467
- }
468
-
469
- function register(config) {
470
- if (!config) {
471
- console.log('You must pass a config object to register the kit ' + name);
472
- return;
473
- }
474
-
475
- if (!isobject$1(config)) {
476
- console.log('\'config\' must be an object. You passed in a ' + typeof config);
477
- return;
478
- }
479
-
480
- if (isobject$1(config.kits)) {
481
- config.kits[name] = {
482
- constructor: constructor
483
- };
484
- } else {
485
- config.kits = {};
486
- config.kits[name] = {
487
- constructor: constructor
488
- };
489
- }
490
- console.log('Successfully registered ' + name + ' to your mParticle configuration');
491
- }
492
-
493
- if (typeof window !== 'undefined') {
494
- if (window && window.mParticle && window.mParticle.addForwarder) {
495
- window.mParticle.addForwarder({
496
- name: name,
497
- constructor: constructor,
498
- getId: getId
499
- });
500
- }
501
- }
502
-
503
- var FacebookEventForwarder = {
504
- register: register
25
+ /* eslint-disable no-undef */
26
+ // Copyright 2015 mParticle, Inc.
27
+ //
28
+ // Licensed under the Apache License, Version 2.0 (the "License");
29
+ // you may not use this file except in compliance with the License.
30
+ // You may obtain a copy of the License at
31
+ //
32
+ // http://www.apache.org/licenses/LICENSE-2.0
33
+ //
34
+ // Unless required by applicable law or agreed to in writing, software
35
+ // distributed under the License is distributed on an "AS IS" BASIS,
36
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
37
+ // See the License for the specific language governing permissions and
38
+ // limitations under the License.
39
+
40
+
41
+ var name = 'Facebook',
42
+ moduleId = 45,
43
+ MessageType = {
44
+ SessionStart: 1,
45
+ SessionEnd: 2,
46
+ PageView: 3,
47
+ PageEvent: 4,
48
+ CrashReport: 5,
49
+ OptOut: 6,
50
+ Commerce: 16,
51
+ },
52
+ IdentityType = {
53
+ Other: 0,
54
+ CustomerId: 1,
55
+ Facebook: 2,
56
+ Twitter: 3,
57
+ Google: 4,
58
+ Microsoft: 5,
59
+ Yahoo: 6,
60
+ Email: 7,
61
+ FacebookCustomAudienceId: 9,
62
+ Other2: 10,
63
+ Other3: 11,
64
+ Other4: 12,
65
+ Other5: 13,
66
+ Other6: 14,
67
+ Other7: 15,
68
+ Other8: 16,
69
+ Other9: 17,
70
+ Other10: 18,
71
+ MobileNumber: 19,
72
+ PhoneNumber2: 20,
73
+ PhoneNumber3: 21,
74
+ },
75
+ SupportedCommerceTypes = [],
76
+ // Standard FB Event Names from https://developers.facebook.com/docs/facebook-pixel/reference#standard-events
77
+ ADD_TO_CART_EVENT_NAME = 'AddToCart',
78
+ ADD_TO_WISHLIST_EVENT_NAME = 'AddToWishlist',
79
+ CHECKOUT_EVENT_NAME = 'InitiateCheckout',
80
+ PAGE_VIEW_EVENT_NAME = 'PageView',
81
+ PURCHASE_EVENT_NAME = 'Purchase',
82
+ REMOVE_FROM_CART_EVENT_NAME = 'RemoveFromCart',
83
+ VIEW_CONTENT_EVENT_NAME = 'ViewContent',
84
+ constructor = function() {
85
+ var self = this,
86
+ isInitialized = false,
87
+ reportingService = null,
88
+ settings,
89
+ productAttributeMapping;
90
+
91
+ self.name = name;
92
+
93
+ function initForwarder(
94
+ forwarderSettings,
95
+ service,
96
+ testMode,
97
+ trackerId,
98
+ userAttributes,
99
+ userIdentities
100
+ ) {
101
+ settings = forwarderSettings;
102
+ reportingService = service;
103
+
104
+ SupportedCommerceTypes = [
105
+ mParticle.ProductActionType.Checkout,
106
+ mParticle.ProductActionType.Purchase,
107
+ mParticle.ProductActionType.AddToCart,
108
+ mParticle.ProductActionType.RemoveFromCart,
109
+ mParticle.ProductActionType.AddToWishlist,
110
+ mParticle.ProductActionType.ViewDetail,
111
+ ];
112
+
113
+ try {
114
+ if (!testMode) {
115
+ !(function(f, b, e, v, n, t, s) {
116
+ if (f.fbq) return;
117
+ n = f.fbq = function() {
118
+ n.callMethod
119
+ ? n.callMethod.apply(n, arguments)
120
+ : n.queue.push(arguments);
121
+ };
122
+ if (!f._fbq) f._fbq = n;
123
+ n.push = n;
124
+ n.loaded = !0;
125
+ n.version = '2.0';
126
+ n.queue = [];
127
+ t = b.createElement(e);
128
+ t.async = !0;
129
+ t.src = v;
130
+ s = b.getElementsByTagName(e)[0];
131
+ s.parentNode.insertBefore(t, s);
132
+ })(
133
+ window,
134
+ document,
135
+ 'script',
136
+ 'https://connect.facebook.net/en_US/fbevents.js'
137
+ );
138
+
139
+ var visitorData = {};
140
+
141
+ if (
142
+ settings.externalUserIdentityType &&
143
+ userIdentities &&
144
+ userIdentities.length > 0
145
+ ) {
146
+ var selectedType =
147
+ IdentityType[settings.externalUserIdentityType];
148
+ var selectedIdentity = userIdentities.filter(function(
149
+ identityElement
150
+ ) {
151
+ if (identityElement.Type === selectedType) {
152
+ return identityElement.Identity;
153
+ }
154
+ });
155
+
156
+ if (selectedIdentity.length > 0) {
157
+ visitorData['external_id'] =
158
+ selectedIdentity[0].Identity;
159
+ }
160
+ }
161
+ }
162
+
163
+ if (settings.disablePushState === 'True') {
164
+ // Facebook will automatically track page views whenever a new state is pushed to the HTML 5 History State API
165
+ // this option can be disabled to prevent duplicate page views
166
+ // https://developers.facebook.com/docs/facebook-pixel/implementation/tag_spa/#tagging-single-page-applications
167
+ fbq.disablePushState = true;
168
+ }
169
+ fbq('init', settings.pixelId, visitorData);
170
+
171
+ loadMappings();
172
+
173
+ isInitialized = true;
174
+
175
+ return 'Successfully initialized: ' + name;
176
+ } catch (e) {
177
+ return "Can't initialize forwarder: " + name + ':' + e;
178
+ }
179
+ }
180
+
181
+ function loadMappings() {
182
+ productAttributeMapping = settings.productAttributeMapping
183
+ ? JSON.parse(
184
+ settings.productAttributeMapping.replace(/"/g, '"')
185
+ )
186
+ : [];
187
+ }
188
+
189
+ function processEvent(event) {
190
+ var reportEvent = false;
191
+
192
+ if (!isInitialized) {
193
+ return "Can't send forwarder " + name + ', not initialized';
194
+ }
195
+
196
+ try {
197
+ if (event.EventDataType == MessageType.PageView) {
198
+ reportEvent = true;
199
+ logPageView(event);
200
+ } else if (event.EventDataType == MessageType.PageEvent) {
201
+ reportEvent = true;
202
+ logPageEvent(event);
203
+ } else if (event.EventDataType == MessageType.Commerce) {
204
+ reportEvent = logCommerceEvent(event);
205
+ }
206
+
207
+ if (reportEvent && reportingService) {
208
+ reportingService(self, event);
209
+ }
210
+
211
+ return 'Successfully sent to forwarder ' + name;
212
+ } catch (error) {
213
+ return "Can't send to forwarder: " + name + ' ' + error;
214
+ }
215
+ }
216
+
217
+ function logCommerceEvent(event) {
218
+ if (
219
+ event.ProductAction &&
220
+ event.ProductAction.ProductList &&
221
+ event.ProductAction.ProductActionType &&
222
+ SupportedCommerceTypes.indexOf(
223
+ event.ProductAction.ProductActionType
224
+ ) > -1
225
+ ) {
226
+ var eventName,
227
+ totalValue,
228
+ params = cloneEventAttributes(event),
229
+ eventID = createEventId(event),
230
+ sendProductNamesAsContents =
231
+ settings.sendProductNamesasContents || false;
232
+
233
+ params['currency'] = event.CurrencyCode || 'USD';
234
+
235
+ if (event.EventName) {
236
+ params['content_name'] = event.EventName;
237
+ }
238
+
239
+ var productSkus = event.ProductAction.ProductList.reduce(
240
+ function(arr, curr) {
241
+ if (curr.Sku) {
242
+ arr.push(curr.Sku);
243
+ }
244
+ return arr;
245
+ },
246
+ []
247
+ );
248
+
249
+ if (productSkus && productSkus.length > 0) {
250
+ params['content_ids'] = productSkus;
251
+ }
252
+
253
+ // Override content_name with product names array if setting enabled
254
+ if (sendProductNamesAsContents) {
255
+ var productNames = buildProductNames(
256
+ event.ProductAction.ProductList
257
+ );
258
+ if (productNames && productNames.length > 0) {
259
+ params['content_name'] = productNames;
260
+ }
261
+ }
262
+
263
+ // Set order_id if TransactionId exists
264
+ if (event.ProductAction.TransactionId) {
265
+ params['order_id'] = event.ProductAction.TransactionId;
266
+ }
267
+
268
+ // Build contents array
269
+ var contents = buildProductContents(
270
+ event.ProductAction.ProductList
271
+ );
272
+ if (contents && contents.length > 0) {
273
+ params['contents'] = contents;
274
+ }
275
+
276
+ if (
277
+ event.ProductAction.ProductActionType ==
278
+ mParticle.ProductActionType.AddToWishlist ||
279
+ event.ProductAction.ProductActionType ==
280
+ mParticle.ProductActionType.Checkout
281
+ ) {
282
+ var eventCategory = getEventCategoryString(event);
283
+ if (eventCategory) {
284
+ params['content_category'] = eventCategory;
285
+ }
286
+ if (
287
+ event.ProductAction.ProductActionType ==
288
+ mParticle.ProductActionType.Checkout &&
289
+ event.ProductAction.CheckoutStep
290
+ ) {
291
+ params['checkout_step'] =
292
+ event.ProductAction.CheckoutStep;
293
+ }
294
+ }
295
+
296
+ if (
297
+ event.ProductAction.ProductActionType ==
298
+ mParticle.ProductActionType.AddToCart ||
299
+ event.ProductAction.ProductActionType ==
300
+ mParticle.ProductActionType.AddToWishlist ||
301
+ event.ProductAction.ProductActionType ==
302
+ mParticle.ProductActionType.ViewDetail
303
+ ) {
304
+ totalValue = event.ProductAction.ProductList.reduce(
305
+ function(sum, product) {
306
+ if (
307
+ isNumeric(product.Price) &&
308
+ isNumeric(product.Quantity)
309
+ ) {
310
+ sum += product.Price * product.Quantity;
311
+ }
312
+ return sum;
313
+ },
314
+ 0
315
+ );
316
+
317
+ params['value'] = totalValue;
318
+
319
+ if (
320
+ event.ProductAction.ProductActionType ==
321
+ mParticle.ProductActionType.AddToWishlist
322
+ ) {
323
+ eventName = ADD_TO_WISHLIST_EVENT_NAME;
324
+ } else if (
325
+ event.ProductAction.ProductActionType ==
326
+ mParticle.ProductActionType.AddToCart
327
+ ) {
328
+ eventName = ADD_TO_CART_EVENT_NAME;
329
+ } else {
330
+ eventName = VIEW_CONTENT_EVENT_NAME;
331
+ }
332
+ } else if (
333
+ event.ProductAction.ProductActionType ==
334
+ mParticle.ProductActionType.Checkout ||
335
+ event.ProductAction.ProductActionType ==
336
+ mParticle.ProductActionType.Purchase
337
+ ) {
338
+ eventName =
339
+ event.ProductAction.ProductActionType ==
340
+ mParticle.ProductActionType.Checkout
341
+ ? CHECKOUT_EVENT_NAME
342
+ : PURCHASE_EVENT_NAME;
343
+
344
+ if (event.ProductAction.TotalAmount) {
345
+ params['value'] = event.ProductAction.TotalAmount;
346
+ }
347
+
348
+ var num_items = event.ProductAction.ProductList.reduce(
349
+ function(sum, product) {
350
+ if (isNumeric(product.Quantity)) {
351
+ sum += product.Quantity;
352
+ }
353
+ return sum;
354
+ },
355
+ 0
356
+ );
357
+ params['num_items'] = num_items;
358
+ } else if (
359
+ event.ProductAction.ProductActionType ==
360
+ mParticle.ProductActionType.RemoveFromCart
361
+ ) {
362
+ eventName = REMOVE_FROM_CART_EVENT_NAME;
363
+
364
+ // remove from cart can be performed in 1 of 2 ways:
365
+ // 1. mParticle.eCommerce.logProductEvent(), which contains event.ProductAction.TotalAmount
366
+ // 2. mParticle.eCommerce.Cart.remove(), which does not contain event.ProductAction.TotalAmount
367
+ // when there is no TotalAmount, a manual calculation must be done
368
+ if (event.ProductAction.TotalAmount) {
369
+ totalValue = event.ProductAction.TotalAmount;
370
+ } else {
371
+ totalValue = event.ProductAction.ProductList.reduce(
372
+ function(sum, product) {
373
+ if (isNumeric(product.TotalAmount)) {
374
+ sum += product.TotalAmount;
375
+ }
376
+ return sum;
377
+ },
378
+ 0
379
+ );
380
+ }
381
+
382
+ params['value'] = totalValue;
383
+
384
+ fbq(
385
+ 'trackCustom',
386
+ eventName || 'customEvent',
387
+ params,
388
+ eventID
389
+ );
390
+ return true;
391
+ }
392
+
393
+ if (eventName) {
394
+ fbq('track', eventName, params, eventID);
395
+ } else {
396
+ return false;
397
+ }
398
+
399
+ return true;
400
+ }
401
+
402
+ return false;
403
+ }
404
+
405
+ function logPageView(event) {
406
+ logPageEvent(event, PAGE_VIEW_EVENT_NAME);
407
+ }
408
+
409
+ function logPageEvent(event, eventName) {
410
+ var params = cloneEventAttributes(event);
411
+ var eventID = createEventId(event);
412
+
413
+ eventName = eventName || event.EventName;
414
+ if (event.EventName) {
415
+ params['content_name'] = event.EventName;
416
+ }
417
+
418
+ fbq('trackCustom', eventName || 'customEvent', params, eventID);
419
+ }
420
+
421
+ function cloneEventAttributes(event) {
422
+ var attr = {};
423
+ if (event && event.EventAttributes) {
424
+ try {
425
+ attr = JSON.parse(JSON.stringify(event.EventAttributes));
426
+ } catch (e) {
427
+ //
428
+ }
429
+ }
430
+ return attr;
431
+ }
432
+
433
+ function isNumeric(n) {
434
+ return !isNaN(parseFloat(n)) && isFinite(n);
435
+ }
436
+
437
+ function getEventCategoryString(event) {
438
+ var enumTypeValues;
439
+ var enumValue;
440
+ if (event.EventDataType == MessageType.Commerce) {
441
+ enumTypeValues = event.EventCategory
442
+ ? mParticle.CommerceEventType
443
+ : mParticle.ProductActionType;
444
+ enumValue =
445
+ event.EventCategory ||
446
+ event.ProductAction.ProductActionType;
447
+ } else {
448
+ enumTypeValues = mParticle.EventType;
449
+ enumValue = event.EventCategory;
450
+ }
451
+
452
+ if (enumTypeValues && enumValue) {
453
+ for (var category in enumTypeValues) {
454
+ if (enumValue == enumTypeValues[category]) {
455
+ return category;
456
+ }
457
+ }
458
+ }
459
+
460
+ return null;
461
+ }
462
+
463
+ /**
464
+ * Builds contents array for Facebook Pixel commerce events.
465
+ * Creates a nested array of content items with product details.
466
+ *
467
+ * @param {Array} productList - Array of products from event.ProductAction.ProductList
468
+ * @returns {Array} Array of content objects for Facebook Pixel
469
+ */
470
+ function buildProductContents(productList) {
471
+ if (!productList || productList.length === 0) {
472
+ return [];
473
+ }
474
+
475
+ return productList
476
+ .filter(function(product) {
477
+ return product && product.Sku;
478
+ })
479
+ .map(function(product) {
480
+ var contentItem = {
481
+ id: product.Sku,
482
+ quantity: isNumeric(product.Quantity)
483
+ ? product.Quantity
484
+ : 1,
485
+ name: product.Name,
486
+ brand: product.Brand,
487
+ category: product.Category,
488
+ variant: product.Variant,
489
+ item_price: isNumeric(product.Price)
490
+ ? product.Price
491
+ : null,
492
+ };
493
+
494
+ // Apply configured mappings to custom attributes
495
+ productAttributeMapping.forEach(function(productMapping) {
496
+ if (
497
+ !isobject$1(productMapping) ||
498
+ !productMapping.map ||
499
+ !productMapping.value
500
+ ) {
501
+ return;
502
+ }
503
+
504
+ var sourceField = productMapping.map;
505
+ var facebookFieldName = productMapping.value;
506
+ var value = null;
507
+
508
+ // Check for Product level field first
509
+ if (product.hasOwnProperty(sourceField)) {
510
+ value = product[sourceField];
511
+ }
512
+ // then check for Product.Attributes level field
513
+ else if (
514
+ product.Attributes &&
515
+ product.Attributes[sourceField]
516
+ ) {
517
+ value = product.Attributes[sourceField];
518
+ }
519
+
520
+ if (value !== null && value !== undefined) {
521
+ contentItem[facebookFieldName] = value;
522
+ }
523
+ });
524
+ return contentItem;
525
+ });
526
+ }
527
+
528
+ // https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events#event-deduplication-options
529
+ function createEventId(event) {
530
+ return {
531
+ eventID: event.SourceMessageId || null,
532
+ };
533
+ }
534
+
535
+ /**
536
+ * Builds array of product names from product list
537
+ * @param {Array} productList - Array of products
538
+ * @returns {Array} Array of product names
539
+ */
540
+ function buildProductNames(productList) {
541
+ if (!productList || productList.length === 0) {
542
+ return [];
543
+ }
544
+
545
+ return productList
546
+ .filter(function(product) {
547
+ return product && product.Name;
548
+ })
549
+ .map(function(product) {
550
+ return product.Name;
551
+ });
552
+ }
553
+
554
+ this.init = initForwarder;
555
+ this.process = processEvent;
556
+ };
557
+
558
+ function getId() {
559
+ return moduleId;
560
+ }
561
+
562
+ function register(config) {
563
+ if (!config) {
564
+ console.log(
565
+ 'You must pass a config object to register the kit ' + name
566
+ );
567
+ return;
568
+ }
569
+
570
+ if (!isobject$1(config)) {
571
+ console.log(
572
+ "'config' must be an object. You passed in a " + typeof config
573
+ );
574
+ return;
575
+ }
576
+
577
+ if (isobject$1(config.kits)) {
578
+ config.kits[name] = {
579
+ constructor: constructor,
580
+ };
581
+ } else {
582
+ config.kits = {};
583
+ config.kits[name] = {
584
+ constructor: constructor,
585
+ };
586
+ }
587
+ console.log(
588
+ 'Successfully registered ' + name + ' to your mParticle configuration'
589
+ );
590
+ }
591
+
592
+ if (typeof window !== 'undefined') {
593
+ if (window && window.mParticle && window.mParticle.addForwarder) {
594
+ window.mParticle.addForwarder({
595
+ name: name,
596
+ constructor: constructor,
597
+ getId: getId,
598
+ });
599
+ }
600
+ }
601
+
602
+ var FacebookEventForwarder = {
603
+ register: register,
505
604
  };
506
605
  var FacebookEventForwarder_1 = FacebookEventForwarder.register;
507
606