Skip to content

Commit

Permalink
feat support excludeReferrers regex (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mercy811 authored Aug 23, 2024
1 parent 484b979 commit e1eaac0
Showing 1 changed file with 231 additions and 21 deletions.
252 changes: 231 additions & 21 deletions template.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -812,9 +812,16 @@ ___TEMPLATE_PARAMETERS___
{
"type": "TEXT",
"name": "attributionExcludeReferrers",
"displayName": "Exclude Referrers",
"displayName": "Exclude Referrers String",
"simpleValueType": true,
"help": "Pass a comma-separated list of referring domains you want to exclude from campaign attribution. \u003ca href\u003d\"\"\u003eRead more\u003c/a\u003e."
"help": "Pass a comma-separated list of referring domains you want to exclude from campaign attribution. Each one of them performs exact match. For regex, use \"Exclude Referrers Regex\" instead\u003ca href\u003d\"https://amplitude.com/docs/data/source-catalog/google-tag-manager#init\"\u003eRead more\u003c/a\u003e."
},
{
"type": "TEXT",
"name": "attributionExcludeReferrersRegex",
"displayName": "Exclude Referrers Regex",
"simpleValueType": true,
"help": "Pass a comma-separated list of referring domains you want to exclude from campaign attribution. Each one of them is converted to a Regex object and performs regex match\u003ca href\u003d\"https://amplitude.com/docs/data/source-catalog/google-tag-manager#init\"\u003eRead more\u003c/a\u003e."
},
{
"type": "CHECKBOX",
Expand Down Expand Up @@ -1243,7 +1250,7 @@ const makeTableMap = require('makeTableMap');
const JSON = require('JSON');

// Constants
const WRAPPER_VERSION = '3.8.0';
const WRAPPER_VERSION = '3.9.0';
const JS_URL = 'https://cdn.amplitude.com/libs/analytics-browser-gtm-wrapper-'+WRAPPER_VERSION+'.js.br';
const LOG_PREFIX = '[Amplitude / GTM] ';
const WRAPPER_NAMESPACE = '_amplitude';
Expand Down Expand Up @@ -1357,11 +1364,15 @@ const generateConfiguration = () => {

if (!!data.detAttribution) {
initOptions.defaultTracking.attribution = {};

if (!!data.attributionExcludeReferrers) {
// TODO: How to deal with regular expression input
initOptions.defaultTracking.attribution.excludeReferrers = getType(data.attributionExcludeReferrers) === 'array' ? data.attributionExcludeReferrers : stringToArrayAndTrim(data.attributionExcludeReferrers);
initOptions.defaultTracking.attribution.excludeReferrersText = getType(data.attributionExcludeReferrers) === 'array' ? data.attributionExcludeReferrers : stringToArrayAndTrim(data.attributionExcludeReferrers);
}

if (!!data.attributionExcludeReferrersRegex) {
initOptions.defaultTracking.attribution.excludeReferrersRegex = getType(data.attributionExcludeReferrersRegex) === 'array' ? data.attributionExcludeReferrersRegex : stringToArrayAndTrim(data.attributionExcludeReferrersRegex);
}

initOptions.defaultTracking.attribution.resetSessionOnNewCampaign = data.attributionResetSession;
initOptions.defaultTracking.attribution.initialEmptyValue = data.attributionInitialEmptyValue || 'EMPTY';
} else {
Expand Down Expand Up @@ -1669,6 +1680,205 @@ ___WEB_PERMISSIONS___
___TESTS___

scenarios:
- name: Init tag with a single exclude referrer
code: |-
const excludeReferrers = "test.com";
const expectedConfig = {
defaultTracking: {
attribution: {
excludeReferrersText: [excludeReferrers],
resetSessionOnNewCampaign: undefined,
initialEmptyValue: 'EMPTY',
},
pageViews: false,
sessions: false,
fileDownloads: false,
formInteractions: false,
}
};

mockData.type = 'init';
mockData.defaultEventTracking = true;
mockData.detAttribution = true;
mockData.attributionExcludeReferrers = excludeReferrers;

// Test the following line:
// _amplitude(instanceName, 'init', data.apiKey, initUserId, generateConfiguration());
mock('copyFromWindow', key => {
return function() {
assertThat(arguments[0], 'Incorrect instance name').isEqualTo(mockData.instanceName);
assertThat(arguments[1], 'Incorrect tag type').isEqualTo(mockData.type);
assertThat(arguments[2], 'Incorrect apiKey object').isEqualTo(mockData.apiKey);
assertThat(arguments[3], 'Incorrect user Id').isEqualTo(null);
assertThat(arguments[4], 'Incorrect config').isEqualTo(expectedConfig);
};
});

// Call runCode to run the template's code.
runCode(mockData);

// Verify that the tag finished successfully.
assertApi('gtmOnSuccess').wasCalled();
- name: Init tag with multiple exclude referrers
code: |-
const excludeReferrers = ["test.com", "text.org"];
const expectedConfig = {
defaultTracking: {
attribution: {
excludeReferrersText: excludeReferrers,
resetSessionOnNewCampaign: undefined,
initialEmptyValue: 'EMPTY',
},
pageViews: false,
sessions: false,
fileDownloads: false,
formInteractions: false,
}
};

mockData.type = 'init';
mockData.defaultEventTracking = true;
mockData.detAttribution = true;
mockData.attributionExcludeReferrers = excludeReferrers;

// Test the following line:
// _amplitude(instanceName, 'init', data.apiKey, initUserId, generateConfiguration());
mock('copyFromWindow', key => {
return function() {
assertThat(arguments[0], 'Incorrect instance name').isEqualTo(mockData.instanceName);
assertThat(arguments[1], 'Incorrect tag type').isEqualTo(mockData.type);
assertThat(arguments[2], 'Incorrect apiKey object').isEqualTo(mockData.apiKey);
assertThat(arguments[3], 'Incorrect user Id').isEqualTo(null);
assertThat(arguments[4], 'Incorrect config').isEqualTo(expectedConfig);
};
});

// Call runCode to run the template's code.
runCode(mockData);

// Verify that the tag finished successfully.
assertApi('gtmOnSuccess').wasCalled();
- name: Init tag with single exclude referrers regex
code: |-
const excludeReferrersRegex = "test.com";
const expectedConfig = {
defaultTracking: {
attribution: {
excludeReferrersRegex: [excludeReferrersRegex],
resetSessionOnNewCampaign: undefined,
initialEmptyValue: 'EMPTY',
},
pageViews: false,
sessions: false,
fileDownloads: false,
formInteractions: false,
}
};

mockData.type = 'init';
mockData.defaultEventTracking = true;
mockData.detAttribution = true;
mockData.attributionExcludeReferrersRegex = excludeReferrersRegex;

// Test the following line:
// _amplitude(instanceName, 'init', data.apiKey, initUserId, generateConfiguration());
mock('copyFromWindow', key => {
return function() {
assertThat(arguments[0], 'Incorrect instance name').isEqualTo(mockData.instanceName);
assertThat(arguments[1], 'Incorrect tag type').isEqualTo(mockData.type);
assertThat(arguments[2], 'Incorrect apiKey object').isEqualTo(mockData.apiKey);
assertThat(arguments[3], 'Incorrect user Id').isEqualTo(null);
assertThat(arguments[4], 'Incorrect config').isEqualTo(expectedConfig);
};
});

// Call runCode to run the template's code.
runCode(mockData);

// Verify that the tag finished successfully.
assertApi('gtmOnSuccess').wasCalled();
- name: Init tag with multiple exclude referrers regex
code: |-
const excludeReferrersRegex = ["test.com", "text.org"];
const expectedConfig = {
defaultTracking: {
attribution: {
excludeReferrersRegex: excludeReferrersRegex,
resetSessionOnNewCampaign: undefined,
initialEmptyValue: 'EMPTY',
},
pageViews: false,
sessions: false,
fileDownloads: false,
formInteractions: false,
}
};

mockData.type = 'init';
mockData.defaultEventTracking = true;
mockData.detAttribution = true;
mockData.attributionExcludeReferrersRegex = excludeReferrersRegex;

// Test the following line:
// _amplitude(instanceName, 'init', data.apiKey, initUserId, generateConfiguration());
mock('copyFromWindow', key => {
return function() {
assertThat(arguments[0], 'Incorrect instance name').isEqualTo(mockData.instanceName);
assertThat(arguments[1], 'Incorrect tag type').isEqualTo(mockData.type);
assertThat(arguments[2], 'Incorrect apiKey object').isEqualTo(mockData.apiKey);
assertThat(arguments[3], 'Incorrect user Id').isEqualTo(null);
assertThat(arguments[4], 'Incorrect config').isEqualTo(expectedConfig);
};
});

// Call runCode to run the template's code.
runCode(mockData);

// Verify that the tag finished successfully.
assertApi('gtmOnSuccess').wasCalled();
- name: Init tag with both exclude referrers text and regex
code: |-
const excludeReferrers = ["a.com", "b.org"];
const excludeReferrersRegex = ["c.com", "d.org"];
const expectedConfig = {
defaultTracking: {
attribution: {
excludeReferrersText: excludeReferrers,
excludeReferrersRegex: excludeReferrersRegex,
resetSessionOnNewCampaign: undefined,
initialEmptyValue: 'EMPTY',
},
pageViews: false,
sessions: false,
fileDownloads: false,
formInteractions: false,
}
};

mockData.type = 'init';
mockData.defaultEventTracking = true;
mockData.detAttribution = true;
mockData.attributionExcludeReferrers = excludeReferrers;
mockData.attributionExcludeReferrersRegex = excludeReferrersRegex;

// Test the following line:
// _amplitude(instanceName, 'init', data.apiKey, initUserId, generateConfiguration());
mock('copyFromWindow', key => {
return function() {
assertThat(arguments[0], 'Incorrect instance name').isEqualTo(mockData.instanceName);
assertThat(arguments[1], 'Incorrect tag type').isEqualTo(mockData.type);
assertThat(arguments[2], 'Incorrect apiKey object').isEqualTo(mockData.apiKey);
assertThat(arguments[3], 'Incorrect user Id').isEqualTo(null);
assertThat(arguments[4], 'Incorrect config').isEqualTo(expectedConfig);
};
});

// Call runCode to run the template's code.
runCode(mockData);

// Verify that the tag finished successfully.
assertApi('gtmOnSuccess').wasCalled();
- name: Track tag with individual event properties
code: "\nmockData.type = 'track';\nmockData.eventType = 'test_event';\n\nconst eventProperties\
\ = {\n 'individual_ep_key1': 'individual_ep_value1', \n 'individual_ep_key2':\
Expand Down Expand Up @@ -2077,21 +2287,21 @@ scenarios:

// Verify that the tag finished successfully.
assertApi('gtmOnSuccess').wasCalled();
setup: "const object = require('Object');\n\nconst mockData = {\n instanceName: '$default_instance'\n\
};\n\n// Helper function\nconst convertObjectToArray = function (obj, nameKey, valueKey){\n\
\ var result = [];\n for (var key in obj) {\n if (obj.hasOwnProperty(key))\
\ {\n var entry = {};\n entry[nameKey] = key;\n \
\ entry[valueKey] = obj[key];\n result.push(entry);\n }\n \
\ }\n return result;\n};\n\nconst mergeProperties = function(obj, result, ignoredKey)\
\ {\n object.entries(obj).forEach((entry) => {\n const key = entry[0];\n \
\ if (key !== ignoredKey) {\n const value = entry[1];\n result[key] =\
\ value; \n }\n });\n return result;\n};\n\nconst mergeObject = function\
\ (baseObj, overwriteObj, ignoredKey){\n const filteredBaseObj = mergeProperties(baseObj,\
\ {}, ignoredKey); // Merge base object into new object\n const filteredMergedObj\
\ = mergeProperties(overwriteObj, filteredBaseObj, ignoredKey); // Overwrite with\
\ the second object\n return filteredMergedObj;\n};\n\nlet success, failure;\n\
mock('injectScript', (url, onsuccess, onfailure) => {\n success = onsuccess;\n\
\ failure = onfailure;\n onsuccess();\n});\n "
setup: "const object = require('Object');\n\nconst mockData = {\n instanceName: '$default_instance',\n\
\ apiKey: 'test_api_key',\n};\n\n// Helper function\nconst convertObjectToArray\
\ = function (obj, nameKey, valueKey){\n var result = [];\n for (var key in\
\ obj) {\n if (obj.hasOwnProperty(key)) {\n var entry = {};\n\
\ entry[nameKey] = key;\n entry[valueKey] = obj[key];\n \
\ result.push(entry);\n }\n }\n return result;\n};\n\nconst\
\ mergeProperties = function(obj, result, ignoredKey) {\n object.entries(obj).forEach((entry)\
\ => {\n const key = entry[0];\n if (key !== ignoredKey) {\n const value\
\ = entry[1];\n result[key] = value; \n }\n });\n return result;\n\
};\n\nconst mergeObject = function (baseObj, overwriteObj, ignoredKey){\n const\
\ filteredBaseObj = mergeProperties(baseObj, {}, ignoredKey); // Merge base object\
\ into new object\n const filteredMergedObj = mergeProperties(overwriteObj, filteredBaseObj,\
\ ignoredKey); // Overwrite with the second object\n return filteredMergedObj;\n\
};\n\nlet success, failure;\nmock('injectScript', (url, onsuccess, onfailure) =>\
\ {\n success = onsuccess;\n failure = onfailure;\n onsuccess();\n});\n "


___NOTES___
Expand Down

0 comments on commit e1eaac0

Please sign in to comment.