@webex/plugin-meetings 3.4.0-next.2 → 3.4.0-next.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -209,7 +209,7 @@ var Breakout = _webexCore.WebexPlugin.extend({
209
209
  sessionId: this.sessionId
210
210
  });
211
211
  },
212
- version: "3.4.0-next.2"
212
+ version: "3.4.0-next.3"
213
213
  });
214
214
  var _default = exports.default = Breakout;
215
215
  //# sourceMappingURL=breakout.js.map
@@ -1046,7 +1046,7 @@ var Breakouts = _webexCore.WebexPlugin.extend({
1046
1046
  this.trigger(_constants.BREAKOUTS.EVENTS.ASK_RETURN_TO_MAIN);
1047
1047
  }
1048
1048
  },
1049
- version: "3.4.0-next.2"
1049
+ version: "3.4.0-next.3"
1050
1050
  });
1051
1051
  var _default = exports.default = Breakouts;
1052
1052
  //# sourceMappingURL=index.js.map
@@ -373,7 +373,7 @@ var SimultaneousInterpretation = _webexCore.WebexPlugin.extend({
373
373
  throw error;
374
374
  });
375
375
  },
376
- version: "3.4.0-next.2"
376
+ version: "3.4.0-next.3"
377
377
  });
378
378
  var _default = exports.default = SimultaneousInterpretation;
379
379
  //# sourceMappingURL=index.js.map
@@ -18,7 +18,7 @@ var SILanguage = _webexCore.WebexPlugin.extend({
18
18
  languageCode: 'number',
19
19
  languageName: 'string'
20
20
  },
21
- version: "3.4.0-next.2"
21
+ version: "3.4.0-next.3"
22
22
  });
23
23
  var _default = exports.default = SILanguage;
24
24
  //# sourceMappingURL=siLanguage.js.map
@@ -48,14 +48,13 @@ var RtcMetrics = exports.default = /*#__PURE__*/function () {
48
48
  (0, _defineProperty2.default)(this, "meetingId", void 0);
49
49
  (0, _defineProperty2.default)(this, "correlationId", void 0);
50
50
  (0, _defineProperty2.default)(this, "connectionId", void 0);
51
+ (0, _defineProperty2.default)(this, "initialMetricsSent", void 0);
51
52
  // `window` is used to prevent typescript from returning a NodeJS.Timer.
52
53
  this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);
53
54
  this.meetingId = meetingId;
54
55
  this.webex = webex;
55
56
  this.correlationId = correlationId;
56
- this.setNewConnectionId();
57
- // Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.
58
- setTimeout(this.sendMetricsInQueue.bind(this), 5 * 1000);
57
+ this.resetConnection();
59
58
  }
60
59
 
61
60
  /**
@@ -87,12 +86,18 @@ var RtcMetrics = exports.default = /*#__PURE__*/function () {
87
86
  data.payload = data.payload.map(this.anonymizeIp);
88
87
  }
89
88
  this.metricsQueue.push(data);
