@webex/internal-plugin-metrics 3.10.0 → 3.11.0-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.
Files changed (42) hide show
  1. package/dist/batcher.js.map +1 -1
  2. package/dist/behavioral-metrics.js +6 -8
  3. package/dist/behavioral-metrics.js.map +1 -1
  4. package/dist/business-metrics.js +6 -8
  5. package/dist/business-metrics.js.map +1 -1
  6. package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -1
  7. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +10 -13
  8. package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
  9. package/dist/call-diagnostic/call-diagnostic-metrics.js +49 -49
  10. package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
  11. package/dist/call-diagnostic/call-diagnostic-metrics.util.js +35 -3
  12. package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
  13. package/dist/call-diagnostic/config.js +1 -0
  14. package/dist/call-diagnostic/config.js.map +1 -1
  15. package/dist/client-metrics-batcher.js.map +1 -1
  16. package/dist/client-metrics-prelogin-batcher.js.map +1 -1
  17. package/dist/config.js.map +1 -1
  18. package/dist/generic-metrics.js +11 -14
  19. package/dist/generic-metrics.js.map +1 -1
  20. package/dist/index.js +1 -2
  21. package/dist/index.js.map +1 -1
  22. package/dist/metrics.js +1 -2
  23. package/dist/metrics.js.map +1 -1
  24. package/dist/metrics.types.js.map +1 -1
  25. package/dist/new-metrics.js +24 -27
  26. package/dist/new-metrics.js.map +1 -1
  27. package/dist/operational-metrics.js +6 -8
  28. package/dist/operational-metrics.js.map +1 -1
  29. package/dist/prelogin-metrics-batcher.js.map +1 -1
  30. package/dist/rtcMetrics/constants.js.map +1 -1
  31. package/dist/rtcMetrics/index.js +2 -4
  32. package/dist/rtcMetrics/index.js.map +1 -1
  33. package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +3 -1
  34. package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +21 -0
  35. package/dist/types/call-diagnostic/config.d.ts +1 -0
  36. package/dist/utils.js.map +1 -1
  37. package/package.json +10 -10
  38. package/src/call-diagnostic/call-diagnostic-metrics.ts +5 -2
  39. package/src/call-diagnostic/call-diagnostic-metrics.util.ts +37 -0
  40. package/src/call-diagnostic/config.ts +1 -0
  41. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +1 -1
  42. package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +55 -0
