Skip to content

Commit 3bcebe0

Browse files
authored
[STRATCONN-14] DC Floodlight Pass Top Level UserId on Conversion Event (segmentio#457)
* Check analytics for previous added userId from identify call * Add unit test * Add support for products custom variables * Add unit tests * Update HISTORY.md and package.json * Update products to be comma separated string * [STRATCONN-86] Add support for transaction based counting in DCF (segmentio#461) * Add support for transaction counting * Update unit tests * Update History for transaction method changes
1 parent 0a00eec commit 3bcebe0

File tree

4 files changed

+225
-4
lines changed

4 files changed

+225
-4
lines changed

integrations/doubleclick-floodlight/HISTORY.md

+7
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
1.5.1 / 2020-04-16
2+
==================
3+
4+
* Adds support for top level `{{userId}}` proprety to be used as Custom Variable on Conversion Events.
5+
* Adds support for nested products propreties (ie. `products.$.price`) to be mapped in as a comma separated array on Conversion Events.
6+
* Adds support to use Transaction Method instead of Items Sold for `qty` if `useTransactionCounting` setting is enabled.
7+
18
1.5.0 / 2019-12-05
29
==================
310

integrations/doubleclick-floodlight/lib/index.js

+23-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ var Floodlight = (module.exports = integration('DoubleClick Floodlight')
2020
.option('getDoubleClickId', false)
2121
.option('googleNetworkId', '')
2222
.option('segmentWriteKey', '')
23+
.option('useTransactionCounting', false)
2324
.tag(
2425
'counter',
2526
'<iframe src="https://{{ src }}.fls.doubleclick.net/activityi;src={{ src }};type={{ type }};cat={{ cat }};dc_lat=;dc_rdid=;tag_for_child_directed_treatment=;ord={{ ord }}{{ customVariables }}?">'
@@ -80,6 +81,7 @@ Floodlight.prototype.track = function(track) {
8081
mappedEvents.push(item);
8182
}
8283
}
84+
8385
var settings = this.options;
8486

8587
// Must have events mapped and DoubleClick Advertiser ID
@@ -101,11 +103,27 @@ Floodlight.prototype.track = function(track) {
101103
each(function(variable) {
102104
var floodlightProp = variable.value;
103105
var segmentProp = variable.key.match(/{{(.*)}}/) || variable.key;
104-
var segmentPropValue;
106+
if (variable.key.includes('$')) {
107+
segmentProp = variable.key.split('.$.');
108+
}
105109

106-
if (Array.isArray(segmentProp)) {
110+
var segmentPropValue;
111+
if (Array.isArray(segmentProp) && segmentProp[0] === 'products') {
112+
segmentProp = segmentProp.pop();
113+
var productPropArray = [];
114+
each(function(product) {
115+
if (product[segmentProp]) {
116+
productPropArray.push(product[segmentProp]);
117+
}
118+
}, track.products());
119+
segmentPropValue = productPropArray.join(',');
120+
} else if (Array.isArray(segmentProp)) {
107121
segmentProp = segmentProp.pop();
108-
segmentPropValue = find(track.json(), segmentProp);
122+
if (segmentProp === 'userId') {
123+
segmentPropValue = self.analytics.user().id();
124+
} else {
125+
segmentPropValue = find(track.json(), segmentProp);
126+
}
109127
} else {
110128
segmentPropValue = properties[segmentProp];
111129
}
@@ -142,6 +160,8 @@ Floodlight.prototype.track = function(track) {
142160
quantity = properties.quantity;
143161
}
144162
if (quantity) tagParams.qty = quantity;
163+
// overwrite qty param with 1 if customer is using Trasaction Counting mehtod instead of Items Sold method
164+
if (settings.useTransactionCounting) tagParams.qty = 1;
145165
// doubleclick wants revenue under this cost param, yes
146166
if (track.revenue()) tagParams.cost = track.revenue();
147167
tagParams.ord = track.proxy(tag.ordKey);

integrations/doubleclick-floodlight/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@segment/analytics.js-integration-doubleclick-floodlight",
33
"description": "The DoubleClick Floodlight analytics.js integration.",
4-
"version": "1.5.0",
4+
"version": "1.5.1",
55
"keywords": [
66
"analytics.js",
77
"analytics.js-integration",

integrations/doubleclick-floodlight/test/index.test.js

+194
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,200 @@ describe('DoubleClick Floodlight', function() {
265265
analytics.loaded(iframe);
266266
});
267267

268+
it('should fire a floodlight sales tag properly with qty default to 1 when useTransactionCounting', function() {
269+
floodlight.options.useTransactionCounting = true;
270+
var properties = {
271+
checkout_id: 'fksdjfsdjfisjf9sdfjsd9f',
272+
order_id: '50314b8e9bcf000000000000',
273+
affiliation: 'Google Store',
274+
total: 30,
275+
revenue: 25,
276+
shipping: 3,
277+
tax: 2,
278+
discount: 2.5,
279+
coupon: 'hasbros',
280+
currency: 'USD',
281+
products: [
282+
{
283+
product_id: '507f1f77bcf86cd799439011',
284+
sku: '45790-32',
285+
name: 'Monopoly: 3rd Edition',
286+
price: 19,
287+
quantity: 1,
288+
category: 'Games'
289+
},
290+
{
291+
product_id: '505bd76785ebb509fc183733',
292+
sku: '46493-32',
293+
name: 'Uno Card Game',
294+
price: 3,
295+
quantity: 2,
296+
category: 'Games'
297+
}
298+
]
299+
};
300+
var iframe =
301+
'<iframe src="https://' +
302+
options.source +
303+
'.fls.doubleclick.net/activityi' +
304+
';src=' +
305+
options.source +
306+
';type=' +
307+
options.events[1].value.type +
308+
';cat=' +
309+
options.events[1].value.cat +
310+
';qty=' +
311+
1 +
312+
';cost=' +
313+
properties.revenue +
314+
';dc_lat=;dc_rdid=;tag_for_child_directed_treatment=' +
315+
';ord=50314b8e9bcf000000000000?">';
316+
317+
analytics.track('Order Completed', properties);
318+
analytics.called(floodlight.load);
319+
analytics.loaded(iframe);
320+
});
321+
322+
it('should fire a floodlight sales tag properly with top level userId when identify previously triggered', function() {
323+
floodlight.options.events[3] = {
324+
key: 'Order Completed',
325+
value: {
326+
event: 'Order Completed',
327+
cat: 'activityTag',
328+
type: 'groupTag',
329+
customVariable: [
330+
{
331+
key: '{{userId}}',
332+
value: 'u8'
333+
}
334+
],
335+
isSalesTag: true,
336+
ordKey: 'orderId'
337+
}
338+
};
339+
var properties = {
340+
checkout_id: 'fksdjfsdjfisjf9sdfjsd9f',
341+
order_id: '50314b8e9bcf000000000000',
342+
affiliation: 'Google Store',
343+
total: 30,
344+
revenue: 25,
345+
shipping: 3,
346+
tax: 2,
347+
discount: 2.5,
348+
coupon: 'hasbros',
349+
currency: 'USD',
350+
products: [
351+
{
352+
product_id: '507f1f77bcf86cd799439011',
353+
sku: '45790-32',
354+
name: 'Monopoly: 3rd Edition',
355+
price: 19,
356+
quantity: 1,
357+
category: 'Games'
358+
},
359+
{
360+
product_id: '505bd76785ebb509fc183733',
361+
sku: '46493-32',
362+
name: 'Uno Card Game',
363+
price: 3,
364+
quantity: 2,
365+
category: 'Games'
366+
}
367+
]
368+
};
369+
var iframe =
370+
'<iframe src="https://' +
371+
options.source +
372+
'.fls.doubleclick.net/activityi' +
373+
';src=' +
374+
options.source +
375+
';type=' +
376+
options.events[1].value.type +
377+
';cat=' +
378+
options.events[1].value.cat +
379+
';qty=' +
380+
3 +
381+
';cost=' +
382+
properties.revenue +
383+
';dc_lat=;dc_rdid=;tag_for_child_directed_treatment=' +
384+
';ord=50314b8e9bcf000000000000;u8=some_previous_userId?">';
385+
386+
analytics.identify('some_previous_userId');
387+
analytics.track('Order Completed', properties);
388+
analytics.called(floodlight.load);
389+
analytics.loaded(iframe);
390+
});
391+
392+
it('should fire a floodlight sales tag properly with product information', function() {
393+
floodlight.options.events[3] = {
394+
key: 'Order Completed',
395+
value: {
396+
event: 'Order Completed',
397+
cat: 'activityTag',
398+
type: 'groupTag',
399+
customVariable: [
400+
{
401+
key: 'products.$.category',
402+
value: 'u8'
403+
}
404+
],
405+
isSalesTag: true,
406+
ordKey: 'orderId'
407+
}
408+
};
409+
var properties = {
410+
checkout_id: 'fksdjfsdjfisjf9sdfjsd9f',
411+
order_id: '50314b8e9bcf000000000000',
412+
affiliation: 'Google Store',
413+
total: 30,
414+
revenue: 25,
415+
shipping: 3,
416+
tax: 2,
417+
discount: 2.5,
418+
coupon: 'hasbros',
419+
currency: 'USD',
420+
products: [
421+
{
422+
product_id: '507f1f77bcf86cd799439011',
423+
sku: '45790-32',
424+
name: 'Monopoly: 3rd Edition',
425+
price: 19,
426+
quantity: 1,
427+
category: 'Games'
428+
},
429+
{
430+
product_id: '505bd76785ebb509fc183733',
431+
sku: '46493-32',
432+
name: 'Uno Card Game',
433+
price: 3,
434+
quantity: 2,
435+
category: 'Games'
436+
}
437+
]
438+
};
439+
var iframe =
440+
'<iframe src="https://' +
441+
options.source +
442+
'.fls.doubleclick.net/activityi' +
443+
';src=' +
444+
options.source +
445+
';type=' +
446+
options.events[1].value.type +
447+
';cat=' +
448+
options.events[1].value.cat +
449+
';qty=' +
450+
3 +
451+
';cost=' +
452+
properties.revenue +
453+
';dc_lat=;dc_rdid=;tag_for_child_directed_treatment=' +
454+
';ord=50314b8e9bcf000000000000;u8=Games%2CGames?">';
455+
456+
analytics.identify('some_previous_userId');
457+
analytics.track('Order Completed', properties);
458+
analytics.called(floodlight.load);
459+
analytics.loaded(iframe);
460+
});
461+
268462
it('should handle property lookups as custom variable keys', function() {
269463
var event = options.events[4];
270464
var context = { campaign: { name: 'campaignName' } };

0 commit comments

Comments
 (0)