89
+ if (!this.initialMetricsSent && data.name === 'stats-report') {
90
+ // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately
91
+ // in case the user is unhappy and closes the browser early
92
+ this.sendMetricsInQueue();
93
+ this.initialMetricsSent = true;
94
+ }
90
95
  try {
91
96
  // If a connection fails, send the rest of the metrics in queue and get a new connection id.
92
97
  var parsedPayload = parseJsonPayload(data.payload);
93
98
  if (data.name === 'onconnectionstatechange' && parsedPayload && parsedPayload.value === 'failed') {
94
99
  this.sendMetricsInQueue();
95
- this.setNewConnectionId();
100
+ this.resetConnection();
96
101
  }
97
102
  } catch (e) {
98
103
  console.error(e);
@@ -137,9 +142,10 @@ var RtcMetrics = exports.default = /*#__PURE__*/function () {
137
142
  * @returns {void}
138
143
  */
139
144
  }, {
140
- key: "setNewConnectionId",
141
- value: function setNewConnectionId() {
145
+ key: "resetConnection",
146
+ value: function resetConnection() {
142
147
  this.connectionId = _uuid.default.v4();
148
+ this.initialMetricsSent = false;
143
149
  }
144
150
 
145
151
  /**
@@ -1 +1 @@
1
- {"version":3,"names":["_internalPluginMetrics","require","_uuid","_interopRequireDefault","_constants","parseJsonPayload","payload","JSON","parse","_","RtcMetrics","exports","default","webex","meetingId","correlationId","_classCallCheck2","_defineProperty2","intervalId","window","setInterval","sendMetricsInQueue","bind","setNewConnectionId","setTimeout","_createClass2","key","value","metricsQueue","length","sendMetrics","addMetrics","data","name","map","anonymizeIp","push","parsedPayload","e","console","error","closeMetrics","clearInterval","stats","type","ip","CallDiagnosticUtils","anonymizeIPAddress","undefined","address","relatedAddress","_stringify","connectionId","uuid","v4","request","method","service","resource","headers","appId","RTC_METRICS","APP_ID","body","metrics","version","userId","internal","device"],"sources":["index.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\nimport {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';\nimport uuid from 'uuid';\nimport RTC_METRICS from './constants';\n\nconst parseJsonPayload = (payload: any[]): any | null => {\n try {\n if (payload && payload[0]) {\n return JSON.parse(payload[0]);\n }\n\n return null;\n } catch (_) {\n return null;\n }\n};\n\n/**\n * Rtc Metrics\n */\nexport default class RtcMetrics {\n /**\n * Array of MetricData items to be sent to the metrics service.\n */\n metricsQueue = [];\n\n intervalId: number;\n\n webex: any;\n\n meetingId: string;\n\n correlationId: string;\n\n connectionId: string;\n\n /**\n * Initialize the interval.\n *\n * @param {object} webex - The main `webex` object.\n * @param {string} meetingId - The meeting id.\n * @param {string} correlationId - The correlation id.\n */\n constructor(webex, meetingId, correlationId) {\n // `window` is used to prevent typescript from returning a NodeJS.Timer.\n this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);\n this.meetingId = meetingId;\n this.webex = webex;\n this.correlationId = correlationId;\n this.setNewConnectionId();\n // Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.\n setTimeout(this.sendMetricsInQueue.bind(this), 5 * 1000);\n }\n\n /**\n * Check to see if the metrics queue has any items.\n *\n * @returns {void}\n */\n public sendMetricsInQueue() {\n if (this.metricsQueue.length) {\n this.sendMetrics();\n this.metricsQueue = [];\n }\n }\n\n /**\n * Add metrics items to the metrics queue.\n *\n * @param {object} data - An object with a payload array of metrics items.\n *\n * @returns {void}\n */\n addMetrics(data) {\n if (data.payload.length) {\n if (data.name === 'stats-report') {\n data.payload = data.payload.map(this.anonymizeIp);\n }\n\n this.metricsQueue.push(data);\n\n try {\n // If a connection fails, send the rest of the metrics in queue and get a new connection id.\n const parsedPayload = parseJsonPayload(data.payload);\n if (\n data.name === 'onconnectionstatechange' &&\n parsedPayload &&\n parsedPayload.value === 'failed'\n ) {\n this.sendMetricsInQueue();\n this.setNewConnectionId();\n }\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n /**\n * Clear the metrics interval.\n *\n * @returns {void}\n */\n closeMetrics() {\n this.sendMetricsInQueue();\n clearInterval(this.intervalId);\n }\n\n /**\n * Anonymize IP addresses.\n *\n * @param {array} stats - An RTCStatsReport organized into an array of strings.\n * @returns {string}\n */\n anonymizeIp(stats: string): string {\n const data = JSON.parse(stats);\n // on local and remote candidates, anonymize the last 4 bits.\n if (data.type === 'local-candidate' || data.type === 'remote-candidate') {\n data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;\n data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;\n data.relatedAddress =\n CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;\n }\n\n return JSON.stringify(data);\n }\n\n /**\n * Set a new connection id.\n *\n * @returns {void}\n */\n private setNewConnectionId() {\n this.connectionId = uuid.v4();\n }\n\n /**\n * Send metrics to the metrics service.\n *\n * @returns {void}\n */\n private sendMetrics() {\n this.webex.request({\n method: 'POST',\n service: 'unifiedTelemetry',\n resource: 'metric/v2',\n headers: {\n type: 'webrtcMedia',\n appId: RTC_METRICS.APP_ID,\n },\n body: {\n metrics: [\n {\n type: 'webrtc',\n version: '1.1.0',\n userId: this.webex.internal.device.userId,\n meetingId: this.meetingId,\n correlationId: this.correlationId,\n connectionId: this.connectionId,\n data: this.metricsQueue,\n },\n ],\n },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_internalPluginMetrics","require","_uuid","_interopRequireDefault","_constants","parseJsonPayload","payload","JSON","parse","_","RtcMetrics","exports","default","webex","meetingId","correlationId","_classCallCheck2","_defineProperty2","intervalId","window","setInterval","sendMetricsInQueue","bind","resetConnection","_createClass2","key","value","metricsQueue","length","sendMetrics","addMetrics","data","name","map","anonymizeIp","push","initialMetricsSent","parsedPayload","e","console","error","closeMetrics","clearInterval","stats","type","ip","CallDiagnosticUtils","anonymizeIPAddress","undefined","address","relatedAddress","_stringify","connectionId","uuid","v4","request","method","service","resource","headers","appId","RTC_METRICS","APP_ID","body","metrics","version","userId","internal","device"],"sources":["index.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\nimport {CallDiagnosticUtils} from '@webex/internal-plugin-metrics';\nimport uuid from 'uuid';\nimport RTC_METRICS from './constants';\n\nconst parseJsonPayload = (payload: any[]): any | null => {\n try {\n if (payload && payload[0]) {\n return JSON.parse(payload[0]);\n }\n\n return null;\n } catch (_) {\n return null;\n }\n};\n\n/**\n * Rtc Metrics\n */\nexport default class RtcMetrics {\n /**\n * Array of MetricData items to be sent to the metrics service.\n */\n metricsQueue = [];\n\n intervalId: number;\n\n webex: any;\n\n meetingId: string;\n\n correlationId: string;\n\n connectionId: string;\n\n initialMetricsSent: boolean;\n\n /**\n * Initialize the interval.\n *\n * @param {object} webex - The main `webex` object.\n * @param {string} meetingId - The meeting id.\n * @param {string} correlationId - The correlation id.\n */\n constructor(webex, meetingId, correlationId) {\n // `window` is used to prevent typescript from returning a NodeJS.Timer.\n this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);\n this.meetingId = meetingId;\n this.webex = webex;\n this.correlationId = correlationId;\n this.resetConnection();\n }\n\n /**\n * Check to see if the metrics queue has any items.\n *\n * @returns {void}\n */\n public sendMetricsInQueue() {\n if (this.metricsQueue.length) {\n this.sendMetrics();\n this.metricsQueue = [];\n }\n }\n\n /**\n * Add metrics items to the metrics queue.\n *\n * @param {object} data - An object with a payload array of metrics items.\n *\n * @returns {void}\n */\n addMetrics(data) {\n if (data.payload.length) {\n if (data.name === 'stats-report') {\n data.payload = data.payload.map(this.anonymizeIp);\n }\n\n this.metricsQueue.push(data);\n\n if (!this.initialMetricsSent && data.name === 'stats-report') {\n // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately\n // in case the user is unhappy and closes the browser early\n this.sendMetricsInQueue();\n this.initialMetricsSent = true;\n }\n\n try {\n // If a connection fails, send the rest of the metrics in queue and get a new connection id.\n const parsedPayload = parseJsonPayload(data.payload);\n if (\n data.name === 'onconnectionstatechange' &&\n parsedPayload &&\n parsedPayload.value === 'failed'\n ) {\n this.sendMetricsInQueue();\n this.resetConnection();\n }\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n /**\n * Clear the metrics interval.\n *\n * @returns {void}\n */\n closeMetrics() {\n this.sendMetricsInQueue();\n clearInterval(this.intervalId);\n }\n\n /**\n * Anonymize IP addresses.\n *\n * @param {array} stats - An RTCStatsReport organized into an array of strings.\n * @returns {string}\n */\n anonymizeIp(stats: string): string {\n const data = JSON.parse(stats);\n // on local and remote candidates, anonymize the last 4 bits.\n if (data.type === 'local-candidate' || data.type === 'remote-candidate') {\n data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;\n data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;\n data.relatedAddress =\n CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;\n }\n\n return JSON.stringify(data);\n }\n\n /**\n * Set a new connection id.\n *\n * @returns {void}\n */\n private resetConnection() {\n this.connectionId = uuid.v4();\n this.initialMetricsSent = false;\n }\n\n /**\n * Send metrics to the metrics service.\n *\n * @returns {void}\n */\n private sendMetrics() {\n this.webex.request({\n method: 'POST',\n service: 'unifiedTelemetry',\n resource: 'metric/v2',\n headers: {\n type: 'webrtcMedia',\n appId: RTC_METRICS.APP_ID,\n },\n body: {\n metrics: [\n {\n type: 'webrtc',\n version: '1.1.0',\n userId: this.webex.internal.device.userId,\n meetingId: this.meetingId,\n correlationId: this.correlationId,\n connectionId: this.connectionId,\n data: this.metricsQueue,\n },\n ],\n },\n });\n }\n}\n"],"mappings":"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"}
@@ -11,6 +11,7 @@ export default class RtcMetrics {
11
11
  meetingId: string;
12
12
  correlationId: string;
13
13
  connectionId: string;
14
+ initialMetricsSent: boolean;
14
15
  /**
15
16
  * Initialize the interval.
16
17
  *
@@ -51,7 +52,7 @@ export default class RtcMetrics {
51
52
  *
52
53
  * @returns {void}
53
54
  */
54
- private setNewConnectionId;
55
+ private resetConnection;
55
56
  /**
56
57
  * Send metrics to the metrics service.
57
58
  *
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
62
62
  updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
63
63
  this.set('canManageWebcast', canManageWebcast);
64
64
  },
65
- version: "3.4.0-next.2"
65
+ version: "3.4.0-next.3"
66
66
  });
67
67
  var _default = exports.default = Webinar;
68
68
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -43,7 +43,7 @@
43
43
  "@webex/eslint-config-legacy": "0.0.0",
44
44
  "@webex/jest-config-legacy": "0.0.0",
45
45
  "@webex/legacy-tools": "0.0.0",
46
- "@webex/plugin-meetings": "3.4.0-next.2",
46
+ "@webex/plugin-meetings": "3.4.0-next.3",
47
47
  "@webex/plugin-rooms": "3.3.1-next.14",
48
48
  "@webex/test-helper-chai": "3.3.1-next.13",
49
49
  "@webex/test-helper-mocha": "3.3.1-next.13",
@@ -70,7 +70,7 @@
70
70
  "@webex/internal-plugin-metrics": "3.3.1-next.13",
71
71
  "@webex/internal-plugin-support": "3.3.1-next.14",
72
72
  "@webex/internal-plugin-user": "3.3.1-next.13",
73
- "@webex/internal-plugin-voicea": "3.4.0-next.2",
73
+ "@webex/internal-plugin-voicea": "3.4.0-next.3",
74
74
  "@webex/media-helpers": "3.4.0-next.1",
75
75
  "@webex/plugin-people": "3.3.1-next.14",
76
76
  "@webex/plugin-rooms": "3.3.1-next.14",
@@ -91,5 +91,5 @@
91
91
  "//": [
92
92
  "TODO: upgrade jwt-decode when moving to node 18"
93
93
  ],
94
- "version": "3.4.0-next.2"
94
+ "version": "3.4.0-next.3"
95
95
  }
@@ -34,6 +34,8 @@ export default class RtcMetrics {
34
34
 
35
35
  connectionId: string;
36
36
 
37
+ initialMetricsSent: boolean;
38
+
37
39
  /**
38
40
  * Initialize the interval.
39
41
  *
@@ -47,9 +49,7 @@ export default class RtcMetrics {
47
49
  this.meetingId = meetingId;
48
50
  this.webex = webex;
49
51
  this.correlationId = correlationId;
50
- this.setNewConnectionId();
51
- // Send the first set of metrics at 5 seconds in the case of a user leaving the call shortly after joining.
52
- setTimeout(this.sendMetricsInQueue.bind(this), 5 * 1000);
52
+ this.resetConnection();
53
53
  }
54
54
 
55
55
  /**
@@ -79,6 +79,13 @@ export default class RtcMetrics {
79
79
 
80
80
  this.metricsQueue.push(data);
81
81
 
82
+ if (!this.initialMetricsSent && data.name === 'stats-report') {
83
+ // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately
84
+ // in case the user is unhappy and closes the browser early
85
+ this.sendMetricsInQueue();
86
+ this.initialMetricsSent = true;
87
+ }
88
+
82
89
  try {
83
90
  // If a connection fails, send the rest of the metrics in queue and get a new connection id.
84
91
  const parsedPayload = parseJsonPayload(data.payload);
@@ -88,7 +95,7 @@ export default class RtcMetrics {
88
95
  parsedPayload.value === 'failed'
89
96
  ) {
90
97
  this.sendMetricsInQueue();
91
- this.setNewConnectionId();
98
+ this.resetConnection();
92
99
  }
93
100
  } catch (e) {
94
101
  console.error(e);
@@ -130,8 +137,9 @@ export default class RtcMetrics {
130
137
  *
131
138
  * @returns {void}
132
139
  */
133
- private setNewConnectionId() {
140
+ private resetConnection() {
134
141
  this.connectionId = uuid.v4();
142
+ this.initialMetricsSent = false;
135
143
  }
136
144
 
137
145
  /**
@@ -120,4 +120,35 @@ describe('RtcMetrics', () => {
120
120
  metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
121
121
  assert.calledOnce(anonymizeIpSpy);
122
122
  })
123
+
124
+ it('should send metrics on first stats-report', () => {
125
+ assert.callCount(webex.request, 0);
126
+
127
+ metrics.addMetrics(FAKE_METRICS_ITEM);
128
+ assert.callCount(webex.request, 0);
129
+
130
+ // first stats-report should trigger a call to webex.request
131
+ metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
132
+ assert.callCount(webex.request, 1);
133
+ });
134
+
135
+ it('should send metrics on first stats-report after a new connection', () => {
136
+ assert.callCount(webex.request, 0);
137
+
138
+ // first stats-report should trigger a call to webex.request
139
+ metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
140
+ assert.callCount(webex.request, 1);
141
+
142
+ // subsequent stats-report doesn't trigger it
143
+ metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
144
+ assert.callCount(webex.request, 1);
145
+
146
+ // now, simulate a failure - that triggers a new connection and upload of the metrics
147
+ metrics.addMetrics(FAILURE_METRICS_ITEM);
148
+ assert.callCount(webex.request, 2);
149
+
150
+ // and another stats-report should trigger another upload of the metrics
151
+ metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
152
+ assert.callCount(webex.request, 3);
153
+ });
123
154
  });