@@ -1 +1 @@
1
- {"version":3,"names":["_uuid","_interopRequireDefault","require","CallDiagnosticUtils","_interopRequireWildcard","_constants","_getRequireWildcardCache","e","_WeakMap","r","t","__esModule","_typeof","default","has","get","n","__proto__","a","_Object$defineProperty","_Object$getOwnPropertyDescriptor","u","Object","prototype","hasOwnProperty","call","i","set","parseJsonPayload","payload","JSON","parse","_","RtcMetrics","exports","webex","_ref","correlationId","meetingId","callId","_classCallCheck2","_defineProperty2","intervalId","window","setInterval","sendMetricsInQueue","bind","resetConnection","_createClass2","key","value","updateCallId","metricsQueue","length","sendMetrics","sendNextMetrics","shouldSendMetricsOnNextStatsReport","addMetrics","data","name","map","anonymizeIp","push","parsedPayload","console","error","closeMetrics","clearInterval","stats","type","ip","anonymizeIPAddress","undefined","address","relatedAddress","_stringify","connectionId","uuid","v4","metricsAttributes","version","userId","internal","device","request","method","service","resource","headers","appId","RTC_METRICS","APP_ID","body","metrics"],"sources":["index.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\nimport uuid from 'uuid';\nimport * as CallDiagnosticUtils from '../call-diagnostic/call-diagnostic-metrics.util';\nimport RTC_METRICS from './constants';\nimport {IdType, IMetricsAttributes} from '../metrics.types';\n\nconst parseJsonPayload = (payload: any[]): any | null => {\n try {\n if (payload && payload[0]) {\n return JSON.parse(payload[0]);\n }\n\n return null;\n } catch (_) {\n return null;\n }\n};\n\n/**\n * Rtc Metrics\n */\nexport default class RtcMetrics {\n /**\n * Array of MetricData items to be sent to the metrics service.\n */\n metricsQueue = [];\n\n intervalId: number;\n\n webex: any;\n\n meetingId?: string;\n\n callId?: string;\n\n correlationId: string;\n\n connectionId: string;\n\n shouldSendMetricsOnNextStatsReport: boolean;\n\n /**\n * Initialize the interval.\n *\n * @param {object} webex - The main `webex` object.\n * @param {IdType} Ids - Meeting or Calling id.\n * @param {string} correlationId - The correlation id.\n */\n constructor(webex, {meetingId, callId}: IdType, correlationId) {\n // `window` is used to prevent typescript from returning a NodeJS.Timer.\n this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);\n this.meetingId = meetingId;\n this.callId = callId;\n this.webex = webex;\n this.correlationId = correlationId;\n this.resetConnection();\n }\n\n /**\n * Updates the call identifier with the provided value.\n *\n * @param {string} callId - The new call identifier to set.\n * @returns {void}\n */\n public updateCallId(callId: string) {\n this.callId = callId;\n }\n\n /**\n * Check to see if the metrics queue has any items.\n *\n * @returns {void}\n */\n public sendMetricsInQueue() {\n if (this.metricsQueue.length) {\n this.sendMetrics();\n this.metricsQueue = [];\n }\n }\n\n /**\n * Forces sending metrics when we get the next stats-report\n *\n * This is useful for cases when something important happens that affects the media connection,\n * for example when we move from lobby into the meeting.\n *\n * @returns {void}\n */\n public sendNextMetrics() {\n this.shouldSendMetricsOnNextStatsReport = true;\n }\n\n /**\n * Add metrics items to the metrics queue.\n *\n * @param {object} data - An object with a payload array of metrics items.\n *\n * @returns {void}\n */\n addMetrics(data) {\n if (data.payload.length) {\n if (data.name === 'stats-report') {\n data.payload = data.payload.map(this.anonymizeIp);\n }\n\n this.metricsQueue.push(data);\n\n if (this.shouldSendMetricsOnNextStatsReport && data.name === 'stats-report') {\n // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately\n // in case the user is unhappy and closes the browser early\n this.sendMetricsInQueue();\n this.shouldSendMetricsOnNextStatsReport = false;\n }\n\n try {\n // If a connection fails, send the rest of the metrics in queue and get a new connection id.\n const parsedPayload = parseJsonPayload(data.payload);\n if (\n data.name === 'onconnectionstatechange' &&\n parsedPayload &&\n parsedPayload.value === 'failed'\n ) {\n this.sendMetricsInQueue();\n this.resetConnection();\n }\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n /**\n * Clear the metrics interval.\n *\n * @returns {void}\n */\n closeMetrics() {\n this.sendMetricsInQueue();\n clearInterval(this.intervalId);\n }\n\n /**\n * Anonymize IP addresses.\n *\n * @param {array} stats - An RTCStatsReport organized into an array of strings.\n * @returns {string}\n */\n anonymizeIp(stats: string): string {\n const data = JSON.parse(stats);\n // on local and remote candidates, anonymize the last 4 bits.\n if (data.type === 'local-candidate' || data.type === 'remote-candidate') {\n data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;\n data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;\n data.relatedAddress =\n CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;\n }\n\n return JSON.stringify(data);\n }\n\n /**\n * Set a new connection id.\n *\n * @returns {void}\n */\n private resetConnection() {\n this.connectionId = uuid.v4();\n this.shouldSendMetricsOnNextStatsReport = true;\n }\n\n /**\n * Send metrics to the metrics service.\n *\n * @returns {void}\n */\n private sendMetrics() {\n const metricsAttributes: IMetricsAttributes = {\n type: 'webrtc',\n version: '1.1.0',\n userId: this.webex.internal.device.userId,\n correlationId: this.correlationId,\n connectionId: this.connectionId,\n data: this.metricsQueue,\n };\n\n if (this.meetingId) {\n metricsAttributes.meetingId = this.meetingId;\n } else if (this.callId) {\n metricsAttributes.callId = this.callId;\n }\n\n this.webex.request({\n method: 'POST',\n service: 'unifiedTelemetry',\n resource: 'metric/v2',\n headers: {\n type: 'webrtcMedia',\n appId: RTC_METRICS.APP_ID,\n },\n body: {\n metrics: [metricsAttributes],\n },\n });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"names":["_uuid","_interopRequireDefault","require","CallDiagnosticUtils","_interopRequireWildcard","_constants","e","t","_WeakMap","r","n","__esModule","o","i","f","__proto__","default","_typeof","has","get","set","_t","hasOwnProperty","call","_Object$defineProperty","_Object$getOwnPropertyDescriptor","parseJsonPayload","payload","JSON","parse","_","RtcMetrics","exports","webex","_ref","correlationId","meetingId","callId","_classCallCheck2","_defineProperty2","intervalId","window","setInterval","sendMetricsInQueue","bind","resetConnection","_createClass2","key","value","updateCallId","metricsQueue","length","sendMetrics","sendNextMetrics","shouldSendMetricsOnNextStatsReport","addMetrics","data","name","map","anonymizeIp","push","parsedPayload","console","error","closeMetrics","clearInterval","stats","type","ip","anonymizeIPAddress","undefined","address","relatedAddress","_stringify","connectionId","uuid","v4","metricsAttributes","version","userId","internal","device","request","method","service","resource","headers","appId","RTC_METRICS","APP_ID","body","metrics"],"sources":["index.ts"],"sourcesContent":["/* eslint-disable class-methods-use-this */\nimport uuid from 'uuid';\nimport * as CallDiagnosticUtils from '../call-diagnostic/call-diagnostic-metrics.util';\nimport RTC_METRICS from './constants';\nimport {IdType, IMetricsAttributes} from '../metrics.types';\n\nconst parseJsonPayload = (payload: any[]): any | null => {\n try {\n if (payload && payload[0]) {\n return JSON.parse(payload[0]);\n }\n\n return null;\n } catch (_) {\n return null;\n }\n};\n\n/**\n * Rtc Metrics\n */\nexport default class RtcMetrics {\n /**\n * Array of MetricData items to be sent to the metrics service.\n */\n metricsQueue = [];\n\n intervalId: number;\n\n webex: any;\n\n meetingId?: string;\n\n callId?: string;\n\n correlationId: string;\n\n connectionId: string;\n\n shouldSendMetricsOnNextStatsReport: boolean;\n\n /**\n * Initialize the interval.\n *\n * @param {object} webex - The main `webex` object.\n * @param {IdType} Ids - Meeting or Calling id.\n * @param {string} correlationId - The correlation id.\n */\n constructor(webex, {meetingId, callId}: IdType, correlationId) {\n // `window` is used to prevent typescript from returning a NodeJS.Timer.\n this.intervalId = window.setInterval(this.sendMetricsInQueue.bind(this), 30 * 1000);\n this.meetingId = meetingId;\n this.callId = callId;\n this.webex = webex;\n this.correlationId = correlationId;\n this.resetConnection();\n }\n\n /**\n * Updates the call identifier with the provided value.\n *\n * @param {string} callId - The new call identifier to set.\n * @returns {void}\n */\n public updateCallId(callId: string) {\n this.callId = callId;\n }\n\n /**\n * Check to see if the metrics queue has any items.\n *\n * @returns {void}\n */\n public sendMetricsInQueue() {\n if (this.metricsQueue.length) {\n this.sendMetrics();\n this.metricsQueue = [];\n }\n }\n\n /**\n * Forces sending metrics when we get the next stats-report\n *\n * This is useful for cases when something important happens that affects the media connection,\n * for example when we move from lobby into the meeting.\n *\n * @returns {void}\n */\n public sendNextMetrics() {\n this.shouldSendMetricsOnNextStatsReport = true;\n }\n\n /**\n * Add metrics items to the metrics queue.\n *\n * @param {object} data - An object with a payload array of metrics items.\n *\n * @returns {void}\n */\n addMetrics(data) {\n if (data.payload.length) {\n if (data.name === 'stats-report') {\n data.payload = data.payload.map(this.anonymizeIp);\n }\n\n this.metricsQueue.push(data);\n\n if (this.shouldSendMetricsOnNextStatsReport && data.name === 'stats-report') {\n // this is the first useful set of data (WCME gives it to us after 5s), send it out immediately\n // in case the user is unhappy and closes the browser early\n this.sendMetricsInQueue();\n this.shouldSendMetricsOnNextStatsReport = false;\n }\n\n try {\n // If a connection fails, send the rest of the metrics in queue and get a new connection id.\n const parsedPayload = parseJsonPayload(data.payload);\n if (\n data.name === 'onconnectionstatechange' &&\n parsedPayload &&\n parsedPayload.value === 'failed'\n ) {\n this.sendMetricsInQueue();\n this.resetConnection();\n }\n } catch (e) {\n console.error(e);\n }\n }\n }\n\n /**\n * Clear the metrics interval.\n *\n * @returns {void}\n */\n closeMetrics() {\n this.sendMetricsInQueue();\n clearInterval(this.intervalId);\n }\n\n /**\n * Anonymize IP addresses.\n *\n * @param {array} stats - An RTCStatsReport organized into an array of strings.\n * @returns {string}\n */\n anonymizeIp(stats: string): string {\n const data = JSON.parse(stats);\n // on local and remote candidates, anonymize the last 4 bits.\n if (data.type === 'local-candidate' || data.type === 'remote-candidate') {\n data.ip = CallDiagnosticUtils.anonymizeIPAddress(data.ip) || undefined;\n data.address = CallDiagnosticUtils.anonymizeIPAddress(data.address) || undefined;\n data.relatedAddress =\n CallDiagnosticUtils.anonymizeIPAddress(data.relatedAddress) || undefined;\n }\n\n return JSON.stringify(data);\n }\n\n /**\n * Set a new connection id.\n *\n * @returns {void}\n */\n private resetConnection() {\n this.connectionId = uuid.v4();\n this.shouldSendMetricsOnNextStatsReport = true;\n }\n\n /**\n * Send metrics to the metrics service.\n *\n * @returns {void}\n */\n private sendMetrics() {\n const metricsAttributes: IMetricsAttributes = {\n type: 'webrtc',\n version: '1.1.0',\n userId: this.webex.internal.device.userId,\n correlationId: this.correlationId,\n connectionId: this.connectionId,\n data: this.metricsQueue,\n };\n\n if (this.meetingId) {\n metricsAttributes.meetingId = this.meetingId;\n } else if (this.callId) {\n metricsAttributes.callId = this.callId;\n }\n\n this.webex.request({\n method: 'POST',\n service: 'unifiedTelemetry',\n resource: 'metric/v2',\n headers: {\n type: 'webrtcMedia',\n appId: RTC_METRICS.APP_ID,\n },\n body: {\n metrics: [metricsAttributes],\n },\n });\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -105,7 +105,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
105
105
  browser?: string;
106
106
  browserVersion?: string;
107
107
  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" | "TEAMS_PHONE" | "WEBEX_RELAY";
108
- subClientType?: "TEAMS_DEVICE" | "SIP" | "AUTOMOTIVE_APP" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MIXED" | "MOBILE_APP" | "MOBILE_NETWORK" | "PAGE" | "VDI_APP" | "WEB_APP" | "PHONE_NOVUM" | "PHONE_ESPRESSO" | "PHONE_BUMBLEBEE" | "SIP_PSTN";
108
+ subClientType?: "TEAMS_DEVICE" | "SIP" | "AUTOMOTIVE_APP" | "BROWSER_EXTENSION" | "DESKTOP_APP" | "DESKTOP_APP_VDI" | "DEVICE_CURRENT" | "DEVICE_LEGACY_2020" | "HOLOGRAM_HEADSET_APP" | "HVDI_APP" | "MIXED" | "MOBILE_APP" | "MOBILE_NETWORK" | "PAGE" | "VDI_APP" | "WEB_APP" | "PHONE_NOVUM" | "PHONE_ESPRESSO" | "PHONE_BUMBLEBEE" | "SIP_PSTN";
109
109
  schedulingClientType?: "TEAMS_CLIENT" | "GOOGLE_ADDON" | "PT" | "PUBLIC_API" | "UNIFIED_PAGE" | "WEBEX_PAGE" | "GOOGLE_NOTIFICATION_CALENDAR" | "MSFT_NOTIFICATION_ADDIN" | "MSFT_NOTIFICATION_CALENDAR" | "OUTLOOK_ADDIN";
110
110
  clientVersion?: string;
111
111
  clientVersionStatus?: "CURRENT" | "LEGACY" | "UNSUPPORTED";
@@ -149,6 +149,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
149
149
  mtaVersion?: string;
150
150
  isWarholOpening?: boolean;
151
151
  vendorId?: string;
152
+ staticPerformanceLevel?: string;
153
+ staticPerformanceScore?: number;
152
154
  additionalProperties?: false;
153
155
  };
154
156
  emmVendorId?: string;
@@ -59,6 +59,27 @@ export declare const isUnauthorizedError: (rawError: any) => boolean;
59
59
  * @returns {boolean}
60
60
  */
61
61
  export declare const isSdpOfferCreationError: (rawError: any) => boolean;
62
+ export declare const isWebrtcApiNotAvailableError: (rawError: {
63
+ code: number;
64
+ message: string;
65
+ name: string;
66
+ } | unknown) => boolean;
67
+ /**
68
+ * Checks if the given error is a browser media error by its name.
69
+ * Returns true if the error name matches any known browser media error name in the mapping.
70
+ *
71
+ * @param {Object} rawError - The error object to check.
72
+ * @returns {boolean} True if the error is a browser media error, false otherwise.
73
+ */
74
+ export declare const isBrowserMediaError: (rawError: any) => boolean;
75
+ /**
76
+ * Returns the client error code mapped to the given browser media error name.
77
+ * If the error name is not found in the mapping, returns undefined.
78
+ *
79
+ * @param {Object} rawError - The error object containing the error name.
80
+ * @returns {string|undefined} The mapped client error code, or undefined if not found.
81
+ */
82
+ export declare const getBrowserMediaErrorCode: (rawError: any) => number;
62
83
  /**
63
84
  * MDN Media Devices getUserMedia() method returns a name if it errs
64
85
  * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
@@ -99,6 +99,7 @@ export declare const ERROR_DESCRIPTIONS: {
99
99
  MULTISTREAM_NOT_AVAILABLE: string;
100
100
  SDP_OFFER_CREATION_ERROR: string;
101
101
  SDP_OFFER_CREATION_ERROR_MISSING_CODEC: string;
102
+ WEBRTC_API_NOT_AVAILABLE: string;
102
103
  WDM_RESTRICTED_REGION: string;
103
104
  USER_NOT_ALLOWED_JOIN_WEBINAR: string;
104
105
  };
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"names":["generateCommonErrorMetadata","exports","error","Error","_stringify","default","message","name","stack"],"sources":["utils.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\n/**\n * Generates common metadata for errors\n * @param {any} error\n * @returns {object}\n */\nexport const generateCommonErrorMetadata = (error) => {\n if (error instanceof Error) {\n return JSON.stringify({\n message: error?.message,\n name: error?.name,\n stack: error?.stack,\n });\n }\n\n return error;\n};\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACO,IAAMA,2BAA2B,GAAAC,OAAA,CAAAD,2BAAA,GAAG,SAA9BA,2BAA2BA,CAAIE,KAAK,EAAK;EACpD,IAAIA,KAAK,YAAYC,KAAK,EAAE;IAC1B,OAAO,IAAAC,UAAA,CAAAC,OAAA,EAAe;MACpBC,OAAO,EAAEJ,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEI,OAAO;MACvBC,IAAI,EAAEL,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEK,IAAI;MACjBC,KAAK,EAAEN,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEM;IAChB,CAAC,CAAC;EACJ;EAEA,OAAON,KAAK;AACd,CAAC"}
1
+ {"version":3,"names":["generateCommonErrorMetadata","exports","error","Error","_stringify","default","message","name","stack"],"sources":["utils.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\n/**\n * Generates common metadata for errors\n * @param {any} error\n * @returns {object}\n */\nexport const generateCommonErrorMetadata = (error) => {\n if (error instanceof Error) {\n return JSON.stringify({\n message: error?.message,\n name: error?.name,\n stack: error?.stack,\n });\n }\n\n return error;\n};\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACO,IAAMA,2BAA2B,GAAAC,OAAA,CAAAD,2BAAA,GAAG,SAA9BA,2BAA2BA,CAAIE,KAAK,EAAK;EACpD,IAAIA,KAAK,YAAYC,KAAK,EAAE;IAC1B,OAAO,IAAAC,UAAA,CAAAC,OAAA,EAAe;MACpBC,OAAO,EAAEJ,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEI,OAAO;MACvBC,IAAI,EAAEL,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEK,IAAI;MACjBC,KAAK,EAAEN,KAAK,aAALA,KAAK,uBAALA,KAAK,CAAEM;IAChB,CAAC,CAAC;EACJ;EAEA,OAAON,KAAK;AACd,CAAC","ignoreList":[]}
package/package.json CHANGED
@@ -26,21 +26,21 @@
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.10.0",
30
- "@webex/test-helper-mocha": "3.10.0",
31
- "@webex/test-helper-mock-webex": "3.10.0",
32
- "@webex/test-helper-test-users": "3.10.0",
29
+ "@webex/test-helper-chai": "3.10.0-next.1",
30
+ "@webex/test-helper-mocha": "3.10.0-next.1",
31
+ "@webex/test-helper-mock-webex": "3.10.0-next.1",
32
+ "@webex/test-helper-test-users": "3.10.0-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.10.0",
39
- "@webex/common-timers": "3.10.0",
38
+ "@webex/common": "3.10.0-next.1",
39
+ "@webex/common-timers": "3.10.0-next.1",
40
40
  "@webex/event-dictionary-ts": "^1.0.1930",
41
- "@webex/test-helper-chai": "3.10.0",
42
- "@webex/test-helper-mock-webex": "3.10.0",
43
- "@webex/webex-core": "3.10.0",
41
+ "@webex/test-helper-chai": "3.10.0-next.1",
42
+ "@webex/test-helper-mock-webex": "3.10.0-next.1",
43
+ "@webex/webex-core": "3.11.0-next.1",
44
44
  "ip-anonymize": "^0.1.0",
45
45
  "lodash": "^4.17.21",
46
46
  "uuid": "^3.3.2"
@@ -53,5 +53,5 @@
53
53
  "test:style": "eslint ./src/**/*.*",
54
54
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
55
55
  },
56
- "version": "3.10.0"
56
+ "version": "3.11.0-next.1"
57
57
  }
@@ -1415,8 +1415,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
1415
1415
  */
1416
1416
  public setDeviceInfo(device: any): void {
1417
1417
  // This was created to fix the circular dependency between internal-plugin-device and internal-plugin-metrics
1418
- this.logger.log('CallDiagnosticMetrics: @setDeviceInfo called', device);
1419
-
1418
+ this.logger.log('CallDiagnosticMetrics: @setDeviceInfo called', {
1419
+ userId: device?.userId,
1420
+ deviceId: device?.url,
1421
+ orgId: device?.orgId,
1422
+ });
1420
1423
  this.device = device;
1421
1424
  }
1422
1425
  }
@@ -179,6 +179,43 @@ export const isSdpOfferCreationError = (rawError: any) => {
179
179
  return false;
180
180
  };
181
181
 
182
+ export const isWebrtcApiNotAvailableError = (
183
+ rawError: {code: number; message: string; name: string} | unknown
184
+ ) => {
185
+ if ((rawError as {name: string}).name === ERROR_DESCRIPTIONS.WEBRTC_API_NOT_AVAILABLE) {
186
+ return true;
187
+ }
188
+
189
+ return false;
190
+ };
191
+
192
+ /**
193
+ * Checks if the given error is a browser media error by its name.
194
+ * Returns true if the error name matches any known browser media error name in the mapping.
195
+ *
196
+ * @param {Object} rawError - The error object to check.
197
+ * @returns {boolean} True if the error is a browser media error, false otherwise.
198
+ */
199
+ export const isBrowserMediaError = (rawError) => {
200
+ // eslint-disable-next-line no-use-before-define
201
+ if (isBrowserMediaErrorName(rawError.name)) {
202
+ return true;
203
+ }
204
+
205
+ return false;
206
+ };
207
+
208
+ /**
209
+ * Returns the client error code mapped to the given browser media error name.
210
+ * If the error name is not found in the mapping, returns undefined.
211
+ *
212
+ * @param {Object} rawError - The error object containing the error name.
213
+ * @returns {string|undefined} The mapped client error code, or undefined if not found.
214
+ */
215
+ export const getBrowserMediaErrorCode = (rawError) => {
216
+ return BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name];
217
+ };
218
+
182
219
  /**
183
220
  * MDN Media Devices getUserMedia() method returns a name if it errs
184
221
  * Documentation can be found here: https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
@@ -133,6 +133,7 @@ export const ERROR_DESCRIPTIONS = {
133
133
  MULTISTREAM_NOT_AVAILABLE: 'MultistreamNotAvailable',
134
134
  SDP_OFFER_CREATION_ERROR: 'SdpOfferCreationError',
135
135
  SDP_OFFER_CREATION_ERROR_MISSING_CODEC: 'SdpOfferCreationErrorMissingCodec',
136
+ WEBRTC_API_NOT_AVAILABLE: 'WebrtcApiNotAvailableError',
136
137
  WDM_RESTRICTED_REGION: 'WdmRestrictedRegion',
137
138
  USER_NOT_ALLOWED_JOIN_WEBINAR: 'UserNotAllowedJoinWebinar',
138
139
  };
@@ -3906,7 +3906,7 @@ describe('internal-plugin-metrics', () => {
3906
3906
 
3907
3907
  assert.deepEqual(webexLoggerLogCalls[0].args, [
3908
3908
  'CallDiagnosticMetrics: @setDeviceInfo called',
3909
- device,
3909
+ {userId: 'userId', deviceId: 'deviceUrl', orgId: 'orgId'},
3910
3910
  ]);
3911
3911
 
3912
3912
  assert.deepEqual(cd.device, device);
@@ -10,6 +10,7 @@ import {
10
10
  ICE_AND_REACHABILITY_FAILED_CLIENT_CODE,
11
11
  ICE_FAILED_WITH_TURN_TLS_CLIENT_CODE,
12
12
  MISSING_ROAP_ANSWER_CLIENT_CODE,
13
+ BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP,
13
14
  } from '../../../../src/call-diagnostic/config';
14
15
  import Logger from '@webex/plugin-logger';
15
16
 
@@ -26,6 +27,7 @@ const {
26
27
  isUnauthorizedError,
27
28
  generateClientErrorCodeForIceFailure,
28
29
  isSdpOfferCreationError,
30
+ isWebrtcApiNotAvailableError,
29
31
  } = CallDiagnosticUtils;
30
32
 
31
33
  describe('internal-plugin-metrics', () => {
@@ -205,6 +207,29 @@ describe('internal-plugin-metrics', () => {
205
207
  });
206
208
  });
207
209
 
210
+ describe('isWebrtcApiNotAvailableError', () => {
211
+ type TestWebrtcApiNotAvailableError = {
212
+ code: number;
213
+ message: string;
214
+ name: string;
215
+ };
216
+
217
+ const error: TestWebrtcApiNotAvailableError = {
218
+ code: 30007,
219
+ name: 'WebrtcApiNotAvailableError',
220
+ message: 'RTCPeerConnection API is not available in this environment',
221
+ };
222
+
223
+ [
224
+ ['WebrtcApiNotAvailableError', error, true],
225
+ ['generic error', new Error('this is an error'), false],
226
+ ].forEach(([errorType, rawError, expected]) => {
227
+ it(`for ${errorType} rawError returns the correct result`, () => {
228
+ assert.strictEqual(isWebrtcApiNotAvailableError(rawError), expected);
229
+ });
230
+ });
231
+ });
232
+
208
233
  describe('isBrowserMediaErrorName', () => {
209
234
  [
210
235
  ['PermissionDeniedError', true],
@@ -685,4 +710,34 @@ describe('internal-plugin-metrics', () => {
685
710
  });
686
711
  });
687
712
  });
713
+
714
+ describe('isBrowserMediaError', () => {
715
+ it('should return true if error name is in BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP', () => {
716
+ // Use a known browser media error name from the config map
717
+ const errorName = Object.keys(BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP)[0];
718
+ const error = {name: errorName};
719
+ assert.isTrue(CallDiagnosticUtils.isBrowserMediaError(error));
720
+ });
721
+
722
+ it('should return false if error name is not in BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP', () => {
723
+ const error = {name: 'SomeOtherError'};
724
+ assert.isFalse(CallDiagnosticUtils.isBrowserMediaError(error));
725
+ });
726
+ });
727
+
728
+ describe('getBrowserMediaErrorCode', () => {
729
+ it('should return correct error code for known error name', () => {
730
+ const errorName = Object.keys(BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP)[0];
731
+ const error = {name: errorName};
732
+ assert.strictEqual(
733
+ CallDiagnosticUtils.getBrowserMediaErrorCode(error),
734
+ BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[errorName]
735
+ );
736
+ });
737
+
738
+ it('should return undefined for unknown error name', () => {
739
+ const error = {name: 'UnknownError'};
740
+ assert.isUndefined(CallDiagnosticUtils.getBrowserMediaErrorCode(error));
741
+ });
742
+ });
688
743
  });