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

MatomoHandler.js 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* global _paq */
  2. import { getJitsiMeetGlobalNS } from '../../base/util';
  3. import AbstractHandler from './AbstractHandler';
  4. /**
  5. * Analytics handler for Matomo.
  6. */
  7. export default class MatomoHandler extends AbstractHandler {
  8. /**
  9. * Creates new instance of the Matomo handler.
  10. *
  11. * @param {Object} options -
  12. * @param {string} options.matomoEndpoint - The Matomo endpoint.
  13. * @param {string} options.matomoSiteID - The site ID.
  14. */
  15. constructor(options) {
  16. super(options);
  17. this._userProperties = {};
  18. if (!options.matomoEndpoint) {
  19. throw new Error(
  20. 'Failed to initialize Matomo handler: no endpoint defined.'
  21. );
  22. }
  23. if (!options.matomoSiteID) {
  24. throw new Error(
  25. 'Failed to initialize Matomo handler: no site ID defined.'
  26. );
  27. }
  28. this._enabled = true;
  29. this._initMatomo(options);
  30. }
  31. /**
  32. * Initializes the _paq object.
  33. *
  34. * @param {Object} options -
  35. * @param {string} options.matomoEndpoint - The Matomo endpoint.
  36. * @param {string} options.matomoSiteID - The site ID.
  37. * @returns {void}
  38. */
  39. _initMatomo(options) {
  40. const _paq = window._paq || [];
  41. window._paq = _paq;
  42. _paq.push([ 'trackPageView' ]);
  43. _paq.push([ 'enableLinkTracking' ]);
  44. (function() {
  45. // add trailing slash if needed
  46. const u = options.matomoEndpoint.endsWith('/')
  47. ? options.matomoEndpoint
  48. : `${options.matomoEndpoint}/`;
  49. // configure the tracker
  50. _paq.push([ 'setTrackerUrl', `${u}matomo.php` ]);
  51. _paq.push([ 'setSiteId', options.matomoSiteID ]);
  52. // insert the matomo script
  53. const d = document,
  54. g = d.createElement('script'),
  55. s = d.getElementsByTagName('script')[0];
  56. g.type = 'text/javascript';
  57. g.async = true;
  58. g.defer = true;
  59. g.src = `${u}matomo.js`;
  60. s.parentNode.insertBefore(g, s);
  61. })();
  62. }
  63. /**
  64. * Extracts the integer to use for a Matomo event's value field
  65. * from a lib-jitsi-meet analytics event.
  66. *
  67. * @param {Object} event - The lib-jitsi-meet analytics event.
  68. * @returns {number} - The integer to use for the 'value' of a Matomo
  69. * event, or NaN if the lib-jitsi-meet event doesn't contain a
  70. * suitable value.
  71. * @private
  72. */
  73. _extractValue(event) {
  74. const value = event && event.attributes && event.attributes.value;
  75. // Try to extract an integer from the 'value' attribute.
  76. return Math.round(parseFloat(value));
  77. }
  78. /**
  79. * Sets the permanent properties for the current session.
  80. *
  81. * @param {Object} userProps - The permanent properties.
  82. * @returns {void}
  83. */
  84. setUserProperties(userProps = {}) {
  85. if (!this._enabled) {
  86. return;
  87. }
  88. const visitScope = [ 'user_agent', 'callstats_name', 'browser_name' ];
  89. // add variables in the 'page' scope
  90. Object.keys(userProps)
  91. .filter(key => visitScope.indexOf(key) === -1)
  92. .forEach((key, index) => {
  93. _paq.push([
  94. 'setCustomVariable',
  95. 1 + index,
  96. key,
  97. userProps[key],
  98. 'page'
  99. ]);
  100. });
  101. // add variables in the 'visit' scope
  102. Object.keys(userProps)
  103. .filter(key => visitScope.indexOf(key) !== -1)
  104. .forEach((key, index) => {
  105. _paq.push([
  106. 'setCustomVariable',
  107. 1 + index,
  108. key,
  109. userProps[key],
  110. 'visit'
  111. ]);
  112. });
  113. }
  114. /**
  115. * This is the entry point of the API. The function sends an event to
  116. * the Matomo endpoint. The format of the event is described in
  117. * analyticsAdapter in lib-jitsi-meet.
  118. *
  119. * @param {Object} event - The event in the format specified by
  120. * lib-jitsi-meet.
  121. * @returns {void}
  122. */
  123. sendEvent(event) {
  124. if (this._shouldIgnore(event)) {
  125. return;
  126. }
  127. const value = this._extractValue(event);
  128. const matomoEvent = [ 'trackEvent', 'jitsi-meet', this._extractName(event) ];
  129. if (!isNaN(value)) {
  130. matomoEvent.push(value);
  131. }
  132. _paq.push(matomoEvent);
  133. }
  134. }
  135. const globalNS = getJitsiMeetGlobalNS();
  136. globalNS.analyticsHandlers = globalNS.analyticsHandlers || [];
  137. globalNS.analyticsHandlers.push(MatomoHandler);