@webex/internal-plugin-metrics 3.0.0-beta.24 → 3.0.0-beta.241

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 (60) hide show
  1. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +66 -0
  2. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -0
  3. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +446 -0
  4. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -0
  5. package/dist/call-diagnostic/call-diagnostic-metrics.js +704 -0
  6. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -0
  7. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +281 -0
  8. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -0
  9. package/dist/call-diagnostic/config.js +582 -0
  10. package/dist/call-diagnostic/config.js.map +1 -0
  11. package/dist/config.js +20 -1
  12. package/dist/config.js.map +1 -1
  13. package/dist/index.js +30 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/metrics.js +30 -30
  16. package/dist/metrics.js.map +1 -1
  17. package/dist/metrics.types.js +7 -0
  18. package/dist/metrics.types.js.map +1 -0
  19. package/dist/new-metrics.js +323 -0
  20. package/dist/new-metrics.js.map +1 -0
  21. package/dist/types/batcher.d.ts +2 -0
  22. package/dist/types/call-diagnostic/call-diagnostic-metrics-batcher.d.ts +2 -0
  23. package/dist/types/call-diagnostic/call-diagnostic-metrics-latencies.d.ts +189 -0
  24. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +385 -0
  25. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +73 -0
  26. package/dist/types/call-diagnostic/config.d.ts +87 -0
  27. package/dist/types/client-metrics-batcher.d.ts +2 -0
  28. package/dist/types/config.d.ts +35 -0
  29. package/dist/types/index.d.ts +13 -0
  30. package/dist/types/metrics.d.ts +3 -0
  31. package/dist/types/metrics.types.d.ts +99 -0
  32. package/dist/types/new-metrics.d.ts +133 -0
  33. package/dist/types/utils.d.ts +6 -0
  34. package/dist/utils.js +27 -0
  35. package/dist/utils.js.map +1 -0
  36. package/package.json +13 -8
  37. package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +80 -0
  38. package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +403 -0
  39. package/src/call-diagnostic/call-diagnostic-metrics.ts +762 -0
  40. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +291 -0
  41. package/src/call-diagnostic/config.ts +580 -0
  42. package/src/config.js +19 -0
  43. package/src/index.ts +43 -0
  44. package/src/metrics.js +25 -27
  45. package/src/metrics.types.ts +152 -0
  46. package/src/new-metrics.ts +314 -0
  47. package/src/utils.ts +17 -0
  48. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +398 -0
  49. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +465 -0
  50. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +1303 -0
  51. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +479 -0
  52. package/test/unit/spec/metrics.js +65 -97
  53. package/test/unit/spec/new-metrics.ts +269 -0
  54. package/test/unit/spec/utils.ts +22 -0
  55. package/tsconfig.json +6 -0
  56. package/dist/call-diagnostic-events-batcher.js +0 -60
  57. package/dist/call-diagnostic-events-batcher.js.map +0 -1
  58. package/src/call-diagnostic-events-batcher.js +0 -62
  59. package/src/index.js +0 -17
  60. package/test/unit/spec/call-diagnostic-events-batcher.js +0 -195
