@raona/ga
Version:
Raona utilities to work with Google Analytics
284 lines (277 loc) • 12.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleAnalyticsService = exports.GA_Info = void 0;
exports.GA_Info = {
UserInfo: 'UserInfo',
PageInfo: 'PageInfo',
PageView: 'IntranetPageView'
};
var noScriptWarn = "GA function doesn't exist, reinserting the script, maybe the user is not initialized";
var noUserSetted = "The user is not initialized";
var noViewSetted = "The view is not initialized";
var noItemSetted = "The original item info is not initialized";
// You'll need to configure the different dimensions on the admin panel from Google Analytics
/** Current structure, the ones with * are optional:
DIMENSIONS:
* Dimension1 === User Language
* Dimension2 === User Country
* Dimension3 === User Department
* Dimension4 === User JobTitle
* Dimension5 === View origin (If the visit comes from the Intranet or external source, add a query string in your code for this)
* *Dimension6 === Content type of the element that generates de trace
* *Dimension7 === Element Category (Category of the element that generates the trace)
* Dimension8 === Origin Url (Url where the trace is launched)
* *Dimension9 === Destination Url (in case it's a redirect)
* Dimension10 === Webpart (will be called Section) name that launches the trace
* Dimension11 === User info, this is an agregation of dimension1,d2,d3,d4. Why? PowerBI has a limitation of 8 variables being used at the same time. Agregated so the report can show more info
METRICS:
* *Metric1 === ID of the element that interacts.
EVENTS CATEGORIES: GA_Category
EVENTS ACTIONS: GA_Action
*/
var GoogleAnalyticsService = /** @class */ (function () {
/**
* Initializes Google Analytics
* @param gaTrackingID Requiered track ID. Should be in "UA-XXXXXXXXX-X" format
* @throws Exception if the track ID doesn't follow the required format
*/
function GoogleAnalyticsService(gaTrackingID, debugMode) {
this.gaTrackingID = '';
this.previousPage = '';
this.DEBUG = false;
if (/^UA-([0-9]){9}-([0-9])$/.test(gaTrackingID)) {
this.gaTrackingID = gaTrackingID;
this.previousPage = location.href;
this.DEBUG = debugMode;
if (!document.querySelector("[id=\"" + GoogleAnalyticsService.GLOBAL_KEY + "\"]")) {
this.insertGAScript();
}
}
else {
throw new Error("The given GA's track ID doesn't follow the required \"UA-XXXXXXXXX-X\" format");
}
}
/** ---------- INITIALIZE ---------- */
/**
* Function that inserts the GA script onto the page
*/
GoogleAnalyticsService.prototype.insertGAScript = function () {
if (!document.querySelector("[id=\"" + GoogleAnalyticsService.GLOBAL_KEY + "\"]")) {
var html = '';
var disableAsync = true;
// Google supports an async and sync approach to calling Google Analytics
// Async is more efficient, but isn't supported on -- ahem -- legacy browsers.
// If your organization still supports legacy browsers (and, most likely, faxes) you can disable
// async support in the extension's configuration, by passing disableAsync: true
if (disableAsync === true) {
html += "\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');\n ga('create', '" + this.gaTrackingID + "', 'auto');";
}
else {
html = "window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;\n ga('create', '" + this.gaTrackingID + "', 'auto');";
}
// Create an element at the end of the document
var body = document.documentElement;
var script = document.createElement("script");
script.id = GoogleAnalyticsService.GLOBAL_KEY;
script.type = "text/javascript";
try {
script.appendChild(document.createTextNode(html));
body.insertAdjacentElement("beforeend", script);
}
catch (e) {
this.error(e);
}
// If we're using the async method, we also want to refer to the Google Analytics JavaScript file
// asynchronously -- of course
if (disableAsync !== true) {
// Create an async script link
var scriptLink = document.createElement("script");
scriptLink.type = "text/javascript";
scriptLink.async = true;
scriptLink.src = "https://www.google-analytics.com/analytics.js";
body.insertAdjacentElement("beforeend", scriptLink);
}
}
if (this.previousPage != location.href && this.user != undefined && this.user.language != undefined
&& this.view != undefined && this.view.viewOrigin != undefined) {
this.intranetView();
}
if (!this.user || !this.user.language) {
this.user = {
department: '',
jobtitle: '',
language: '',
office: ''
};
this.warn(noUserSetted);
}
if (!this.view || !this.view.viewOrigin) {
this.view = {
viewOrigin: '',
originUrl: location.href,
sectionName: ''
};
this.warn(noViewSetted);
}
if (!this.itemInfo || !this.itemInfo.elementId) {
//this step is not necessary but it's done to avoid future errors at code
this.itemInfo = {
category: '',
contentType: '',
elementId: -1,
destinationUrl: '',
title: '',
keywords: []
};
this.warn(noItemSetted);
}
this.startTiming();
this.exitPage = this.exitPage.bind(this);
this.previousPage = location.href;
};
/**
* Test if the ga function exists on window, if not, it reinserts the script onto it
*/
GoogleAnalyticsService.prototype.testGA = function () {
if (!window['ga']) {
this.warn(noScriptWarn);
this.insertGAScript();
}
};
/** ----------- SETTERS ---------- */
/**
* Sets/Updates the user information saved onto the service
* @param user The user information
*/
GoogleAnalyticsService.prototype.setUser = function (user) {
this.user = user;
};
GoogleAnalyticsService.prototype.setView = function (view) {
this.view = view;
};
GoogleAnalyticsService.prototype.setItemInfo = function (itemInfo) {
this.itemInfo = itemInfo;
};
/* -------------------- GETTERS -------------------- */
/**
* Generates the object for the custom dimensions and metrics
*/
GoogleAnalyticsService.prototype.getDMObject = function () {
return {
'dimension1': this.user.language,
'dimension2': this.user.office,
'dimension3': this.user.department,
'dimension4': this.user.jobtitle,
'dimension5': this.view.viewOrigin,
'dimension6': this.itemInfo.contentType,
'dimension7': this.itemInfo.category,
'dimension8': location.href,
'dimension9': this.itemInfo.destinationUrl ? this.itemInfo.destinationUrl : location.href,
'dimension10': this.view.sectionName,
'dimension11': "" + (this.itemInfo.keywords ? this.itemInfo.keywords.join(',') : ''),
'dimension12': this.user.language + "," + this.user.office + "," + this.user.department + "," + this.user.jobtitle,
'metric1': this.itemInfo.elementId,
};
};
/* -------------------- PAGE VIEW -------------------- */
/**
* Sends a page view of the current location.
*/
GoogleAnalyticsService.prototype.currentLocationView = function () {
this.testGA();
window['ga']('send', 'pageview', this.getDMObject());
};
/**
* Sends a page view of the current location. Specifically sends: location.pathname
* @param url The url being viewed
*/
GoogleAnalyticsService.prototype.pageView = function (url) {
this.testGA();
window['ga']('set', 'page', "" + url);
window['ga']('send', 'pageview', this.getDMObject());
window['ga']('set', 'page', "'" + location.href + "'");
};
/**
* Sends a page view of the current location. Specifically sends: location.pathname
*/
GoogleAnalyticsService.prototype.intranetView = function () {
this.testGA();
window['ga']('send', 'pageview', this.getDMObject());
};
/* -------------------- TIMING -------------------- */
/**
* Sets the start time to take note when the page loads
*/
GoogleAnalyticsService.prototype.startTiming = function () {
this.startTime = (new Date()).getTime();
};
/**
* Sends timing for the current page visit
*/
GoogleAnalyticsService.prototype.exitPage = function () {
this.testGA();
window['ga']('send', 'timing', 'pageview', 'accessing other url', (new Date()).getTime() - this.startTime, this.getDMObject());
};
/* -------------------- EVENT -------------------- */
/**
* Sends a custom event to GA
* @param category Category of the event, includes the action in itself
* @param action Action done that triggered the event
* @param label Any description you want to give the event
*/
GoogleAnalyticsService.prototype.event = function (category, action, label) {
this.testGA();
window['ga']('send', 'event', "" + category, "" + action, "" + label, this.getDMObject());
};
/**
* Sends an intranet event
* @param category A category for the event, limited options to events that can happen on the intranet
* @param action An action for the event, limited options to events that can happen on the intranet
* @requires itemInfo to be set beforehand
*/
GoogleAnalyticsService.prototype.intranetEvent = function (category, action) {
this.testGA();
window['ga']('send', 'event', "" + category, "" + action, "" + this.itemInfo.title, this.getDMObject());
};
/**
* Sends a trace when is invoked about if a search value ends having results or not
* @param hasResults If the search done has generated results
* @param section Where the search was done (subsite or webpart)
* @param searchValue The value searched
*/
GoogleAnalyticsService.prototype.searchEvent = function (hasResults, searchValue) {
this.testGA();
window['ga']('send', 'event', "B\u00FAsqueda", "" + (hasResults ? 'Results' : 'No results'), "" + searchValue, this.getDMObject());
};
/** --------- UTILS ---------- */
/**
* console.warn IF it's debugging
* @param warning Warning string message
*/
GoogleAnalyticsService.prototype.warn = function (warning) {
if (this.DEBUG)
console.warn('⚠️ GA WARNING ⚠️ - ', warning);
};
/**
* console.error IF it's debugging
* @param error Error message
*/
GoogleAnalyticsService.prototype.error = function (error) {
if (this.DEBUG)
console.error('🚨 GA ERROR 🚨 - ', error);
};
/** --------- DEBUG & DISCOVERY PURPOSES ---------- */
GoogleAnalyticsService.prototype.pageViewDebug = function () {
this.testGA();
console.log('ga', window['ga']);
window['ga']('send', 'pageview', this.getDMObject());
};
GoogleAnalyticsService.prototype.customEventDebug = function () {
this.testGA();
console.log('ga', window['ga']);
window['ga']('send', 'event', 'debugcategory', 'debugaction', 'debuglabel', this.getDMObject());
};
GoogleAnalyticsService.GLOBAL_KEY = 'RAONA_GoogleAnalytics';
return GoogleAnalyticsService;
}());
exports.GoogleAnalyticsService = GoogleAnalyticsService;