您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

GoogleAnalyticsHandler.js 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* global ga */
  2. import { getJitsiMeetGlobalNS } from '../../base/util';
  3. import AbstractHandler from './AbstractHandler';
  4. /**
  5. * Analytics handler for Google Analytics.
  6. */
  7. class GoogleAnalyticsHandler extends AbstractHandler {
  8. /**
  9. * Creates new instance of the GA analytics handler.
  10. *
  11. * @param {Object} options -
  12. * @param {string} options.googleAnalyticsTrackingId - The GA track id
  13. * required by the GA API.
  14. */
  15. constructor(options) {
  16. super(options);
  17. this._userProperties = {};
  18. if (!options.googleAnalyticsTrackingId) {
  19. throw new Error('Failed to initialize Google Analytics handler, no tracking ID');
  20. }
  21. this._enabled = true;
  22. this._initGoogleAnalytics(options);
  23. }
  24. /**
  25. * Initializes the ga object.
  26. *
  27. * @param {Object} options -
  28. * @param {string} options.googleAnalyticsTrackingId - The GA track id
  29. * required by the GA API.
  30. * @returns {void}
  31. */
  32. _initGoogleAnalytics(options) {
  33. /**
  34. * TODO: Keep this local, there's no need to add it to window.
  35. */
  36. /* eslint-disable */
  37. (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  38. (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)
  39. })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  40. /* eslint-enable */
  41. ga('create', options.googleAnalyticsTrackingId, 'auto');
  42. ga('send', 'pageview');
  43. }
  44. /**
  45. * Extracts the integer to use for a Google Analytics event's value field
  46. * from a lib-jitsi-meet analytics event.
  47. *
  48. * @param {Object} event - The lib-jitsi-meet analytics event.
  49. * @returns {number} - The integer to use for the 'value' of a Google
  50. * analytics event, or NaN if the lib-jitsi-meet event doesn't contain a
  51. * suitable value.
  52. * @private
  53. */
  54. _extractValue(event) {
  55. let value = event && event.attributes && event.attributes.value;
  56. // Try to extract an integer from the "value" attribute.
  57. value = Math.round(parseFloat(value));
  58. return value;
  59. }
  60. /**
  61. * Extracts the string to use for a Google Analytics event's label field
  62. * from a lib-jitsi-meet analytics event.
  63. *
  64. * @param {Object} event - The lib-jitsi-meet analytics event.
  65. * @returns {string} - The string to use for the 'label' of a Google
  66. * analytics event.
  67. * @private
  68. */
  69. _extractLabel(event) {
  70. const { attributes = {} } = event;
  71. const labelsArray
  72. = Object.keys(attributes).map(key => `${key}=${attributes[key]}`);
  73. labelsArray.push(this._userPropertiesString);
  74. return labelsArray.join('&');
  75. }
  76. /**
  77. * Sets the permanent properties for the current session.
  78. *
  79. * @param {Object} userProps - The permanent portperties.
  80. * @returns {void}
  81. */
  82. setUserProperties(userProps = {}) {
  83. if (!this._enabled) {
  84. return;
  85. }
  86. // The label field is limited to 500B. We will concatenate all
  87. // attributes of the event, except the user agent because it may be
  88. // lengthy and is probably included from elsewhere.
  89. const filter = [ 'user_agent', 'callstats_name' ];
  90. this._userPropertiesString
  91. = Object.keys(userProps)
  92. .filter(key => filter.indexOf(key) === -1)
  93. .map(key => `permanent_${key}=${userProps[key]}`)
  94. .join('&');
  95. }
  96. /**
  97. * This is the entry point of the API. The function sends an event to
  98. * google analytics. The format of the event is described in
  99. * analyticsAdapter in lib-jitsi-meet.
  100. *
  101. * @param {Object} event - The event in the format specified by
  102. * lib-jitsi-meet.
  103. * @returns {void}
  104. */
  105. sendEvent(event) {
  106. if (this._shouldIgnore(event)) {
  107. return;
  108. }
  109. const gaEvent = {
  110. 'eventCategory': 'jitsi-meet',
  111. 'eventAction': this._extractName(event),
  112. 'eventLabel': this._extractLabel(event)
  113. };
  114. const value = this._extractValue(event);
  115. if (!isNaN(value)) {
  116. gaEvent.eventValue = value;
  117. }
  118. ga('send', 'event', gaEvent);
  119. }
  120. }
  121. const globalNS = getJitsiMeetGlobalNS();
  122. globalNS.analyticsHandlers = globalNS.analyticsHandlers || [];
  123. globalNS.analyticsHandlers.push(GoogleAnalyticsHandler);