@webex/internal-plugin-metrics 3.8.0 → 3.8.1-next.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/call-diagnostic/call-diagnostic-metrics.js +102 -37
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/config.js +29 -2
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +15 -4
- package/dist/new-metrics.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +22 -22
- package/dist/types/call-diagnostic/config.d.ts +12 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/metrics.types.d.ts +11 -1
- package/dist/types/new-metrics.d.ts +10 -3
- package/package.json +12 -12
- package/src/call-diagnostic/call-diagnostic-metrics.ts +89 -42
- package/src/call-diagnostic/config.ts +28 -0
- package/src/index.ts +2 -0
- package/src/metrics.types.ts +14 -1
- package/src/new-metrics.ts +21 -4
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +783 -97
- package/test/unit/spec/new-metrics.ts +27 -3
- package/dist/call-diagnostic-events-batcher.js +0 -59
- package/dist/call-diagnostic-events-batcher.js.map +0 -1
|
@@ -99,6 +99,7 @@ export declare const ERROR_DESCRIPTIONS: {
|
|
|
99
99
|
SDP_OFFER_CREATION_ERROR: string;
|
|
100
100
|
SDP_OFFER_CREATION_ERROR_MISSING_CODEC: string;
|
|
101
101
|
WDM_RESTRICTED_REGION: string;
|
|
102
|
+
USER_NOT_ALLOWED_JOIN_WEBINAR: string;
|
|
102
103
|
};
|
|
103
104
|
export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
104
105
|
58400: number;
|
|
@@ -108,6 +109,8 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
|
108
109
|
400001: number;
|
|
109
110
|
403004: number;
|
|
110
111
|
403028: number;
|
|
112
|
+
403025: number;
|
|
113
|
+
403125: number;
|
|
111
114
|
403032: number;
|
|
112
115
|
403034: number;
|
|
113
116
|
403036: number;
|
|
@@ -133,6 +136,15 @@ export declare const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP: {
|
|
|
133
136
|
423012: number;
|
|
134
137
|
423013: number;
|
|
135
138
|
429005: number;
|
|
139
|
+
403021: number;
|
|
140
|
+
403022: number;
|
|
141
|
+
403024: number;
|
|
142
|
+
403137: number;
|
|
143
|
+
423007: number;
|
|
144
|
+
403026: number;
|
|
145
|
+
403037: number;
|
|
146
|
+
403003: number;
|
|
147
|
+
403030: number;
|
|
136
148
|
2403001: number;
|
|
137
149
|
2403002: number;
|
|
138
150
|
2403003: number;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import config from './config';
|
|
5
5
|
import NewMetrics from './new-metrics';
|
|
6
6
|
import * as Utils from './utils';
|
|
7
|
-
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitMQE, PreComputedLatencies } from './metrics.types';
|
|
7
|
+
import { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitOperationalEvent, SubmitBusinessEvent, SubmitMQE, PreComputedLatencies } from './metrics.types';
|
|
8
8
|
import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
|
|
9
9
|
import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
|
|
10
10
|
import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
@@ -15,4 +15,4 @@ import BusinessMetrics from './business-metrics';
|
|
|
15
15
|
import RtcMetrics from './rtcMetrics';
|
|
16
16
|
export { default, getOSNameInternal } from './metrics';
|
|
17
17
|
export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, BehavioralMetrics, OperationalMetrics, BusinessMetrics, RtcMetrics, };
|
|
18
|
-
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, PreComputedLatencies, };
|
|
18
|
+
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, SubmitBusinessEvent, PreComputedLatencies, };
|
|
@@ -6,8 +6,10 @@ export type ClientEventError = NonNullable<RawClientEvent['errors']>[0];
|
|
|
6
6
|
export type EnvironmentType = NonNullable<RawEvent['origin']['environment']>;
|
|
7
7
|
export type NewEnvironmentType = NonNullable<RawEvent['origin']['newEnvironment']>;
|
|
8
8
|
export type ClientLaunchMethodType = NonNullable<RawEvent['origin']['clientInfo']>['clientLaunchMethod'];
|
|
9
|
+
export type ClientUserNameInput = NonNullable<RawClientEvent['userNameInput']>;
|
|
10
|
+
export type ClientEmailInput = NonNullable<RawClientEvent['emailInput']>;
|
|
9
11
|
export type BrowserLaunchMethodType = NonNullable<RawEvent['origin']['clientInfo']>['browserLaunchMethod'];
|
|
10
|
-
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm';
|
|
12
|
+
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm' | 'wxcc_sdk';
|
|
11
13
|
export type MetricEventAgent = 'user' | 'browser' | 'system' | 'sdk' | 'redux' | 'service' | 'api';
|
|
12
14
|
export type MetricEventVerb = 'abort' | 'accept' | 'activate' | 'apply' | 'answer' | 'authorize' | 'build' | 'cancel' | 'change' | 'click' | 'close' | 'complete' | 'connect' | 'create' | 'deactivate' | 'decrypt' | 'delete' | 'deliver' | 'destroy' | 'disable' | 'disconnect' | 'dismiss' | 'display' | 'download' | 'edit' | 'enable' | 'encrypt' | 'end' | 'expire' | 'fail' | 'fetch' | 'fire' | 'generate' | 'get' | 'hide' | 'hover' | 'ignore' | 'initialize' | 'initiate' | 'invalidate' | 'join' | 'list' | 'load' | 'login' | 'logout' | 'notify' | 'offer' | 'open' | 'press' | 'receive' | 'refer' | 'refresh' | 'register' | 'release' | 'reload' | 'reject' | 'request' | 'reset' | 'resize' | 'respond' | 'retry' | 'revoke' | 'save' | 'search' | 'select' | 'send' | 'set' | 'sign' | 'start' | 'submit' | 'switch' | 'sync' | 'toggle' | 'transfer' | 'unregister' | 'update' | 'upload' | 'use' | 'validate' | 'view' | 'visit' | 'wait' | 'warn' | 'exit';
|
|
13
15
|
export type MetricEventJoinFlowVersion = 'Other' | 'NewFTE';
|
|
@@ -28,6 +30,8 @@ export type SubmitClientEventOptions = {
|
|
|
28
30
|
joinFlowVersion?: MetricEventJoinFlowVersion;
|
|
29
31
|
meetingJoinPhase?: MetricEventMeetingJoinPhase;
|
|
30
32
|
triggeredTime?: string;
|
|
33
|
+
emailInput?: ClientEmailInput;
|
|
34
|
+
userNameInput?: ClientUserNameInput;
|
|
31
35
|
};
|
|
32
36
|
export type SubmitMQEOptions = {
|
|
33
37
|
meetingId: string;
|
|
@@ -132,6 +136,12 @@ export type SubmitOperationalEvent = (args: {
|
|
|
132
136
|
name: OperationalEvent['metricName'];
|
|
133
137
|
payload: EventPayload;
|
|
134
138
|
}) => void;
|
|
139
|
+
export type SubmitBusinessEvent = (args: {
|
|
140
|
+
name: OperationalEvent['metricName'];
|
|
141
|
+
payload: EventPayload;
|
|
142
|
+
metadata?: EventPayload;
|
|
143
|
+
table?: Table;
|
|
144
|
+
}) => void;
|
|
135
145
|
export type SubmitMQE = (args: {
|
|
136
146
|
name: MediaQualityEvent['name'];
|
|
137
147
|
payload: SubmitMQEPayload;
|
|
@@ -3,7 +3,7 @@ import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
|
3
3
|
import BehavioralMetrics from './behavioral-metrics';
|
|
4
4
|
import OperationalMetrics from './operational-metrics';
|
|
5
5
|
import BusinessMetrics from './business-metrics';
|
|
6
|
-
import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table } from './metrics.types';
|
|
6
|
+
import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table, DelayedClientEvent } from './metrics.types';
|
|
7
7
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
8
8
|
/**
|
|
9
9
|
* Metrics plugin to centralize all types of metrics.
|
|
@@ -22,6 +22,10 @@ declare class Metrics extends WebexPlugin {
|
|
|
22
22
|
* Whether or not to delay the submission of client events.
|
|
23
23
|
*/
|
|
24
24
|
delaySubmitClientEvents: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
|
|
27
|
+
*/
|
|
28
|
+
delayedClientEventsOverrides: Partial<DelayedClientEvent['options']>;
|
|
25
29
|
/**
|
|
26
30
|
* Constructor
|
|
27
31
|
* @param args
|
|
@@ -178,8 +182,11 @@ declare class Metrics extends WebexPlugin {
|
|
|
178
182
|
* Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
|
|
179
183
|
* set to false, delayed client events will be submitted.
|
|
180
184
|
*
|
|
181
|
-
* @param {
|
|
185
|
+
* @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of client events, overrides: An object containing overrides for the client events}
|
|
182
186
|
*/
|
|
183
|
-
setDelaySubmitClientEvents(shouldDelay
|
|
187
|
+
setDelaySubmitClientEvents({ shouldDelay, overrides, }: {
|
|
188
|
+
shouldDelay: boolean;
|
|
189
|
+
overrides?: Partial<DelayedClientEvent['options']>;
|
|
190
|
+
}): Promise<any[]> | Promise<void>;
|
|
184
191
|
}
|
|
185
192
|
export default Metrics;
|
package/package.json
CHANGED
|
@@ -26,22 +26,22 @@
|
|
|
26
26
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
27
27
|
"@webex/jest-config-legacy": "0.0.0",
|
|
28
28
|
"@webex/legacy-tools": "0.0.0",
|
|
29
|
-
"@webex/test-helper-chai": "3.8.
|
|
30
|
-
"@webex/test-helper-mocha": "3.8.
|
|
31
|
-
"@webex/test-helper-mock-webex": "3.8.
|
|
32
|
-
"@webex/test-helper-test-users": "3.8.
|
|
29
|
+
"@webex/test-helper-chai": "3.8.1-next.1",
|
|
30
|
+
"@webex/test-helper-mocha": "3.8.1-next.1",
|
|
31
|
+
"@webex/test-helper-mock-webex": "3.8.1-next.1",
|
|
32
|
+
"@webex/test-helper-test-users": "3.8.1-next.1",
|
|
33
33
|
"eslint": "^8.24.0",
|
|
34
34
|
"prettier": "^2.7.1",
|
|
35
35
|
"sinon": "^9.2.4"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@webex/common": "3.8.
|
|
39
|
-
"@webex/common-timers": "3.8.
|
|
40
|
-
"@webex/event-dictionary-ts": "^1.0.
|
|
41
|
-
"@webex/internal-plugin-metrics": "3.8.
|
|
42
|
-
"@webex/test-helper-chai": "3.8.
|
|
43
|
-
"@webex/test-helper-mock-webex": "3.8.
|
|
44
|
-
"@webex/webex-core": "3.8.
|
|
38
|
+
"@webex/common": "3.8.1-next.1",
|
|
39
|
+
"@webex/common-timers": "3.8.1-next.1",
|
|
40
|
+
"@webex/event-dictionary-ts": "^1.0.1753",
|
|
41
|
+
"@webex/internal-plugin-metrics": "3.8.1-next.1",
|
|
42
|
+
"@webex/test-helper-chai": "3.8.1-next.1",
|
|
43
|
+
"@webex/test-helper-mock-webex": "3.8.1-next.1",
|
|
44
|
+
"@webex/webex-core": "3.8.1-next.1",
|
|
45
45
|
"ip-anonymize": "^0.1.0",
|
|
46
46
|
"lodash": "^4.17.21",
|
|
47
47
|
"uuid": "^3.3.2"
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"test:style": "eslint ./src/**/*.*",
|
|
55
55
|
"test:unit": "webex-legacy-tools test --unit --runner mocha"
|
|
56
56
|
},
|
|
57
|
-
"version": "3.8.
|
|
57
|
+
"version": "3.8.1-next.1"
|
|
58
58
|
}
|
|
@@ -97,6 +97,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
97
97
|
private hasLoggedBrowserSerial: boolean;
|
|
98
98
|
private device: any;
|
|
99
99
|
private delayedClientEvents: DelayedClientEvent[] = [];
|
|
100
|
+
private eventErrorCache: WeakMap<any, any> = new WeakMap();
|
|
101
|
+
private isMercuryConnected = false;
|
|
100
102
|
|
|
101
103
|
// the default validator before piping an event to the batcher
|
|
102
104
|
// this function can be overridden by the user
|
|
@@ -149,6 +151,16 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
149
151
|
return undefined;
|
|
150
152
|
}
|
|
151
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Sets mercury connected status for event data object in CA events
|
|
156
|
+
* @public
|
|
157
|
+
* @param status - boolean value indicating mercury connection status
|
|
158
|
+
* @return {void}
|
|
159
|
+
*/
|
|
160
|
+
public setMercuryConnectedStatus(status: boolean): void {
|
|
161
|
+
this.isMercuryConnected = status;
|
|
162
|
+
}
|
|
163
|
+
|
|
152
164
|
/**
|
|
153
165
|
* Returns meeting's subServiceType
|
|
154
166
|
* @param meeting
|
|
@@ -166,23 +178,17 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
166
178
|
if (meetingInfo?.webexScheduled && !meetingInfo?.enableEvent && !meetingInfo?.pmr) {
|
|
167
179
|
return WEBEX_SUB_SERVICE_TYPES.SCHEDULED_MEETING;
|
|
168
180
|
}
|
|
169
|
-
|
|
170
|
-
if
|
|
171
|
-
|
|
172
|
-
meetingInfo?.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
) {
|
|
176
|
-
return WEBEX_SUB_SERVICE_TYPES.WEBINAR;
|
|
181
|
+
|
|
182
|
+
// if ConvergedArchitecture enable and isConvergedWebinarWebcast -- then webcast
|
|
183
|
+
if (meetingInfo?.enableConvergedArchitecture && meetingInfo?.enableEvent) {
|
|
184
|
+
return meetingInfo?.isConvergedWebinarWebcast
|
|
185
|
+
? WEBEX_SUB_SERVICE_TYPES.WEBCAST
|
|
186
|
+
: WEBEX_SUB_SERVICE_TYPES.WEBINAR;
|
|
177
187
|
}
|
|
178
|
-
|
|
179
|
-
if
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
!meetingInfo?.pmr &&
|
|
183
|
-
meetingInfo?.isConvergedWebinarWebcast
|
|
184
|
-
) {
|
|
185
|
-
return WEBEX_SUB_SERVICE_TYPES.WEBCAST;
|
|
188
|
+
|
|
189
|
+
// if Scheduled, enable event, not pmr - then Webinar
|
|
190
|
+
if (meetingInfo?.webexScheduled && meetingInfo?.enableEvent && !meetingInfo?.pmr) {
|
|
191
|
+
return WEBEX_SUB_SERVICE_TYPES.WEBINAR;
|
|
186
192
|
}
|
|
187
193
|
}
|
|
188
194
|
|
|
@@ -561,16 +567,31 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
561
567
|
return undefined;
|
|
562
568
|
}
|
|
563
569
|
|
|
570
|
+
/**
|
|
571
|
+
* Clear the error cache
|
|
572
|
+
*/
|
|
573
|
+
clearErrorCache() {
|
|
574
|
+
this.eventErrorCache = new WeakMap();
|
|
575
|
+
}
|
|
576
|
+
|
|
564
577
|
/**
|
|
565
578
|
* Generate error payload for Client Event
|
|
566
579
|
* @param rawError
|
|
567
580
|
*/
|
|
568
581
|
generateClientEventErrorPayload(rawError: any) {
|
|
582
|
+
const cachedError = this.eventErrorCache.get(rawError);
|
|
583
|
+
|
|
584
|
+
if (cachedError) {
|
|
585
|
+
return [cachedError, true];
|
|
586
|
+
}
|
|
587
|
+
|
|
569
588
|
const rawErrorMessage = rawError.message;
|
|
570
589
|
const httpStatusCode = rawError.statusCode;
|
|
590
|
+
let payload;
|
|
591
|
+
|
|
571
592
|
if (rawError.name) {
|
|
572
593
|
if (isBrowserMediaErrorName(rawError.name)) {
|
|
573
|
-
|
|
594
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
574
595
|
serviceErrorCode: undefined,
|
|
575
596
|
clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],
|
|
576
597
|
serviceErrorName: rawError.name,
|
|
@@ -580,11 +601,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
580
601
|
}
|
|
581
602
|
}
|
|
582
603
|
|
|
583
|
-
if (isSdpOfferCreationError(rawError)) {
|
|
604
|
+
if (isSdpOfferCreationError(rawError) && !payload) {
|
|
584
605
|
// error code is 30005, but that's not specific enough. we also need to check error.cause.type
|
|
585
606
|
const causeType = rawError.cause?.type;
|
|
586
607
|
|
|
587
|
-
|
|
608
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
588
609
|
serviceErrorCode: undefined,
|
|
589
610
|
clientErrorCode:
|
|
590
611
|
SDP_OFFER_CREATION_ERROR_MAP[causeType] || SDP_OFFER_CREATION_ERROR_MAP.GENERAL,
|
|
@@ -602,8 +623,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
602
623
|
|
|
603
624
|
if (serviceErrorCode) {
|
|
604
625
|
const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];
|
|
605
|
-
if (clientErrorCode) {
|
|
606
|
-
|
|
626
|
+
if (clientErrorCode && !payload) {
|
|
627
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
607
628
|
clientErrorCode,
|
|
608
629
|
serviceErrorCode,
|
|
609
630
|
rawErrorMessage,
|
|
@@ -612,8 +633,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
612
633
|
}
|
|
613
634
|
|
|
614
635
|
// by default, if it is locus error, return new locus err
|
|
615
|
-
if (isLocusServiceErrorCode(serviceErrorCode)) {
|
|
616
|
-
|
|
636
|
+
if (isLocusServiceErrorCode(serviceErrorCode) && !payload) {
|
|
637
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
617
638
|
clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,
|
|
618
639
|
serviceErrorCode,
|
|
619
640
|
rawErrorMessage,
|
|
@@ -622,8 +643,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
622
643
|
}
|
|
623
644
|
}
|
|
624
645
|
|
|
625
|
-
if (isMeetingInfoServiceError(rawError)) {
|
|
626
|
-
|
|
646
|
+
if (isMeetingInfoServiceError(rawError) && !payload) {
|
|
647
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
627
648
|
clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,
|
|
628
649
|
serviceErrorCode,
|
|
629
650
|
rawErrorMessage,
|
|
@@ -631,8 +652,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
631
652
|
});
|
|
632
653
|
}
|
|
633
654
|
|
|
634
|
-
if (isNetworkError(rawError)) {
|
|
635
|
-
|
|
655
|
+
if (isNetworkError(rawError) && !payload) {
|
|
656
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
636
657
|
clientErrorCode: NETWORK_ERROR,
|
|
637
658
|
serviceErrorCode,
|
|
638
659
|
payloadOverrides: rawError.payloadOverrides,
|
|
@@ -641,8 +662,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
641
662
|
});
|
|
642
663
|
}
|
|
643
664
|
|
|
644
|
-
if (isUnauthorizedError(rawError)) {
|
|
645
|
-
|
|
665
|
+
if (isUnauthorizedError(rawError) && !payload) {
|
|
666
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
646
667
|
clientErrorCode: AUTHENTICATION_FAILED_CODE,
|
|
647
668
|
serviceErrorCode,
|
|
648
669
|
payloadOverrides: rawError.payloadOverrides,
|
|
@@ -651,15 +672,22 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
651
672
|
});
|
|
652
673
|
}
|
|
653
674
|
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
675
|
+
if (!payload) {
|
|
676
|
+
// otherwise return unkown error but passing serviceErrorCode and serviceErrorName so that we know the issue
|
|
677
|
+
payload = this.getErrorPayloadForClientErrorCode({
|
|
678
|
+
clientErrorCode: UNKNOWN_ERROR,
|
|
679
|
+
serviceErrorCode: serviceErrorCode || UNKNOWN_ERROR,
|
|
680
|
+
serviceErrorName: rawError?.name,
|
|
681
|
+
payloadOverrides: rawError.payloadOverrides,
|
|
682
|
+
rawErrorMessage,
|
|
683
|
+
httpStatusCode,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// cache the payload for future use
|
|
688
|
+
this.eventErrorCache.set(rawError, payload);
|
|
689
|
+
|
|
690
|
+
return [payload, false];
|
|
663
691
|
}
|
|
664
692
|
|
|
665
693
|
/**
|
|
@@ -722,6 +750,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
722
750
|
errors,
|
|
723
751
|
eventData: {
|
|
724
752
|
webClientDomain: window.location.hostname,
|
|
753
|
+
isMercuryConnected: this.isMercuryConnected,
|
|
725
754
|
},
|
|
726
755
|
userType: meeting.getCurUserType(),
|
|
727
756
|
loginType:
|
|
@@ -731,6 +760,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
731
760
|
isConvergedArchitectureEnabled: this.getIsConvergedArchitectureEnabled({
|
|
732
761
|
meetingId,
|
|
733
762
|
}),
|
|
763
|
+
...(meeting.userNameInput && {userNameInput: meeting.userNameInput}),
|
|
764
|
+
...(meeting.emailInput && {emailInput: meeting.emailInput}),
|
|
734
765
|
webexSubServiceType: this.getSubServiceType(meeting),
|
|
735
766
|
// @ts-ignore
|
|
736
767
|
webClientPreload: this.webex.meetings?.config?.metrics?.webClientPreload,
|
|
@@ -740,6 +771,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
740
771
|
if (joinFlowVersion) {
|
|
741
772
|
clientEventObject.joinFlowVersion = joinFlowVersion;
|
|
742
773
|
}
|
|
774
|
+
const meetingJoinedTime = meeting.isoLocalClientMeetingJoinTime;
|
|
775
|
+
if (meetingJoinedTime) {
|
|
776
|
+
clientEventObject.meetingJoinedTime = meetingJoinedTime;
|
|
777
|
+
}
|
|
743
778
|
|
|
744
779
|
if (options.meetingJoinPhase) {
|
|
745
780
|
clientEventObject.meetingJoinPhase = options.meetingJoinPhase;
|
|
@@ -784,6 +819,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
784
819
|
identifiers,
|
|
785
820
|
eventData: {
|
|
786
821
|
webClientDomain: window.location.hostname,
|
|
822
|
+
isMercuryConnected: this.isMercuryConnected,
|
|
787
823
|
},
|
|
788
824
|
loginType: this.getCurLoginType(),
|
|
789
825
|
// @ts-ignore
|
|
@@ -798,6 +834,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
798
834
|
clientEventObject.meetingJoinPhase = options.meetingJoinPhase;
|
|
799
835
|
}
|
|
800
836
|
|
|
837
|
+
if (options.userNameInput) {
|
|
838
|
+
clientEventObject.userNameInput = options.userNameInput;
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (options.emailInput) {
|
|
842
|
+
clientEventObject.emailInput = options.emailInput;
|
|
843
|
+
}
|
|
844
|
+
|
|
801
845
|
return clientEventObject;
|
|
802
846
|
}
|
|
803
847
|
|
|
@@ -826,14 +870,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
826
870
|
const errors: ClientEventPayloadError = [];
|
|
827
871
|
|
|
828
872
|
if (rawError) {
|
|
829
|
-
const generatedError = this.generateClientEventErrorPayload(rawError);
|
|
873
|
+
const [generatedError, cached] = this.generateClientEventErrorPayload(rawError);
|
|
830
874
|
if (generatedError) {
|
|
831
875
|
errors.push(generatedError);
|
|
832
876
|
}
|
|
833
877
|
this.logger.log(
|
|
834
878
|
CALL_DIAGNOSTIC_LOG_IDENTIFIER,
|
|
835
879
|
'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
|
|
836
|
-
`generatedError: ${JSON.stringify(generatedError)}`
|
|
880
|
+
`generatedError (cached: ${cached}): ${JSON.stringify(generatedError)}`
|
|
837
881
|
);
|
|
838
882
|
}
|
|
839
883
|
|
|
@@ -911,7 +955,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
911
955
|
/**
|
|
912
956
|
* Submit Delayed Client Event CA events. Clears delayedClientEvents array after submission.
|
|
913
957
|
*/
|
|
914
|
-
public submitDelayedClientEvents() {
|
|
958
|
+
public submitDelayedClientEvents(overrides?: Partial<DelayedClientEvent['options']>) {
|
|
915
959
|
this.logger.log(
|
|
916
960
|
CALL_DIAGNOSTIC_LOG_IDENTIFIER,
|
|
917
961
|
'CallDiagnosticMetrics: @submitDelayedClientEvents. Submitting delayed client events.'
|
|
@@ -922,7 +966,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
922
966
|
}
|
|
923
967
|
|
|
924
968
|
const promises = this.delayedClientEvents.map((delayedSubmitClientEventParams) => {
|
|
925
|
-
|
|
969
|
+
const {name, payload, options} = delayedSubmitClientEventParams;
|
|
970
|
+
const optionsWithOverrides: DelayedClientEvent['options'] = {...options, ...overrides};
|
|
971
|
+
|
|
972
|
+
return this.submitClientEvent({name, payload, options: optionsWithOverrides});
|
|
926
973
|
});
|
|
927
974
|
|
|
928
975
|
this.delayedClientEvents = [];
|
|
@@ -133,6 +133,7 @@ export const ERROR_DESCRIPTIONS = {
|
|
|
133
133
|
SDP_OFFER_CREATION_ERROR: 'SdpOfferCreationError',
|
|
134
134
|
SDP_OFFER_CREATION_ERROR_MISSING_CODEC: 'SdpOfferCreationErrorMissingCodec',
|
|
135
135
|
WDM_RESTRICTED_REGION: 'WdmRestrictedRegion',
|
|
136
|
+
USER_NOT_ALLOWED_JOIN_WEBINAR: 'UserNotAllowedJoinWebinar',
|
|
136
137
|
};
|
|
137
138
|
|
|
138
139
|
export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
@@ -151,6 +152,10 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
151
152
|
403004: 4005,
|
|
152
153
|
// Wrong password. Meeting is not allow to access since password error
|
|
153
154
|
403028: 4005,
|
|
155
|
+
// meeting is not allow to access since require panelist password
|
|
156
|
+
403025: 4005,
|
|
157
|
+
// wrong password. Meeting is not allow to access since panelist password error
|
|
158
|
+
403125: 4005,
|
|
154
159
|
// Wrong or expired permission. Meeting is not allow to access since permissionToken error or expire
|
|
155
160
|
403032: 4005,
|
|
156
161
|
// Meeting is required login for current user
|
|
@@ -202,6 +207,24 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
|
|
|
202
207
|
423013: 4005,
|
|
203
208
|
// Too many requests access
|
|
204
209
|
429005: 4100,
|
|
210
|
+
// Webinar: Meeting registration is required
|
|
211
|
+
403021: 4104,
|
|
212
|
+
// Webinar: Meeting registration is still pending
|
|
213
|
+
403022: 4104,
|
|
214
|
+
// Webinar: Meeting registration have been rejected
|
|
215
|
+
403024: 4104,
|
|
216
|
+
// Webinar: Registration ID verified failure
|
|
217
|
+
403137: 4104,
|
|
218
|
+
// Webinar: Registration ID input too many time,please input captcha code
|
|
219
|
+
423007: 4104,
|
|
220
|
+
// Webinar: Need to join meeting via webcast
|
|
221
|
+
403026: 4104,
|
|
222
|
+
// Webinar: Meeting join required registration ID
|
|
223
|
+
403037: 4104,
|
|
224
|
+
// Not reach JBH, can't join meeting
|
|
225
|
+
403003: 4101,
|
|
226
|
+
// Attendee email is required
|
|
227
|
+
403030: 4101,
|
|
205
228
|
|
|
206
229
|
// ---- Locus ------
|
|
207
230
|
// FREE_USER_MAX_PARTICIPANTS_EXCEEDED
|
|
@@ -666,6 +689,11 @@ export const CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD: Record<number, Partial<ClientEv
|
|
|
666
689
|
category: 'expected',
|
|
667
690
|
fatal: true,
|
|
668
691
|
},
|
|
692
|
+
4104: {
|
|
693
|
+
errorDescription: ERROR_DESCRIPTIONS.USER_NOT_ALLOWED_JOIN_WEBINAR,
|
|
694
|
+
category: 'expected',
|
|
695
|
+
fatal: true,
|
|
696
|
+
},
|
|
669
697
|
2729: {
|
|
670
698
|
errorDescription: ERROR_DESCRIPTIONS.NO_MEDIA_FOUND,
|
|
671
699
|
category: 'expected',
|
package/src/index.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
SubmitClientEvent,
|
|
16
16
|
SubmitInternalEvent,
|
|
17
17
|
SubmitOperationalEvent,
|
|
18
|
+
SubmitBusinessEvent,
|
|
18
19
|
SubmitMQE,
|
|
19
20
|
PreComputedLatencies,
|
|
20
21
|
} from './metrics.types';
|
|
@@ -58,5 +59,6 @@ export type {
|
|
|
58
59
|
SubmitInternalEvent,
|
|
59
60
|
SubmitMQE,
|
|
60
61
|
SubmitOperationalEvent,
|
|
62
|
+
SubmitBusinessEvent,
|
|
61
63
|
PreComputedLatencies,
|
|
62
64
|
};
|
package/src/metrics.types.ts
CHANGED
|
@@ -16,11 +16,15 @@ export type ClientLaunchMethodType = NonNullable<
|
|
|
16
16
|
RawEvent['origin']['clientInfo']
|
|
17
17
|
>['clientLaunchMethod'];
|
|
18
18
|
|
|
19
|
+
export type ClientUserNameInput = NonNullable<RawClientEvent['userNameInput']>;
|
|
20
|
+
|
|
21
|
+
export type ClientEmailInput = NonNullable<RawClientEvent['emailInput']>;
|
|
22
|
+
|
|
19
23
|
export type BrowserLaunchMethodType = NonNullable<
|
|
20
24
|
RawEvent['origin']['clientInfo']
|
|
21
25
|
>['browserLaunchMethod'];
|
|
22
26
|
|
|
23
|
-
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm';
|
|
27
|
+
export type MetricEventProduct = 'webex' | 'wxcc_desktop' | 'wxcc_crm' | 'wxcc_sdk';
|
|
24
28
|
|
|
25
29
|
export type MetricEventAgent = 'user' | 'browser' | 'system' | 'sdk' | 'redux' | 'service' | 'api';
|
|
26
30
|
|
|
@@ -129,6 +133,8 @@ export type SubmitClientEventOptions = {
|
|
|
129
133
|
joinFlowVersion?: MetricEventJoinFlowVersion;
|
|
130
134
|
meetingJoinPhase?: MetricEventMeetingJoinPhase;
|
|
131
135
|
triggeredTime?: string;
|
|
136
|
+
emailInput?: ClientEmailInput;
|
|
137
|
+
userNameInput?: ClientUserNameInput;
|
|
132
138
|
};
|
|
133
139
|
|
|
134
140
|
export type SubmitMQEOptions = {
|
|
@@ -281,6 +287,13 @@ export type SubmitOperationalEvent = (args: {
|
|
|
281
287
|
payload: EventPayload;
|
|
282
288
|
}) => void;
|
|
283
289
|
|
|
290
|
+
export type SubmitBusinessEvent = (args: {
|
|
291
|
+
name: OperationalEvent['metricName'];
|
|
292
|
+
payload: EventPayload;
|
|
293
|
+
metadata?: EventPayload;
|
|
294
|
+
table?: Table;
|
|
295
|
+
}) => void;
|
|
296
|
+
|
|
284
297
|
export type SubmitMQE = (args: {
|
|
285
298
|
name: MediaQualityEvent['name'];
|
|
286
299
|
payload: SubmitMQEPayload;
|
package/src/new-metrics.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
InternalEvent,
|
|
23
23
|
SubmitClientEventOptions,
|
|
24
24
|
Table,
|
|
25
|
+
DelayedClientEvent,
|
|
25
26
|
} from './metrics.types';
|
|
26
27
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
27
28
|
import {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';
|
|
@@ -50,6 +51,11 @@ class Metrics extends WebexPlugin {
|
|
|
50
51
|
*/
|
|
51
52
|
delaySubmitClientEvents = false;
|
|
52
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
|
|
56
|
+
*/
|
|
57
|
+
delayedClientEventsOverrides: Partial<DelayedClientEvent['options']> = {};
|
|
58
|
+
|
|
53
59
|
/**
|
|
54
60
|
* Constructor
|
|
55
61
|
* @param args
|
|
@@ -74,6 +80,10 @@ class Metrics extends WebexPlugin {
|
|
|
74
80
|
// @ts-ignore
|
|
75
81
|
this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
|
|
76
82
|
this.isReady = true;
|
|
83
|
+
this.setDelaySubmitClientEvents({
|
|
84
|
+
shouldDelay: this.delaySubmitClientEvents,
|
|
85
|
+
overrides: this.delayedClientEventsOverrides,
|
|
86
|
+
});
|
|
77
87
|
});
|
|
78
88
|
}
|
|
79
89
|
|
|
@@ -404,13 +414,20 @@ class Metrics extends WebexPlugin {
|
|
|
404
414
|
* Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
|
|
405
415
|
* set to false, delayed client events will be submitted.
|
|
406
416
|
*
|
|
407
|
-
* @param {
|
|
417
|
+
* @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of client events, overrides: An object containing overrides for the client events}
|
|
408
418
|
*/
|
|
409
|
-
public setDelaySubmitClientEvents(
|
|
419
|
+
public setDelaySubmitClientEvents({
|
|
420
|
+
shouldDelay,
|
|
421
|
+
overrides,
|
|
422
|
+
}: {
|
|
423
|
+
shouldDelay: boolean;
|
|
424
|
+
overrides?: Partial<DelayedClientEvent['options']>;
|
|
425
|
+
}) {
|
|
410
426
|
this.delaySubmitClientEvents = shouldDelay;
|
|
427
|
+
this.delayedClientEventsOverrides = overrides || {};
|
|
411
428
|
|
|
412
|
-
if (!shouldDelay) {
|
|
413
|
-
return this.callDiagnosticMetrics.submitDelayedClientEvents();
|
|
429
|
+
if (this.isReady && !shouldDelay) {
|
|
430
|
+
return this.callDiagnosticMetrics.submitDelayedClientEvents(overrides);
|
|
414
431
|
}
|
|
415
432
|
|
|
416
433
|
return Promise.resolve();
|