@webex/plugin-meetings 3.0.0-beta.107 → 3.0.0-beta.109

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 (51) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +1 -1
  3. package/dist/constants.js +21 -2
  4. package/dist/constants.js.map +1 -1
  5. package/dist/controls-options-manager/enums.js +2 -0
  6. package/dist/controls-options-manager/enums.js.map +1 -1
  7. package/dist/controls-options-manager/types.js.map +1 -1
  8. package/dist/controls-options-manager/util.js +36 -0
  9. package/dist/controls-options-manager/util.js.map +1 -1
  10. package/dist/locus-info/controlsUtils.js +39 -1
  11. package/dist/locus-info/controlsUtils.js.map +1 -1
  12. package/dist/locus-info/index.js +55 -0
  13. package/dist/locus-info/index.js.map +1 -1
  14. package/dist/meeting/in-meeting-actions.js +9 -1
  15. package/dist/meeting/in-meeting-actions.js.map +1 -1
  16. package/dist/meeting/index.js +110 -17
  17. package/dist/meeting/index.js.map +1 -1
  18. package/dist/meeting-info/meeting-info-v2.js +33 -17
  19. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  20. package/dist/metrics/config.js +46 -3
  21. package/dist/metrics/config.js.map +1 -1
  22. package/dist/metrics/index.js +32 -1
  23. package/dist/metrics/index.js.map +1 -1
  24. package/dist/types/constants.d.ts +16 -0
  25. package/dist/types/controls-options-manager/enums.d.ts +2 -0
  26. package/dist/types/controls-options-manager/types.d.ts +7 -1
  27. package/dist/types/meeting/in-meeting-actions.d.ts +8 -0
  28. package/dist/types/meeting/index.d.ts +9 -4
  29. package/dist/types/meeting-info/meeting-info-v2.d.ts +4 -1
  30. package/dist/types/metrics/config.d.ts +23 -0
  31. package/dist/types/metrics/index.d.ts +17 -0
  32. package/package.json +19 -19
  33. package/src/constants.ts +22 -0
  34. package/src/controls-options-manager/enums.ts +2 -0
  35. package/src/controls-options-manager/types.ts +10 -0
  36. package/src/controls-options-manager/util.ts +45 -0
  37. package/src/locus-info/controlsUtils.ts +54 -0
  38. package/src/locus-info/index.ts +55 -0
  39. package/src/meeting/in-meeting-actions.ts +16 -0
  40. package/src/meeting/index.ts +107 -16
  41. package/src/meeting-info/meeting-info-v2.ts +22 -6
  42. package/src/metrics/config.ts +46 -0
  43. package/src/metrics/index.ts +29 -0
  44. package/test/unit/spec/controls-options-manager/util.js +108 -7
  45. package/test/unit/spec/locus-info/controlsUtils.js +112 -0
  46. package/test/unit/spec/locus-info/index.js +84 -1
  47. package/test/unit/spec/meeting/in-meeting-actions.ts +8 -0
  48. package/test/unit/spec/meeting/index.js +281 -18
  49. package/test/unit/spec/meeting-info/meetinginfov2.js +81 -16
  50. package/test/unit/spec/meetings/index.js +1 -1
  51. package/test/unit/spec/metrics/index.js +59 -1
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","triggerTimers","event","meeting","data","eventType","CALL_INITIATED","setStartCallInitJoinReq","LOCUS_JOIN_REQUEST","setEndCallInitJoinReq","setStartJoinReqResp","LOCUS_JOIN_RESPONSE","setEndJoinReqResp","setStartSetupDelay","mediaType","AUDIO","VIDEO","setStartSendingMediaDelay","RECEIVING_MEDIA_START","setEndSetupDelay","SENDING_MEDIA_START","setEndSendingMediaDelay","LOCAL_SDP_GENERATED","setStartLocalSDPGenRemoteSDPRecvDelay","REMOTE_SDP_RECEIVED","setEndLocalSDPGenRemoteSDPRecvDelay","Metrics","instance","_events","meetingCollection","keys","webex","options","meetingId","indexOf","LoggerProxy","logger","error","get","callEvents","MEDIA_QUALITY","sendMediaQualityAnalyzerMetrics","push","sendCallAnalyzerMetrics","info","identifiers","payload","eventId","uuid","v4","version","origin","name","networkType","userAgent","userAgentToString","userType","loginType","channel","clientInfo","clientType","clientVersion","CLIENT_NAME","localNetworkPrefix","meetings","geoHintInfo","clientAddress","osVersion","subClientType","os","getOSNameInternal","browser","browserVersion","originTime","triggered","Date","toISOString","senderCountryCode","countryCode","canProceed","eventData","webClientDomain","window","location","hostname","Object","prototype","hasOwnProperty","call","errors","trigger","pstnAudioType","mediaCapabilities","recoveredBy","joinTimes","isRoapCallEnabled","forEach","item","audioSetupDelay","videoSetupDelay","UNKNOWN","intervals","intervalData","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","err","showToUser","errorCode","statusCode","body","ERROR_CODE","MEETING_ERRORS","FREE_USER_MAX_PARTICIPANTS_EXCEEDED","PAID_USER_MAX_PARTICIPANTS_EXCEEDED","SERVICE_MAX_PARTICIPANTS_EXCEEDED","INACTIVE","EXCEEDED_MAX_JOINED_PARTICIPANTS","EXCEEDED_SERVICE_MAX_PARTICIPANTS","MEETING_IS_LOCKED","MEETING_IS_TERMINATING","MEETING_REQUIRE_MODERATOR_PIN_INTENT","MEETING_REQUIRE_MODERATOR_PIN","MEETING_REQUIRE_MODERATOR_ROLE","JOIN_RESTRICTED_USER","GET_RESTRICTED_USER","CREATE_MEDIA_RESTRICTED_USER","JOIN_RESTRICTED_USER_NOT_IN_ROOM","MEETING_NOT_FOUND","NOT_WEBEX_SITE","INVALID_JOIN_TIME","PHONE_NUMBER_NOT_A_NUMBER","PHONE_NUMBER_TOO_LONG","INVALID_DIALABLE_KEY","ONE_ON_ONE_TO_SELF_NOT_ALLOWED","REMOVED_PARTICIPANT","MEETING_LINK_NOT_FOUND","PHONE_NUMBER_TOO_SHORT_AFTER_IDD","INVALID_INVITEE_ADDRESS","PMR_ACCOUNT_LOCKED","RESOURCE_GUEST_FORBIDDEN","PMR_ACCOUNT_SUSPENDED","EMPTY_PHONE_NUMBER_OR_COUNTRY_CODE","INVALID_SINCE_OR_SEQUENCE_HASH_IN_REQUEST","CONVERSATION_NOT_FOUND","RECORDING_CONTROL_NOT_SUPPORTED","RECORDING_NOT_STARTED","RECORDING_NOT_ENABLED","generateErrorPayload","LOCUS_RESPONSE","shownToUser","errorPayload","category","errorDescription","fatal","notFatalErrorList","OTHER","errorData","httpCode","userAgentOption","browserInfo","util","format","metrics","clientName","toLowerCase","split","osInfo","process","env","NODE_ENV","metricName","metricFields","metricTags","internal","submitClientMetrics","type","config","fields","tags"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\nimport util from 'util';\n\nimport {includes} from 'lodash';\nimport uuid from 'uuid';\nimport window from 'global/window';\nimport anonymize from 'ip-anonymize';\n\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {MEETING_ERRORS} from '../constants';\nimport BrowserDetection from '../common/browser-detection';\n\nimport {\n error,\n eventType,\n errorCodes as ERROR_CODE,\n UNKNOWN,\n CLIENT_NAME,\n mediaType,\n} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\n// Apply a CIDR /28 format to the IPV4 and /96 to the IPV6 addresses\n// For reference : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing\nconst anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\nconst triggerTimers = ({event, meeting, data}) => {\n switch (event) {\n case eventType.CALL_INITIATED:\n meeting.setStartCallInitJoinReq();\n break;\n case eventType.LOCUS_JOIN_REQUEST:\n meeting.setEndCallInitJoinReq();\n meeting.setStartJoinReqResp();\n break;\n case eventType.LOCUS_JOIN_RESPONSE:\n meeting.setEndJoinReqResp();\n meeting.setStartSetupDelay(mediaType.AUDIO);\n meeting.setStartSetupDelay(mediaType.VIDEO);\n meeting.setStartSendingMediaDelay(mediaType.AUDIO);\n meeting.setStartSendingMediaDelay(mediaType.VIDEO);\n break;\n case eventType.RECEIVING_MEDIA_START:\n meeting.setEndSetupDelay(data.mediaType);\n break;\n case eventType.SENDING_MEDIA_START:\n meeting.setEndSendingMediaDelay(data.mediaType);\n break;\n case eventType.LOCAL_SDP_GENERATED:\n meeting.setStartLocalSDPGenRemoteSDPRecvDelay();\n break;\n case eventType.REMOTE_SDP_RECEIVED:\n meeting.setEndLocalSDPGenRemoteSDPRecvDelay();\n break;\n default:\n break;\n }\n};\n\n/**\n * @description Metrics handles all the call metrics events\n * @export\n * @class Metrics\n */\nclass Metrics {\n static instance: Metrics;\n\n _events: any;\n keys: any;\n meetingCollection: any;\n webex: any;\n\n /**\n * Create Metrics Object\n * @constructor\n * @public\n * @memberof Meetings\n */\n constructor() {\n if (!Metrics.instance) {\n /**\n * @instance\n * @type {Array}\n * @private\n * @memberof Metrics\n */\n this._events = [];\n /**\n * @instance\n * @type {MeetingCollection}\n * @private\n * @memberof Metrics\n */\n this.meetingCollection = null;\n /**\n * @instance\n * @type {MeetingCollection}\n * @private\n * @memberof Metrics\n */\n this.keys = Object.values(eventType);\n /**\n * @instance\n * @type {Metrics}\n * @private\n * @memberof Metrics\n */\n Metrics.instance = this;\n }\n\n // eslint-disable-next-line no-constructor-return\n return Metrics.instance;\n }\n\n /**\n * Initializes the Metrics singleton with a meeting Collection.\n *\n * @param {Object} meetingCollection meetings object\n * @param {Object} webex webex SDK object\n *\n * @returns {void}\n */\n initialSetup(meetingCollection: object, webex: object) {\n this.meetingCollection = meetingCollection;\n this.webex = webex;\n }\n\n /**\n * poste Meeting event metrics\n * @param {object} options {meetingId/meeting} as a json object\n * @param {Meeting} options.meeting Meeting object\n * @param {String} options.meetingId\n * @param {object} options.data\n * @param {object} options.event\n * @returns {object} null\n */\n postEvent(options: {meeting?: any; meetingId?: string; data?: object; event?: any} | any) {\n const {meetingId, data = {}, event} = options;\n let {meeting} = options;\n\n if (this.keys.indexOf(event) === -1) {\n LoggerProxy.logger.error(\n `Metrics:index#postEvent --> Event ${event} doesn't exist in dictionary`\n );\n }\n\n if (!meeting && meetingId) {\n meeting = this.meetingCollection.get(meetingId);\n options.meeting = meeting;\n }\n\n if (meeting) {\n triggerTimers(options);\n\n if (!meeting.callEvents) {\n meeting.callEvents = [];\n }\n if (event === eventType.MEDIA_QUALITY) {\n data.event = event;\n meeting.sendMediaQualityAnalyzerMetrics(data);\n } else {\n meeting.callEvents.push(event);\n data.event = event;\n meeting.sendCallAnalyzerMetrics(data);\n }\n } else {\n LoggerProxy.logger.info(\n `Metrics:index#postEvent --> Event received for meetingId:${meetingId}, but meeting not found in collection.`\n );\n }\n }\n\n /**\n * Docs for Call analyzer metrics\n * https://sqbu-github.cisco.com/WebExSquared/call-analyzer/wiki\n * https://sqbu-github.cisco.com/WebExSquared/event-dictionary/blob/master/diagnostic-events.raml\n */\n\n // eslint-disable-next-line @typescript-eslint/no-shadow\n initPayload(eventType, identifiers, options) {\n const payload: any = {\n eventId: uuid.v4(),\n version: 1,\n origin: {\n name: 'endpoint',\n networkType: 'unknown',\n userAgent: this.userAgentToString(),\n userType: options.userType,\n loginType: options.loginType,\n channel: options.channel,\n clientInfo: {\n clientType: options.clientType,\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),\n osVersion: getOSVersion() || 'unknown',\n subClientType: options.subClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n },\n originTime: {\n triggered: new Date().toISOString(),\n },\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: {\n name: eventType,\n canProceed: true,\n identifiers,\n eventData: {webClientDomain: window.location.hostname},\n },\n };\n\n // TODO: more options should be checked and some of them should be mandatory in certain conditions\n if (options) {\n if (Object.prototype.hasOwnProperty.call(options, 'canProceed')) {\n payload.event.canProceed = options.canProceed;\n }\n if (options.errors) {\n payload.event.errors = options.errors;\n }\n if (options.mediaType) {\n payload.event.mediaType = options.mediaType;\n }\n if (options.trigger) {\n payload.event.trigger = options.trigger;\n }\n if (options.pstnAudioType) {\n payload.event.pstnAudioType = options.pstnAudioType;\n }\n if (options.mediaCapabilities) {\n payload.event.mediaCapabilities = options.mediaCapabilities;\n }\n if (options.recoveredBy) {\n payload.event.recoveredBy = options.recoveredBy;\n }\n if (options.joinTimes) {\n payload.event.joinTimes = options.joinTimes;\n }\n if (options.isRoapCallEnabled) {\n payload.event.isRoapCallEnabled = options.isRoapCallEnabled;\n }\n ['breakoutMoveId', 'breakoutSessionId', 'breakoutGroupId'].forEach((item) => {\n if (options[item]) {\n payload.event.identifiers[item] = options[item];\n }\n });\n }\n\n return payload;\n }\n\n /**\n * get the payload specific for a media quality event through call analyzer\n * @param {String} eventType the event name\n * @param {Object} identifiers contains the identifiers needed for CA\n * @param {String} identifiers.correlationId\n * @param {String} identifiers.locusUrl\n * @param {String} identifiers.locusId\n * @param {Object} options\n * @param {Object} options.intervalData\n * @param {String} options.clientType\n * @returns {Object}\n * @public\n * @memberof Metrics\n */\n public initMediaPayload(\n // eslint-disable-next-line @typescript-eslint/no-shadow\n eventType: string,\n identifiers: {\n correlationId: string;\n locusUrl: string;\n locusId: string;\n },\n options:\n | {\n intervalData: object;\n clientType: string;\n }\n | any = {}\n ) {\n const {audioSetupDelay, videoSetupDelay, joinTimes} = options;\n\n const payload = {\n eventId: uuid.v4(),\n version: 1,\n origin: {\n audioSetupDelay,\n videoSetupDelay,\n name: 'endpoint',\n networkType: options.networkType || UNKNOWN,\n userAgent: this.userAgentToString(),\n clientInfo: {\n clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),\n os: getOSNameInternal(),\n osVersion: getOSVersion() || UNKNOWN,\n subClientType: options.subClientType,\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n },\n originTime: {\n triggered: new Date().toISOString(),\n },\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: {\n name: eventType,\n canProceed: true,\n identifiers,\n intervals: [options.intervalData],\n joinTimes,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || UNKNOWN,\n startTime: new Date().toISOString(),\n },\n },\n };\n\n return payload;\n }\n\n /**\n * This function Parses a Locus error and returns a diagnostic event payload.\n * It should keep updating from:\n * https://sqbu-github.cisco.com/WebExSquared/spark-client-framework/blob/master/spark-client-framework/Adapters/TelephonyAdapter/TelephonyAdapter.cpp#L920\n *\n * @param {Object} err the error Object from Locus response\n * @param {boolean} showToUser true if a toast is shown to user\n * @returns {{showToUser: boolean, category: string, errorDescription: string,\n * errorCode: number, errorData: *, fatal: boolean, name: string}}\n */\n parseLocusError(err: any, showToUser: boolean) {\n let errorCode;\n\n if (err && err.statusCode && err.statusCode >= 500) {\n errorCode = 1003;\n } else if (err && err.body && err.body.errorCode) {\n // locus error codes: https://sqbu-github.cisco.com/WebExSquared/locus/blob/master/server/src/main/resources/locus-error-codes.properties\n switch (ERROR_CODE[err.body.errorCode]) {\n case MEETING_ERRORS.FREE_USER_MAX_PARTICIPANTS_EXCEEDED:\n errorCode = 3007;\n break;\n case MEETING_ERRORS.PAID_USER_MAX_PARTICIPANTS_EXCEEDED:\n case MEETING_ERRORS.SERVICE_MAX_PARTICIPANTS_EXCEEDED:\n errorCode = 3002;\n break;\n case MEETING_ERRORS.INACTIVE:\n errorCode = 4001;\n break;\n case MEETING_ERRORS.EXCEEDED_MAX_JOINED_PARTICIPANTS:\n case MEETING_ERRORS.EXCEEDED_SERVICE_MAX_PARTICIPANTS:\n errorCode = 3001;\n break;\n case MEETING_ERRORS.MEETING_IS_LOCKED:\n errorCode = 4002;\n break;\n case MEETING_ERRORS.MEETING_IS_TERMINATING:\n errorCode = 4003;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_PIN_INTENT:\n errorCode = 4004;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_PIN:\n errorCode = 4005;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_ROLE:\n errorCode = 4006;\n break;\n case MEETING_ERRORS.JOIN_RESTRICTED_USER:\n case MEETING_ERRORS.GET_RESTRICTED_USER:\n case MEETING_ERRORS.CREATE_MEDIA_RESTRICTED_USER:\n errorCode = 3005;\n break;\n case MEETING_ERRORS.JOIN_RESTRICTED_USER_NOT_IN_ROOM:\n errorCode = 4007;\n break;\n case MEETING_ERRORS.MEETING_NOT_FOUND:\n errorCode = 4011;\n break;\n case MEETING_ERRORS.NOT_WEBEX_SITE:\n errorCode = 4012;\n break;\n case MEETING_ERRORS.INVALID_JOIN_TIME:\n errorCode = 4013;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_NOT_A_NUMBER:\n errorCode = 4016;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_TOO_LONG:\n errorCode = 4017;\n break;\n case MEETING_ERRORS.INVALID_DIALABLE_KEY:\n errorCode = 4018;\n break;\n case MEETING_ERRORS.ONE_ON_ONE_TO_SELF_NOT_ALLOWED:\n errorCode = 4019;\n break;\n case MEETING_ERRORS.REMOVED_PARTICIPANT:\n errorCode = 4020;\n break;\n case MEETING_ERRORS.MEETING_LINK_NOT_FOUND:\n errorCode = 4021;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_TOO_SHORT_AFTER_IDD:\n errorCode = 4022;\n break;\n case MEETING_ERRORS.INVALID_INVITEE_ADDRESS:\n errorCode = 4023;\n break;\n case MEETING_ERRORS.PMR_ACCOUNT_LOCKED:\n errorCode = 4024;\n break;\n case MEETING_ERRORS.RESOURCE_GUEST_FORBIDDEN:\n errorCode = 4025;\n break;\n case MEETING_ERRORS.PMR_ACCOUNT_SUSPENDED:\n errorCode = 4026;\n break;\n case MEETING_ERRORS.EMPTY_PHONE_NUMBER_OR_COUNTRY_CODE:\n errorCode = 4027;\n break;\n case MEETING_ERRORS.INVALID_SINCE_OR_SEQUENCE_HASH_IN_REQUEST:\n errorCode = 1006;\n break;\n case MEETING_ERRORS.CONVERSATION_NOT_FOUND:\n errorCode = 4028;\n break;\n case MEETING_ERRORS.RECORDING_CONTROL_NOT_SUPPORTED:\n case MEETING_ERRORS.RECORDING_NOT_STARTED:\n case MEETING_ERRORS.RECORDING_NOT_ENABLED:\n errorCode = 4029;\n break;\n default:\n errorCode = 4008;\n }\n } else {\n errorCode = 4008;\n }\n\n return this.generateErrorPayload(errorCode, showToUser, error.name.LOCUS_RESPONSE, err);\n }\n\n generateErrorPayload(errorCode, shownToUser, name, err) {\n if (error.errors[errorCode]) {\n const errorPayload: any = {\n shownToUser: shownToUser || false,\n category: error.errors[errorCode][2],\n errorDescription: error.errors[errorCode][0],\n errorCode,\n fatal: !includes(error.notFatalErrorList, errorCode),\n name: name || error.name.OTHER,\n };\n\n if (err && err.body) {\n errorPayload.errorData = {error: err.body};\n }\n\n if (err && err.statusCode) {\n errorPayload.httpCode = err.statusCode;\n }\n\n return errorPayload;\n }\n\n return null;\n }\n\n /**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\n userAgentToString() {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !==\n -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${this.webex.version}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${this.webex.version}`);\n }\n\n /**\n * Uploads given metric to the Metrics service as an Behavioral metric.\n * Metadata about the environment such as browser, OS, SDK and their versions\n * are automatically added when the metric is sent.\n *\n * The Metrics service will send an Behavioral metric to InfluxDB for\n * aggregation.\n * See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service.\n *\n * @param {string} metricName Name of the metric (measurement) to send\n * @param {Object} metricFields Key-valye pairs of data or values about this metric\n * @param {Object} metricTags Key-value pairs of metric metadata\n *\n * @returns {void}\n */\n sendBehavioralMetric(metricName: string, metricFields: object = {}, metricTags: object = {}) {\n this.webex.internal.metrics.submitClientMetrics(metricName, {\n type: this.webex.config.metrics.type,\n fields: metricFields,\n tags: metricTags,\n });\n }\n}\n\n// Export Metrics singleton ---------------------------------------------------\nconst instance = new Metrics();\n\nexport default instance;\n"],"mappings":"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"}
1
+ {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","triggerTimers","event","meeting","data","eventType","CALL_INITIATED","setStartCallInitJoinReq","LOCUS_JOIN_REQUEST","setEndCallInitJoinReq","setStartJoinReqResp","LOCUS_JOIN_RESPONSE","setEndJoinReqResp","setStartSetupDelay","mediaType","AUDIO","VIDEO","setStartSendingMediaDelay","RECEIVING_MEDIA_START","setEndSetupDelay","SENDING_MEDIA_START","setEndSendingMediaDelay","LOCAL_SDP_GENERATED","setStartLocalSDPGenRemoteSDPRecvDelay","REMOTE_SDP_RECEIVED","setEndLocalSDPGenRemoteSDPRecvDelay","Metrics","instance","_events","meetingCollection","keys","webex","options","meetingId","indexOf","LoggerProxy","logger","error","get","callEvents","MEDIA_QUALITY","sendMediaQualityAnalyzerMetrics","push","sendCallAnalyzerMetrics","info","identifiers","payload","eventId","uuid","v4","version","origin","name","networkType","userAgent","userAgentToString","userType","loginType","channel","clientInfo","clientType","clientVersion","CLIENT_NAME","localNetworkPrefix","meetings","geoHintInfo","clientAddress","osVersion","subClientType","os","getOSNameInternal","browser","browserVersion","originTime","triggered","Date","toISOString","senderCountryCode","countryCode","canProceed","eventData","webClientDomain","window","location","hostname","Object","prototype","hasOwnProperty","call","errors","trigger","pstnAudioType","mediaCapabilities","recoveredBy","joinTimes","isRoapCallEnabled","forEach","item","audioSetupDelay","videoSetupDelay","UNKNOWN","intervals","intervalData","sourceMetadata","applicationSoftwareType","applicationSoftwareVersion","mediaEngineSoftwareType","mediaEngineSoftwareVersion","startTime","err","showToUser","errorCode","statusCode","body","ERROR_CODE","MEETING_ERRORS","FREE_USER_MAX_PARTICIPANTS_EXCEEDED","PAID_USER_MAX_PARTICIPANTS_EXCEEDED","SERVICE_MAX_PARTICIPANTS_EXCEEDED","INACTIVE","EXCEEDED_MAX_JOINED_PARTICIPANTS","EXCEEDED_SERVICE_MAX_PARTICIPANTS","MEETING_IS_LOCKED","MEETING_IS_TERMINATING","MEETING_REQUIRE_MODERATOR_PIN_INTENT","MEETING_REQUIRE_MODERATOR_PIN","MEETING_REQUIRE_MODERATOR_ROLE","JOIN_RESTRICTED_USER","GET_RESTRICTED_USER","CREATE_MEDIA_RESTRICTED_USER","JOIN_RESTRICTED_USER_NOT_IN_ROOM","MEETING_NOT_FOUND","NOT_WEBEX_SITE","INVALID_JOIN_TIME","PHONE_NUMBER_NOT_A_NUMBER","PHONE_NUMBER_TOO_LONG","INVALID_DIALABLE_KEY","ONE_ON_ONE_TO_SELF_NOT_ALLOWED","REMOVED_PARTICIPANT","MEETING_LINK_NOT_FOUND","PHONE_NUMBER_TOO_SHORT_AFTER_IDD","INVALID_INVITEE_ADDRESS","PMR_ACCOUNT_LOCKED","RESOURCE_GUEST_FORBIDDEN","PMR_ACCOUNT_SUSPENDED","EMPTY_PHONE_NUMBER_OR_COUNTRY_CODE","INVALID_SINCE_OR_SEQUENCE_HASH_IN_REQUEST","CONVERSATION_NOT_FOUND","RECORDING_CONTROL_NOT_SUPPORTED","RECORDING_NOT_STARTED","RECORDING_NOT_ENABLED","generateErrorPayload","LOCUS_RESPONSE","serviceErrorCode","code","clientCodeError","WebexAPIServiceErrorCodes","OTHER","shownToUser","errorPayload","category","errorDescription","fatal","notFatalErrorList","errorData","httpCode","userAgentOption","browserInfo","util","format","metrics","clientName","toLowerCase","split","osInfo","process","env","NODE_ENV","metricName","metricFields","metricTags","internal","submitClientMetrics","type","config","fields","tags"],"sources":["index.ts"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\nimport util from 'util';\n\nimport {includes} from 'lodash';\nimport uuid from 'uuid';\nimport window from 'global/window';\nimport anonymize from 'ip-anonymize';\n\nimport {getOSNameInternal} from '@webex/internal-plugin-metrics';\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {MEETING_ERRORS} from '../constants';\nimport BrowserDetection from '../common/browser-detection';\n\nimport {\n error,\n eventType,\n errorCodes as ERROR_CODE,\n UNKNOWN,\n CLIENT_NAME,\n mediaType,\n WebexAPIServiceErrorCodes,\n} from './config';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\n// Apply a CIDR /28 format to the IPV4 and /96 to the IPV6 addresses\n// For reference : https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing\nconst anonymizeIPAddress = (localIp) => anonymize(localIp, 28, 96);\n\nconst triggerTimers = ({event, meeting, data}) => {\n switch (event) {\n case eventType.CALL_INITIATED:\n meeting.setStartCallInitJoinReq();\n break;\n case eventType.LOCUS_JOIN_REQUEST:\n meeting.setEndCallInitJoinReq();\n meeting.setStartJoinReqResp();\n break;\n case eventType.LOCUS_JOIN_RESPONSE:\n meeting.setEndJoinReqResp();\n meeting.setStartSetupDelay(mediaType.AUDIO);\n meeting.setStartSetupDelay(mediaType.VIDEO);\n meeting.setStartSendingMediaDelay(mediaType.AUDIO);\n meeting.setStartSendingMediaDelay(mediaType.VIDEO);\n break;\n case eventType.RECEIVING_MEDIA_START:\n meeting.setEndSetupDelay(data.mediaType);\n break;\n case eventType.SENDING_MEDIA_START:\n meeting.setEndSendingMediaDelay(data.mediaType);\n break;\n case eventType.LOCAL_SDP_GENERATED:\n meeting.setStartLocalSDPGenRemoteSDPRecvDelay();\n break;\n case eventType.REMOTE_SDP_RECEIVED:\n meeting.setEndLocalSDPGenRemoteSDPRecvDelay();\n break;\n default:\n break;\n }\n};\n\n/**\n * @description Metrics handles all the call metrics events\n * @export\n * @class Metrics\n */\nclass Metrics {\n static instance: Metrics;\n\n _events: any;\n keys: any;\n meetingCollection: any;\n webex: any;\n\n /**\n * Create Metrics Object\n * @constructor\n * @public\n * @memberof Meetings\n */\n constructor() {\n if (!Metrics.instance) {\n /**\n * @instance\n * @type {Array}\n * @private\n * @memberof Metrics\n */\n this._events = [];\n /**\n * @instance\n * @type {MeetingCollection}\n * @private\n * @memberof Metrics\n */\n this.meetingCollection = null;\n /**\n * @instance\n * @type {MeetingCollection}\n * @private\n * @memberof Metrics\n */\n this.keys = Object.values(eventType);\n /**\n * @instance\n * @type {Metrics}\n * @private\n * @memberof Metrics\n */\n Metrics.instance = this;\n }\n\n // eslint-disable-next-line no-constructor-return\n return Metrics.instance;\n }\n\n /**\n * Initializes the Metrics singleton with a meeting Collection.\n *\n * @param {Object} meetingCollection meetings object\n * @param {Object} webex webex SDK object\n *\n * @returns {void}\n */\n initialSetup(meetingCollection: object, webex: object) {\n this.meetingCollection = meetingCollection;\n this.webex = webex;\n }\n\n /**\n * poste Meeting event metrics\n * @param {object} options {meetingId/meeting} as a json object\n * @param {Meeting} options.meeting Meeting object\n * @param {String} options.meetingId\n * @param {object} options.data\n * @param {object} options.event\n * @returns {object} null\n */\n postEvent(options: {meeting?: any; meetingId?: string; data?: object; event?: any} | any) {\n const {meetingId, data = {}, event} = options;\n let {meeting} = options;\n\n if (this.keys.indexOf(event) === -1) {\n LoggerProxy.logger.error(\n `Metrics:index#postEvent --> Event ${event} doesn't exist in dictionary`\n );\n }\n\n if (!meeting && meetingId) {\n meeting = this.meetingCollection.get(meetingId);\n options.meeting = meeting;\n }\n\n if (meeting) {\n triggerTimers(options);\n\n if (!meeting.callEvents) {\n meeting.callEvents = [];\n }\n if (event === eventType.MEDIA_QUALITY) {\n data.event = event;\n meeting.sendMediaQualityAnalyzerMetrics(data);\n } else {\n meeting.callEvents.push(event);\n data.event = event;\n meeting.sendCallAnalyzerMetrics(data);\n }\n } else {\n LoggerProxy.logger.info(\n `Metrics:index#postEvent --> Event received for meetingId:${meetingId}, but meeting not found in collection.`\n );\n }\n }\n\n /**\n * Docs for Call analyzer metrics\n * https://sqbu-github.cisco.com/WebExSquared/call-analyzer/wiki\n * https://sqbu-github.cisco.com/WebExSquared/event-dictionary/blob/master/diagnostic-events.raml\n */\n\n // eslint-disable-next-line @typescript-eslint/no-shadow\n initPayload(eventType, identifiers, options) {\n const payload: any = {\n eventId: uuid.v4(),\n version: 1,\n origin: {\n name: 'endpoint',\n networkType: 'unknown',\n userAgent: this.userAgentToString(),\n userType: options.userType,\n loginType: options.loginType,\n channel: options.channel,\n clientInfo: {\n clientType: options.clientType,\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),\n osVersion: getOSVersion() || 'unknown',\n subClientType: options.subClientType,\n os: getOSNameInternal(),\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n },\n originTime: {\n triggered: new Date().toISOString(),\n },\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: {\n name: eventType,\n canProceed: true,\n identifiers,\n eventData: {webClientDomain: window.location.hostname},\n },\n };\n\n // TODO: more options should be checked and some of them should be mandatory in certain conditions\n if (options) {\n if (Object.prototype.hasOwnProperty.call(options, 'canProceed')) {\n payload.event.canProceed = options.canProceed;\n }\n if (options.errors) {\n payload.event.errors = options.errors;\n }\n if (options.mediaType) {\n payload.event.mediaType = options.mediaType;\n }\n if (options.trigger) {\n payload.event.trigger = options.trigger;\n }\n if (options.pstnAudioType) {\n payload.event.pstnAudioType = options.pstnAudioType;\n }\n if (options.mediaCapabilities) {\n payload.event.mediaCapabilities = options.mediaCapabilities;\n }\n if (options.recoveredBy) {\n payload.event.recoveredBy = options.recoveredBy;\n }\n if (options.joinTimes) {\n payload.event.joinTimes = options.joinTimes;\n }\n if (options.isRoapCallEnabled) {\n payload.event.isRoapCallEnabled = options.isRoapCallEnabled;\n }\n ['breakoutMoveId', 'breakoutSessionId', 'breakoutGroupId'].forEach((item) => {\n if (options[item]) {\n payload.event.identifiers[item] = options[item];\n }\n });\n }\n\n return payload;\n }\n\n /**\n * get the payload specific for a media quality event through call analyzer\n * @param {String} eventType the event name\n * @param {Object} identifiers contains the identifiers needed for CA\n * @param {String} identifiers.correlationId\n * @param {String} identifiers.locusUrl\n * @param {String} identifiers.locusId\n * @param {Object} options\n * @param {Object} options.intervalData\n * @param {String} options.clientType\n * @returns {Object}\n * @public\n * @memberof Metrics\n */\n public initMediaPayload(\n // eslint-disable-next-line @typescript-eslint/no-shadow\n eventType: string,\n identifiers: {\n correlationId: string;\n locusUrl: string;\n locusId: string;\n },\n options:\n | {\n intervalData: object;\n clientType: string;\n }\n | any = {}\n ) {\n const {audioSetupDelay, videoSetupDelay, joinTimes} = options;\n\n const payload = {\n eventId: uuid.v4(),\n version: 1,\n origin: {\n audioSetupDelay,\n videoSetupDelay,\n name: 'endpoint',\n networkType: options.networkType || UNKNOWN,\n userAgent: this.userAgentToString(),\n clientInfo: {\n clientType: options.clientType, // TODO: Only clientType: 'TEAMS_CLIENT' is whitelisted\n clientVersion: `${CLIENT_NAME}/${this.webex.version}`,\n localNetworkPrefix: anonymizeIPAddress(this.webex.meetings.geoHintInfo?.clientAddress),\n os: getOSNameInternal(),\n osVersion: getOSVersion() || UNKNOWN,\n subClientType: options.subClientType,\n browser: getBrowserName(),\n browserVersion: getBrowserVersion(),\n },\n },\n originTime: {\n triggered: new Date().toISOString(),\n },\n senderCountryCode: this.webex.meetings.geoHintInfo?.countryCode,\n event: {\n name: eventType,\n canProceed: true,\n identifiers,\n intervals: [options.intervalData],\n joinTimes,\n eventData: {\n webClientDomain: window.location.hostname,\n },\n sourceMetadata: {\n applicationSoftwareType: CLIENT_NAME,\n applicationSoftwareVersion: this.webex.version,\n mediaEngineSoftwareType: getBrowserName() || 'browser',\n mediaEngineSoftwareVersion: getOSVersion() || UNKNOWN,\n startTime: new Date().toISOString(),\n },\n },\n };\n\n return payload;\n }\n\n /**\n * This function Parses a Locus error and returns a diagnostic event payload.\n * It should keep updating from:\n * https://sqbu-github.cisco.com/WebExSquared/spark-client-framework/blob/master/spark-client-framework/Adapters/TelephonyAdapter/TelephonyAdapter.cpp#L920\n *\n * @param {Object} err the error Object from Locus response\n * @param {boolean} showToUser true if a toast is shown to user\n * @returns {{showToUser: boolean, category: string, errorDescription: string,\n * errorCode: number, errorData: *, fatal: boolean, name: string}}\n */\n parseLocusError(err: any, showToUser: boolean) {\n let errorCode;\n\n if (err && err.statusCode && err.statusCode >= 500) {\n errorCode = 1003;\n } else if (err && err.body && err.body.errorCode) {\n // locus error codes: https://sqbu-github.cisco.com/WebExSquared/locus/blob/master/server/src/main/resources/locus-error-codes.properties\n switch (ERROR_CODE[err.body.errorCode]) {\n case MEETING_ERRORS.FREE_USER_MAX_PARTICIPANTS_EXCEEDED:\n errorCode = 3007;\n break;\n case MEETING_ERRORS.PAID_USER_MAX_PARTICIPANTS_EXCEEDED:\n case MEETING_ERRORS.SERVICE_MAX_PARTICIPANTS_EXCEEDED:\n errorCode = 3002;\n break;\n case MEETING_ERRORS.INACTIVE:\n errorCode = 4001;\n break;\n case MEETING_ERRORS.EXCEEDED_MAX_JOINED_PARTICIPANTS:\n case MEETING_ERRORS.EXCEEDED_SERVICE_MAX_PARTICIPANTS:\n errorCode = 3001;\n break;\n case MEETING_ERRORS.MEETING_IS_LOCKED:\n errorCode = 4002;\n break;\n case MEETING_ERRORS.MEETING_IS_TERMINATING:\n errorCode = 4003;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_PIN_INTENT:\n errorCode = 4004;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_PIN:\n errorCode = 4005;\n break;\n case MEETING_ERRORS.MEETING_REQUIRE_MODERATOR_ROLE:\n errorCode = 4006;\n break;\n case MEETING_ERRORS.JOIN_RESTRICTED_USER:\n case MEETING_ERRORS.GET_RESTRICTED_USER:\n case MEETING_ERRORS.CREATE_MEDIA_RESTRICTED_USER:\n errorCode = 3005;\n break;\n case MEETING_ERRORS.JOIN_RESTRICTED_USER_NOT_IN_ROOM:\n errorCode = 4007;\n break;\n case MEETING_ERRORS.MEETING_NOT_FOUND:\n errorCode = 4011;\n break;\n case MEETING_ERRORS.NOT_WEBEX_SITE:\n errorCode = 4012;\n break;\n case MEETING_ERRORS.INVALID_JOIN_TIME:\n errorCode = 4013;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_NOT_A_NUMBER:\n errorCode = 4016;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_TOO_LONG:\n errorCode = 4017;\n break;\n case MEETING_ERRORS.INVALID_DIALABLE_KEY:\n errorCode = 4018;\n break;\n case MEETING_ERRORS.ONE_ON_ONE_TO_SELF_NOT_ALLOWED:\n errorCode = 4019;\n break;\n case MEETING_ERRORS.REMOVED_PARTICIPANT:\n errorCode = 4020;\n break;\n case MEETING_ERRORS.MEETING_LINK_NOT_FOUND:\n errorCode = 4021;\n break;\n case MEETING_ERRORS.PHONE_NUMBER_TOO_SHORT_AFTER_IDD:\n errorCode = 4022;\n break;\n case MEETING_ERRORS.INVALID_INVITEE_ADDRESS:\n errorCode = 4023;\n break;\n case MEETING_ERRORS.PMR_ACCOUNT_LOCKED:\n errorCode = 4024;\n break;\n case MEETING_ERRORS.RESOURCE_GUEST_FORBIDDEN:\n errorCode = 4025;\n break;\n case MEETING_ERRORS.PMR_ACCOUNT_SUSPENDED:\n errorCode = 4026;\n break;\n case MEETING_ERRORS.EMPTY_PHONE_NUMBER_OR_COUNTRY_CODE:\n errorCode = 4027;\n break;\n case MEETING_ERRORS.INVALID_SINCE_OR_SEQUENCE_HASH_IN_REQUEST:\n errorCode = 1006;\n break;\n case MEETING_ERRORS.CONVERSATION_NOT_FOUND:\n errorCode = 4028;\n break;\n case MEETING_ERRORS.RECORDING_CONTROL_NOT_SUPPORTED:\n case MEETING_ERRORS.RECORDING_NOT_STARTED:\n case MEETING_ERRORS.RECORDING_NOT_ENABLED:\n errorCode = 4029;\n break;\n default:\n errorCode = 4008;\n }\n } else {\n errorCode = 4008;\n }\n\n return this.generateErrorPayload(errorCode, showToUser, error.name.LOCUS_RESPONSE, err);\n }\n\n /**\n * Pareses webex api error.\n *\n * @param {object} err\n * @param {boolean} showToUser\n * @returns {object | null}\n */\n parseWebexApiError(err: any, showToUser: boolean) {\n const serviceErrorCode = err?.body?.code;\n const clientCodeError = WebexAPIServiceErrorCodes[serviceErrorCode];\n\n if (clientCodeError) {\n return this.generateErrorPayload(clientCodeError, showToUser, error.name.OTHER, err);\n }\n\n return null;\n }\n\n /**\n * Generates Error for the CA event\n *\n * @param {integer} errorCode\n * @param {boolean} shownToUser\n * @param {string} name\n * @param {any} err\n * @returns {any}\n */\n generateErrorPayload(errorCode, shownToUser, name, err) {\n if (error.errors[errorCode]) {\n const errorPayload: any = {\n shownToUser: shownToUser || false,\n category: error.errors[errorCode][2],\n errorDescription: error.errors[errorCode][0],\n errorCode,\n fatal: !includes(error.notFatalErrorList, errorCode),\n name: name || error.name.OTHER,\n serviceErrorCode: err?.body?.code,\n };\n\n if (err && err.body) {\n errorPayload.errorData = {error: err.body};\n }\n\n if (err && err.statusCode) {\n errorPayload.httpCode = err.statusCode;\n }\n\n return errorPayload;\n }\n\n return null;\n }\n\n /**\n * Returns a formated string of the user agent.\n *\n * @returns {string} formatted user agent information\n */\n userAgentToString() {\n let userAgentOption;\n let browserInfo;\n const clientInfo = util.format('client=%s', `${this.webex.meetings?.metrics?.clientName}`);\n\n if (\n ['chrome', 'firefox', 'msie', 'msedge', 'safari'].indexOf(getBrowserName().toLowerCase()) !==\n -1\n ) {\n browserInfo = util.format(\n 'browser=%s',\n `${getBrowserName().toLowerCase()}/${getBrowserVersion().split('.')[0]}`\n );\n }\n const osInfo = util.format('os=%s', `${getOSName()}/${getOSVersion().split('.')[0]}`);\n\n if (browserInfo) {\n userAgentOption = `(${browserInfo}`;\n }\n if (osInfo) {\n userAgentOption = userAgentOption\n ? `${userAgentOption}; ${clientInfo}; ${osInfo}`\n : `${clientInfo}; (${osInfo}`;\n }\n if (userAgentOption) {\n userAgentOption += ')';\n\n return util.format(\n 'webex-js-sdk/%s %s',\n `${process.env.NODE_ENV}-${this.webex.version}`,\n userAgentOption\n );\n }\n\n return util.format('webex-js-sdk/%s', `${process.env.NODE_ENV}-${this.webex.version}`);\n }\n\n /**\n * Uploads given metric to the Metrics service as an Behavioral metric.\n * Metadata about the environment such as browser, OS, SDK and their versions\n * are automatically added when the metric is sent.\n *\n * The Metrics service will send an Behavioral metric to InfluxDB for\n * aggregation.\n * See https://confluence-eng-gpk2.cisco.com/conf/display/WBXT/Getting+started+with+Metrics+Service.\n *\n * @param {string} metricName Name of the metric (measurement) to send\n * @param {Object} metricFields Key-valye pairs of data or values about this metric\n * @param {Object} metricTags Key-value pairs of metric metadata\n *\n * @returns {void}\n */\n sendBehavioralMetric(metricName: string, metricFields: object = {}, metricTags: object = {}) {\n this.webex.internal.metrics.submitClientMetrics(metricName, {\n type: this.webex.config.metrics.type,\n fields: metricFields,\n tags: metricTags,\n });\n }\n}\n\n// Export Metrics singleton ---------------------------------------------------\nconst instance = new Metrics();\n\nexport default instance;\n"],"mappings":"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"}
@@ -244,6 +244,12 @@ export declare const EVENT_TRIGGERS: {
244
244
  REMOTE_MEDIA_AUDIO_CREATED: string;
245
245
  REMOTE_MEDIA_SCREEN_SHARE_AUDIO_CREATED: string;
246
246
  REMOTE_MEDIA_VIDEO_LAYOUT_CHANGED: string;
247
+ MEETING_CONTROLS_MUTE_ON_ENTRY_UPDATED: string;
248
+ MEETING_CONTROLS_SHARE_CONTROL_UPDATED: string;
249
+ MEETING_CONTROLS_DISALLOW_UNMUTE_UPDATED: string;
250
+ MEETING_CONTROLS_REACTIONS_UPDATED: string;
251
+ MEETING_CONTROLS_VIEW_THE_PARTICIPANTS_LIST_UPDATED: string;
252
+ MEETING_CONTROLS_RAISE_HAND_UPDATED: string;
247
253
  };
