UNPKG

@raona/ga

Version:

Raona utilities to work with Google Analytics

284 lines (277 loc) 12.8 kB
"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;