diff --git a/Traffic Source Tracker GTM Container.json b/Traffic Source Tracker GTM Container.json
new file mode 100644
index 0000000..b0cd09c
--- /dev/null
+++ b/Traffic Source Tracker GTM Container.json
@@ -0,0 +1,175 @@
+{
+ "exportFormatVersion": 2,
+ "exportTime": "2018-10-24 14:25:34",
+ "containerVersion": {
+ "path": "accounts/152155806/containers/10246515/versions/0",
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "containerVersionId": "0",
+ "container": {
+ "path": "accounts/152155806/containers/10246515",
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "name": "Traffic Source Cookie Library",
+ "publicId": "GTM-WZKBQNM",
+ "usageContext": [
+ "WEB"
+ ],
+ "fingerprint": "1540391097055",
+ "tagManagerUrl": "https://tagmanager.google.com/#/container/accounts/152155806/containers/10246515/workspaces?apiLink=container"
+ },
+ "tag": [
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "tagId": "2",
+ "name": "JS - Traffic Source Initiator",
+ "type": "html",
+ "parameter": [
+ {
+ "type": "TEMPLATE",
+ "key": "html",
+ "value": ""
+ },
+ {
+ "type": "BOOLEAN",
+ "key": "supportDocumentWrite",
+ "value": "false"
+ }
+ ],
+ "fingerprint": "1540390347969",
+ "firingTriggerId": [
+ "5",
+ "6"
+ ],
+ "tagFiringOption": "ONCE_PER_EVENT"
+ },
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "tagId": "1",
+ "name": "Traffic Source Tracker Library",
+ "type": "html",
+ "parameter": [
+ {
+ "type": "TEMPLATE",
+ "key": "html",
+ "value": ""
+ },
+ {
+ "type": "BOOLEAN",
+ "key": "supportDocumentWrite",
+ "value": "false"
+ }
+ ],
+ "fingerprint": "1540390870257",
+ "firingTriggerId": [
+ "2147479553"
+ ],
+ "tagFiringOption": "ONCE_PER_LOAD"
+ }
+ ],
+ "trigger": [
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "triggerId": "5",
+ "name": "Dom Ready - All Pages",
+ "type": "DOM_READY",
+ "fingerprint": "1540390288643"
+ },
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "triggerId": "6",
+ "name": "Dom Ready - Referrer Does not Contain Self Domain",
+ "type": "DOM_READY",
+ "filter": [
+ {
+ "type": "MATCH_REGEX",
+ "parameter": [
+ {
+ "type": "TEMPLATE",
+ "key": "arg0",
+ "value": "{{Referrer}}"
+ },
+ {
+ "type": "TEMPLATE",
+ "key": "arg1",
+ "value": "marketlytics.com"
+ },
+ {
+ "type": "BOOLEAN",
+ "key": "ignore_case",
+ "value": "true"
+ },
+ {
+ "type": "BOOLEAN",
+ "key": "negate",
+ "value": "true"
+ }
+ ]
+ }
+ ],
+ "fingerprint": "1540390342688"
+ }
+ ],
+ "variable": [
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "variableId": "1",
+ "name": "Traffic Source Cookie",
+ "type": "k",
+ "parameter": [
+ {
+ "type": "BOOLEAN",
+ "key": "decodeCookie",
+ "value": "false"
+ },
+ {
+ "type": "TEMPLATE",
+ "key": "name",
+ "value": "traffic_src"
+ }
+ ],
+ "fingerprint": "1540390942201",
+ "formatValue": {}
+ }
+ ],
+ "builtInVariable": [
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "type": "PAGE_URL",
+ "name": "Page URL"
+ },
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "type": "PAGE_HOSTNAME",
+ "name": "Page Hostname"
+ },
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "type": "PAGE_PATH",
+ "name": "Page Path"
+ },
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "type": "REFERRER",
+ "name": "Referrer"
+ },
+ {
+ "accountId": "152155806",
+ "containerId": "10246515",
+ "type": "EVENT",
+ "name": "Event"
+ }
+ ],
+ "fingerprint": "0",
+ "tagManagerUrl": "https://tagmanager.google.com/#/versions/accounts/152155806/containers/10246515/versions/0?apiLink=version"
+ }
+}
\ No newline at end of file
diff --git a/library_initiator.js b/library_initiator.js
new file mode 100644
index 0000000..2532457
--- /dev/null
+++ b/library_initiator.js
@@ -0,0 +1,22 @@
+
diff --git a/trafficSourceTracker.js b/trafficSourceTracker.js
index 79c841e..f727490 100644
--- a/trafficSourceTracker.js
+++ b/trafficSourceTracker.js
@@ -5,9 +5,9 @@
# This project is free software, distributed under the MIT license.
# MarketLytics offers digital analytics consulting and integration services.
*/
-(function (window, document)
-{
-
+(function (window, document){
+ window.dataLayer=window.dataLayer||[];
+ //including javascript in web page when JSON is undifined(first time), creating json source attribute, appending in head tag.
if(typeof JSON === 'undefined') {
var fileref = document.createElement('script');
fileref.setAttribute('type', 'text/javascript');
@@ -15,12 +15,11 @@
document.getElementsByTagName("head")[0].appendChild(fileref);
}
- // set cookie name
+ //cookieStrKey is used to set cookie name.
var cookieStrKey = 'traffic_src';
- //inject global function for cookie retrieval
- window.getTrafficSrcCookie = function()
- {
+ //inject global function for cookie retrieval.
+ window.getTrafficSrcCookie = function(){
var cookies = document.cookie.split(';');
var cookieObj;
for(var i = 0; i < cookies.length; i++) {
@@ -29,6 +28,7 @@
break;
}
}
+ //cookie values are copied into cookieObj and return in JSON format.
if(cookieObj)
{
cookieObj = cookieObj.substring(cookieObj.indexOf('=') + 1, cookieObj.length);
@@ -38,33 +38,37 @@
};
var utils = {
- getParameterByName: function(url, name)
- {
+ /*function is use to compare two parameters and return value if valid,
+ *it looks for name(any variable) in url and returns its docoded value if found in url.
+ */
+ getParameterByName: function(url, name){
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^]*)");
var results = regex.exec(url);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
},
- getKeywords: function(url)
- {
+ getKeywords: function(url){
+ //return empty sting if url is empty or direct, which indicate no keywords used.
if(url === '' || url === '(direct)') return '';
+ //we compare pre-define searchEngines object to find relavent keywords in url.
var searchEngines = 'daum:q eniro:search_word naver:query pchome:q images.google:q google:q yahoo:p yahoo:q msn:q bing:q aol:query aol:q lycos:q lycos:query ask:q cnn:query virgilio:qs baidu:wd baidu:word alice:qs yandex:text najdi:q seznam:q rakuten:qt biglobe:q goo.ne:MT search.smt.docomo:MT onet:qt onet:q kvasir:q terra:query rambler:query conduit:q babylon:q search-results:q avg:q comcast:q incredimail:q startsiden:q go.mail.ru:q centrum.cz:q 360.cn:q sogou:query tut.by:query globo:q ukr:q so.com:q haosou.com:q auone:q'.split(' ');
for(var i = 0; i < searchEngines.length; i++)
- {
+ {//set source of traffic to search engine
var val = searchEngines[i].split(':');
var name = val[0];
var queryParam = val[1];
- if(url.indexOf(name) >= 0){
- // set source of traffic to search engine
- cookieObj.ga_source = name;
- if(this.getParameterByName(url, queryParam) !== '') {
+ if(url.indexOf(name) >= 0) {
+ cookieObj.ga_source = name; // set source to searchEngine name.
+ if(this.getParameterByName(url, queryParam) !== ''){
+ //return value of queryParamter, extracted keyowrd.
return this.getParameterByName(url, queryParam);
}
}
}
-
+
+ //if url matches exact case of below regix we return not provided, which means campaign data is not present.
var google = new RegExp('^https?:\/\/(www\.)?google(\.com?)?(\.[a-z]{2}t?)?\/?$', 'i');
var yahoo = new RegExp('^https?:\/\/(r\.)?search\.yahoo\.com\/?[^?]*$', 'i');
var bing = new RegExp('^https?:\/\/(www\.)?bing\.com\/?$', 'i');
@@ -75,8 +79,8 @@
return '';
},
- getMedium: function(ccokieObj)
- {
+ //function to set medium based on different params.
+ getMedium: function(ccokieObj){
if(cookieObj.ga_medium !== '') return cookieObj.ga_medium;
if(cookieObj.ga_gclid !== '') return 'cpc';
@@ -90,13 +94,13 @@
return 'referral';
},
- getDateAfterYears: function(years)
- {
+ //getting date and time for define number of years from today.
+ getDateAfterYears: function(years){
return new Date(new Date().getTime() + (years * 365 * 24 * 60 * 60 * 1000));
},
- getHostname: function(url)
- {
+ //checking url to return approprate hostname.
+ getHostname: function(url){
var re = new RegExp('^(https:\/\/|http:\/\/)?([^\/?:#]+)');
var match = re.exec(url)[2];
if(match !== null) {
@@ -105,6 +109,9 @@
return '';
},
+ /*function that waits for the givent condition to be true,
+ * Checks the condition every 100 milisecond till timeout variable is wqual to 0
+ */
waitLoad: function(condition, callback) {
var timeout = 100;
var poll = function() {
@@ -120,10 +127,24 @@
}, 100);
};
poll();
+ },
+
+ removeSubdomain : function (host) {
+ var firstTLDs = "ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|be|bf|bg|bh|bi|bj|bm|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|cl|cm|cn|co|cr|cu|cv|cw|cx|cz|de|dj|dk|dm|do|dz|ec|ee|eg|es|et|eu|fi|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|im|in|io|iq|ir|is|it|je|jo|jp|kg|ki|km|kn|kp|kr|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|na|nc|ne|nf|ng|nl|no|nr|nu|nz|om|pa|pe|pf|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|yt".split('|');
+ var secondTLDs = "com|edu|gov|net|mil|org|nom|sch|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc".split('|');
+ host = host.replace(/^www\./, '');
+ var parts = host.split('.');
+ while (parts.length > 3) {
+ parts.shift();
+ }
+ if (parts.length === 3 && ((parts[1].length > 2 && parts[2].length > 2) || (secondTLDs.indexOf(parts[1]) === -1) && firstTLDs.indexOf(parts[2]) === -1)) {
+ parts.shift();
+ }
+ return parts.join('.');
}
- };
+ };
- // query params keys to look for to get utm data
+ // query params keys to look for to get utm data.
var parameters = [{
key: 'utm_source',
label: 'ga_source',
@@ -131,11 +152,11 @@
}, {
key: 'utm_medium',
label: 'ga_medium',
- required: true
+ required: false
}, {
key: 'utm_campaign',
label: 'ga_campaign',
- required: true
+ required: false
}, {
key: 'utm_content',
label: 'ga_content',
@@ -146,10 +167,16 @@
required: false
}];
+ //code starts from here, above declare functions are used here.
var cookieObj = {};
- var setCookie = function()
- {
+ /* gclid = checks for presensce of adword.
+ * function below sets all the required values (traffic detials) in an object name 'cookiObj',
+ * which is later converted to JSON and saved as cookie,
+ * function is used to save values in cookie defined above.
+ */
+
+ var setCookie = function(getGaClient){
cookieObj.ga_gclid = utils.getParameterByName(document.location.href, 'gclid');
var ignoreUtmParameters = false;
@@ -165,38 +192,98 @@
cookieObj[parameters[i]['label']] = value;
}
- if (cookieObj.ga_gclid !== '' && cookieObj.ga_source === '')
- {
+ //source is assumed to be google when gclid is present and source is NULL
+ if (cookieObj.ga_gclid !== '' && cookieObj.ga_source === ''){
cookieObj.ga_source = 'google';
}
- else if(ignoreUtmParameters)
- {
+ //Checks if ignoreUtmParameters is true.
+ else if(ignoreUtmParameters){
+ //Checks is referrer exists.
if(document.referrer.indexOf(document.location.host) >= 0) return;
- if(window.getTrafficSrcCookie() !== null && document.referrer === '') return;
+
+ //Checks is Cookie already exists and also checks if referrer exists.
+ if(getTrafficSrcCookie() !== null && document.referrer === '') return;
+ //Set the default source value '(direct)'.
cookieObj.ga_source = document.referrer !== '' ? document.referrer : '(direct)';
}
+ //Saves values in cookie object i.e 'cookieObj'.
cookieObj.ga_keyword = cookieObj.ga_keyword === '' ? utils.getKeywords(cookieObj.ga_source) : cookieObj.ga_keyword;
cookieObj.ga_medium = utils.getMedium(cookieObj);
+ //landing page is set to current page url.
cookieObj.ga_landing_page = document.location.href;
cookieObj.ga_source = utils.getHostname(cookieObj.ga_source);
- cookieObj.ga_client_id = ga.getAll()[0].get('clientId');
+ if (getGaClient) {
+ cookieObj.ga_client_id = ga.getAll()[0].get('clientId');
+ }
if(cookieObj.ga_source !== '') {
+ //coverting Javascript value under cookieObj to JSON String, cookieStr varaible is used to save data in cookie.
var cookieStr = JSON.stringify(cookieObj);
+ //Creating cookie with expiry set for one year, can be accessed by function getTrafficSrcCookie().
document.cookie = cookieStrKey + '=; expires=' + new Date(-1);
- document.cookie = cookieStrKey + '=' + cookieStr + '; expires=' + utils.getDateAfterYears(1) + '; path=/';
+ document.cookie = cookieStrKey + '=' + cookieStr + '; expires=' + utils.getDateAfterYears(1) + '; path=/; domain=' + utils.removeSubdomain(location.hostname);
}
-
+ //Pushes event to dataLayer to prompt that cookies have been saved successfully.
+ dataLayer.push({'event':'trafficSrcCookieSet'})
+ // Creates an event in jQuery on script ready.
+ if(jQuery){
+ jQuery.event.trigger({
+ type: "Traffic_Source_Ready_jQuery",
+ message: "Traffic Source Ready",
+ cookieData:getTrafficSrcCookie(),
+ time: new Date()
+ });
+ }
+ if($){
+ $.event.trigger({
+ type: "Traffic_Source_Ready_$",
+ message: "Traffic Source Ready",
+ cookieData:getTrafficSrcCookie(),
+ time: new Date()
+ });
+ }
+
+ // Create the event
+ var event = new CustomEvent("Traffic_Source_Ready_Dom", {
+ type: "Traffic_Source_Ready",
+ message: "Traffic Source Ready",
+ cookieData:getTrafficSrcCookie(),
+ time: new Date()
+ });
+
+ // Dispatch/Trigger/Fire the event
+ document.dispatchEvent(event);
+
+ cookieObj = {};
};
- utils.waitLoad(function() {
- return typeof JSON !== 'undefined';
- }, function() {
+ var setTrafficSrcCookie = function(options) {
+ if (!options) {
+ options = {};
+ }
+
utils.waitLoad(function() {
- return typeof ga.getAll !== 'undefined';
- }, setCookie);
- });
+ //Checks if JSON Lib is included.
+ return typeof JSON !== 'undefined';
+ }, function() {
+ if (options.getGaClient) {
+ //works when Analytics tracker(ga) exists on site, wait for some type before returing ga values and calling function setcookie.
+ utils.waitLoad(function() {
+ return typeof ga.getAll !== 'undefined';
+ }, function() {
+ setCookie(true);
+ });
+ return;
+ }
+ setCookie(false);
+
+ });
+ }
-})(window, document)
+ window.trafficSrcCookie = {
+ setCookie: setTrafficSrcCookie,
+ getCookie: getTrafficSrcCookie
+ };
+})(window, document);