@webex/internal-plugin-metrics 3.7.0 → 3.8.0-next.10

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.
Files changed (41) hide show
  1. package/dist/business-metrics.js +74 -100
  2. package/dist/business-metrics.js.map +1 -1
  3. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +24 -15
  4. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +76 -10
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  7. package/dist/call-diagnostic/config.js +19 -12
  8. package/dist/call-diagnostic/config.js.map +1 -1
  9. package/dist/generic-metrics.js +2 -2
  10. package/dist/generic-metrics.js.map +1 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/metrics.js +1 -1
  13. package/dist/metrics.types.js.map +1 -1
  14. package/dist/new-metrics.js +28 -5
  15. package/dist/new-metrics.js.map +1 -1
  16. package/dist/types/business-metrics.d.ts +10 -28
  17. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +14 -1
  18. package/dist/types/call-diagnostic/config.d.ts +2 -0
  19. package/dist/types/generic-metrics.d.ts +2 -2
  20. package/dist/types/index.d.ts +2 -2
  21. package/dist/types/metrics.types.d.ts +17 -1
  22. package/dist/types/new-metrics.d.ts +15 -3
  23. package/package.json +12 -12
  24. package/src/business-metrics.ts +66 -76
  25. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +36 -14
  26. package/src/call-diagnostic/call-diagnostic-metrics.ts +80 -3
  27. package/src/call-diagnostic/config.ts +8 -0
  28. package/src/generic-metrics.ts +2 -2
  29. package/src/index.ts +2 -0
  30. package/src/metrics.types.ts +21 -1
  31. package/src/new-metrics.ts +32 -4
  32. package/test/unit/spec/business/business-metrics.ts +2 -2
  33. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +85 -0
  34. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +674 -32
  35. package/test/unit/spec/new-metrics.ts +23 -0
  36. package/dist/behavioral/behavioral-metrics.js +0 -199
  37. package/dist/behavioral/behavioral-metrics.js.map +0 -1
  38. package/dist/behavioral/config.js +0 -11
  39. package/dist/behavioral/config.js.map +0 -1
  40. package/dist/types/behavioral/behavioral-metrics.d.ts +0 -63
  41. package/dist/types/behavioral/config.d.ts +0 -1
@@ -1,51 +1,33 @@
1
1
  import GenericMetrics from './generic-metrics';
2
2
  import { EventPayload, Table } from './metrics.types';
3
3
  /**
4
- * @description Util class to handle Buisness Metrics
4
+ * @description Util class to handle Business Metrics
5
5
  * @export
6
6
  * @class BusinessMetrics
7
7
  */
