You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

analytics-ga.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* global ga */
  2. (function(ctx) {
  3. /**
  4. *
  5. */
  6. function Analytics(options) {
  7. /* eslint-disable */
  8. if (!options.googleAnalyticsTrackingId) {
  9. console.log(
  10. 'Failed to initialize Google Analytics handler, no tracking ID');
  11. return;
  12. }
  13. /**
  14. * Google Analytics
  15. * TODO: Keep this local, there's no need to add it to window.
  16. */
  17. (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  18. (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  19. })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  20. ga('create', options.googleAnalyticsTrackingId, 'auto');
  21. ga('send', 'pageview');
  22. /* eslint-enable */
  23. }
  24. /**
  25. * Extracts the integer to use for a Google Analytics event's value field
  26. * from a lib-jitsi-meet analytics event.
  27. * @param {Object} event - The lib-jitsi-meet analytics event.
  28. * @returns {Object} - The integer to use for the 'value' of a Google
  29. * Analytics event.
  30. * @private
  31. */
  32. Analytics.prototype._extractAction = function(event) {
  33. // Page events have a single 'name' field.
  34. if (event.type === 'page') {
  35. return event.name;
  36. }
  37. // All other events have action, actionSubject, and source fields. All
  38. // three fields are required, and the often jitsi-meet and
  39. // lib-jitsi-meet use the same value when separate values are not
  40. // necessary (i.e. event.action == event.actionSubject).
  41. // Here we concatenate these three fields, but avoid adding the same
  42. // value twice, because it would only make the GA event's action harder
  43. // to read.
  44. let action = event.action;
  45. if (event.actionSubject && event.actionSubject !== event.action) {
  46. // Intentionally use string concatenation as analytics needs to
  47. // work on IE but this file does not go through babel. For some
  48. // reason disabling this globally for the file does not have an
  49. // effect.
  50. // eslint-disable-next-line prefer-template
  51. action = event.actionSubject + '.' + action;
  52. }
  53. if (event.source && event.source !== event.action
  54. && event.source !== event.action) {
  55. // eslint-disable-next-line prefer-template
  56. action = event.source + '.' + action;
  57. }
  58. return action;
  59. };
  60. /**
  61. * Extracts the integer to use for a Google Analytics event's value field
  62. * from a lib-jitsi-meet analytics event.
  63. * @param {Object} event - The lib-jitsi-meet analytics event.
  64. * @returns {Object} - The integer to use for the 'value' of a Google
  65. * Analytics event, or NaN if the lib-jitsi-meet event doesn't contain a
  66. * suitable value.
  67. * @private
  68. */
  69. Analytics.prototype._extractValue = function(event) {
  70. let value = event && event.attributes && event.attributes.value;
  71. // Try to extract an integer from the "value" attribute.
  72. value = Math.round(parseFloat(value));
  73. return value;
  74. };
  75. /**
  76. * Extracts the string to use for a Google Analytics event's label field
  77. * from a lib-jitsi-meet analytics event.
  78. * @param {Object} event - The lib-jitsi-meet analytics event.
  79. * @returns {string} - The string to use for the 'label' of a Google
  80. * Analytics event.
  81. * @private
  82. */
  83. Analytics.prototype._extractLabel = function(event) {
  84. let label = '';
  85. // The label field is limited to 500B. We will concatenate all
  86. // attributes of the event, except the user agent because it may be
  87. // lengthy and is probably included from elsewhere.
  88. for (const property in event.attributes) {
  89. if (property !== 'permanent_user_agent'
  90. && property !== 'permanent_callstats_name'
  91. && event.attributes.hasOwnProperty(property)) {
  92. // eslint-disable-next-line prefer-template
  93. label += property + '=' + event.attributes[property] + '&';
  94. }
  95. }
  96. if (label.length > 0) {
  97. label = label.slice(0, -1);
  98. }
  99. return label;
  100. };
  101. /**
  102. * This is the entry point of the API. The function sends an event to
  103. * google analytics. The format of the event is described in
  104. * AnalyticsAdapter in lib-jitsi-meet.
  105. * @param {Object} event - the event in the format specified by
  106. * lib-jitsi-meet.
  107. */
  108. Analytics.prototype.sendEvent = function(event) {
  109. if (!event || !ga) {
  110. return;
  111. }
  112. const ignoredEvents
  113. = [ 'e2e_rtt', 'rtp.stats', 'rtt.by.region', 'available.device',
  114. 'stream.switch.delay', 'ice.state.changed', 'ice.duration' ];
  115. // Temporary removing some of the events that are too noisy.
  116. if (ignoredEvents.indexOf(event.action) !== -1) {
  117. return;
  118. }
  119. const gaEvent = {
  120. 'eventCategory': 'jitsi-meet',
  121. 'eventAction': this._extractAction(event),
  122. 'eventLabel': this._extractLabel(event)
  123. };
  124. const value = this._extractValue(event);
  125. if (!isNaN(value)) {
  126. gaEvent.eventValue = value;
  127. }
  128. ga('send', 'event', gaEvent);
  129. };
  130. if (typeof ctx.JitsiMeetJS === 'undefined') {
  131. ctx.JitsiMeetJS = {};
  132. }
  133. if (typeof ctx.JitsiMeetJS.app === 'undefined') {
  134. ctx.JitsiMeetJS.app = {};
  135. }
  136. if (typeof ctx.JitsiMeetJS.app.analyticsHandlers === 'undefined') {
  137. ctx.JitsiMeetJS.app.analyticsHandlers = [];
  138. }
  139. ctx.JitsiMeetJS.app.analyticsHandlers.push(Analytics);
  140. })(window);
  141. /* eslint-enable prefer-template */