@@ -0,0 +1 @@
1
+ {"version":3,"names":["Metrics","args","onReady","webex","once","callDiagnosticMetrics","CallDiagnosticMetrics","parent","callDiagnosticLatencies","CallDiagnosticLatencies","name","payload","options","clearTimestamps","saveTimestamp","key","Error","submitMQE","logger","log","resolve","meetingId","submitClientEvent","preLoginId","request","method","api","resource","headers","authorization","body","metrics","then","res","catch","err","error","generateCommonErrorMetadata","reject","qs","alias","buildClientEventFetchRequestOptions","setTimingsAndFetch","setMetricTimings","WebexPlugin"],"sources":["new-metrics.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unused-vars */\n/* eslint-disable class-methods-use-this */\n/* eslint-disable valid-jsdoc */\n\n// @ts-ignore\nimport {WebexPlugin} from '@webex/webex-core';\n\nimport CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';\nimport {\n RecursivePartial,\n ClientEvent,\n FeatureEvent,\n BehavioralEvent,\n OperationalEvent,\n MediaQualityEvent,\n InternalEvent,\n SubmitClientEventOptions,\n} from './metrics.types';\nimport CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';\nimport {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';\nimport {generateCommonErrorMetadata} from './utils';\n\n/**\n * Metrics plugin to centralize all types of metrics.\n * @class\n */\nclass Metrics extends WebexPlugin {\n // eslint-disable-next-line no-use-before-define\n static instance: Metrics;\n\n // Call Diagnostic latencies\n callDiagnosticLatencies: CallDiagnosticLatencies;\n // Helper classes to handle the different types of metrics\n callDiagnosticMetrics: CallDiagnosticMetrics;\n\n /**\n * Constructor\n * @param args\n * @constructor\n * @private\n * @returns\n */\n constructor(...args) {\n super(...args);\n\n this.onReady();\n }\n\n /**\n * On Ready\n */\n private onReady() {\n // @ts-ignore\n this.webex.once('ready', () => {\n // @ts-ignore\n this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});\n // @ts-ignore\n this.callDiagnosticLatencies = new CallDiagnosticLatencies({}, {parent: this.webex});\n });\n }\n\n /**\n * Used for internal purposes only\n * @param args\n */\n submitInternalEvent({\n name,\n payload,\n options,\n }: {\n name: InternalEvent['name'];\n payload?: RecursivePartial<InternalEvent['payload']>;\n options?: any;\n }) {\n if (name === 'internal.reset.join.latencies') {\n this.callDiagnosticLatencies.clearTimestamps();\n } else {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n }\n }\n\n /**\n * Behavioral event\n * @param args\n */\n submitBehavioralEvent({\n name,\n payload,\n options,\n }: {\n name: BehavioralEvent['name'];\n payload?: RecursivePartial<BehavioralEvent['payload']>;\n options?: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n throw new Error('Not implemented.');\n }\n\n /**\n * Operational event\n * @param args\n */\n submitOperationalEvent({\n name,\n payload,\n options,\n }: {\n name: OperationalEvent['name'];\n payload?: RecursivePartial<OperationalEvent['payload']>;\n options?: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Media Quality Event\n * @param args\n */\n submitMQE({\n name,\n payload,\n options,\n }: {\n name: MediaQualityEvent['name'];\n payload: RecursivePartial<MediaQualityEvent['payload']> & {\n intervals: MediaQualityEvent['payload']['intervals'];\n };\n options: any;\n }) {\n this.callDiagnosticLatencies.saveTimestamp({key: name});\n this.callDiagnosticMetrics.submitMQE({name, payload, options});\n }\n\n /**\n * Call Analyzer: Feature Usage Event\n * @param args\n */\n submitFeatureEvent({\n name,\n payload,\n options,\n }: {\n name: FeatureEvent['name'];\n payload?: RecursivePartial<FeatureEvent['payload']>;\n options: any;\n }) {\n throw new Error('Not implemented.');\n }\n\n /**\n * Call Analyzer: Client Event\n * @public\n * @param args\n */\n public submitClientEvent({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n if (!this.callDiagnosticLatencies || !this.callDiagnosticMetrics) {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @submitClientEvent. Attempted to submit before webex.ready. Event name: ${name}`\n );\n\n return Promise.resolve();\n }\n this.callDiagnosticLatencies.saveTimestamp({\n key: name,\n options: {meetingId: options?.meetingId},\n });\n\n return this.callDiagnosticMetrics.submitClientEvent({name, payload, options});\n }\n\n /**\n * Submit a pre-login metric to clientmetrics\n * @public\n * @param payload\n * @param preLoginId - pre-login ID of user\n * @returns\n */\n public postPreLoginMetric(payload: any, preLoginId: string): Promise<any> {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics-prelogin',\n headers: {\n authorization: false,\n 'x-prelogin-userid': preLoginId,\n },\n body: {\n metrics: [payload],\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @postPreLoginMetric. Request successful:`,\n `res: ${JSON.stringify(res)}`\n );\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @postPreLoginMetric. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Issue request to alias a user's pre-login ID with their CI UUID\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n public clientMetricsAliasUser(preLoginId: string) {\n // @ts-ignore\n return this.webex\n .request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics',\n headers: {\n 'x-prelogin-userid': preLoginId,\n },\n body: {},\n qs: {\n alias: true,\n },\n })\n .then((res) => {\n // @ts-ignore\n this.webex.logger.log(\n `NewMetrics: @clientMetricsAliasUser. Request successful:`,\n `res: ${JSON.stringify(res)}`\n );\n\n return res;\n })\n .catch((err) => {\n // @ts-ignore\n this.logger.error(\n `NewMetrics: @clientMetricsAliasUser. Request failed:`,\n `err: ${generateCommonErrorMetadata(err)}`\n );\n\n return Promise.reject(err);\n });\n }\n\n /**\n * Returns a promise that will resolve to fetch options for submitting a metric.\n *\n * This is to support quickly submitting metrics when the browser/tab is closing.\n * Calling submitClientEvent will not work because there some async steps that will\n * not complete before the browser is closed. Instead, we pre-gather all the\n * information/options needed for the request(s), and then simply and quickly\n * fire the fetch(es) when beforeUnload is triggered.\n *\n * We must use fetch instead of request because fetch has a keepalive option that\n * allows the request it to outlive the page.\n *\n * Note: the timings values will be wrong, but setMetricTimingsAndFetch() will\n * properly adjust them before submitting.\n *\n * @public\n * @param {Object} arg\n * @param {String} arg.name - event name\n * @param {Object} arg.payload - event payload\n * @param {Object} arg.options - other options\n * @returns {Promise} promise that resolves to options to be used with fetch\n */\n public async buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n }: {\n name: ClientEvent['name'];\n payload?: RecursivePartial<ClientEvent['payload']>;\n options?: SubmitClientEventOptions;\n }): Promise<any> {\n return this.callDiagnosticMetrics.buildClientEventFetchRequestOptions({\n name,\n payload,\n options,\n });\n }\n\n /**\n * Submits a metric from pre-built request options via the fetch API. Updates\n * the \"$timings\" and \"originTime\" values to Date.now() since the existing times\n * were set when the options were built (not submitted).\n\n * @param {any} options - the pre-built request options for submitting a metric\n * @returns {Promise} promise that resolves to the response object\n */\n public setMetricTimingsAndFetch(options: any): Promise<any> {\n // @ts-ignore\n return this.webex.setTimingsAndFetch(setMetricTimings(options));\n }\n}\n\nexport default Metrics;\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export default MetricsBatcher;
2
+ declare const MetricsBatcher: any;
@@ -0,0 +1,2 @@
1
+ declare const CallDiagnosticEventsBatcher: any;
2
+ export default CallDiagnosticEventsBatcher;
@@ -0,0 +1,189 @@
1
+ import { WebexPlugin } from '@webex/webex-core';
2
+ import { MetricEventNames } from '../metrics.types';
3
+ /**
4
+ * @description Helper class to store latencies timestamp and to calculate various latencies for CA.
5
+ * @exports
6
+ * @class CallDiagnosticLatencies
7
+ */
8
+ export default class CallDiagnosticLatencies extends WebexPlugin {
9
+ latencyTimestamps: Map<MetricEventNames, number>;
10
+ precomputedLatencies: Map<string, number>;
11
+ private meetingId?;
12
+ /**
13
+ * @constructor
14
+ */
15
+ constructor(...args: any[]);
16
+ /**
17
+ * Clear timestamps
18
+ */
19
+ clearTimestamps(): void;
20
+ /**
21
+ * Associate current latencies with a meeting id
22
+ * @param meetingId
23
+ */
24
+ private setMeetingId;
25
+ /**
26
+ * Returns the meeting object associated with current latencies
27
+ * @returns meeting object
28
+ */
29
+ private getMeeting;
30
+ /**
31
+ * Store timestamp value
32
+ * @param key - key
33
+ * @param value -value
34
+ * @throws
35
+ * @returns
36
+ */
37
+ saveTimestamp({ key, value, options, }: {
38
+ key: MetricEventNames;
39
+ value?: number;
40
+ options?: {
41
+ meetingId?: string;
42
+ };
43
+ }): void;
44
+ /**
45
+ * Store precomputed latency value
46
+ * @param key - key
47
+ * @param value -value
48
+ * @throws
49
+ * @returns
50
+ */
51
+ saveLatency(key: string, value: number): void;
52
+ /**
53
+ * Store only the first timestamp value for the given key
54
+ * @param key - key
55
+ * @param value -value
56
+ * @throws
57
+ * @returns
58
+ */
59
+ saveFirstTimestampOnly(key: MetricEventNames, value?: number): void;
60
+ /**
61
+ * Helper to calculate end - start
62
+ * @param a start
63
+ * @param b end
64
+ * @returns latency
65
+ */
66
+ getDiffBetweenTimestamps(a: MetricEventNames, b: MetricEventNames): number;
67
+ /**
68
+ * Meeting Info Request
69
+ * @note Meeting Info request happen not just in the join phase. CA requires
70
+ * metrics around meeting info request that are only part of join phase.
71
+ * This internal.* event is used to track the real timestamps
72
+ * (when the actual request/response happen). This is because the actual CA event is
73
+ * sent inside the join method on the meeting object based on some logic, but that's not exactly when
74
+ * those events are actually fired. The logic only confirms that they have happened, and we send them over.
75
+ * @returns - latency
76
+ */
77
+ getMeetingInfoReqResp(): number;
78
+ /**
79
+ * Interstitial Time
80
+ * @returns - latency
81
+ */
82
+ getShowInterstitialTime(): number;
83
+ /**
84
+ * Call Init Join Request
85
+ * @returns - latency
86
+ */
87
+ getCallInitJoinReq(): number;
88
+ /**
89
+ * Locus Join Request
90
+ * @returns - latency
91
+ */
92
+ getJoinReqResp(): number;
93
+ /**
94
+ * Locus Join Response Sent Received
95
+ * @returns - latency
96
+ */
97
+ getJoinRespSentReceived(): any;
98
+ /**
99
+ * Local SDP Generated Remote SDP REceived
100
+ * @returns - latency
101
+ */
102
+ getLocalSDPGenRemoteSDPRecv(): number;
103
+ /**
104
+ * ICE Setup Time
105
+ * @returns - latency
106
+ */
107
+ getICESetupTime(): number;
108
+ /**
109
+ * Audio ICE time
110
+ * @returns - latency
111
+ */
112
+ getAudioICESetupTime(): number;
113
+ /**
114
+ * Video ICE Time
115
+ * @returns - latency
116
+ */
117
+ getVideoICESetupTime(): number;
118
+ /**
119
+ * Share ICE Time
120
+ * @returns - latency
121
+ */
122
+ getShareICESetupTime(): number;
123
+ /**
124
+ * Stay Lobby Time
125
+ * @returns - latency
126
+ */
127
+ getStayLobbyTime(): number;
128
+ /**
129
+ * Page JMT
130
+ * @returns - latency
131
+ */
132
+ getPageJMT(): number;
133
+ /**
134
+ * Click To Interstitial
135
+ * @returns - latency
136
+ */
137
+ getClickToInterstitial(): number;
138
+ /**
139
+ * Interstitial To Join Ok
140
+ * @returns - latency
141
+ */
142
+ getInterstitialToJoinOK(): number;
143
+ /**
144
+ * Call Init To MediaEngineReady
145
+ * @returns - latency
146
+ */
147
+ getCallInitMediaEngineReady(): number;
148
+ /**
149
+ * Interstitial To Media Ok
150
+ * @returns - latency
151
+ */
152
+ getInterstitialToMediaOKJMT(): number;
153
+ /**
154
+ * Total JMT
155
+ * @returns - latency
156
+ */
157
+ getTotalJMT(): number;
158
+ /**
159
+ * Join Conf JMT
160
+ * @returns - latency
161
+ */
162
+ getJoinConfJMT(): number;
163
+ /**
164
+ * Total Media JMT
165
+ * @returns - latency
166
+ */
167
+ getTotalMediaJMT(): number;
168
+ /**
169
+ * Client JMT
170
+ * @returns - latency
171
+ */
172
+ getClientJMT(): number;
173
+ /**
174
+ * Audio setup delay receive
175
+ */
176
+ getAudioJoinRespRxStart(): number;
177
+ /**
178
+ * Video setup delay receive
179
+ */
180
+ getVideoJoinRespRxStart(): number;
181
+ /**
182
+ * Audio setup delay transmit
183
+ */
184
+ getAudioJoinRespTxStart(): number;
185
+ /**
186
+ * Video setup delay transmit
187
+ */
188
+ getVideoJoinRespTxStart(): number;
189
+ }
@@ -0,0 +1,385 @@
1
+ import { StatelessWebexPlugin } from '@webex/webex-core';
2
+ import { Event, ClientType, SubClientType, NetworkType, EnvironmentType, NewEnvironmentType, ClientEvent, SubmitClientEventOptions, MediaQualityEvent, SubmitMQEOptions, SubmitMQEPayload, ClientLaunchMethodType, ClientEventError, ClientEventPayload } from '../metrics.types';
3
+ type GetOriginOptions = {
4
+ clientType: ClientType;
5
+ subClientType: SubClientType;
6
+ networkType?: NetworkType;
7
+ clientLaunchMethod?: ClientLaunchMethodType;
8
+ environment?: EnvironmentType;
9
+ newEnvironment?: NewEnvironmentType;
10
+ };
11
+ type GetIdentifiersOptions = {
12
+ meeting?: any;
13
+ mediaConnections?: any[];
14
+ correlationId?: string;
15
+ };
16
+ /**
17
+ * @description Util class to handle Call Analyzer Metrics
18
+ * @export
19
+ * @class CallDiagnosticMetrics
20
+ */
21
+ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
22
+ private callDiagnosticEventsBatcher;
23
+ private logger;
24
+ /**
25
+ * Constructor
26
+ * @param args
27
+ */
28
+ constructor(...args: any[]);
29
+ /**
30
+ * Returns the login type of the current user
31
+ * @returns one of 'login-ci','unverified-guest', null
32
+ */
33
+ getCurLoginType(): "unverified-guest" | "login-ci";
34
+ /**
35
+ * Returns if the meeting has converged architecture enabled
36
+ * @param options.meetingId
37
+ */
38
+ getIsConvergedArchitectureEnabled({ meetingId }: {
39
+ meetingId?: string;
40
+ }): boolean;
41
+ /**
42
+ * Get origin object for Call Diagnostic Event payload.
43
+ * @param options
44
+ * @param meetingId
45
+ * @returns
46
+ */
47
+ getOrigin(options: GetOriginOptions, meetingId?: string): {
48
+ name: "endpoint" | "antares" | "beech" | "breakout" | "cb" | "cloudproxy" | "edonus" | "givr" | "hecate" | "hedge" | "hesiod" | "homer" | "superhomer" | "l2sip" | "linus" | "locus" | "mcc" | "mcs" | "mercury" | "mes" | "mjs" | "mmp" | "mygdon" | "orpheus" | "page" | "poros" | "rhesos" | "terminus" | "tpgw" | "ucc" | "wdm" | "webexivr";
49
+ userAgent: string;
50
+ buildType?: "debug" | "test" | "prod" | "tap" | "analyzer-test";
51
+ upgradeChannel?: string;
52
+ instanceId?: string;
53
+ networkType: "wifi" | "ethernet" | "cellular" | "unknown";
54
+ localIP?: string;
55
+ usingProxy?: boolean;
56
+ mediaEngineSoftwareVersion?: string;
57
+ environment?: string;
58
+ newEnvironment?: string;
59
+ clientInfo?: {
60
+ os?: "windows" | "mac" | "ios" | "android" | "chrome" | "linux" | "other" | "android-x64" | "uwp-arm64";
61
+ osVersion?: string;
62
+ localIP?: string;
63
+ gatewayIP?: string;
64
+ macAddress?: string;
65
+ localNetworkPrefix?: string;
66
+ publicNetworkPrefix?: string;
67
+ browserLaunchMethod?: "url-handler" | "activex" | "npapi" | "extension" | "cwsapi" | "java" | "tfs" | "webacd" | "thinclient";
68
+ clientLaunchMethod?: "url-handler" | "universal-link" | "voice-command" | "notification" | "manual" | "teams-cross-launch" | "mc-cross-launch";
69
+ browser?: string;
70
+ browserVersion?: string;
71
+ clientType?: "MEETING_CENTER" | "EVENT_CENTER" | "TRAINING_CENTER" | "TEAMS_CLIENT" | "TEAMS_DEVICE" | "TEAMS_SHARE" | "SIP" | "RECORDING" | "CLOUD_AWARE_SIP" | "TEAMS_WXC_CLIENT" | "WXC_CLIENT" | "WXC_DEVICE" | "WEBEX_JS_SDK" | "VOICEA_CLIENT" | "CISCO_SIP_GW" | "WEBEX_SDK" | "CPAAS_THIRD_PARTY_SDK" | "WXC_THIRD_PARTY" | "WXCC"; /**
72
+ * Returns if the meeting has converged architecture enabled
73
+ * @param options.meetingId
74
+ */
75
+ subClientType?: "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HVDI_APP" | "MOBILE_APP" | "VDI_APP" | "WEB_APP" | "MOBILE_NETWORK" | "HOLOGRAM_HEADSET_APP";
76
+ clientVersion?: string;
77
+ localClientVersion?: string;
78
+ modelNumber?: string;
79
+ joinFirstUpdateLater?: "ep-enabled" | "sp-enabled" | "not-enabled";
80
+ standbyUsed?: boolean;
81
+ prefetchDocShowUsed?: boolean;
82
+ fastJoinUsed?: boolean;
83
+ clientDownloadSize?: number;
84
+ clientDownloadFileCount?: number;
85
+ nodeId?: number;
86
+ machineInfo?: string;
87
+ parentAppName?: string;
88
+ parentAppInPermitList?: boolean;
89
+ meetingSiteType?: "train" | "webex-11" | "orion";
90
+ CDNEnabled?: boolean;
91
+ clientMajorVersion?: string;
92
+ majorVersion?: number;
93
+ minorVersion?: number;
94
+ revision?: number;
95
+ isValidClientVersion?: boolean;
96
+ cpuInfo?: {
97
+ description: string;
98
+ clockSpeedGigaHertz: number;
99
+ numberOfCores: number;
100
+ architecture: "unknown" | "intel32" | "intel64" | "amd32" | "amd64" | "arm32" | "arm64";
101
+ staticPerformance?: string;
102
+ additionalProperties?: false;
103
+ };
104
+ 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";
105
+ videoDisplayMode?: "grid-view" | "active-speaker-view";
106
+ videoLayoutType?: "stack" | "stackWithShare" | "sideBySide" | "sideBySideWithShare" | "grid" | "floatingActive" | "floatingThumbnail" | "floatingGrid" | "overlay" | "focus" | "prominent" | "focusWithShare" | "prominentWithShare" | "equal" | "equalWithShare";
107
+ videoRenderType?: "wme" | "client_d3d" | "client_gdi";
108
+ vdiInfo?: {};
109
+ is64BitsClient?: boolean;
110
+ webexAppVersion?: string;
111
+ launch32BitsReason?: "forcewin32" | "disablewin64" | "platform_win32" | "platform_arm" | "platform_unknown" | "version_below_41.11";
112
+ inMeetingUpdate?: boolean;
113
+ mtaVersion?: string;
114
+ isWarholOpening?: boolean;
115
+ additionalProperties?: false;
116
+ };
117
+ emmVendorId?: string;
118
+ isHybridMedia?: boolean;
119
+ originData?: {};
120
+ additionalProperties?: false;
121
+ };
122
+ /**
123
+ * Gather identifier details for call diagnostic payload.
124
+ * @throws Error if initialization fails.
125
+ * @param options
126
+ */
127
+ getIdentifiers(options: GetIdentifiersOptions): {
128
+ attendeeId?: string;
129
+ breakoutGroupId?: string;
130
+ breakoutMoveId?: string;
131
+ breakoutSessionId?: string;
132
+ confluenceId?: string;
133
+ cpaasIdentifiers?: {
134
+ imiTenantId: string;
135
+ devClientId: string;
136
+ imiServiceId: string;
137
+ imiAppId: string;
138
+ sessionId: string;
139
+ sessionInstanceId: string;
140
+ additionalProperties?: false;
141
+ };
142
+ csdmDeviceUrl?: string;
143
+ destinationBreakoutSessionId?: string;
144
+ destinationLocusSessionId?: string;
145
+ destinationLocusUrl?: string;
146
+ destinationVenueId?: string;
147
+ deviceId?: string;
148
+ ivrCallId?: string;
149
+ ivrDialogId?: string;
150
+ ivrId?: string;
151
+ callId?: string;
152
+ locusId?: string;
153
+ locusSessionId?: string;
154
+ locusStartTime?: string;
155
+ locusUrl?: string;
156
+ mediaAgentAlias?: string;
157
+ mediaAgentGroupId?: string;
158
+ meetClusterName?: string;
159
+ meetingLookupUrl?: string;
160
+ meetingOrgId?: string;
161
+ msteamsTenantGuid?: string;
162
+ msteamsConferenceId?: string;
163
+ oauth2ClientId?: string;
164
+ orgId?: string;
165
+ provisionalCorrelationId?: string;
166
+ roomId?: string;
167
+ sipCallId?: string;
168
+ sipSessionId?: {
169
+ local?: string;
170
+ remote?: string;
171
+ additionalProperties?: false;
172
+ };
173
+ sipUri?: string;
174
+ subConfId?: string;
175
+ tenantId?: string;
176
+ trackingId?: string;
177
+ userId?: string;
178
+ venueId?: string;
179
+ venueUrl?: string;
180
+ whiteboardUrl?: string;
181
+ webexConferenceId?: number;
182
+ webexClusterName?: string;
183
+ webexConferenceIdStr?: string;
184
+ webexDataCenter?: string;
185
+ webexGuestId?: number;
186
+ webexMeetingId?: number;
187
+ webexNodeId?: number;
188
+ webexSiteId?: number;
189
+ webexSiteName?: string;
190
+ webexUserId?: number;
191
+ webexWebDomain?: string;
192
+ correlationId: string;
193
+ additionalProperties?: false;
194
+ } | {
195
+ attendeeId?: string;
196
+ breakoutGroupId?: string;
197
+ breakoutMoveId?: string;
198
+ breakoutSessionId?: string;
199
+ confluenceId?: string;
200
+ cpaasIdentifiers?: {
201
+ imiTenantId: string;
202
+ devClientId: string;
203
+ imiServiceId: string;
204
+ imiAppId: string;
205
+ sessionId: string;
206
+ sessionInstanceId: string;
207
+ additionalProperties?: false;
208
+ };
209
+ csdmDeviceUrl?: string;
210
+ destinationBreakoutSessionId?: string;
211
+ destinationLocusSessionId?: string;
212
+ destinationLocusUrl?: string;
213
+ destinationVenueId?: string;
214
+ deviceId?: string;
215
+ ivrCallId?: string;
216
+ ivrDialogId?: string;
217
+ ivrId?: string;
218
+ callId?: string;
219
+ locusId?: string;
220
+ locusSessionId?: string;
221
+ locusStartTime?: string;
222
+ locusUrl?: string;
223
+ mediaAgentAlias?: string;
224
+ mediaAgentGroupId?: string;
225
+ meetClusterName?: string;
226
+ meetingLookupUrl?: string;
227
+ meetingOrgId?: string;
228
+ msteamsTenantGuid?: string;
229
+ msteamsConferenceId?: string;
230
+ oauth2ClientId?: string;
231
+ orgId?: string;
232
+ provisionalCorrelationId?: string;
233
+ roomId?: string;
234
+ sipCallId?: string;
235
+ sipSessionId?: {
236
+ local?: string;
237
+ remote?: string;
238
+ additionalProperties?: false;
239
+ };
240
+ sipUri?: string;
241
+ subConfId?: string;
242
+ tenantId?: string;
243
+ trackingId?: string;
244
+ userId?: string;
245
+ venueId?: string;
246
+ venueUrl?: string;
247
+ whiteboardUrl?: string;
248
+ webexConferenceId?: number;
249
+ webexClusterName?: string;
250
+ webexConferenceIdStr?: string;
251
+ webexDataCenter?: string;
252
+ webexGuestId?: number;
253
+ webexMeetingId?: number;
254
+ webexNodeId?: number;
255
+ webexSiteId?: number;
256
+ webexSiteName?: string;
257
+ webexUserId?: number;
258
+ webexWebDomain?: string;
259
+ correlationId: string;
260
+ additionalProperties?: false;
261
+ };
262
+ /**
263
+ * Create diagnostic event, which can hold client event, feature event or MQE event data.
264
+ * This just initiates the shared properties that are required for all the 3 event categories.
265
+ * @param eventData
266
+ * @param options
267
+ * @returns
268
+ */
269
+ prepareDiagnosticEvent(eventData: Event['event'], options: any): Event;
270
+ /**
271
+ * TODO: NOT IMPLEMENTED
272
+ * Submit Feature Event
273
+ * @returns
274
+ */
275
+ submitFeatureEvent(): void;
276
+ /**
277
+ * Submit Media Quality Event
278
+ * @param args - submit params
279
+ * @param arg.name - event key
280
+ * @param arg.payload - additional payload to be merge with the default payload
281
+ * @param arg.options - options
282
+ */
283
+ submitMQE({ name, payload, options, }: {
284
+ name: MediaQualityEvent['name'];
285
+ payload: SubmitMQEPayload;
286
+ options: SubmitMQEOptions;
287
+ }): void;
288
+ /**
289
+ * Return Client Event payload by client error code
290
+ * @param arg - get error arg
291
+ * @param arg.clientErrorCode
292
+ * @param arg.serviceErrorCode
293
+ * @returns
294
+ */
295
+ getErrorPayloadForClientErrorCode({ clientErrorCode, serviceErrorCode, serviceErrorName, }: {
296
+ clientErrorCode: number;
297
+ serviceErrorCode: any;
298
+ serviceErrorName?: any;
299
+ }): ClientEventError;
300
+ /**
301
+ * Generate error payload for Client Event
302
+ * @param rawError
303
+ */
304
+ generateClientEventErrorPayload(rawError: any): {
305
+ fatal: boolean;
306
+ category: "other" | "signaling" | "media" | "expected";
307
+ errorDescription?: string;
308
+ errorCode?: number;
309
+ errorCodeStr?: string;
310
+ httpCode?: number;
311
+ errorCodeExt1?: number;
312
+ errorData?: {};
313
+ shownToUser: boolean;
314
+ serviceErrorCode?: number;
315
+ name: "other" | "locus.response" | "media-engine" | "ice.failed" | "locus.leave" | "client.leave" | "media-device" | "media-sca" | "wxc";
316
+ additionalProperties?: false;
317
+ };
318
+ /**
319
+ * Create client event object for in meeting events
320
+ * @param arg - create args
321
+ * @param arg.event - event key
322
+ * @param arg.options - options
323
+ * @returns object
324
+ */
325
+ private createClientEventObjectInMeeting;
326
+ /**
327
+ * Create client event object for pre meeting events
328
+ * @param arg - create args
329
+ * @param arg.event - event key
330
+ * @param arg.options - payload
331
+ * @returns object
332
+ */
333
+ private createClientEventObjectPreMeeting;
334
+ /**
335
+ * Prepare Client Event CA event.
336
+ * @param arg - submit params
337
+ * @param arg.event - event key
338
+ * @param arg.payload - additional payload to be merged with default payload
339
+ * @param arg.options - payload
340
+ * @returns {any} options to be with fetch
341
+ * @throws
342
+ */
343
+ private prepareClientEvent;
344
+ /**
345
+ * Submit Client Event CA event.
346
+ * @param arg - submit params
347
+ * @param arg.event - event key
348
+ * @param arg.payload - additional payload to be merged with default payload
349
+ * @param arg.options - payload
350
+ * @throws
351
+ */
352
+ submitClientEvent({ name, payload, options, }: {
353
+ name: ClientEvent['name'];
354
+ payload?: ClientEventPayload;
355
+ options?: SubmitClientEventOptions;
356
+ }): Promise<any>;
357
+ /**
358
+ * Prepare the event and send the request to metrics-a service.
359
+ * @param event
360
+ * @returns promise
361
+ */
362
+ submitToCallDiagnostics(event: Event): Promise<any>;
363
+ /**
364
+ * Pre login events are not batched. We make the request directly.
365
+ * @param event
366
+ * @param preLoginId
367
+ * @returns
368
+ */
369
+ submitToCallDiagnosticsPreLogin: (event: Event, preLoginId?: string) => Promise<any>;
370
+ /**
371
+ * Builds a request options object to later be passed to fetch().
372
+ * @param arg - submit params
373
+ * @param arg.event - event key
374
+ * @param arg.payload - additional payload to be merged with default payload
375
+ * @param arg.options - client event options
376
+ * @returns {Promise<any>}
377
+ * @throws
378
+ */
379
+ buildClientEventFetchRequestOptions({ name, payload, options, }: {
380
+ name: ClientEvent['name'];
381
+ payload?: ClientEventPayload;
382
+ options?: SubmitClientEventOptions;
383
+ }): Promise<any>;
384
+ }
385
+ export {};
@@ -0,0 +1,73 @@
1
+ import { Event } from '../metrics.types';
2
+ export declare const anonymizeIPAddress: (localIp: any) => string;
3
+ /**
4
+ * Returns a formated string of the user agent.
5
+ *
6
+ * @returns {string} formatted user agent information
7
+ */
8
+ export declare const userAgentToString: ({ clientName, webexVersion }: {
9
+ clientName: any;
10
+ webexVersion: any;
11
+ }) => string;
12
+ /**
13
+ * Iterates object recursively and removes any
14
+ * property that returns isEmpty for it's associated value
15
+ * isEmpty = implementation from Lodash.
16
+ *
17
+ * It modifies the object in place (mutable)
18
+ *
19
+ * @param obj - input
20
+ * @returns
21
+ */
22
+ export declare const clearEmptyKeysRecursively: (obj: any) => void;
23
+ /**
24
+ * Locus error codes start with 2. The next three digits are the
25
+ * HTTP status code related to the error code (like 400, 403, 502, etc.)
26
+ * The remaining three digits are just an increasing integer.
27
+ * If it is 7 digits and starts with a 2, it is locus.
28
+ *
29
+ * @param errorCode
30
+ * @returns {boolean}
31
+ */
32
+ export declare const isLocusServiceErrorCode: (errorCode: string | number) => boolean;
33
+ /**
34
+ * MeetingInfo errors sometimes has body.data.meetingInfo object
35
+ * MeetingInfo errors come with a wbxappapi url
36
+ *
37
+ * @param {Object} rawError
38
+ * @returns {boolean}
39
+ */
40
+ export declare const isMeetingInfoServiceError: (rawError: any) => boolean;
41
+ /**
42
+ * MDN Media Devices getUserMedia() method returns a name if it errs
43
+ * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
44
+ *
45
+ * @param errorCode
46
+ * @returns
47
+ */
48
+ export declare const isBrowserMediaErrorName: (errorName: any) => boolean;
49
+ /**
50
+ * @param webClientDomain
51
+ * @returns
52
+ */
53
+ export declare const getBuildType: (webClientDomain: any, markAsTestEvent?: boolean) => Event['origin']['buildType'];
54
+ /**
55
+ * Prepare metric item for submission.
56
+ * @param {Object} webex sdk instance
57
+ * @param {Object} item
58
+ * @returns {Object} prepared item
59
+ */
60
+ export declare const prepareDiagnosticMetricItem: (webex: any, item: any) => any;
61
+ /**
62
+ * Sets the originTime value(s) before the request/fetch.
63
+ * This function is only useful if you are about to submit a metrics
64
+ * request using pre-built fetch options;
65
+ *
66
+ * @param {any} options
67
+ * @returns {any} the updated options object
68
+ */
69
+ export declare const setMetricTimings: (options: any) => any;
70
+ export declare const extractVersionMetadata: (version: string) => {
71
+ majorVersion: number;
72
+ minorVersion: number;
73
+ };