@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.
@@ -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;
@@ -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 {boolean} shouldDelay - A boolean value indicating whether to delay the submission of client events.
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: boolean): Promise<any[]> | Promise<void>;
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.0",
30
- "@webex/test-helper-mocha": "3.8.0",
31
- "@webex/test-helper-mock-webex": "3.8.0",
32
- "@webex/test-helper-test-users": "3.8.0",
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.0",
39
- "@webex/common-timers": "3.8.0",
40
- "@webex/event-dictionary-ts": "^1.0.1688",
41
- "@webex/internal-plugin-metrics": "3.8.0",
42
- "@webex/test-helper-chai": "3.8.0",
43
- "@webex/test-helper-mock-webex": "3.8.0",
44
- "@webex/webex-core": "3.8.0",
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.0"
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
- // if Scheduled, Webinar, not pmr - then Webinar
170
- if (
171
- meetingInfo?.webexScheduled &&
172
- meetingInfo?.enableEvent &&
173
- !meetingInfo?.pmr &&
174
- meetingInfo?.isConvergedWebinar
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
- // if Scheduled, Webinar enable webcast - then webcast
179
- if (
180
- meetingInfo?.webexScheduled &&
181
- meetingInfo?.enableEvent &&
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
- return this.getErrorPayloadForClientErrorCode({
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
- return this.getErrorPayloadForClientErrorCode({
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
- return this.getErrorPayloadForClientErrorCode({
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
- return this.getErrorPayloadForClientErrorCode({
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
- return this.getErrorPayloadForClientErrorCode({
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
- return this.getErrorPayloadForClientErrorCode({
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
- return this.getErrorPayloadForClientErrorCode({
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
- // otherwise return unkown error but passing serviceErrorCode and serviceErrorName so that we know the issue
655
- return this.getErrorPayloadForClientErrorCode({
656
- clientErrorCode: UNKNOWN_ERROR,
657
- serviceErrorCode: serviceErrorCode || UNKNOWN_ERROR,
658
- serviceErrorName: rawError?.name,
659
- payloadOverrides: rawError.payloadOverrides,
660
- rawErrorMessage,
661
- httpStatusCode,
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
- return this.submitClientEvent(delayedSubmitClientEventParams);
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
  };
@@ -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;
@@ -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 {boolean} shouldDelay - A boolean value indicating whether to delay the submission of client events.
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(shouldDelay: boolean) {
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();