@webex/internal-plugin-metrics 3.12.0-next.9 → 3.12.0-webex-services-ready.1
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.
- package/dist/batcher.js +3 -0
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +23 -0
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +29 -25
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +55 -8
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +14 -2
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/prelogin-metrics-batcher.js +23 -0
- package/dist/prelogin-metrics-batcher.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +23 -0
- package/dist/types/call-diagnostic/config.d.ts +4 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/metrics.types.d.ts +2 -2
- package/package.json +11 -11
- package/src/batcher.js +4 -0
- package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +26 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +54 -38
- package/src/call-diagnostic/call-diagnostic-metrics.ts +46 -1
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
- package/src/call-diagnostic/config.ts +13 -0
- package/src/config.js +1 -0
- package/src/metrics.types.ts +1 -1
- package/src/prelogin-metrics-batcher.ts +26 -0
- package/test/unit/spec/batcher.js +43 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +145 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +105 -95
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +680 -159
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
- package/test/unit/spec/prelogin-metrics-batcher.ts +190 -36
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_lodash","require","_batcher","_interopRequireDefault","_callDiagnosticMetrics","_utils","PRE_LOGIN_METRICS_IDENTIFIER","PreLoginMetricsBatcher","Batcher","extend","namespace","preLoginId","undefined","savePreLoginId","prepareItem","item","_promise","default","resolve","prepareDiagnosticMetricItem","webex","prepareRequest","queue","forEach","eventPayload","originTime","sent","Date","toISOString","submitHttpRequest","payload","_this","batchId","uniqueId","logger","error","concat","reject","Error","request","method","service","resource","headers","authorization","body","metrics","waitForServiceTimeout","config","then","res","log","catch","err","generateCommonErrorMetadata","_default","exports"],"sources":["prelogin-metrics-batcher.ts"],"sourcesContent":["import {uniqueId} from 'lodash';\nimport Batcher from './batcher';\nimport {prepareDiagnosticMetricItem} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\n\nconst PRE_LOGIN_METRICS_IDENTIFIER = 'Pre Login Metrics -->';\n\nconst PreLoginMetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n preLoginId: undefined,\n\n /**\n * Save the pre-login ID.\n * @param {string} preLoginId The pre-login ID to be saved.\n * @returns {void}\n */\n savePreLoginId(preLoginId) {\n this.preLoginId = preLoginId;\n },\n\n /**\n * Prepare item\n * @param {any} item\n * @returns {Promise<any>}\n */\n prepareItem(item) {\n return Promise.resolve(prepareDiagnosticMetricItem(this.webex, item));\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param {any[]} queue\n * @returns {Promise<any[]>}\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param {any} payload\n * @returns {Promise<any>}\n */\n submitHttpRequest(payload: any) {\n const batchId = uniqueId('prelogin-batch-');\n if (this.preLoginId === undefined) {\n this.webex.logger.error(\n PRE_LOGIN_METRICS_IDENTIFIER,\n `PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. PreLoginId is not set.`\n );\n\n return Promise.reject(new Error('PreLoginId is not set.'));\n }\n\n return this.webex\n .request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics-prelogin',\n headers: {\n authorization: false,\n 'x-prelogin-userid': this.preLoginId,\n },\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n })\n .then((res) => {\n this.webex.logger.log(\n PRE_LOGIN_METRICS_IDENTIFIER,\n `PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. Request successful.`\n );\n\n return res;\n })\n .catch((err) => {\n this.webex.logger.error(\n PRE_LOGIN_METRICS_IDENTIFIER,\n `PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. Request failed:`,\n `error: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n },\n});\n\nexport default PreLoginMetricsBatcher;\n"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_lodash","require","_batcher","_interopRequireDefault","_callDiagnosticMetrics","_utils","PRE_LOGIN_METRICS_IDENTIFIER","PreLoginMetricsBatcher","Batcher","extend","namespace","preLoginId","undefined","savePreLoginId","prepareItem","item","_promise","default","resolve","prepareDiagnosticMetricItem","webex","prepareRequest","queue","forEach","eventPayload","originTime","sent","Date","toISOString","submitHttpRequest","payload","_this","batchId","uniqueId","logger","error","concat","reject","Error","request","method","service","resource","headers","authorization","body","metrics","waitForServiceTimeout","config","then","res","log","handleHttpResponseStatus","statusCode","catch","err","generateCommonErrorMetadata","shouldMark","_isArray","some","markTelemetryOptOutOnResponse","_this$webex$internal$","_this$webex$internal$2","internal","newMetrics","callDiagnosticMetrics","setIsTelemetryOptOutAutomatic","_default","exports"],"sources":["prelogin-metrics-batcher.ts"],"sourcesContent":["import {uniqueId} from 'lodash';\nimport Batcher from './batcher';\nimport {prepareDiagnosticMetricItem} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\n\nconst PRE_LOGIN_METRICS_IDENTIFIER = 'Pre Login Metrics -->';\n\nconst PreLoginMetricsBatcher = Batcher.extend({\n namespace: 'Metrics',\n preLoginId: undefined,\n\n /**\n * Save the pre-login ID.\n * @param {string} preLoginId The pre-login ID to be saved.\n * @returns {void}\n */\n savePreLoginId(preLoginId) {\n this.preLoginId = preLoginId;\n },\n\n /**\n * Prepare item\n * @param {any} item\n * @returns {Promise<any>}\n */\n prepareItem(item) {\n return Promise.resolve(prepareDiagnosticMetricItem(this.webex, item));\n },\n\n /**\n * Prepare request, add time sensitive date etc.\n * @param {any[]} queue\n * @returns {Promise<any[]>}\n */\n prepareRequest(queue) {\n // Add sent timestamp\n queue.forEach((item) => {\n item.eventPayload.originTime = item.eventPayload.originTime || {};\n item.eventPayload.originTime.sent = new Date().toISOString();\n });\n\n return Promise.resolve(queue);\n },\n\n /**\n *\n * @param {any} payload\n * @returns {Promise<any>}\n */\n submitHttpRequest(payload: any) {\n const batchId = uniqueId('prelogin-batch-');\n if (this.preLoginId === undefined) {\n this.webex.logger.error(\n PRE_LOGIN_METRICS_IDENTIFIER,\n `PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. PreLoginId is not set.`\n );\n\n return Promise.reject(new Error('PreLoginId is not set.'));\n }\n\n return this.webex\n .request({\n method: 'POST',\n service: 'metrics',\n resource: 'clientmetrics-prelogin',\n headers: {\n authorization: false,\n 'x-prelogin-userid': this.preLoginId,\n },\n body: {\n metrics: payload,\n },\n waitForServiceTimeout: this.webex.config.metrics.waitForServiceTimeout,\n })\n .then((res) => {\n this.webex.logger.log(\n PRE_LOGIN_METRICS_IDENTIFIER,\n `PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. Request successful.`\n );\n\n this.handleHttpResponseStatus(res?.statusCode, payload);\n\n return res;\n })\n .catch((err) => {\n this.webex.logger.error(\n PRE_LOGIN_METRICS_IDENTIFIER,\n `PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. Request failed:`,\n `error: ${generateCommonErrorMetadata(err)}`\n );\n\n this.handleHttpResponseStatus(err?.statusCode, payload);\n\n return Promise.reject(err);\n });\n },\n\n /**\n * React to the HTTP status code returned by the prelogin metrics endpoint.\n * Only items submitted with `markTelemetryOptOutOnResponse: true` opt into\n * this behavior.\n * @param {number | undefined} statusCode\n * @param {any[]} payload Items flushed in this HTTP batch.\n * @returns {void}\n */\n handleHttpResponseStatus(statusCode: number | undefined, payload: any[]) {\n const shouldMark =\n Array.isArray(payload) &&\n payload.some((item) => item?.markTelemetryOptOutOnResponse === true);\n\n if (!shouldMark) {\n return;\n }\n\n if (statusCode === 200) {\n this.webex.internal.newMetrics?.callDiagnosticMetrics?.setIsTelemetryOptOutAutomatic(true);\n }\n },\n});\n\nexport default PreLoginMetricsBatcher;\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -36,6 +36,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
36
36
|
private isMercuryConnected;
|
|
37
37
|
private eventLimitTracker;
|
|
38
38
|
private eventLimitWarningsLogged;
|
|
39
|
+
private isTelemetryOptOutManual;
|
|
40
|
+
private isTelemetryOptOutAutomatic;
|
|
39
41
|
validator: (options: {
|
|
40
42
|
type: 'mqe' | 'ce';
|
|
41
43
|
event: Event;
|
|
@@ -53,6 +55,21 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
53
55
|
* @returns one of 'login-ci','unverified-guest', null
|
|
54
56
|
*/
|
|
55
57
|
getCurLoginType(): "unverified-guest" | "login-ci";
|
|
58
|
+
/**
|
|
59
|
+
* Returns the telemetryOptOut value of the current user
|
|
60
|
+
* @returns one of 'manual', 'automatic', undefined
|
|
61
|
+
*/
|
|
62
|
+
getTelemetryOptOut(): "manual" | "automatic";
|
|
63
|
+
/**
|
|
64
|
+
* Sets the manual telemetry opt-out status for the current user
|
|
65
|
+
* @param value - boolean value indicating manual telemetry opt-out status
|
|
66
|
+
*/
|
|
67
|
+
setIsTelemetryOptOutManual(value: boolean): void;
|
|
68
|
+
/**
|
|
69
|
+
* Sets the automatic telemetry opt-out status for the current user
|
|
70
|
+
* @param value - boolean value indicating automatic telemetry opt-out status
|
|
71
|
+
*/
|
|
72
|
+
setIsTelemetryOptOutAutomatic(value: boolean): void;
|
|
56
73
|
/**
|
|
57
74
|
* Returns if the meeting has converged architecture enabled
|
|
58
75
|
* @param options.meetingId
|
|
@@ -84,6 +101,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
84
101
|
userAgent: string;
|
|
85
102
|
buildType?: "debug" | "test" | "prod" | "tap" | "analyzer-test";
|
|
86
103
|
upgradeChannel?: string;
|
|
104
|
+
upgradeSource?: string;
|
|
87
105
|
instanceId?: string;
|
|
88
106
|
networkType: "wifi" | "ethernet" | "cellular" | "unknown";
|
|
89
107
|
localIP?: string;
|
|
@@ -142,6 +160,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
142
160
|
shareType?: "cb-normal-share" | "ce-airplay-share" | "ce-direct-share" | "ce-gui-loopback-share" | "ce-input-source-share" | "ce-input-source-share-hdmi" | "ce-input-source-share-usbc" | "ce-jpg-share" | "ce-miracast-share" | "mcs-normal-share" | "mcs-normal-audio-share" | "mcs-hfps-share" | "mcs-hfps-audio-share";
|
|
143
161
|
videoDisplayMode?: "grid-view" | "active-speaker-view";
|
|
144
162
|
videoLayoutType?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
|
|
163
|
+
appliedLayout?: "auto" | "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare" | "largeGallery" | "autoWithShare";
|
|
145
164
|
videoRenderType?: "wme" | "client_d3d" | "client_gdi";
|
|
146
165
|
vdiInfo?: {};
|
|
147
166
|
is64BitsClient?: boolean;
|
|
@@ -203,6 +222,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
203
222
|
callId?: string;
|
|
204
223
|
pairCallId?: string;
|
|
205
224
|
llmWebsocketUrl?: string;
|
|
225
|
+
locusCluster?: string;
|
|
206
226
|
locusId?: string;
|
|
207
227
|
locusJoinUrl?: string;
|
|
208
228
|
locusSessionId?: string;
|
|
@@ -293,6 +313,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
293
313
|
callId?: string;
|
|
294
314
|
pairCallId?: string;
|
|
295
315
|
llmWebsocketUrl?: string;
|
|
316
|
+
locusCluster?: string;
|
|
296
317
|
locusId?: string;
|
|
297
318
|
locusJoinUrl?: string;
|
|
298
319
|
locusSessionId?: string;
|
|
@@ -383,6 +404,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
383
404
|
callId?: string;
|
|
384
405
|
pairCallId?: string;
|
|
385
406
|
llmWebsocketUrl?: string;
|
|
407
|
+
locusCluster?: string;
|
|
386
408
|
locusId?: string;
|
|
387
409
|
locusJoinUrl?: string;
|
|
388
410
|
locusSessionId?: string;
|
|
@@ -609,6 +631,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
609
631
|
* Prepare the event and send the request to metrics-a service, pre login.
|
|
610
632
|
* @param event
|
|
611
633
|
* @param preLoginId
|
|
634
|
+
* @param markTelemetryOptOutOnResponse
|
|
612
635
|
* @returns
|
|
613
636
|
*/
|
|
614
637
|
submitToCallDiagnosticsPreLogin: (event: Event, preLoginId?: string) => Promise<any>;
|
|
@@ -102,11 +102,13 @@ export declare const ERROR_DESCRIPTIONS: {
|
|
|
102
102
|
WEBRTC_API_NOT_AVAILABLE: string;
|
|
103
103
|
WDM_RESTRICTED_REGION: string;
|
|
104
104
|
USER_NOT_ALLOWED_JOIN_WEBINAR: string;
|
|
105
|
+
INVALID_MEETING_INFO: string;
|
|
105
106
|
};
|
|
106
107
|
export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
107
108
|
58400: number;
|
|
108
109
|
99002: number;
|
|
109
110
|
99009: number;
|
|
111
|
+
99019: number;
|
|
110
112
|
58500: number;
|
|
111
113
|
400001: number;
|
|
112
114
|
403004: number;
|
|
@@ -134,6 +136,7 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
|
134
136
|
423001: number;
|
|
135
137
|
423005: number;
|
|
136
138
|
423006: number;
|
|
139
|
+
423008: number;
|
|
137
140
|
423010: number;
|
|
138
141
|
423012: number;
|
|
139
142
|
423013: number;
|
|
@@ -147,6 +150,7 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
|
147
150
|
403037: number;
|
|
148
151
|
403003: number;
|
|
149
152
|
403030: number;
|
|
153
|
+
403106: number;
|
|
150
154
|
2403001: number;
|
|
151
155
|
2403002: number;
|
|
152
156
|
2403003: number;
|
package/dist/types/config.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export type SubmitMQEOptions = {
|
|
|
42
42
|
globalMeetingId?: string;
|
|
43
43
|
};
|
|
44
44
|
export type InternalEvent = {
|
|
45
|
-
name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.register.device.request' | 'internal.register.device.response' | 'internal.reset.join.latencies' | 'internal.
|
|
45
|
+
name: 'internal.client.meetinginfo.request' | 'internal.client.meetinginfo.response' | 'internal.register.device.request' | 'internal.register.device.response' | 'internal.reset.join.latencies' | 'internal.host.meeting.participant.admitted' | 'internal.client.meeting.interstitial-window.showed' | 'internal.client.interstitial-window.click.joinbutton' | 'internal.client.add-media.turn-discovery.start' | 'internal.client.add-media.turn-discovery.end' | 'internal.client.share.initiated' | 'internal.client.share.stopped';
|
|
46
46
|
payload?: never;
|
|
47
47
|
options?: never;
|
|
48
48
|
};
|
|
@@ -154,7 +154,7 @@ export type BuildClientEventFetchRequestOptions = (args: {
|
|
|
154
154
|
payload?: RecursivePartial<ClientEvent['payload']>;
|
|
155
155
|
options?: SubmitClientEventOptions;
|
|
156
156
|
}) => Promise<any>;
|
|
157
|
-
export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.click.to.interstitial.with.user.delay' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';
|
|
157
|
+
export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.click.to.interstitial.with.user.delay' | 'internal.click.to.interstitial.for.client.jmt' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';
|
|
158
158
|
export interface IdType {
|
|
159
159
|
meetingId?: string;
|
|
160
160
|
callId?: string;
|
package/package.json
CHANGED
|
@@ -24,23 +24,23 @@
|
|
|
24
24
|
"@sinonjs/fake-timers": "^6.0.1",
|
|
25
25
|
"@webex/babel-config-legacy": "0.0.0",
|
|
26
26
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
27
|
-
"@webex/event-dictionary-ts": "^1.0.
|
|
27
|
+
"@webex/event-dictionary-ts": "^1.0.2191",
|
|
28
28
|
"@webex/jest-config-legacy": "0.0.0",
|
|
29
29
|
"@webex/legacy-tools": "0.0.0",
|
|
30
|
-
"@webex/test-helper-chai": "3.
|
|
31
|
-
"@webex/test-helper-mocha": "3.
|
|
32
|
-
"@webex/test-helper-mock-webex": "3.
|
|
33
|
-
"@webex/test-helper-test-users": "3.
|
|
30
|
+
"@webex/test-helper-chai": "3.12.0-webex-services-ready.1",
|
|
31
|
+
"@webex/test-helper-mocha": "3.12.0-webex-services-ready.1",
|
|
32
|
+
"@webex/test-helper-mock-webex": "3.12.0-webex-services-ready.1",
|
|
33
|
+
"@webex/test-helper-test-users": "3.12.0-webex-services-ready.1",
|
|
34
34
|
"eslint": "^8.24.0",
|
|
35
35
|
"prettier": "^2.7.1",
|
|
36
36
|
"sinon": "^9.2.4"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@webex/common": "3.
|
|
40
|
-
"@webex/common-timers": "3.
|
|
41
|
-
"@webex/test-helper-chai": "3.
|
|
42
|
-
"@webex/test-helper-mock-webex": "3.
|
|
43
|
-
"@webex/webex-core": "3.12.0-
|
|
39
|
+
"@webex/common": "3.12.0-webex-services-ready.1",
|
|
40
|
+
"@webex/common-timers": "3.12.0-webex-services-ready.1",
|
|
41
|
+
"@webex/test-helper-chai": "3.12.0-webex-services-ready.1",
|
|
42
|
+
"@webex/test-helper-mock-webex": "3.12.0-webex-services-ready.1",
|
|
43
|
+
"@webex/webex-core": "3.12.0-webex-services-ready.1",
|
|
44
44
|
"ip-anonymize": "^0.1.0",
|
|
45
45
|
"lodash": "^4.17.21",
|
|
46
46
|
"uuid": "^3.3.2"
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"test:style": "eslint ./src/**/*.*",
|
|
54
54
|
"test:unit": "webex-legacy-tools test --unit --runner mocha"
|
|
55
55
|
},
|
|
56
|
-
"version": "3.12.0-
|
|
56
|
+
"version": "3.12.0-webex-services-ready.1"
|
|
57
57
|
}
|
package/src/batcher.js
CHANGED
|
@@ -75,6 +75,10 @@ const MetricsBatcher = Batcher.extend({
|
|
|
75
75
|
*/
|
|
76
76
|
handleHttpError(reason) {
|
|
77
77
|
if (reason instanceof WebexHttpError.NetworkOrCORSError) {
|
|
78
|
+
if (!this.config.batcherRetryOnNetworkError) {
|
|
79
|
+
return Reflect.apply(Batcher.prototype.handleHttpError, this, [reason]);
|
|
80
|
+
}
|
|
81
|
+
|
|
78
82
|
this.logger.warn(
|
|
79
83
|
'metrics-batcher: received network error submitting metrics, reenqueuing payload'
|
|
80
84
|
);
|
|
@@ -55,6 +55,8 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
|
|
|
55
55
|
`CallDiagnosticEventsBatcher: @submitHttpRequest#${batchId}. Request successful.`
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
+
this.handleHttpResponseStatus(res?.statusCode, payload);
|
|
59
|
+
|
|
58
60
|
return res;
|
|
59
61
|
})
|
|
60
62
|
.catch((err) => {
|
|
@@ -64,9 +66,33 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
|
|
|
64
66
|
`error: ${generateCommonErrorMetadata(err)}`
|
|
65
67
|
);
|
|
66
68
|
|
|
69
|
+
this.handleHttpResponseStatus(err?.statusCode, payload);
|
|
70
|
+
|
|
67
71
|
return Promise.reject(err);
|
|
68
72
|
});
|
|
69
73
|
},
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* React to the HTTP status code returned by the metrics endpoint.
|
|
77
|
+
* Only items submitted with `markTelemetryOptOutOnResponse: true` opt into
|
|
78
|
+
* this behavior.
|
|
79
|
+
* @param {number | undefined} statusCode
|
|
80
|
+
* @param {any[]} payload Items flushed in this HTTP batch.
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
handleHttpResponseStatus(statusCode: number | undefined, payload: any[]) {
|
|
84
|
+
const shouldMark =
|
|
85
|
+
Array.isArray(payload) &&
|
|
86
|
+
payload.some((item) => item?.markTelemetryOptOutOnResponse === true);
|
|
87
|
+
|
|
88
|
+
if (!shouldMark) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (statusCode === 200) {
|
|
93
|
+
this.webex.internal.newMetrics?.callDiagnosticMetrics?.setIsTelemetryOptOutAutomatic(true);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
70
96
|
});
|
|
71
97
|
|
|
72
98
|
export default CallDiagnosticEventsBatcher;
|
|
@@ -224,11 +224,17 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
224
224
|
* @returns - latency
|
|
225
225
|
*/
|
|
226
226
|
public getCallInitJoinReq() {
|
|
227
|
-
|
|
228
|
-
'internal.client.interstitial-window.
|
|
229
|
-
'client.locus.join.request'
|
|
230
|
-
{maximum: 1200000}
|
|
227
|
+
const interstitialShowedToJoinReq = this.getDiffBetweenTimestamps(
|
|
228
|
+
'internal.client.meeting.interstitial-window.showed',
|
|
229
|
+
'client.locus.join.request'
|
|
231
230
|
);
|
|
231
|
+
const showInterstitialTime = this.getShowInterstitialTime() || 0;
|
|
232
|
+
|
|
233
|
+
if (typeof interstitialShowedToJoinReq !== 'number') {
|
|
234
|
+
return undefined;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return clamp(interstitialShowedToJoinReq - showInterstitialTime, 0, 1200000);
|
|
232
238
|
}
|
|
233
239
|
|
|
234
240
|
/**
|
|
@@ -363,14 +369,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
363
369
|
* @returns - latency
|
|
364
370
|
*/
|
|
365
371
|
public getClickToInterstitial() {
|
|
366
|
-
// for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
|
|
367
|
-
if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
|
|
368
|
-
return this.getDiffBetweenTimestamps(
|
|
369
|
-
'internal.client.meeting.click.joinbutton',
|
|
370
|
-
'internal.client.meeting.interstitial-window.showed'
|
|
371
|
-
);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
372
|
const clickToInterstitialLatency = this.precomputedLatencies.get(
|
|
375
373
|
'internal.click.to.interstitial'
|
|
376
374
|
);
|
|
@@ -387,14 +385,6 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
387
385
|
* @returns - latency
|
|
388
386
|
*/
|
|
389
387
|
public getClickToInterstitialWithUserDelay() {
|
|
390
|
-
// for normal join (where green join button exists before interstitial, i.e reminder, space list etc)
|
|
391
|
-
if (this.latencyTimestamps.get('internal.client.meeting.click.joinbutton')) {
|
|
392
|
-
return this.getDiffBetweenTimestamps(
|
|
393
|
-
'internal.client.meeting.click.joinbutton',
|
|
394
|
-
'internal.client.meeting.interstitial-window.showed'
|
|
395
|
-
);
|
|
396
|
-
}
|
|
397
|
-
|
|
398
388
|
const clickToInterstitialWithUserDelayLatency = this.precomputedLatencies.get(
|
|
399
389
|
'internal.click.to.interstitial.with.user.delay'
|
|
400
390
|
);
|
|
@@ -411,10 +401,17 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
411
401
|
* @returns - latency
|
|
412
402
|
*/
|
|
413
403
|
public getInterstitialToJoinOK() {
|
|
414
|
-
|
|
415
|
-
'internal.client.interstitial-window.
|
|
404
|
+
const interstitialShowedToJoinResp = this.getDiffBetweenTimestamps(
|
|
405
|
+
'internal.client.meeting.interstitial-window.showed',
|
|
416
406
|
'client.locus.join.response'
|
|
417
407
|
);
|
|
408
|
+
const showInterstitialTime = this.getShowInterstitialTime() || 0;
|
|
409
|
+
|
|
410
|
+
if (typeof interstitialShowedToJoinResp !== 'number') {
|
|
411
|
+
return undefined;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return clamp(interstitialShowedToJoinResp - showInterstitialTime, 0, this.MAX_INTEGER);
|
|
418
415
|
}
|
|
419
416
|
|
|
420
417
|
/**
|
|
@@ -430,18 +427,19 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
430
427
|
* @returns - latency
|
|
431
428
|
*/
|
|
432
429
|
public getInterstitialToMediaOKJMT() {
|
|
433
|
-
const
|
|
434
|
-
'internal.client.interstitial-window.
|
|
430
|
+
const interstitialShowedToIceEnd = this.getDiffBetweenTimestamps(
|
|
431
|
+
'internal.client.meeting.interstitial-window.showed',
|
|
435
432
|
'client.ice.end'
|
|
436
433
|
);
|
|
434
|
+
const showInterstitialTime = this.getShowInterstitialTime() || 0;
|
|
437
435
|
const stayLobbyTimeCappedByIceEnd = this.getStayLobbyTimeCappedBy('client.ice.end');
|
|
438
436
|
|
|
439
437
|
if (
|
|
440
|
-
typeof
|
|
438
|
+
typeof interstitialShowedToIceEnd === 'number' &&
|
|
441
439
|
typeof stayLobbyTimeCappedByIceEnd === 'number'
|
|
442
440
|
) {
|
|
443
441
|
return clamp(
|
|
444
|
-
|
|
442
|
+
interstitialShowedToIceEnd - showInterstitialTime - stayLobbyTimeCappedByIceEnd,
|
|
445
443
|
0,
|
|
446
444
|
this.MAX_INTEGER
|
|
447
445
|
);
|
|
@@ -456,17 +454,18 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
456
454
|
*/
|
|
457
455
|
public getTotalJMT() {
|
|
458
456
|
const clickToInterstitial = this.getClickToInterstitial();
|
|
459
|
-
const
|
|
460
|
-
'internal.client.interstitial-window.
|
|
457
|
+
const interstitialShowedToJoinLocusResponse = this.getDiffBetweenTimestamps(
|
|
458
|
+
'internal.client.meeting.interstitial-window.showed',
|
|
461
459
|
'client.locus.join.response'
|
|
462
460
|
);
|
|
461
|
+
const showInterstitialTime = this.getShowInterstitialTime() || 0;
|
|
463
462
|
|
|
464
463
|
if (
|
|
465
464
|
typeof clickToInterstitial === 'number' &&
|
|
466
|
-
typeof
|
|
465
|
+
typeof interstitialShowedToJoinLocusResponse === 'number'
|
|
467
466
|
) {
|
|
468
467
|
return clamp(
|
|
469
|
-
clickToInterstitial +
|
|
468
|
+
clickToInterstitial + interstitialShowedToJoinLocusResponse - showInterstitialTime,
|
|
470
469
|
0,
|
|
471
470
|
this.MAX_INTEGER
|
|
472
471
|
);
|
|
@@ -521,22 +520,24 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
521
520
|
*/
|
|
522
521
|
public getTotalMediaJMT() {
|
|
523
522
|
const clickToInterstitial = this.getClickToInterstitial();
|
|
524
|
-
const
|
|
525
|
-
'internal.client.interstitial-window.
|
|
523
|
+
const interstitialShowedToMediaEngineReady = this.getDiffBetweenTimestamps(
|
|
524
|
+
'internal.client.meeting.interstitial-window.showed',
|
|
526
525
|
'client.media-engine.ready'
|
|
527
526
|
);
|
|
527
|
+
const showInterstitialTime = this.getShowInterstitialTime() || 0;
|
|
528
528
|
const stayLobbyTimeCappedByMediaEngineReady = this.getStayLobbyTimeCappedBy(
|
|
529
529
|
'client.media-engine.ready'
|
|
530
530
|
);
|
|
531
531
|
|
|
532
532
|
if (
|
|
533
533
|
typeof clickToInterstitial === 'number' &&
|
|
534
|
-
typeof
|
|
534
|
+
typeof interstitialShowedToMediaEngineReady === 'number' &&
|
|
535
535
|
typeof stayLobbyTimeCappedByMediaEngineReady === 'number'
|
|
536
536
|
) {
|
|
537
537
|
return clamp(
|
|
538
538
|
clickToInterstitial +
|
|
539
|
-
|
|
539
|
+
interstitialShowedToMediaEngineReady -
|
|
540
|
+
showInterstitialTime -
|
|
540
541
|
stayLobbyTimeCappedByMediaEngineReady,
|
|
541
542
|
0,
|
|
542
543
|
this.MAX_INTEGER
|
|
@@ -576,11 +577,26 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
|
|
|
576
577
|
* @returns - latency
|
|
577
578
|
*/
|
|
578
579
|
public getClientJMT() {
|
|
579
|
-
const
|
|
580
|
-
|
|
580
|
+
const clickToInterstitialForClientJmt = this.precomputedLatencies.get(
|
|
581
|
+
'internal.click.to.interstitial.for.client.jmt'
|
|
582
|
+
);
|
|
583
|
+
const interstitialShowedToLocusJoinRequest = this.getDiffBetweenTimestamps(
|
|
584
|
+
'internal.client.meeting.interstitial-window.showed',
|
|
585
|
+
'client.locus.join.request'
|
|
586
|
+
);
|
|
587
|
+
const showInterstitialTime = this.getShowInterstitialTime() || 0;
|
|
581
588
|
|
|
582
|
-
if (
|
|
583
|
-
|
|
589
|
+
if (
|
|
590
|
+
typeof clickToInterstitialForClientJmt === 'number' &&
|
|
591
|
+
typeof interstitialShowedToLocusJoinRequest === 'number'
|
|
592
|
+
) {
|
|
593
|
+
return clamp(
|
|
594
|
+
clickToInterstitialForClientJmt +
|
|
595
|
+
interstitialShowedToLocusJoinRequest -
|
|
596
|
+
showInterstitialTime,
|
|
597
|
+
0,
|
|
598
|
+
this.MAX_INTEGER
|
|
599
|
+
);
|
|
584
600
|
}
|
|
585
601
|
|
|
586
602
|
return undefined;
|
|
@@ -108,6 +108,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
108
108
|
private isMercuryConnected = false;
|
|
109
109
|
private eventLimitTracker: Map<string, number> = new Map();
|
|
110
110
|
private eventLimitWarningsLogged: Set<string> = new Set();
|
|
111
|
+
private isTelemetryOptOutManual = false;
|
|
112
|
+
private isTelemetryOptOutAutomatic = false;
|
|
111
113
|
|
|
112
114
|
// the default validator before piping an event to the batcher
|
|
113
115
|
// this function can be overridden by the user
|
|
@@ -145,6 +147,37 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
145
147
|
return null;
|
|
146
148
|
}
|
|
147
149
|
|
|
150
|
+
/**
|
|
151
|
+
* Returns the telemetryOptOut value of the current user
|
|
152
|
+
* @returns one of 'manual', 'automatic', undefined
|
|
153
|
+
*/
|
|
154
|
+
public getTelemetryOptOut() {
|
|
155
|
+
if (this.isTelemetryOptOutManual) {
|
|
156
|
+
return 'manual';
|
|
157
|
+
}
|
|
158
|
+
if (this.isTelemetryOptOutAutomatic) {
|
|
159
|
+
return 'automatic';
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Sets the manual telemetry opt-out status for the current user
|
|
167
|
+
* @param value - boolean value indicating manual telemetry opt-out status
|
|
168
|
+
*/
|
|
169
|
+
public setIsTelemetryOptOutManual(value: boolean) {
|
|
170
|
+
this.isTelemetryOptOutManual = value;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Sets the automatic telemetry opt-out status for the current user
|
|
175
|
+
* @param value - boolean value indicating automatic telemetry opt-out status
|
|
176
|
+
*/
|
|
177
|
+
public setIsTelemetryOptOutAutomatic(value: boolean) {
|
|
178
|
+
this.isTelemetryOptOutAutomatic = value;
|
|
179
|
+
}
|
|
180
|
+
|
|
148
181
|
/**
|
|
149
182
|
* Returns if the meeting has converged architecture enabled
|
|
150
183
|
* @param options.meetingId
|
|
@@ -607,6 +640,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
607
640
|
mediaEngineSoftwareVersion: getOSVersion() || 'unknown',
|
|
608
641
|
startTime: new Date().toISOString(),
|
|
609
642
|
},
|
|
643
|
+
webexSubServiceType: this.getSubServiceType(meeting),
|
|
610
644
|
};
|
|
611
645
|
|
|
612
646
|
// merge any new properties, or override existing ones
|
|
@@ -989,7 +1023,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
989
1023
|
sessionCorrelationId,
|
|
990
1024
|
});
|
|
991
1025
|
|
|
992
|
-
// create common event object
|
|
1026
|
+
// create common event object structure
|
|
993
1027
|
const commonEventObject = {
|
|
994
1028
|
name,
|
|
995
1029
|
canProceed: true,
|
|
@@ -1002,6 +1036,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1002
1036
|
'loginType' in meeting.callStateForMetrics
|
|
1003
1037
|
? meeting.callStateForMetrics.loginType
|
|
1004
1038
|
: this.getCurLoginType(),
|
|
1039
|
+
telemetryOptOut: this.getTelemetryOptOut(),
|
|
1005
1040
|
isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({
|
|
1006
1041
|
meetingId,
|
|
1007
1042
|
}),
|
|
@@ -1010,6 +1045,9 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1010
1045
|
webexSubServiceType: this.getSubServiceType(meeting),
|
|
1011
1046
|
// @ts-ignore
|
|
1012
1047
|
webClientPreload: this.webex.meetings?.config?.metrics?.webClientPreload,
|
|
1048
|
+
isVipMeeting: meeting?.meetingInfo?.vipmeeting || false,
|
|
1049
|
+
isAutomatedUser:
|
|
1050
|
+
typeof window !== 'undefined' && typeof navigator !== 'undefined' && !!navigator?.webdriver, // if webdriver is true, it's most likely in a test environment
|
|
1013
1051
|
};
|
|
1014
1052
|
|
|
1015
1053
|
const joinFlowVersion = options.joinFlowVersion ?? meeting.callStateForMetrics?.joinFlowVersion;
|
|
@@ -1129,8 +1167,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1129
1167
|
isMercuryConnected: this.isMercuryConnected,
|
|
1130
1168
|
},
|
|
1131
1169
|
loginType: this.getCurLoginType(),
|
|
1170
|
+
telemetryOptOut: this.getTelemetryOptOut(),
|
|
1132
1171
|
// @ts-ignore
|
|
1133
1172
|
webClientPreload: this.webex.meetings?.config?.metrics?.webClientPreload,
|
|
1173
|
+
isAutomatedUser:
|
|
1174
|
+
typeof window !== 'undefined' && typeof navigator !== 'undefined' && !!navigator?.webdriver, // if webdriver is true, it's most likely in a test environment
|
|
1134
1175
|
};
|
|
1135
1176
|
|
|
1136
1177
|
if (options.joinFlowVersion) {
|
|
@@ -1323,6 +1364,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1323
1364
|
const finalEvent = {
|
|
1324
1365
|
eventPayload: event,
|
|
1325
1366
|
type: ['diagnostic-event'],
|
|
1367
|
+
markTelemetryOptOutOnResponse: true,
|
|
1326
1368
|
};
|
|
1327
1369
|
|
|
1328
1370
|
return this.callDiagnosticEventsBatcher.request(finalEvent);
|
|
@@ -1332,6 +1374,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1332
1374
|
* Prepare the event and send the request to metrics-a service, pre login.
|
|
1333
1375
|
* @param event
|
|
1334
1376
|
* @param preLoginId
|
|
1377
|
+
* @param markTelemetryOptOutOnResponse
|
|
1335
1378
|
* @returns
|
|
1336
1379
|
*/
|
|
1337
1380
|
submitToCallDiagnosticsPreLogin = (event: Event, preLoginId?: string): Promise<any> => {
|
|
@@ -1339,7 +1382,9 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
1339
1382
|
const finalEvent = {
|
|
1340
1383
|
eventPayload: event,
|
|
1341
1384
|
type: ['diagnostic-event'],
|
|
1385
|
+
markTelemetryOptOutOnResponse: true,
|
|
1342
1386
|
};
|
|
1387
|
+
|
|
1343
1388
|
this.preLoginMetricsBatcher.savePreLoginId(preLoginId);
|
|
1344
1389
|
|
|
1345
1390
|
return this.preLoginMetricsBatcher.request(finalEvent);
|
|
@@ -390,6 +390,11 @@ export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
|
390
390
|
|
|
391
391
|
item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);
|
|
392
392
|
|
|
393
|
+
// Mark call milestones in logs for easier filtering and analysis
|
|
394
|
+
if (eventName) {
|
|
395
|
+
webex.logger.log('Milestone,CallDiagnostic', eventName);
|
|
396
|
+
}
|
|
397
|
+
|
|
393
398
|
webex.logger.log(
|
|
394
399
|
`CallDiagnosticLatencies,prepareDiagnosticMetricItem: ${JSON.stringify({
|
|
395
400
|
latencies: Object.fromEntries(cdl.latencyTimestamps),
|
|
@@ -137,6 +137,7 @@ export const ERROR_DESCRIPTIONS = {
|
|
|
137
137
|
WEBRTC_API_NOT_AVAILABLE: 'WebrtcApiNotAvailableError',
|
|
138
138
|
WDM_RESTRICTED_REGION: 'WdmRestrictedRegion',
|
|
139
139
|
USER_NOT_ALLOWED_JOIN_WEBINAR: 'UserNotAllowedJoinWebinar',
|
|
140
|
+
INVALID_MEETING_INFO: 'InvalidMeetingInfo',
|
|
140
141
|
};
|
|
141
142
|
|
|
142
143
|
export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
@@ -147,6 +148,8 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
147
148
|
99002: 4100,
|
|
148
149
|
// Cannot find the data. Unkown meeting.
|
|
149
150
|
99009: 4100,
|
|
151
|
+
// The input parameters contain invalid item
|
|
152
|
+
99019: 4105,
|
|
150
153
|
// Meeting is not allow to cross env
|
|
151
154
|
58500: 4100,
|
|
152
155
|
// Input parameters contain invalit item
|
|
@@ -202,6 +205,8 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
202
205
|
423005: 4005,
|
|
203
206
|
// Wrong password or host key with too many requests
|
|
204
207
|
423006: 4005,
|
|
208
|
+
// PanelistPasswordError too many time,please input captcha code
|
|
209
|
+
423008: 4005,
|
|
205
210
|
// PasswordError with right captcha, please input captcha code
|
|
206
211
|
423010: 4005,
|
|
207
212
|
// PasswordOrHostKeyError with right captcha, please input captcha code
|
|
@@ -228,6 +233,8 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
228
233
|
403003: 4101,
|
|
229
234
|
// Attendee email is required
|
|
230
235
|
403030: 4101,
|
|
236
|
+
// webinar need login when un-invited attendee join
|
|
237
|
+
403106: 4104,
|
|
231
238
|
|
|
232
239
|
// ---- Locus ------
|
|
233
240
|
// FREE_USER_MAX_PARTICIPANTS_EXCEEDED
|
|
@@ -697,6 +704,12 @@ export const CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD: Record<number, Partial<ClientEv
|
|
|
697
704
|
category: 'expected',
|
|
698
705
|
fatal: true,
|
|
699
706
|
},
|
|
707
|
+
4105: {
|
|
708
|
+
errorDescription: ERROR_DESCRIPTIONS.INVALID_MEETING_INFO,
|
|
709
|
+
category: 'expected',
|
|
710
|
+
fatal: false,
|
|
711
|
+
shownToUser: true,
|
|
712
|
+
},
|
|
700
713
|
2729: {
|
|
701
714
|
errorDescription: ERROR_DESCRIPTIONS.NO_MEDIA_FOUND,
|
|
702
715
|
category: 'expected',
|
package/src/config.js
CHANGED
package/src/metrics.types.ts
CHANGED
|
@@ -156,7 +156,6 @@ export type InternalEvent = {
|
|
|
156
156
|
| 'internal.register.device.request'
|
|
157
157
|
| 'internal.register.device.response'
|
|
158
158
|
| 'internal.reset.join.latencies'
|
|
159
|
-
| 'internal.client.meeting.click.joinbutton'
|
|
160
159
|
| 'internal.host.meeting.participant.admitted'
|
|
161
160
|
| 'internal.client.meeting.interstitial-window.showed'
|
|
162
161
|
| 'internal.client.interstitial-window.click.joinbutton'
|
|
@@ -319,6 +318,7 @@ export type PreComputedLatencies =
|
|
|
319
318
|
| 'internal.get.cluster.time'
|
|
320
319
|
| 'internal.click.to.interstitial'
|
|
321
320
|
| 'internal.click.to.interstitial.with.user.delay'
|
|
321
|
+
| 'internal.click.to.interstitial.for.client.jmt'
|
|
322
322
|
| 'internal.refresh.captcha.time'
|
|
323
323
|
| 'internal.exchange.ci.token.time'
|
|
324
324
|
| 'internal.get.u2c.time'
|