8
8
  export default class BusinessMetrics extends GenericMetrics {
9
9
  /**
10
- * unfortunately, the pinot team does not allow changes to the schema of wbxapp_callend_metrics
11
- * so we have to shim this layer specifically for this
12
- * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Table+wbxapp_callend_metrics
13
- * @param {EventPayload} payload payload of the metric
14
- * @returns {Promise<any>}
15
- */
16
- private submitCallEndEvent;
17
- /**
18
- * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
19
- * all event payload keys are converted into a hex string value
20
- * unfortunately, the pinot team does not allow changes to the schema of business_metrics
21
- * so we have to shim this layer specifically for this
22
- * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Table%3A+business_metrics
23
- * @param {string} name of the metric
24
- * @param {EventPayload} payload payload of the metric
25
- * @returns {Promise<any>}
26
- */
27
- private submitBusinessMetricsEvent;
28
- /**
29
- * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
30
- * all event payload keys are converted into a hex string value
31
- * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Business+metrics++-%3E+ROMA
10
+ * Build the metric event to submit.
32
11
  * @param {string} name of the metric
33
- * @param {EventPayload} user payload of the metric
34
- * @returns {Promise<any>}
12
+ * @param {EventPayload} payload user payload of the metric
13
+ * @param {EventPayload} metadata to include outside of eventPayload.value
14
+ * @returns {MetricEvent} The constructed metric event
35
15
  */
36
- private submitDefaultEvent;
16
+ private buildEvent;
37
17
  /**
38
- * Submit a buisness metric to our metrics endpoint.
18
+ * Submit a business metric to our metrics endpoint.
39
19
  * routes to the correct table with the correct schema payload by table
40
20
  * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Business+metrics++-%3E+ROMA
41
21
  * @param {string} name of the metric, ignored if going to wbxapp_callend_metrics
42
22
  * @param {EventPayload} payload user payload of the metric
43
23
  * @param {Table} table optional - to submit the metric to and adapt the sent schema
24
+ * @param {EventPayload} metadata optional - to include outside of eventPayload.value
44
25
  * @returns {Promise<any>}
45
26
  */
46
- submitBusinessEvent({ name, payload, table, }: {
27
+ submitBusinessEvent({ name, payload, table, metadata, }: {
47
28
  name: string;
48
29
  payload: EventPayload;
49
30
  table?: Table;
31
+ metadata?: EventPayload;
50
32
  }): Promise<void>;
51
33
  }
@@ -29,6 +29,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
29
29
  private logger;
30
30
  private hasLoggedBrowserSerial;
31
31
  private device;
32
+ private delayedClientEvents;
32
33
  validator: (options: {
33
34
  type: 'mqe' | 'ce';
34
35
  event: Event;
@@ -196,6 +197,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
196
197
  provisionalCorrelationId?: string;
197
198
  roomId?: string;
198
199
  sessionCorrelationId?: string;
200
+ sharedMediaId?: string;
199
201
  sipCallId?: string;
200
202
  sipSessionId?: {
201
203
  local?: string;
@@ -223,6 +225,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
223
225
  webexSiteUuid?: string;
224
226
  webexUserId?: number;
225
227
  webexWebDomain?: string;
228
+ recordingId?: string;
229
+ clientCorrelationId?: string;
226
230
  correlationId: string;
227
231
  additionalProperties?: false;
228
232
  } | {
@@ -276,6 +280,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
276
280
  provisionalCorrelationId?: string;
277
281
  roomId?: string;
278
282
  sessionCorrelationId?: string;
283
+ sharedMediaId?: string;
279
284
  sipCallId?: string;
280
285
  sipSessionId?: {
281
286
  local?: string;
@@ -303,6 +308,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
303
308
  webexSiteUuid?: string;
304
309
  webexUserId?: number;
305
310
  webexWebDomain?: string;
311
+ recordingId?: string;
312
+ clientCorrelationId?: string;
306
313
  correlationId: string;
307
314
  additionalProperties?: false;
308
315
  };
@@ -401,13 +408,19 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
401
408
  * @param arg.event - event key
402
409
  * @param arg.payload - additional payload to be merged with default payload
403
410
  * @param arg.options - payload
411
+ * @param arg.delaySubmitEvent - a boolean value indicating whether to delay the submission of client events.
404
412
  * @throws
405
413
  */
406
- submitClientEvent({ name, payload, options, }: {
414
+ submitClientEvent({ name, payload, options, delaySubmitEvent, }: {
407
415
  name: ClientEvent['name'];
408
416
  payload?: ClientEventPayload;
409
417
  options?: SubmitClientEventOptions;
418
+ delaySubmitEvent?: boolean;
410
419
  }): Promise<any>;
420
+ /**
421
+ * Submit Delayed Client Event CA events. Clears delayedClientEvents array after submission.
422
+ */
423
+ submitDelayedClientEvents(): Promise<any[]> | Promise<void>;
411
424
  /**
412
425
  * Prepare the event and send the request to metrics-a service.
413
426
  * @param event
@@ -11,6 +11,7 @@ export declare const DTLS_HANDSHAKE_FAILED_CLIENT_CODE = 2008;
11
11
  export declare const ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE = 2010;
12
12
  export declare const ICE_FAILED_WITHOUT_TURN_TLS_CLIENT_CODE = 2009;
13
13
  export declare const ICE_AND_REACHABILITY_FAILED_CLIENT_CODE = 2011;
14
+ export declare const MULTISTREAM_NOT_AVAILABLE_CLIENT_CODE = 2012;
14
15
  export declare const WBX_APP_API_URL = "wbxappapi";
15
16
  export declare const WEBEX_SUB_SERVICE_TYPES: Record<string, ClientSubServiceType>;
16
17
  export declare const BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP: {
@@ -94,6 +95,7 @@ export declare const ERROR_DESCRIPTIONS: {
94
95
  ICE_FAILED_WITHOUT_TURN_TLS: string;
95
96
  ICE_FAILED_WITH_TURN_TLS: string;
96
97
  ICE_AND_REACHABILITY_FAILED: string;
98
+ MULTISTREAM_NOT_AVAILABLE: string;
97
99
  SDP_OFFER_CREATION_ERROR: string;
98
100
  SDP_OFFER_CREATION_ERROR_MISSING_CODEC: string;
99
101
  WDM_RESTRICTED_REGION: string;
@@ -17,7 +17,7 @@ export default abstract class GenericMetrics extends StatelessWebexPlugin {
17
17
  */
18
18
  constructor(...args: any[]);
19
19
  /**
20
- * Submit a buisness metric to our metrics endpoint.
20
+ * Submit a business metric to our metrics endpoint.
21
21
  * @param {string} kind of metric for logging
22
22
  * @param {string} name of the metric
23
23
  * @param {object} event
@@ -44,7 +44,7 @@ export default abstract class GenericMetrics extends StatelessWebexPlugin {
44
44
  */
45
45
  protected getBrowserDetails(): object;
46
46
  /**
47
- * Returns true once we have the deviceId we need to submit behavioral/operational/buisness events
47
+ * Returns true once we have the deviceId we need to submit behavioral/operational/business events
48
48
  * @returns {boolean}
49
49
  */
50
50
  isReadyToSubmitEvents(): boolean;
@@ -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,11 +6,14 @@ 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';
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';
16
+ export type MetricEventMeetingJoinPhase = 'pre-join' | 'join' | 'in-meeting';
14
17
  export type SubmitClientEventOptions = {
15
18
  meetingId?: string;
16
19
  mediaConnections?: any[];
@@ -25,6 +28,10 @@ export type SubmitClientEventOptions = {
25
28
  webexConferenceIdStr?: string;
26
29
  globalMeetingId?: string;
27
30
  joinFlowVersion?: MetricEventJoinFlowVersion;
31
+ meetingJoinPhase?: MetricEventMeetingJoinPhase;
32
+ triggeredTime?: string;
33
+ emailInput?: ClientEmailInput;
34
+ userNameInput?: ClientUserNameInput;
28
35
  };
29
36
  export type SubmitMQEOptions = {
30
37
  meetingId: string;
@@ -129,6 +136,10 @@ export type SubmitOperationalEvent = (args: {
129
136
  name: OperationalEvent['metricName'];
130
137
  payload: EventPayload;
131
138
  }) => void;
139
+ export type SubmitBusinessEvent = (args: {
140
+ name: OperationalEvent['metricName'];
141
+ payload: EventPayload;
142
+ }) => void;
132
143
  export type SubmitMQE = (args: {
133
144
  name: MediaQualityEvent['name'];
134
145
  payload: SubmitMQEPayload;
@@ -154,4 +165,9 @@ export interface IMetricsAttributes {
154
165
  meetingId?: string;
155
166
  callId?: string;
156
167
  }
168
+ export interface DelayedClientEvent {
169
+ name: ClientEvent['name'];
170
+ payload?: RecursivePartial<ClientEvent['payload']>;
171
+ options?: SubmitClientEventOptions;
172
+ }
157
173
  export {};
@@ -18,6 +18,10 @@ declare class Metrics extends WebexPlugin {
18
18
  operationalMetrics: OperationalMetrics;
19
19
  businessMetrics: BusinessMetrics;
20
20
  isReady: boolean;
21
+ /**
22
+ * Whether or not to delay the submission of client events.
23
+ */
24
+ delaySubmitClientEvents: boolean;
21
25
  /**
22
26
  * Constructor
23
27
  * @param args
@@ -60,7 +64,7 @@ declare class Metrics extends WebexPlugin {
60
64
  */
61
65
  isReadyToSubmitOperationalEvents(): boolean;
62
66
  /**
63
- * @returns true once we have the deviceId we need to submit buisness events
67
+ * @returns true once we have the deviceId we need to submit business events
64
68
  */
65
69
  isReadyToSubmitBusinessEvents(): boolean;
66
70
  /**
@@ -83,13 +87,14 @@ declare class Metrics extends WebexPlugin {
83
87
  payload?: EventPayload;
84
88
  }): void | Promise<void>;
85
89
  /**
86
- * Buisness event
90
+ * Business event
87
91
  * @param args
88
92
  */
89
- submitBusinessEvent({ name, payload, table, }: {
93
+ submitBusinessEvent({ name, payload, table, metadata, }: {
90
94
  name: string;
91
95
  payload: EventPayload;
92
96
  table?: Table;
97
+ metadata?: EventPayload;
93
98
  }): Promise<void>;
94
99
  /**
95
100
  * Call Analyzer: Media Quality Event
@@ -169,5 +174,12 @@ declare class Metrics extends WebexPlugin {
169
174
  * @returns {boolean}
170
175
  */
171
176
  isServiceErrorExpected(serviceErrorCode: number): boolean;
177
+ /**
178
+ * Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
179
+ * set to false, delayed client events will be submitted.
180
+ *
181
+ * @param {boolean} shouldDelay - A boolean value indicating whether to delay the submission of client events.
182
+ */
183
+ setDelaySubmitClientEvents(shouldDelay: boolean): Promise<any[]> | Promise<void>;
172
184
  }
173
185
  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.7.0",
30
- "@webex/test-helper-mocha": "3.7.0",
31
- "@webex/test-helper-mock-webex": "3.7.0",
32
- "@webex/test-helper-test-users": "3.7.0",
29
+ "@webex/test-helper-chai": "3.8.0-next.10",
30
+ "@webex/test-helper-mocha": "3.8.0-next.10",
31
+ "@webex/test-helper-mock-webex": "3.8.0-next.10",
32
+ "@webex/test-helper-test-users": "3.8.0-next.10",
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.7.0",
39
- "@webex/common-timers": "3.7.0",
40
- "@webex/event-dictionary-ts": "^1.0.1594",
41
- "@webex/internal-plugin-metrics": "3.7.0",
42
- "@webex/test-helper-chai": "3.7.0",
43
- "@webex/test-helper-mock-webex": "3.7.0",
44
- "@webex/webex-core": "3.7.0",
38
+ "@webex/common": "3.8.0-next.10",
39
+ "@webex/common-timers": "3.8.0-next.10",
40
+ "@webex/event-dictionary-ts": "^1.0.1688",
41
+ "@webex/internal-plugin-metrics": "3.8.0-next.10",
42
+ "@webex/test-helper-chai": "3.8.0-next.10",
43
+ "@webex/test-helper-mock-webex": "3.8.0-next.10",
44
+ "@webex/webex-core": "3.8.0-next.10",
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.7.0"
57
+ "version": "3.8.0-next.10"
58
58
  }
@@ -2,121 +2,111 @@ import GenericMetrics from './generic-metrics';
2
2
  import {EventPayload, Table} from './metrics.types';
3
3
 
4
4
  /**
5
- * @description Util class to handle Buisness Metrics
5
+ * @description Util class to handle Business Metrics
6
6
  * @export
7
7
  * @class BusinessMetrics
8
8
  */
9
9
  export default class BusinessMetrics extends GenericMetrics {
10
10
  /**
11
- * unfortunately, the pinot team does not allow changes to the schema of wbxapp_callend_metrics
12
- * so we have to shim this layer specifically for this
13
- * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Table+wbxapp_callend_metrics
14
- * @param {EventPayload} payload payload of the metric
15
- * @returns {Promise<any>}
16
- */
17
- private submitCallEndEvent({payload}: {payload: EventPayload}) {
18
- const event = {
19
- type: ['business'],
20
- eventPayload: {
21
- key: 'callEnd',
22
- client_timestamp: new Date().toISOString(),
23
- appType: 'Web Client',
24
- value: {
25
- ...payload,
26
- },
27
- },
28
- };
29
-
30
- return this.submitEvent({
31
- kind: 'buisness-events:wbxapp_callend_metrics -> ',
32
- name: 'wbxapp_callend_metrics',
33
- event,
34
- });
35
- }
36
-
37
- /**
38
- * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
39
- * all event payload keys are converted into a hex string value
40
- * unfortunately, the pinot team does not allow changes to the schema of business_metrics
41
- * so we have to shim this layer specifically for this
42
- * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Table%3A+business_metrics
11
+ * Build the metric event to submit.
43
12
  * @param {string} name of the metric
44
- * @param {EventPayload} payload payload of the metric
45
- * @returns {Promise<any>}
46
- */
47
- private submitBusinessMetricsEvent({name, payload}: {name: string; payload: EventPayload}) {
48
- const event = {
49
- type: ['business'],
50
- eventPayload: {
51
- key: name,
52
- client_timestamp: new Date().toISOString(),
53
- appType: 'Web Client',
54
- value: {
55
- ...this.getContext(),
56
- ...this.getBrowserDetails(),
57
- ...payload,
58
- },
59
- },
60
- };
61
-
62
- return this.submitEvent({kind: 'buisness-events:business_metrics -> ', name, event});
63
- }
64
-
65
- /**
66
- * Submit a buisness metric to our metrics endpoint, going to the default business_ucf table
67
- * all event payload keys are converted into a hex string value
68
- * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Business+metrics++-%3E+ROMA
69
- * @param {string} name of the metric
70
- * @param {EventPayload} user payload of the metric
71
- * @returns {Promise<any>}
13
+ * @param {EventPayload} payload user payload of the metric
14
+ * @param {EventPayload} metadata to include outside of eventPayload.value
15
+ * @returns {MetricEvent} The constructed metric event
72
16
  */
73
- private submitDefaultEvent({name, payload}: {name: string; payload: EventPayload}) {
74
- const event = {
17
+ private buildEvent({name, payload, metadata}: {name: string; payload: object; metadata: object}) {
18
+ return {
75
19
  type: ['business'],
76
20
  eventPayload: {
77
21
  key: name,
78
- appType: 'Web Client',
79
22
  client_timestamp: new Date().toISOString(),
80
- context: this.getContext(),
81
- browserDetails: this.getBrowserDetails(),
23
+ ...metadata,
82
24
  value: payload,
83
25
  },
84
26
  };
85
-
86
- return this.submitEvent({kind: 'buisness-events:default -> ', name, event});
87
27
  }
88
28
 
89
29
  /**
90
- * Submit a buisness metric to our metrics endpoint.
30
+ * Submit a business metric to our metrics endpoint.
91
31
  * routes to the correct table with the correct schema payload by table
92
32
  * https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Business+metrics++-%3E+ROMA
93
33
  * @param {string} name of the metric, ignored if going to wbxapp_callend_metrics
94
34
  * @param {EventPayload} payload user payload of the metric
95
35
  * @param {Table} table optional - to submit the metric to and adapt the sent schema
36
+ * @param {EventPayload} metadata optional - to include outside of eventPayload.value
96
37
  * @returns {Promise<any>}
97
38
  */
98
39
  public submitBusinessEvent({
99
40
  name,
100
41
  payload,
101
42
  table,
43
+ metadata,
102
44
  }: {
103
45
  name: string;
104
46
  payload: EventPayload;
105
47
  table?: Table;
48
+ metadata?: EventPayload;
106
49
  }): Promise<void> {
107
50
  if (!table) {
108
51
  table = 'default';
109
52
  }
53
+ if (!metadata) {
54
+ metadata = {};
55
+ }
56
+ if (!metadata.appType) {
57
+ metadata.appType = 'Web Client';
58
+ }
110
59
  switch (table) {
111
- case 'wbxapp_callend_metrics':
112
- return this.submitCallEndEvent({payload});
113
- case 'business_metrics':
114
- return this.submitBusinessMetricsEvent({name, payload});
60
+ case 'wbxapp_callend_metrics': {
61
+ // https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Table+wbxapp_callend_metrics
62
+ const callEndEvent = this.buildEvent({name: 'callEnd', payload, metadata});
63
+
64
+ return this.submitEvent({
65
+ kind: 'business-events:wbxapp_callend_metrics -> ',
66
+ name: 'wbxapp_callend_metrics',
67
+ event: callEndEvent,
68
+ });
69
+ }
70
+
71
+ case 'business_metrics': {
72
+ // all event payload keys are converted into a hex string value
73
+ // unfortunately, the pinot team does not allow changes to the schema of business_metrics
74
+ // so we have to shim this layer specifically for this
75
+ // https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Table%3A+business_metrics
76
+ const businessEvent = this.buildEvent({
77
+ name,
78
+ payload: {
79
+ ...this.getContext(),
80
+ ...this.getBrowserDetails(),
81
+ ...payload,
82
+ },
83
+ metadata,
84
+ });
85
+
86
+ return this.submitEvent({
87
+ kind: 'business-events:business_metrics -> ',
88
+ name,
89
+ event: businessEvent,
90
+ });
91
+ }
92
+
115
93
  case 'business_ucf':
116
- return this.submitDefaultEvent({name, payload});
117
94
  case 'default':
118
- default:
119
- return this.submitDefaultEvent({name, payload});
95
+ default: {
96
+ // all event payload keys are converted into a hex string value
97
+ // https://confluence-eng-gpk2.cisco.com/conf/display/WAP/Business+metrics++-%3E+ROMA
98
+ const defaultEvent = this.buildEvent({
99
+ name,
100
+ payload,
101
+ metadata: {
102
+ context: this.getContext(),
103
+ browserDetails: this.getBrowserDetails(),
104
+ ...metadata,
105
+ },
106
+ });
107
+
108
+ return this.submitEvent({kind: 'business-events:default -> ', name, event: defaultEvent});
109
+ }
120
110
  }
121
111
  }
122
112
  }
@@ -83,11 +83,16 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
83
83
  key === 'client.media.rx.start' ||
84
84
  key === 'client.media.tx.start' ||
85
85
  key === 'internal.client.meetinginfo.request' ||
86
- key === 'internal.client.meetinginfo.response'
86
+ key === 'internal.client.meetinginfo.response' ||
87
+ key === 'client.media-engine.remote-sdp-received'
87
88
  ) {
88
89
  this.saveFirstTimestampOnly(key, value);
89
90
  } else {
90
91
  this.latencyTimestamps.set(key, value);
92
+ // new offer/answer so reset the remote SDP timestamp
93
+ if (key === 'client.media-engine.local-sdp-generated') {
94
+ this.latencyTimestamps.delete('client.media-engine.remote-sdp-received');
95
+ }
91
96
  }
92
97
  }
93
98
 
@@ -146,7 +151,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
146
151
  public getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames) {
147
152
  const start = this.latencyTimestamps.get(a);
148
153
  const end = this.latencyTimestamps.get(b);
149
- if (start && end) {
154
+
155
+ if (typeof start === 'number' && typeof end === 'number') {
150
156
  return end - start;
151
157
  }
152
158
 
@@ -188,7 +194,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
188
194
  public getU2CTime() {
189
195
  const u2cLatency = this.precomputedLatencies.get('internal.get.u2c.time');
190
196
 
191
- return u2cLatency ? Math.floor(u2cLatency) : undefined;
197
+ return typeof u2cLatency === 'number' ? Math.floor(u2cLatency) : undefined;
192
198
  }
193
199
 
194
200
  /**
@@ -291,7 +297,9 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
291
297
  * @returns - latency
292
298
  */
293
299
  public getPageJMT() {
294
- return this.precomputedLatencies.get('internal.client.pageJMT') || undefined;
300
+ const latency = this.precomputedLatencies.get('internal.client.pageJMT');
301
+
302
+ return typeof latency === 'number' ? latency : undefined;
295
303
  }
296
304
 
297
305
  /**
@@ -299,7 +307,9 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
299
307
  * @returns - latency
300
308
  */
301
309
  public getDownloadTimeJMT() {
302
- return this.precomputedLatencies.get('internal.download.time') || undefined;
310
+ const latency = this.precomputedLatencies.get('internal.download.time');
311
+
312
+ return typeof latency === 'number' ? latency : undefined;
303
313
  }
304
314
 
305
315
  /**
@@ -315,8 +325,15 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
315
325
  );
316
326
  }
317
327
 
318
- // for cross launch and guest flows
319
- return this.precomputedLatencies.get('internal.click.to.interstitial') || undefined;
328
+ const clickToInterstitialLatency = this.precomputedLatencies.get(
329
+ 'internal.click.to.interstitial'
330
+ );
331
+
332
+ if (typeof clickToInterstitialLatency === 'number') {
333
+ return clickToInterstitialLatency;
334
+ }
335
+
336
+ return undefined;
320
337
  }
321
338
 
322
339
  /**
@@ -353,7 +370,8 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
353
370
  // get the first timestamp
354
371
  const connectedMedia = this.latencyTimestamps.get('client.ice.end');
355
372
 
356
- const lobbyTime = this.getStayLobbyTime() || 0;
373
+ const lobbyTimeLatency = this.getStayLobbyTime();
374
+ const lobbyTime = typeof lobbyTimeLatency === 'number' ? lobbyTimeLatency : 0;
357
375
 
358
376
  if (interstitialJoinClickTimestamp && connectedMedia) {
359
377
  return connectedMedia - interstitialJoinClickTimestamp - lobbyTime;
@@ -370,7 +388,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
370
388
  const clickToInterstitial = this.getClickToInterstitial();
371
389
  const interstitialToJoinOk = this.getInterstitialToJoinOK();
372
390
 
373
- if (clickToInterstitial && interstitialToJoinOk) {
391
+ if (typeof clickToInterstitial === 'number' && typeof interstitialToJoinOk === 'number') {
374
392
  return clickToInterstitial + interstitialToJoinOk;
375
393
  }
376
394
 
@@ -422,7 +440,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
422
440
  const interstitialToJoinOk = this.getInterstitialToJoinOK();
423
441
  const joinConfJMT = this.getJoinConfJMT();
424
442
 
425
- if (interstitialToJoinOk && joinConfJMT) {
443
+ if (typeof interstitialToJoinOk === 'number' && typeof joinConfJMT === 'number') {
426
444
  return interstitialToJoinOk - joinConfJMT;
427
445
  }
428
446
 
@@ -449,7 +467,9 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
449
467
  public getReachabilityClustersReqResp() {
450
468
  const reachablityClusterReqResp = this.precomputedLatencies.get('internal.get.cluster.time');
451
469
 
452
- return reachablityClusterReqResp ? Math.floor(reachablityClusterReqResp) : undefined;
470
+ return typeof reachablityClusterReqResp === 'number'
471
+ ? Math.floor(reachablityClusterReqResp)
472
+ : undefined;
453
473
  }
454
474
 
455
475
  /**
@@ -472,7 +492,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
472
492
  public getExchangeCITokenJMT() {
473
493
  const exchangeCITokenJMT = this.precomputedLatencies.get('internal.exchange.ci.token.time');
474
494
 
475
- return exchangeCITokenJMT ? Math.floor(exchangeCITokenJMT) : undefined;
495
+ return typeof exchangeCITokenJMT === 'number' ? Math.floor(exchangeCITokenJMT) : undefined;
476
496
  }
477
497
 
478
498
  /**
@@ -481,7 +501,9 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
481
501
  public getRefreshCaptchaReqResp() {
482
502
  const refreshCaptchaReqResp = this.precomputedLatencies.get('internal.refresh.captcha.time');
483
503
 
484
- return refreshCaptchaReqResp ? Math.floor(refreshCaptchaReqResp) : undefined;
504
+ return typeof refreshCaptchaReqResp === 'number'
505
+ ? Math.floor(refreshCaptchaReqResp)
506
+ : undefined;
485
507
  }
486
508
 
487
509
  /**
@@ -493,7 +515,7 @@ export default class CallDiagnosticLatencies extends WebexPlugin {
493
515
  'internal.api.fetch.intelligence.models'
494
516
  );
495
517
 
496
- return downloadIntelligenceModelsReqResp
518
+ return typeof downloadIntelligenceModelsReqResp === 'number'
497
519
  ? Math.floor(downloadIntelligenceModelsReqResp)
498
520
  : undefined;
499
521
  }