Last active
June 4, 2024 22:04
-
-
Save goranefbl/905c69ee6668a6f22d114b5fac75effa to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const wpgensUTMCookieManage = { | |
set: function (name, value, days) { | |
const expires = days ? new Date(Date.now() + days * 24 * 60 * 60 * 1000).toUTCString() : ''; | |
const domain = this.getCleanHost(window.location.href) ? '; domain=' + this.getCleanHost(window.location.href) : ''; | |
document.cookie = `${name}=${encodeURIComponent(value || '')}; expires=${expires}${domain}; path=/`; | |
}, | |
get: function (name) { | |
const cookieArray = document.cookie.split(';'); | |
for (let i = 0; i < cookieArray.length; i++) { | |
let cookie = cookieArray[i].trim(); | |
if (cookie.indexOf(name + '=') === 0) { | |
return decodeURIComponent(cookie.substring(name.length + 1, cookie.length)); | |
} | |
} | |
return null; | |
}, | |
remove: function (name) { | |
document.cookie = name + '=; Max-Age=-99999999;'; | |
}, | |
getCleanHost: function (url) { | |
try { | |
// Create a URL object from the input URL string. | |
var parsedUrl = new URL(url); | |
// Extract the hostname from the URL object. | |
var hostname = parsedUrl.hostname; | |
// Remove 'www.' from the hostname if present. | |
var cleanHostname = hostname.replace(/^www\./, ''); | |
return cleanHostname; | |
} catch (error) { | |
console.error('Error parsing URL: ', error); | |
return null; | |
} | |
}, | |
}; | |
(function () { | |
'use strict'; | |
const clickIdentifiers = { | |
gclid: { | |
source: 'google', | |
medium: 'cpc', | |
}, | |
dclid: { | |
source: 'google', | |
medium: 'cpm', | |
}, | |
fbclid: { | |
source: 'facebook', | |
medium: 'cpc', | |
}, | |
msclkid: { | |
source: 'bing', | |
medium: 'cpc', | |
}, | |
gclsrc: { | |
source: 'google', | |
medium: 'cpc', | |
}, | |
wbraid: { | |
source: 'google', | |
medium: 'cpc', | |
}, | |
gbraid: { | |
source: 'google', | |
medium: 'cpc', | |
}, | |
}; | |
const searchEngines = { | |
google: { | |
p: 'q', | |
n: 'google', | |
regex: true, | |
}, | |
'yahoo.com': { | |
p: 'p', | |
n: 'yahoo', | |
}, | |
'msn.com': { | |
p: 'q', | |
n: 'msn', | |
}, | |
'bing.com': { | |
p: 'q', | |
n: 'bing', | |
}, | |
'duckduckgo.com': { | |
n: 'duckduckgo', | |
}, | |
'daum.net': { | |
p: 'q', | |
n: 'daum', | |
}, | |
'eniro.se': { | |
p: 'search_word', | |
n: 'eniro ', | |
}, | |
'naver.com': { | |
p: 'query', | |
n: 'naver ', | |
}, | |
'aol.com': { | |
p: 'q', | |
n: 'aol', | |
}, | |
'lycos.com': { | |
p: 'q', | |
n: 'lycos', | |
}, | |
'ask.com': { | |
p: 'q', | |
n: 'ask', | |
}, | |
'altavista.com': { | |
p: 'q', | |
n: 'altavista', | |
}, | |
'search.netscape.com': { | |
p: 'query', | |
n: 'netscape', | |
}, | |
'cnn.com': { | |
p: 'query', | |
n: 'cnn', | |
}, | |
'about.com': { | |
p: 'terms', | |
n: 'about', | |
}, | |
'mamma.com': { | |
p: 'query', | |
n: 'mama', | |
}, | |
'alltheweb.com': { | |
p: 'q', | |
n: 'alltheweb', | |
}, | |
'voila.fr': { | |
p: 'rdata', | |
n: 'voila', | |
}, | |
'search.virgilio.it': { | |
p: 'qs', | |
n: 'virgilio', | |
}, | |
'baidu.com': { | |
p: 'wd', | |
n: 'baidu', | |
}, | |
'alice.com': { | |
p: 'qs', | |
n: 'alice', | |
}, | |
'yandex.com': { | |
p: 'text', | |
n: 'yandex', | |
}, | |
'najdi.org.mk': { | |
p: 'q', | |
n: 'najdi', | |
}, | |
'seznam.cz': { | |
p: 'q', | |
n: 'seznam', | |
}, | |
'search.com': { | |
p: 'q', | |
n: 'search', | |
}, | |
'brave.com': { | |
p: 'q', | |
n: 'brave', | |
}, | |
'wp.pl': { | |
p: 'szukaj ', | |
n: 'wirtulana polska', | |
}, | |
'online.onetcenter.org': { | |
p: 'qt', | |
n: 'o*net', | |
}, | |
'szukacz.pl': { | |
p: 'q', | |
n: 'szukacz', | |
}, | |
'yam.com': { | |
p: 'k', | |
n: 'yam', | |
}, | |
'pchome.com': { | |
p: 'q', | |
n: 'pchome', | |
}, | |
'kvasir.no': { | |
p: 'q', | |
n: 'kvasir', | |
}, | |
'sesam.no': { | |
p: 'q', | |
n: 'sesam', | |
}, | |
'ozu.es': { | |
p: 'q', | |
n: 'ozu ', | |
}, | |
'terra.com': { | |
p: 'query', | |
n: 'terra', | |
}, | |
'mynet.com': { | |
p: 'q', | |
n: 'mynet', | |
}, | |
'ekolay.net': { | |
p: 'q', | |
n: 'ekolay', | |
}, | |
'rambler.ru': { | |
p: 'words', | |
n: 'rambler', | |
}, | |
}; | |
const exceptionSLDs = ['co', 'com', 'gov', 'ac', 'org', 'edu', 'net', 'mil', 'sch', 'biz', 'eun', 'sci', 'nom', 'int']; | |
function getDomain_(url, ex_SDLs = exceptionSLDs) { | |
if (url === null) return null; | |
const getProtocol = () => window.location.protocol || 'https:'; | |
url = url.substring(0, 4) == 'http' ? url : getProtocol() + '//' + url; | |
try { | |
const domain = new URL(url).hostname; | |
const sldSet = new Set(ex_SDLs); | |
const domainParts = domain.split('.'); | |
if (sldSet.has(domainParts.slice(-2, -1)[0]) && domainParts.length >= 3) { | |
return domainParts.slice(-3).join('.'); | |
} | |
return domainParts.slice(-2).join('.'); | |
} catch (error) { | |
return null; | |
} | |
} | |
function getUtmTags() { | |
// get url parameters | |
const urlParams = new URLSearchParams(window.location.search); | |
// then turn them into an object with key: value pairs | |
const urlParamsObject = Object.fromEntries(urlParams); | |
const utmTagMap = { | |
utm_source: 'source', | |
utm_medium: 'medium', | |
utm_campaign: 'campaign', | |
utm_content: 'content', | |
utm_term: 'term', | |
}; | |
let utmTagResults = {}; | |
for (const key in urlParamsObject) { | |
if (utmTagMap.hasOwnProperty(key)) { | |
utmTagResults[utmTagMap[key]] = urlParamsObject[key]; | |
} | |
} | |
return Object.keys(utmTagResults).length > 0 ? utmTagResults : null; | |
} | |
function getReferrer() { | |
const referrer = document.referrer; | |
const referringDomain = getDomain_(referrer, exceptionSLDs); | |
return referringDomain == null ? null : { medium: 'referral', source: referringDomain }; | |
} | |
function getPaidUrlData(urlParamsObject, paidUrlParamsConfig) { | |
// Return first Click Id config found. There should never be more than one anyway. | |
for (const key in urlParamsObject) { | |
if (key in paidUrlParamsConfig) { | |
return paidUrlParamsConfig[key]; | |
} | |
} | |
// If no Click Id is found, return null | |
return null; | |
} | |
function getSearchEngineData(referringDomain, urlParamsObject, searchEngineConfig) { | |
if (referringDomain == null) return null; | |
if (searchEngineConfig.hasOwnProperty(referringDomain)) { | |
let returnData = { | |
source: searchEngineConfig[referringDomain]['n'], | |
medium: 'organic', | |
}; | |
const search_p = searchEngineConfig[referringDomain]['p']; | |
if (urlParamsObject.hasOwnProperty(search_p)) { | |
returnData['term'] = urlParamsObject[search_p]; | |
} | |
return returnData; | |
} | |
// This bit takes only those searchEngineConfigs where regex == true | |
// if referring domain isn't otherwise found, we will match against regex, but only then | |
const filteredSearchEngineConfig = Object.keys(searchEngineConfig).reduce((result, key) => { | |
if (searchEngineConfig[key]['regex']) { | |
result[key] = searchEngineConfig[key]; | |
} | |
return result; | |
}, {}); | |
for (const key in filteredSearchEngineConfig) { | |
let safeKey = key.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); | |
let regex = new RegExp(safeKey); | |
if (regex.test(referringDomain)) { | |
return { | |
source: searchEngineConfig[key]['n'], | |
medium: 'organic', | |
}; | |
} | |
} | |
return null; | |
} | |
function getDevice() { | |
const userAgent = navigator.userAgent; | |
const isMobile = /Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent); | |
const isTablet = /iPad|Android.*Tablet|Kindle|Tablet/i.test(userAgent); | |
// Check if Facebook App | |
if (!isMobile && /FBAN|FBAV/i.test(userAgent)) { | |
isMobile = true; | |
} | |
let type = 'desktop'; | |
if (isMobile) { | |
type = 'mobile'; | |
} | |
if (isTablet) { | |
type = 'tablet'; | |
} | |
const dataBrowsers = [ | |
{ name: 'Chrome', value: 'Chrome', version: 'Chrome' }, | |
{ name: 'Firefox', value: 'Firefox', version: 'Firefox' }, | |
{ name: 'Safari', value: 'Safari', version: 'Version' }, | |
{ name: 'Internet Explorer', value: 'MSIE', version: 'MSIE' }, | |
{ name: 'Opera', value: 'Opera', version: 'Opera' }, | |
{ name: 'BlackBerry', value: 'CLDC', version: 'CLDC' }, | |
{ name: 'Mozilla', value: 'Mozilla', version: 'Mozilla' }, | |
]; | |
const browser = getBrowser(userAgent, dataBrowsers); | |
return { type, browser }; | |
} | |
function getBrowser(agentString, browsers) { | |
for (let i = 0; i < browsers.length; i++) { | |
const browser = browsers[i]; | |
const regex = new RegExp(browser.value, 'i'); | |
if (regex.test(agentString)) { | |
const versionRegex = new RegExp(`${browser.version}[- /:;]([\\d._]+)`, 'i'); | |
const matches = agentString.match(versionRegex); | |
let version = matches && matches[1] ? matches[1].split(/[._]+/).join('.') : '0'; | |
return { | |
name: browser.name, | |
version: parseFloat(version), | |
}; | |
} | |
} | |
return { name: 'unknown', version: 0 }; | |
} | |
function getTrafficSource() { | |
// get url parameters | |
const urlParams = new URLSearchParams(window.location.search); | |
// then turn them into an object with key: value pairs | |
const urlParamsObject = Object.fromEntries(urlParams); | |
// this bit strips the protocol away from referrer, since psl doesn't want that | |
const referrer = document.referrer; | |
// get only the top level domain of referrer | |
const referringDomain = getDomain_(referrer, exceptionSLDs); | |
// Is it direct | |
var direct = referrer.length === 0; | |
// Is it internal, just return cookie. | |
var internal = direct ? false : referrer.indexOf(wpgens_utm.homeUrl) === 0; | |
if (internal || direct) { | |
const cookie = JSON.parse(wpgensUTMCookieManage.get('wpg_traffic')); | |
if (cookie) { | |
return cookie; | |
} | |
} | |
// checks for click identifiers in url parameters, and if present, results in cpc/cpm | |
const paidUrlData = getPaidUrlData(urlParamsObject, clickIdentifiers); | |
// checks referring domain for common search engines, and when found, results in organic | |
const searchEngineData = getSearchEngineData(referringDomain, urlParamsObject, searchEngines); | |
const queryString = new URLSearchParams(window.location.search); | |
// Custom extended query params | |
const customParams = {}; | |
if (Array.isArray(wpgens_utm.trackingParams) && wpgens_utm.trackingParams.length > 0) { | |
wpgens_utm.trackingParams.forEach((key) => { | |
const value = queryString.get(key); | |
if (value !== null) { | |
customParams[key] = decodeURIComponent(value); | |
} | |
}); | |
} | |
return { | |
lpt: new Date().toISOString(), | |
lp: typeof window.location.pathname !== 'undefined' ? window.location.pathname : '/', | |
utm_tags: getUtmTags(), | |
url_params: Object.keys(urlParamsObject).length > 0 ? urlParamsObject : null, | |
paid_url_data: paidUrlData, | |
organic_search_data: searchEngineData, | |
referral_data: getReferrer(), | |
custom_params: customParams, | |
device: getDevice(), | |
}; | |
} | |
function wpgensUTMManageCookies() { | |
try { | |
const source = getTrafficSource(); | |
const existingData = wpgensUTMCookieManage.get('wpg_traffic'); | |
if (JSON.stringify(existingData) !== JSON.stringify(source)) { | |
wpgensUTMCookieManage.set('wpg_traffic', JSON.stringify(source), wpgens_utm.cookieTime || 7); | |
} | |
return source; | |
} catch (e) { | |
console.log(e); | |
} | |
} | |
function getFirstPage() { | |
if (!wpgensUTMCookieManage.get('wpg_first')) { | |
wpgensUTMCookieManage.set('wpg_first', JSON.stringify(getTrafficSource()), 90); | |
} | |
} | |
const data = { | |
traffic: wpgensUTMManageCookies(), | |
fl: getFirstPage(), | |
}; | |
console.log(data); | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment