@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.
- package/dist/breakouts/breakout.js +50 -9
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/index.js +13 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +7 -2
- package/dist/constants.js.map +1 -1
- package/dist/locus-info/controlsUtils.js +15 -0
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +9 -6
- package/dist/locus-info/index.js.map +1 -1
- package/dist/meeting/index.js +5 -2
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/collection.js +22 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +91 -11
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/util.js +32 -0
- package/dist/meetings/util.js.map +1 -1
- package/dist/members/collection.js +10 -0
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +21 -1
- package/dist/members/index.js.map +1 -1
- package/dist/metrics/config.js +3 -1
- package/dist/metrics/config.js.map +1 -1
- package/dist/metrics/index.js +5 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/types/constants.d.ts +3 -0
- package/dist/types/locus-info/index.d.ts +3 -3
- package/dist/types/meeting/index.d.ts +1 -0
- package/dist/types/meetings/collection.d.ts +8 -0
- package/dist/types/meetings/index.d.ts +18 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +8 -0
- package/dist/types/metrics/config.d.ts +2 -0
- package/package.json +18 -18
- package/src/breakouts/README.md +6 -0
- package/src/breakouts/breakout.ts +27 -3
- package/src/breakouts/index.ts +14 -0
- package/src/constants.ts +3 -0
- package/src/locus-info/controlsUtils.ts +19 -0
- package/src/locus-info/index.ts +8 -5
- package/src/meeting/index.ts +3 -2
- package/src/meetings/collection.ts +20 -0
- package/src/meetings/index.ts +110 -2
- package/src/meetings/util.ts +38 -0
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +24 -1
- package/src/metrics/config.ts +2 -0
- package/src/metrics/index.ts +5 -0
- package/test/unit/spec/breakouts/breakout.ts +36 -4
- package/test/unit/spec/breakouts/index.ts +10 -0
- package/test/unit/spec/locus-info/controlsUtils.js +21 -0
- package/test/unit/spec/locus-info/index.js +63 -0
- package/test/unit/spec/meetings/collection.js +14 -0
- package/test/unit/spec/meetings/index.js +183 -6
- package/test/unit/spec/meetings/utils.js +46 -0
- 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 {
|
|
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}
|
|
@@ -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
|
|
@@ -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
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
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.
|
|
36
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
37
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
38
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
39
|
-
"@webex/test-helper-retry": "3.0.0-beta.
|
|
40
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
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.
|
|
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.
|
|
52
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
53
|
-
"@webex/internal-plugin-llm": "3.0.0-beta.
|
|
54
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
55
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
56
|
-
"@webex/internal-plugin-support": "3.0.0-beta.
|
|
57
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
58
|
-
"@webex/plugin-people": "3.0.0-beta.
|
|
59
|
-
"@webex/plugin-rooms": "3.0.0-beta.
|
|
60
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
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",
|
package/src/breakouts/README.md
CHANGED
|
@@ -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
|
-
|
|
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
|
/**
|
package/src/breakouts/index.ts
CHANGED
|
@@ -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;
|
package/src/locus-info/index.ts
CHANGED
|
@@ -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 {
|
|
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
|
}
|
package/src/meeting/index.ts
CHANGED
|
@@ -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
|
|
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
|
}
|