Created
January 27, 2019 11:43
-
-
Save lmangani/fa2c9fe6920d58212027f6a2898f6c30 to your computer and use it in GitHub Desktop.
JITSI Analytics Example
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
/* global ga */ | |
(function(ctx) { | |
/** | |
* | |
*/ | |
function Analytics(options) { | |
/* eslint-disable */ | |
if (!options.googleAnalyticsTrackingId) { | |
console.log( | |
'Failed to initialize Google Analytics handler, no tracking ID'); | |
return; | |
} | |
/** | |
* ga-lite: Smaller, cacheable subset of Google Analytics JS client | |
* TODO: Keep this local, there's no need to add it to window. | |
*/ | |
(function(e,t,n,i,s,a,c){e[n]=e[n]||function(){(e[n].q=e[n].q||[]).push(arguments)} | |
;a=t.createElement(i);c=t.getElementsByTagName(i)[0];a.async=true;a.src=s | |
;c.parentNode.insertBefore(a,c) | |
})(window,document,"galite","script","https://cdn.jsdelivr.net/npm/ga-lite@2/dist/ga-lite.min.js"); | |
galite('create', options.googleAnalyticsTrackingId, 'auto'); | |
galite('send', 'pageview'); | |
/* eslint-enable */ | |
} | |
/** | |
* Extracts the integer to use for a Google Analytics event's value field | |
* from a lib-jitsi-meet analytics event. | |
* @param {Object} event - The lib-jitsi-meet analytics event. | |
* @returns {Object} - The integer to use for the 'value' of a Google | |
* Analytics event. | |
* @private | |
*/ | |
Analytics.prototype._extractAction = function(event) { | |
// Page events have a single 'name' field. | |
if (event.type === 'page') { | |
return event.name; | |
} | |
// All other events have action, actionSubject, and source fields. All | |
// three fields are required, and the often jitsi-meet and | |
// lib-jitsi-meet use the same value when separate values are not | |
// necessary (i.e. event.action == event.actionSubject). | |
// Here we concatenate these three fields, but avoid adding the same | |
// value twice, because it would only make the GA event's action harder | |
// to read. | |
let action = event.action; | |
if (event.actionSubject && event.actionSubject !== event.action) { | |
// Intentionally use string concatenation as analytics needs to | |
// work on IE but this file does not go through babel. For some | |
// reason disabling this globally for the file does not have an | |
// effect. | |
// eslint-disable-next-line prefer-template | |
action = event.actionSubject + '.' + action; | |
} | |
if (event.source && event.source !== event.action | |
&& event.source !== event.action) { | |
// eslint-disable-next-line prefer-template | |
action = event.source + '.' + action; | |
} | |
return action; | |
}; | |
/** | |
* Extracts the integer to use for a Google Analytics event's value field | |
* from a lib-jitsi-meet analytics event. | |
* @param {Object} event - The lib-jitsi-meet analytics event. | |
* @returns {Object} - The integer to use for the 'value' of a Google | |
* Analytics event, or NaN if the lib-jitsi-meet event doesn't contain a | |
* suitable value. | |
* @private | |
*/ | |
Analytics.prototype._extractValue = function(event) { | |
let value = event && event.attributes && event.attributes.value; | |
// Try to extract an integer from the "value" attribute. | |
value = Math.round(parseFloat(value)); | |
return value; | |
}; | |
/** | |
* Extracts the string to use for a Google Analytics event's label field | |
* from a lib-jitsi-meet analytics event. | |
* @param {Object} event - The lib-jitsi-meet analytics event. | |
* @returns {string} - The string to use for the 'label' of a Google | |
* Analytics event. | |
* @private | |
*/ | |
Analytics.prototype._extractLabel = function(event) { | |
let label = ''; | |
// The label field is limited to 500B. We will concatenate all | |
// attributes of the event, except the user agent because it may be | |
// lengthy and is probably included from elsewhere. | |
for (const property in event.attributes) { | |
if (property !== 'permanent_user_agent' | |
&& property !== 'permanent_callstats_name' | |
&& event.attributes.hasOwnProperty(property)) { | |
// eslint-disable-next-line prefer-template | |
label += property + '=' + event.attributes[property] + '&'; | |
} | |
} | |
if (label.length > 0) { | |
label = label.slice(0, -1); | |
} | |
return label; | |
}; | |
/** | |
* This is the entry point of the API. The function sends an event to | |
* google analytics. The format of the event is described in | |
* AnalyticsAdapter in lib-jitsi-meet. | |
* @param {Object} event - the event in the format specified by | |
* lib-jitsi-meet. | |
*/ | |
Analytics.prototype.sendEvent = function(event) { | |
if (!event || !ga) { | |
return; | |
} | |
const ignoredEvents | |
= [ 'e2e_rtt', 'rtp.stats', 'rtt.by.region', 'available.device', | |
'stream.switch.delay', 'ice.state.changed', 'ice.duration' ]; | |
// Temporary removing some of the events that are too noisy. | |
if (ignoredEvents.indexOf(event.action) !== -1) { | |
return; | |
} | |
const gaEvent = { | |
'eventCategory': 'jitsi-meet', | |
'eventAction': this._extractAction(event), | |
'eventLabel': this._extractLabel(event) | |
}; | |
const value = this._extractValue(event); | |
if (!isNaN(value)) { | |
gaEvent.eventValue = value; | |
} | |
galite('send', 'event', gaEvent); | |
}; | |
if (typeof ctx.JitsiMeetJS === 'undefined') { | |
ctx.JitsiMeetJS = {}; | |
} | |
if (typeof ctx.JitsiMeetJS.app === 'undefined') { | |
ctx.JitsiMeetJS.app = {}; | |
} | |
if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === 'undefined') { | |
ctx.JitsiMeetJS.app.analyticsHandlers = []; | |
} | |
ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics); | |
})(window); | |
/* eslint-enable prefer-template */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment