@webex/plugin-meetings 3.0.0-beta.66 → 3.0.0-beta.68

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 (57) hide show
  1. package/dist/breakouts/breakout.js +50 -9
  2. package/dist/breakouts/breakout.js.map +1 -1
  3. package/dist/breakouts/index.js +13 -2
  4. package/dist/breakouts/index.js.map +1 -1
  5. package/dist/constants.js +7 -2
  6. package/dist/constants.js.map +1 -1
  7. package/dist/locus-info/controlsUtils.js +15 -0
  8. package/dist/locus-info/controlsUtils.js.map +1 -1
  9. package/dist/locus-info/index.js +9 -6
  10. package/dist/locus-info/index.js.map +1 -1
  11. package/dist/meeting/index.js +5 -2
  12. package/dist/meeting/index.js.map +1 -1
  13. package/dist/meetings/collection.js +22 -0
  14. package/dist/meetings/collection.js.map +1 -1
  15. package/dist/meetings/index.js +91 -11
  16. package/dist/meetings/index.js.map +1 -1
  17. package/dist/meetings/util.js +32 -0
  18. package/dist/meetings/util.js.map +1 -1
  19. package/dist/members/collection.js +10 -0
  20. package/dist/members/collection.js.map +1 -1
  21. package/dist/members/index.js +21 -1
  22. package/dist/members/index.js.map +1 -1
  23. package/dist/metrics/config.js +3 -1
  24. package/dist/metrics/config.js.map +1 -1
  25. package/dist/metrics/index.js +5 -0
  26. package/dist/metrics/index.js.map +1 -1
  27. package/dist/types/constants.d.ts +3 -0
  28. package/dist/types/locus-info/index.d.ts +3 -3
  29. package/dist/types/meeting/index.d.ts +1 -0
  30. package/dist/types/meetings/collection.d.ts +8 -0
  31. package/dist/types/meetings/index.d.ts +18 -0
  32. package/dist/types/members/collection.d.ts +5 -0
  33. package/dist/types/members/index.d.ts +8 -0
  34. package/dist/types/metrics/config.d.ts +2 -0
  35. package/package.json +18 -18
  36. package/src/breakouts/README.md +6 -0
  37. package/src/breakouts/breakout.ts +27 -3
  38. package/src/breakouts/index.ts +14 -0
  39. package/src/constants.ts +3 -0
  40. package/src/locus-info/controlsUtils.ts +19 -0
  41. package/src/locus-info/index.ts +8 -5
  42. package/src/meeting/index.ts +3 -2
  43. package/src/meetings/collection.ts +20 -0
  44. package/src/meetings/index.ts +110 -2
  45. package/src/meetings/util.ts +38 -0
  46. package/src/members/collection.ts +8 -0
  47. package/src/members/index.ts +24 -1
  48. package/src/metrics/config.ts +2 -0
  49. package/src/metrics/index.ts +5 -0
  50. package/test/unit/spec/breakouts/breakout.ts +36 -4
  51. package/test/unit/spec/breakouts/index.ts +10 -0
  52. package/test/unit/spec/locus-info/controlsUtils.js +21 -0
  53. package/test/unit/spec/locus-info/index.js +63 -0
  54. package/test/unit/spec/meetings/collection.js +14 -0
  55. package/test/unit/spec/meetings/index.js +183 -6
  56. package/test/unit/spec/meetings/utils.js +46 -0
  57. package/test/unit/spec/members/index.js +38 -0
@@ -1 +1 @@
1
- {"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","anonymizeIPAddress","localIp","anonymize","triggerTimers","event","meeting","data","eventType","CALL_INITIATED","setStartCallInitiateJoinReq","LOCUS_JOIN_REQUEST","setEndCallInitiateJoinReq","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","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","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.setStartCallInitiateJoinReq();\n break;\n case eventType.LOCUS_JOIN_REQUEST:\n meeting.setEndCallInitiateJoinReq();\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 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 }\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 = 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","setStartCallInitiateJoinReq","LOCUS_JOIN_REQUEST","setEndCallInitiateJoinReq","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","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.setStartCallInitiateJoinReq();\n break;\n case eventType.LOCUS_JOIN_REQUEST:\n meeting.setEndCallInitiateJoinReq();\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 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 = 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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"}
@@ -5,6 +5,7 @@ export declare const ALERT = "alert";
5
5
  export declare const ANSWER = "answer";
6
6
  export declare const CALL = "call";
7
7
  export declare const CORRELATION_ID = "correlationId";
8
+ export declare const MEETINGNUMBER = "meetingNumber";
8
9
  export declare const CONVERSATION_URL = "conversationUrl";
9
10
  export declare const CALENDAR = "calendar";
10
11
  export declare const CALENDAR_EVENTS_API = "calendarEvents";
@@ -66,6 +67,7 @@ export declare const _JOIN_ = "JOIN";
66
67
  export declare const _JOINED_ = "JOINED";
67
68
  export declare const _LOCUS_ID_ = "LOCUS_ID";
68
69
  export declare const _LEFT_ = "LEFT";
70
+ export declare const _MOVED_ = "MOVED";
69
71
  export declare const _MEETING_LINK_ = "MEETING_LINK";
70
72
  export declare const _MEETING_UUID_ = "MEETING_UUID";
71
73
  export declare const _MEETING_ = "MEETING";
@@ -210,6 +212,7 @@ export declare const EVENT_TRIGGERS: {
210
212
  MEETING_BREAKOUTS_CLOSING: string;
211
213
  MEETING_BREAKOUTS_MESSAGE: string;
212
214
  MEMBERS_UPDATE: string;
215
+ MEMBERS_CLEAR: string;
213
216
  MEMBERS_CONTENT_UPDATE: string;
214
217
  MEMBERS_HOST_UPDATE: string;
215
218
  MEMBERS_SELF_UPDATE: string;
@@ -146,13 +146,13 @@ export default class LocusInfo extends EventsScope {
146
146
  */
147
147
  updateParticipantDeltas(participants?: Array<any>): void;
148
148
  /**
149
- *
149
+ * update meeting's members
150
150
  * @param {Object} participants new participants object
151
- * @param {boolen} deltaParticpantFlag delta event
151
+ * @param {Boolean} isReplace is replace the whole members
152
152
  * @returns {Array} updatedParticipants
153
153
  * @memberof LocusInfo
154
154
  */
155
- updateParticipants(participants: object): void;
155
+ updateParticipants(participants: object, isReplace?: boolean): void;
156
156
  /**
157
157
  * @param {Object} controls
158
158
  * @returns {undefined}
@@ -370,6 +370,7 @@ export default class Meeting extends StatelessWebexPlugin {
370
370
  resourceUrl: string;
371
371
  selfId: string;
372
372
  state: any;
373
+ webexMeetingId: string;
373
374
  namespace: string;
374
375
  /**
375
376
  * @param {Object} attrs
@@ -20,4 +20,12 @@ export default class MeetingCollection extends Collection {
20
20
  * @memberof MeetingCollection
21
21
  */
22
22
  getByKey(key: string, value: any): any;
23
+ /**
24
+ * get a specific meeting searching for key
25
+ * @param {String} breakoutUrl
26
+ * @returns {Meeting} if found, else returns null
27
+ * @public
28
+ * @memberof MeetingCollection
29
+ */
30
+ getActiveBreakoutLocus(breakoutUrl: string): any;
23
31
  }
@@ -68,6 +68,24 @@ export default class Meetings extends WebexPlugin {
68
68
  * @memberof Meetings
69
69
  */
70
70
  constructor(...args: any[]);
71
+ /**
72
+ * check whether you need to handle this main session's locus data or not
73
+ * @param {Object} meeting current meeting data
74
+ * @param {Object} newLocus new locus data
75
+ * @returns {boolean}
76
+ * @private
77
+ * @memberof Meetings
78
+ */
79
+ private isNeedHandleMainLocus;
80
+ /**
81
+ * check whether you need to handle this locus data or not
82
+ * @param {Object} meeting old locus data
83
+ * @param {Object} newLocus new locus data
84
+ * @returns {boolean}
85
+ * @private
86
+ * @memberof Meetings
87
+ */
88
+ private isNeedHandleLocusDTO;
71
89
  /**
72
90
  * handle locus events and takes meeting actions with them as they come in
73
91
  * @param {Object} data a locus event
@@ -21,4 +21,9 @@ export default class MembersCollection {
21
21
  * @memberof MembersCollection
22
22
  */
23
23
  getAll(): any;
24
+ /**
25
+ * @returns {void}
26
+ * reset members
27
+ */
28
+ reset(): void;
24
29
  }
@@ -92,6 +92,13 @@ export default class Members extends StatelessWebexPlugin {
92
92
  newHost: any;
93
93
  oldHost: any;
94
94
  }): void;
95
+ /**
96
+ * clear member collection
97
+ * @returns {void}
98
+ * @private
99
+ * @memberof Members
100
+ */
101
+ clearMembers(): void;
95
102
  /**
96
103
  * when new participant updates come in, both delta and full participants, update them in members collection
97
104
  * delta object in the event will have {updated, added} and full will be the full membersCollection
@@ -103,6 +110,7 @@ export default class Members extends StatelessWebexPlugin {
103
110
  */
104
111
  locusParticipantsUpdate(payload: {
105
112
  participants: object;
113
+ isReplace?: boolean;
106
114
  }): void;
107
115
  /**
108
116
  * Internal update the content id
@@ -43,6 +43,8 @@ export declare const eventType: {
43
43
  PSTN_AUDIO_ATTEMPT_START: string;
44
44
  PSTN_AUDIO_ATTEMPT_FINISH: string;
45
45
  PSTN_AUDIO_ATTEMPT_SKIP: string;
46
+ MOVE_TO_BREAKOUT: string;
47
+ JOIN_BREAKOUT_RESPONSE: string;
46
48
  };
47
49
  export declare const error: {
48
50
  name: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webex/plugin-meetings",
3
- "version": "3.0.0-beta.66",
3
+ "version": "3.0.0-beta.68",
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.66",
36
- "@webex/test-helper-chai": "3.0.0-beta.66",
37
- "@webex/test-helper-mocha": "3.0.0-beta.66",
38
- "@webex/test-helper-mock-webex": "3.0.0-beta.66",
39
- "@webex/test-helper-retry": "3.0.0-beta.66",
40
- "@webex/test-helper-test-users": "3.0.0-beta.66",
35
+ "@webex/plugin-meetings": "3.0.0-beta.68",
36
+ "@webex/test-helper-chai": "3.0.0-beta.68",
37
+ "@webex/test-helper-mocha": "3.0.0-beta.68",
38
+ "@webex/test-helper-mock-webex": "3.0.0-beta.68",
39
+ "@webex/test-helper-retry": "3.0.0-beta.68",
40
+ "@webex/test-helper-test-users": "3.0.0-beta.68",
41
41
  "chai": "^4.3.4",
42
42
  "chai-as-promised": "^7.1.1",
43
43
  "jsdom-global": "3.0.2",
@@ -46,18 +46,18 @@
46
46
  "typescript": "^4.7.4"
47
47
  },
48
48
  "dependencies": {
49
- "@webex/common": "3.0.0-beta.66",
49
+ "@webex/common": "3.0.0-beta.68",
50
50
  "@webex/internal-media-core": "1.35.7",
51
- "@webex/internal-plugin-conversation": "3.0.0-beta.66",
52
- "@webex/internal-plugin-device": "3.0.0-beta.66",
53
- "@webex/internal-plugin-llm": "3.0.0-beta.66",
54
- "@webex/internal-plugin-mercury": "3.0.0-beta.66",
55
- "@webex/internal-plugin-metrics": "3.0.0-beta.66",
56
- "@webex/internal-plugin-support": "3.0.0-beta.66",
57
- "@webex/internal-plugin-user": "3.0.0-beta.66",
58
- "@webex/plugin-people": "3.0.0-beta.66",
59
- "@webex/plugin-rooms": "3.0.0-beta.66",
60
- "@webex/webex-core": "3.0.0-beta.66",
51
+ "@webex/internal-plugin-conversation": "3.0.0-beta.68",
52
+ "@webex/internal-plugin-device": "3.0.0-beta.68",
53
+ "@webex/internal-plugin-llm": "3.0.0-beta.68",
54
+ "@webex/internal-plugin-mercury": "3.0.0-beta.68",
55
+ "@webex/internal-plugin-metrics": "3.0.0-beta.68",
56
+ "@webex/internal-plugin-support": "3.0.0-beta.68",
57
+ "@webex/internal-plugin-user": "3.0.0-beta.68",
58
+ "@webex/plugin-people": "3.0.0-beta.68",
59
+ "@webex/plugin-rooms": "3.0.0-beta.68",
60
+ "@webex/webex-core": "3.0.0-beta.68",
61
61
  "ampersand-collection": "^2.0.2",
62
62
  "bowser": "^2.11.0",
63
63
  "btoa": "^1.2.1",
@@ -41,6 +41,12 @@ The following are methods available to attendees of a meeting:
41
41
  ```javascript
42
42
  // Join a breakout
43
43
  // This can be used when the participant is in the main session or in a different breakout session
44
+ // when call join function, should send message to metrics
45
+ /* Breakout Sessions created during meetings allow participants to move into smaller breakout sessions and then
46
+ return to the main meeting at a later time. These moves can be initiated by the user or by the meeting
47
+ host/co-host. The goal of this metric is to track these moves in production by instrumenting them for
48
+ analysis from the end user's experience perspective.
49
+ */
44
50
  breakout.join();
45
51
 
46
52
  // Leave a breakout
@@ -4,11 +4,13 @@
4
4
 
5
5
  import {WebexPlugin} from '@webex/webex-core';
6
6
 
7
+ import uuid from 'uuid';
7
8
  import {HTTP_VERBS, MEETINGS} from '../constants';
8
9
  import LocusInfo from '../locus-info';
9
10
  import Members from '../members';
10
11
  import BreakoutRequest from './request';
11
-
12
+ import Metrics from '../metrics';
13
+ import {eventType} from '../metrics/config';
12
14
  /**
13
15
  * @class
14
16
  */
@@ -55,8 +57,19 @@ const Breakout = WebexPlugin.extend({
55
57
  * Joins the breakout session
56
58
  * @returns {Promise}
57
59
  */
58
- join() {
59
- return this.request({
60
+ async join() {
61
+ const breakoutMoveId = uuid.v4();
62
+ const {meetingId} = this.collection.parent;
63
+ Metrics.postEvent({
64
+ event: eventType.MOVE_TO_BREAKOUT,
65
+ meetingId,
66
+ data: {
67
+ breakoutMoveId,
68
+ breakoutSessionId: this.sessionId,
69
+ breakoutGroupId: this.groupId,
70
+ },
71
+ });
72
+ const result = await this.request({
60
73
  method: HTTP_VERBS.POST,
61
74
  uri: `${this.url}/move`,
62
75
  body: {
@@ -64,6 +77,17 @@ const Breakout = WebexPlugin.extend({
64
77
  sessionId: this.sessionId,
65
78
  },
66
79
  });
80
+ Metrics.postEvent({
81
+ event: eventType.JOIN_BREAKOUT_RESPONSE,
82
+ meetingId,
83
+ data: {
84
+ breakoutMoveId,
85
+ breakoutSessionId: this.sessionId,
86
+ breakoutGroupId: this.groupId,
87
+ },
88
+ });
89
+
90
+ return result;
67
91
  },
68
92
 
69
93
  /**
@@ -39,6 +39,7 @@ const Breakouts = WebexPlugin.extend({
39
39
  groups: 'array', // appears when create breakouts
40
40
  editLock: 'object', // appears when getBreakout info editlock = true
41
41
  intervalID: 'number',
42
+ meetingId: 'string',
42
43
  },
43
44
 
44
45
  children: {
@@ -56,6 +57,19 @@ const Breakouts = WebexPlugin.extend({
56
57
  return this.sessionType === BREAKOUTS.SESSION_TYPES.MAIN;
57
58
  },
58
59
  },
60
+ isActiveBreakout: {
61
+ deps: ['sessionType', 'status'],
62
+ /**
63
+ * Returns true if the breakout status is active
64
+ * @returns {boolean}
65
+ */
66
+ fn() {
67
+ return (
68
+ this.sessionType === BREAKOUTS.SESSION_TYPES.BREAKOUT &&
69
+ (this.status === BREAKOUTS.STATUS.OPEN || this.status === BREAKOUTS.STATUS.CLOSING)
70
+ );
71
+ },
72
+ },
59
73
  breakoutGroupId: {
60
74
  deps: ['groups'],
61
75
  /**
package/src/constants.ts CHANGED
@@ -11,6 +11,7 @@ export const ANSWER = 'answer';
11
11
 
12
12
  export const CALL = 'call';
13
13
  export const CORRELATION_ID = 'correlationId';
14
+ export const MEETINGNUMBER = 'meetingNumber';
14
15
  export const CONVERSATION_URL = 'conversationUrl';
15
16
  export const CALENDAR = 'calendar';
16
17
  export const CALENDAR_EVENTS_API = 'calendarEvents';
@@ -93,6 +94,7 @@ export const _JOINED_ = 'JOINED';
93
94
 
94
95
  export const _LOCUS_ID_ = 'LOCUS_ID';
95
96
  export const _LEFT_ = 'LEFT';
97
+ export const _MOVED_ = 'MOVED';
96
98
 
97
99
  export const _MEETING_LINK_ = 'MEETING_LINK';
98
100
  export const _MEETING_UUID_ = 'MEETING_UUID';
@@ -311,6 +313,7 @@ export const EVENT_TRIGGERS = {
311
313
  MEETING_BREAKOUTS_CLOSING: 'meeting:breakouts:closing',
312
314
  MEETING_BREAKOUTS_MESSAGE: 'meeting:breakouts:message',
313
315
  MEMBERS_UPDATE: 'members:update',
316
+ MEMBERS_CLEAR: 'members:clear',
314
317
  MEMBERS_CONTENT_UPDATE: 'members:content:update',
315
318
  MEMBERS_HOST_UPDATE: 'members:host:update',
316
319
  MEMBERS_SELF_UPDATE: 'members:self:update',
@@ -119,4 +119,23 @@ ControlsUtils.getId = (controls: any) => {
119
119
  return null;
120
120
  };
121
121
 
122
+ /**
123
+ * check whether to replace the meeting's members or not.
124
+ * For case joined breakout session, need replace meeting's members
125
+ * @param {LocusControls} oldControls
126
+ * @param {LocusControls} controls
127
+ * @returns {Boolean}
128
+ */
129
+ ControlsUtils.isNeedReplaceMembers = (oldControls: any, controls: any) => {
130
+ // no breakout case
131
+ if (!oldControls?.breakout || !controls?.breakout) {
132
+ return false;
133
+ }
134
+
135
+ return (
136
+ oldControls.breakout.groupId !== controls.breakout.groupId ||
137
+ oldControls.breakout.sessionId !== controls.breakout.sessionId
138
+ );
139
+ };
140
+
122
141
  export default ControlsUtils;
@@ -276,8 +276,9 @@ export default class LocusInfo extends EventsScope {
276
276
  this.updateParticipantDeltas(locus.participants);
277
277
  this.scheduledMeeting = locus.meeting || null;
278
278
  this.participants = locus.participants;
279
+ const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
279
280
  this.updateLocusInfo(locus);
280
- this.updateParticipants(locus.participants);
281
+ this.updateParticipants(locus.participants, isReplaceMembers);
281
282
  this.isMeetingActive();
282
283
  this.handleOneOnOneEvent(eventType);
283
284
  this.updateEmbeddedApps(locus.embeddedApps);
@@ -336,8 +337,9 @@ export default class LocusInfo extends EventsScope {
336
337
  * @memberof LocusInfo
337
338
  */
338
339
  onDeltaLocus(locus: any) {
340
+ const isReplaceMembers = ControlsUtils.isNeedReplaceMembers(this.controls, locus.controls);
339
341
  this.updateLocusInfo(locus);
340
- this.updateParticipants(locus.participants);
342
+ this.updateParticipants(locus.participants, isReplaceMembers);
341
343
  this.isMeetingActive();
342
344
  }
343
345
 
@@ -653,13 +655,13 @@ export default class LocusInfo extends EventsScope {
653
655
  }
654
656
 
655
657
  /**
656
- *
658
+ * update meeting's members
657
659
  * @param {Object} participants new participants object
658
- * @param {boolen} deltaParticpantFlag delta event
660
+ * @param {Boolean} isReplace is replace the whole members
659
661
  * @returns {Array} updatedParticipants
660
662
  * @memberof LocusInfo
661
663
  */
662
- updateParticipants(participants: object) {
664
+ updateParticipants(participants: object, isReplace?: boolean) {
663
665
  this.emitScoped(
664
666
  {
665
667
  file: 'locus-info',
@@ -672,6 +674,7 @@ export default class LocusInfo extends EventsScope {
672
674
  selfIdentity: this.parsedLocus.self && this.parsedLocus.self.selfIdentity,
673
675
  selfId: this.parsedLocus.self && this.parsedLocus.self.selfId,
674
676
  hostId: this.parsedLocus.host && this.parsedLocus.host.hostId,
677
+ isReplace,
675
678
  }
676
679
  );
677
680
  }
@@ -516,6 +516,7 @@ export default class Meeting extends StatelessWebexPlugin {
516
516
  resourceUrl: string;
517
517
  selfId: string;
518
518
  state: any;
519
+ webexMeetingId: string;
519
520
 
520
521
  namespace = MEETINGS;
521
522
 
@@ -552,7 +553,7 @@ export default class Meeting extends StatelessWebexPlugin {
552
553
  */
553
554
  this.id = uuid.v4();
554
555
  /**
555
- * Correlation ID used for network tracking of meeting join
556
+ * Correlation ID used for network tracking of meeting
556
557
  * @instance
557
558
  * @type {String}
558
559
  * @readonly
@@ -609,7 +610,7 @@ export default class Meeting extends StatelessWebexPlugin {
609
610
  * @memberof Meeting
610
611
  */
611
612
  // @ts-ignore
612
- this.breakouts = new Breakouts({}, {parent: this.webex});
613
+ this.breakouts = new Breakouts({meetingId: this.id}, {parent: this.webex});
613
614
  /**
614
615
  * helper class for managing receive slots (for multistream media connections)
615
616
  */
@@ -40,4 +40,24 @@ export default class MeetingCollection extends Collection {
40
40
 
41
41
  return null;
42
42
  }
43
+
44
+ /**
45
+ * get a specific meeting searching for key
46
+ * @param {String} breakoutUrl
47
+ * @returns {Meeting} if found, else returns null
48
+ * @public
49
+ * @memberof MeetingCollection
50
+ */
51
+ public getActiveBreakoutLocus(breakoutUrl: string) {
52
+ if (breakoutUrl) {
53
+ // @ts-ignore
54
+ return find(
55
+ // @ts-ignore
56
+ this.meetings,
57
+ (meeting) => meeting.breakouts?.url === breakoutUrl && meeting.breakouts?.isActiveBreakout
58
+ );
59
+ }
60
+
61
+ return null;
62
+ }
43
63
  }