248
254
  export declare const EVENT_TYPES: {
249
255
  SELF: string;
@@ -460,6 +466,12 @@ export declare const LOCUSINFO: {
460
466
  CONTROLS_MEETING_CONTAINER_UPDATED: string;
461
467
  CONTROLS_ENTRY_EXIT_TONE_UPDATED: string;
462
468
  CONTROLS_JOIN_BREAKOUT_FROM_MAIN: string;
469
+ CONTROLS_MUTE_ON_ENTRY_CHANGED: string;
470
+ CONTROLS_SHARE_CONTROL_CHANGED: string;
471
+ CONTROLS_DISALLOW_UNMUTE_CHANGED: string;
472
+ CONTROLS_REACTIONS_CHANGED: string;
473
+ CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED: string;
474
+ CONTROLS_RAISE_HAND_CHANGED: string;
463
475
  SELF_UNADMITTED_GUEST: string;
464
476
  SELF_ADMITTED_GUEST: string;
465
477
  SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED: string;
@@ -661,6 +673,10 @@ export declare const DISPLAY_HINTS: {
661
673
  DISABLE_LOBBY_TO_BREAKOUT: string;
662
674
  DISABLE_VIEW_THE_PARTICIPANT_LIST: string;
663
675
  ENABLE_VIEW_THE_PARTICIPANT_LIST: string;
676
+ DISABLE_RAISE_HAND: string;
677
+ ENABLE_RAISE_HAND: string;
678
+ DISABLE_VIDEO: string;
679
+ ENABLE_VIDEO: string;
664
680
  };
665
681
  export declare const SELF_ROLES: {
666
682
  COHOST: string;
@@ -5,8 +5,10 @@ declare enum Setting {
5
5
  }
6
6
  declare enum Control {
7
7
  audio = "audio",
8
+ raiseHand = "raiseHand",
8
9
  reactions = "reactions",
9
10
  shareControl = "shareControl",
11
+ video = "video",
10
12
  viewTheParticipantList = "viewTheParticipantList"
11
13
  }
12
14
  export { Control, Setting };
@@ -14,6 +14,9 @@ export interface AudioProperties {
14
14
  disallowUnmute?: boolean;
15
15
  muteOnEntry?: boolean;
16
16
  }
17
+ export interface RaiseHandProperties {
18
+ enabled?: boolean;
19
+ }
17
20
  export interface ReactionsProperties {
18
21
  enabled?: boolean;
19
22
  showDisplayNameWithReactions?: boolean;
@@ -21,10 +24,13 @@ export interface ReactionsProperties {
21
24
  export interface ShareControlProperties {
22
25
  control?: 'ANYONE' | 'MODERATOR_PRESENTER';
23
26
  }
27
+ export interface VideoProperties {
28
+ enabled?: boolean;
29
+ }
24
30
  export interface ViewTheParticipantListProperties {
25
31
  enabled?: boolean;
26
32
  }
27
- export type Properties = AudioProperties | ReactionsProperties | ShareControlProperties | ViewTheParticipantListProperties;
33
+ export type Properties = AudioProperties | RaiseHandProperties | ReactionsProperties | ShareControlProperties | VideoProperties | ViewTheParticipantListProperties;
28
34
  export interface ControlConfig<Props = Properties> {
29
35
  /**
30
36
  * The scope of the control within this object.
@@ -57,6 +57,10 @@ interface IInMeetingActions {
57
57
  canUpdateShareControl?: boolean;
58
58
  canEnableViewTheParticipantsList?: boolean;
59
59
  canDisableViewTheParticipantsList?: boolean;
60
+ canEnableRaiseHand?: boolean;
61
+ canDisableRaiseHand?: boolean;
62
+ canEnableVideo?: boolean;
63
+ canDisableVideo?: boolean;
60
64
  }
61
65
  /**
62
66
  * @class InMeetingActions
@@ -114,6 +118,10 @@ export default class InMeetingActions implements IInMeetingActions {
114
118
  canUpdateShareControl: any;
115
119
  canEnableViewTheParticipantsList: any;
116
120
  canDisableViewTheParticipantsList: any;
121
+ canEnableRaiseHand: any;
122
+ canDisableRaiseHand: any;
123
+ canEnableVideo: any;
124
+ canDisableVideo: any;
117
125
  /**
118
126
  * Returns all meeting action options
119
127
  * @returns {Object}
@@ -300,7 +300,7 @@ export default class Meeting extends StatelessWebexPlugin {
300
300
  mediaConnections: any[];
301
301
  mediaId?: string;
302
302
  meetingFiniteStateMachine: any;
303
- meetingInfo: object;
303
+ meetingInfo: any;
304
304
  meetingRequest: MeetingRequest;
305
305
  members: Members;
306
306
  options: object;
@@ -481,12 +481,17 @@ export default class Meeting extends StatelessWebexPlugin {
481
481
  * @memberof Meeting
482
482
  */
483
483
  getAnalyzerMetricsPrePayload(options: {
484
+ type?: string;
484
485
  event: string;
485
486
  trackingId: string;
486
487
  locus: object;
487
- mediaConnections: Array<any>;
488
- errors: object;
489
- } | any): {};
488
+ mediaConnections?: Array<any>;
489
+ errors?: object;
490
+ meetingLookupUrl?: string;
491
+ clientType?: any;
492
+ subClientType?: any;
493
+ [key: string]: any;
494
+ }): {};
490
495
  /**
491
496
  * Send the metrics to call-analyzer dashboard
492
497
  * @param {Object} options
@@ -101,6 +101,7 @@ export default class MeetingInfoV2 {
101
101
  * @param {String} installedOrgID
102
102
  * @param {String} locusId
103
103
  * @param {Object} extraParams
104
+ * @param {Object} options
104
105
  * @returns {Promise} returns a meeting info object
105
106
  * @public
106
107
  * @memberof MeetingInfo
@@ -108,5 +109,7 @@ export default class MeetingInfoV2 {
108
109
  fetchMeetingInfo(destination: string, type?: string, password?: string, captchaInfo?: {
109
110
  code: string;
110
111
  id: string;
111
- }, installedOrgID?: any, locusId?: any, extraParams?: {}): Promise<any>;
112
+ }, installedOrgID?: any, locusId?: any, extraParams?: object, options?: {
113
+ meetingId?: string;
114
+ }): Promise<any>;
112
115
  }
@@ -8,6 +8,8 @@ export declare const eventType: {
8
8
  REMOTE_SDP_RECEIVED: string;
9
9
  LOCUS_JOIN_REQUEST: string;
10
10
  LOCUS_JOIN_RESPONSE: string;
11
+ MEETING_INFO_REQUEST: string;
12
+ MEETING_INFO_RESPONSE: string;
11
13
  ALERT_DISPLAYED: string;
12
14
  ICE_START: string;
13
15
  ICE_END: string;
@@ -109,8 +111,29 @@ export declare const error: {
109
111
  4030: string[];
110
112
  5000: string[];
111
113
  5001: string[];
114
+ 4100: string[];
112
115
  };
113
116
  };
117
+ export declare const WebexAPIServiceErrorCodes: {
118
+ 58400: number;
119
+ 99002: number;
120
+ 99009: number;
121
+ 403040: number;
122
+ 403041: number;
123
+ 403038: number;
124
+ 403036: number;
125
+ 403043: number;
126
+ 403048: number;
127
+ 403049: number;
128
+ 403100: number;
129
+ 403101: number;
130
+ 403102: number;
131
+ 403103: number;
132
+ 403104: number;
133
+ 404001: number;
134
+ 404006: number;
135
+ 429005: number;
136
+ };
114
137
  export declare const trigger: {
115
138
  USER_INTERACTION: string;
116
139
  MERCURY_EVENT: string;
@@ -124,6 +124,23 @@ declare class Metrics {
124
124
  * errorCode: number, errorData: *, fatal: boolean, name: string}}
125
125
  */
126
126
  parseLocusError(err: any, showToUser: boolean): any;
127
+ /**
128
+ * Pareses webex api error.
129
+ *
130
+ * @param {object} err
131
+ * @param {boolean} showToUser
132
+ * @returns {object | null}
133
+ */
134
+ parseWebexApiError(err: any, showToUser: boolean): any;
135
+ /**
136
+ * Generates Error for the CA event
137
+ *
138
+ * @param {integer} errorCode
139
+ * @param {boolean} shownToUser
140
+ * @param {string} name
141
+ * @param {any} err
142
+ * @returns {any}
143
+ */
127
144
  generateErrorPayload(errorCode: any, shownToUser: any, name: any, err: any): any;
128
145
  /**
129
146
  * Returns a formated string of the user agent.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.107",
3
+ "version": "3.0.0-beta.109",
4
4
  "description": "",
5
5
  "license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
6
6
  "contributors": [
@@ -32,12 +32,12 @@
32
32
  "build": "yarn run -T tsc --declaration true --declarationDir ./dist/types"
33
33
  },
34
34
  "devDependencies": {
35
- "@webex/plugin-meetings": "3.0.0-beta.107",
36
- "@webex/test-helper-chai": "3.0.0-beta.107",
37
- "@webex/test-helper-mocha": "3.0.0-beta.107",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.107",
39
- "@webex/test-helper-retry": "3.0.0-beta.107",
40
- "@webex/test-helper-test-users": "3.0.0-beta.107",
35
+ "@webex/plugin-meetings": "3.0.0-beta.109",
36
+ "@webex/test-helper-chai": "3.0.0-beta.109",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.109",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.109",
39
+ "@webex/test-helper-retry": "3.0.0-beta.109",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.109",
41
41
  "chai": "^4.3.4",
42
42
  "chai-as-promised": "^7.1.1",
43
43
  "jsdom-global": "3.0.2",
@@ -46,19 +46,19 @@
46
46
  "typescript": "^4.7.4"
47
47
  },
48
48
  "dependencies": {
49
- "@webex/common": "3.0.0-beta.107",
49
+ "@webex/common": "3.0.0-beta.109",
50
50
  "@webex/internal-media-core": "1.38.0",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.107",
52
- "@webex/internal-plugin-device": "3.0.0-beta.107",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.107",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.107",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.107",
56
- "@webex/internal-plugin-support": "3.0.0-beta.107",
57
- "@webex/internal-plugin-user": "3.0.0-beta.107",
58
- "@webex/media-helpers": "3.0.0-beta.107",
59
- "@webex/plugin-people": "3.0.0-beta.107",
60
- "@webex/plugin-rooms": "3.0.0-beta.107",
61
- "@webex/webex-core": "3.0.0-beta.107",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.109",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.109",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.109",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.109",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.109",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.109",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.109",
58
+ "@webex/media-helpers": "3.0.0-beta.109",
59
+ "@webex/plugin-people": "3.0.0-beta.109",
60
+ "@webex/plugin-rooms": "3.0.0-beta.109",
61
+ "@webex/webex-core": "3.0.0-beta.109",
62
62
  "ampersand-collection": "^2.0.2",
63
63
  "bowser": "^2.11.0",
64
64
  "btoa": "^1.2.1",
package/src/constants.ts CHANGED
@@ -346,6 +346,14 @@ export const EVENT_TRIGGERS = {
346
346
  REMOTE_MEDIA_AUDIO_CREATED: 'media:remoteAudio:created',
347
347
  REMOTE_MEDIA_SCREEN_SHARE_AUDIO_CREATED: 'media:remoteScreenShareAudio:created',
348
348
  REMOTE_MEDIA_VIDEO_LAYOUT_CHANGED: 'media:remoteVideo:layoutChanged',
349
+ // Controls
350
+ MEETING_CONTROLS_MUTE_ON_ENTRY_UPDATED: 'meeting:controls:mute-on-entry:updated',
351
+ MEETING_CONTROLS_SHARE_CONTROL_UPDATED: 'meeting:controls:share-control:updated',
352
+ MEETING_CONTROLS_DISALLOW_UNMUTE_UPDATED: 'meeting:controls:disallow-unmute:updated',
353
+ MEETING_CONTROLS_REACTIONS_UPDATED: 'meeting:controls:reactions:updated',
354
+ MEETING_CONTROLS_VIEW_THE_PARTICIPANTS_LIST_UPDATED:
355
+ 'meeting:controls:view-the-participants-list:updated',
356
+ MEETING_CONTROLS_RAISE_HAND_UPDATED: 'meeting:controls:raise-hand:updated',
349
357
  };
350
358
 
351
359
  export const EVENT_TYPES = {
@@ -592,6 +600,12 @@ export const LOCUSINFO = {
592
600
  CONTROLS_MEETING_CONTAINER_UPDATED: 'CONTROLS_MEETING_CONTAINER_UPDATED',
593
601
  CONTROLS_ENTRY_EXIT_TONE_UPDATED: 'CONTROLS_ENTRY_EXIT_TONE_UPDATED',
594
602
  CONTROLS_JOIN_BREAKOUT_FROM_MAIN: 'CONTROLS_JOIN_BREAKOUT_FROM_MAIN',
603
+ CONTROLS_MUTE_ON_ENTRY_CHANGED: 'CONTROLS_MUTE_ON_ENTRY_CHANGED',
604
+ CONTROLS_SHARE_CONTROL_CHANGED: 'CONTROLS_SHARE_CONTROL_CHANGED',
605
+ CONTROLS_DISALLOW_UNMUTE_CHANGED: 'CONTROLS_DISALLOW_UNMUTE_CHANGED',
606
+ CONTROLS_REACTIONS_CHANGED: 'CONTROLS_REACTIONS_CHANGED',
607
+ CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED: 'CONTROLS_VIEW_THE_PARTICIPANTS_LIST_CHANGED',
608
+ CONTROLS_RAISE_HAND_CHANGED: 'CONTROLS_RAISE_HAND_CHANGED',
595
609
  SELF_UNADMITTED_GUEST: 'SELF_UNADMITTED_GUEST',
596
610
  SELF_ADMITTED_GUEST: 'SELF_ADMITTED_GUEST',
597
611
  SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED: 'SELF_REMOTE_VIDEO_MUTE_STATUS_UPDATED',
@@ -831,6 +845,14 @@ export const DISPLAY_HINTS = {
831
845
  // participants list
832
846
  DISABLE_VIEW_THE_PARTICIPANT_LIST: 'DISABLE_VIEW_THE_PARTICIPANT_LIST',
833
847
  ENABLE_VIEW_THE_PARTICIPANT_LIST: 'ENABLE_VIEW_THE_PARTICIPANT_LIST',
848
+
849
+ // raise hand
850
+ DISABLE_RAISE_HAND: 'DISABLE_RAISE_HAND',
851
+ ENABLE_RAISE_HAND: 'ENABLE_RAISE_HAND',
852
+
853
+ // video
854
+ DISABLE_VIDEO: 'DISABLE_VIDEO',
855
+ ENABLE_VIDEO: 'ENABLE_VIDEO',
834
856
  };
835
857
 
836
858
  export const SELF_ROLES = {
@@ -6,8 +6,10 @@ enum Setting {
6
6
 
7
7
  enum Control {
8
8
  audio = 'audio',
9
+ raiseHand = 'raiseHand',
9
10
  reactions = 'reactions',
10
11
  shareControl = 'shareControl',
12
+ video = 'video',
11
13
  viewTheParticipantList = 'viewTheParticipantList',
12
14
  }
13
15
 
@@ -17,6 +17,10 @@ export interface AudioProperties {
17
17
  muteOnEntry?: boolean;
18
18
  }
19
19
 
20
+ export interface RaiseHandProperties {
21
+ enabled?: boolean;
22
+ }
23
+
20
24
  export interface ReactionsProperties {
21
25
  enabled?: boolean;
22
26
  showDisplayNameWithReactions?: boolean;
@@ -26,14 +30,20 @@ export interface ShareControlProperties {
26
30
  control?: 'ANYONE' | 'MODERATOR_PRESENTER';
27
31
  }
28
32
 
33
+ export interface VideoProperties {
34
+ enabled?: boolean;
35
+ }
36
+
29
37
  export interface ViewTheParticipantListProperties {
30
38
  enabled?: boolean;
31
39
  }
32
40
 
33
41
  export type Properties =
34
42
  | AudioProperties
43
+ | RaiseHandProperties
35
44
  | ReactionsProperties
36
45
  | ShareControlProperties
46
+ | VideoProperties
37
47
  | ViewTheParticipantListProperties;
38
48
 
39
49
  export interface ControlConfig<Props = Properties> {
@@ -3,8 +3,10 @@ import {Control} from './enums';
3
3
  import {
4
4
  ControlConfig,
5
5
  AudioProperties,
6
+ RaiseHandProperties,
6
7
  ReactionsProperties,
7
8
  ViewTheParticipantListProperties,
9
+ VideoProperties,
8
10
  } from './types';
9
11
 
10
12
  /**
@@ -122,6 +124,22 @@ class Utils {
122
124
  return Utils.hasHints({requiredHints, displayHints});
123
125
  }
124
126
 
127
+ public static canUpdateRaiseHand(
128
+ control: ControlConfig<RaiseHandProperties>,
129
+ displayHints: Array<string>
130
+ ) {
131
+ const requiredHints = [];
132
+
133
+ if (control.properties.enabled === true) {
134
+ requiredHints.push(DISPLAY_HINTS.ENABLE_RAISE_HAND);
135
+ }
136
+ if (control.properties.enabled === false) {
137
+ requiredHints.push(DISPLAY_HINTS.DISABLE_RAISE_HAND);
138
+ }
139
+
140
+ return Utils.hasHints({requiredHints, displayHints});
141
+ }
142
+
125
143
  /**
126
144
  * Validate if an reactions-scoped control is allowed to be sent to the service.
127
145
  *
@@ -184,6 +202,22 @@ class Utils {
184
202
  return Utils.hasHints({requiredHints, displayHints});
185
203
  }
186
204
 
205
+ public static canUpdateVideo(
206
+ control: ControlConfig<VideoProperties>,
207
+ displayHints: Array<string>
208
+ ) {
209
+ const requiredHints = [];
210
+
211
+ if (control.properties.enabled === true) {
212
+ requiredHints.push(DISPLAY_HINTS.ENABLE_VIDEO);
213
+ }
214
+ if (control.properties.enabled === false) {
215
+ requiredHints.push(DISPLAY_HINTS.DISABLE_VIDEO);
216
+ }
217
+
218
+ return Utils.hasHints({requiredHints, displayHints});
219
+ }
220
+
187
221
  /**
188
222
  * Validate that a control can be sent to the service based on the provided
189
223
  * display hints.
@@ -200,6 +234,13 @@ class Utils {
200
234
  determinant = Utils.canUpdateAudio(control as ControlConfig<AudioProperties>, displayHints);
201
235
  break;
202
236
 
237
+ case Control.raiseHand:
238
+ determinant = Utils.canUpdateRaiseHand(
239
+ control as ControlConfig<RaiseHandProperties>,
240
+ displayHints
241
+ );
242
+ break;
243
+
203
244
  case Control.reactions:
204
245
  determinant = Utils.canUpdateReactions(
205
246
  control as ControlConfig<ReactionsProperties>,
@@ -211,6 +252,10 @@ class Utils {
211
252
  determinant = Utils.canUpdateShareControl(displayHints);
212
253
  break;
213
254
 
255
+ case Control.video:
256
+ determinant = Utils.canUpdateVideo(control as ControlConfig<VideoProperties>, displayHints);
257
+ break;
258
+
214
259
  case Control.viewTheParticipantList:
215
260
  determinant = Utils.canUpdateViewTheParticipantsList(
216
261
  control as ControlConfig<ViewTheParticipantListProperties>,