jam-cloud/web/app/assets/javascripts/meta_tracking.js

109 lines
3.9 KiB
JavaScript

/**
* meta_tracking.js
* A standalone module to capture and persist Meta attribution signals (fbclid, _fbp) in cookies.
*
* Logic adapted for legacy environment (no React hooks).
* - Checks URL for `fbclid` and sets `_fbc` cookie.
* - Checks for `_fbp` cookie; if missing, generates and sets it.
*/
(function (window, document) {
'use strict';
var MetaTracking = {
init: function () {
var location = window.location;
this.handleFbc(location.search);
this.handleFbp();
this.handleUtm(location.search);
},
// 1. Parsing and storing _fbc (Click ID)
handleFbc: function (searchParams) {
var fbclid = this.getQueryParam('fbclid', searchParams);
if (fbclid) {
var version = 'fb';
var subdomainIndex = 1; // 1 = example.com
var creationTime = new Date().getTime(); // Unix timestamp in ms
// Format: fb.1.timestamp.id
var fbcValue = version + '.' + subdomainIndex + '.' + creationTime + '.' + fbclid;
this.setCookie('_fbc', fbcValue, 90);
}
},
handleUtm: function (searchParams) {
var utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
var self = this;
// forEach not supported in IE8, but this is modern enough or we can use for loop
for (var i = 0; i < utmParams.length; i++) {
var param = utmParams[i];
var value = self.getQueryParam(param, searchParams);
if (value) {
self.setCookie(param, value, 90);
}
}
},
// 2. Handling _fbp (Browser ID)
handleFbp: function () {
if (!this.getCookie('_fbp')) {
var version = 'fb';
var subdomainIndex = 1;
var creationTime = new Date().getTime();
var randomInt = Math.floor(Math.random() * 10000000000); // 10-digit random number
// Format: fb.1.timestamp.randomDigits
var fbpValue = version + '.' + subdomainIndex + '.' + creationTime + '.' + randomInt;
this.setCookie('_fbp', fbpValue, 90);
}
},
// Helper: Get query param by name
getQueryParam: function (name, search) {
name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
var regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
var results = regex.exec(search);
return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
},
// Helper: Set cookie
setCookie: function (name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toUTCString();
}
// Ensure path is root and domain is included if needed (defaults to current host)
document.cookie = name + "=" + (value || "") + expires + "; path=/";
},
// Helper: Get cookie
getCookie: function (name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1, c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
};
// Initialize on ready
if (document.readyState === 'complete' || document.readyState === 'interactive') {
MetaTracking.init();
} else {
// IE9+ support for DOMContentLoaded
document.addEventListener('DOMContentLoaded', function () {
MetaTracking.init();
});
}
})(window, document);