@webex/plugin-meetings 3.0.0-beta.39 → 3.0.0-beta.391
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/README.md +58 -8
- package/dist/annotation/annotation.types.js +7 -0
- package/dist/annotation/annotation.types.js.map +1 -0
- package/dist/annotation/constants.js +49 -0
- package/dist/annotation/constants.js.map +1 -0
- package/dist/annotation/index.js +342 -0
- package/dist/annotation/index.js.map +1 -0
- package/dist/breakouts/breakout.js +94 -15
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/events.js +45 -0
- package/dist/breakouts/events.js.map +1 -0
- package/dist/breakouts/index.js +671 -81
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/utils.js +45 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +51 -0
- package/dist/common/errors/no-meeting-info.js.map +1 -0
- package/dist/common/errors/reclaim-host-role-errors.js +158 -0
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
- package/dist/common/errors/webex-errors.js +48 -7
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/logs/logger-proxy.js +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +5 -1
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +24 -9
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +5 -10
- package/dist/config.js.map +1 -1
- package/dist/constants.js +242 -33
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js +14 -2
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +109 -15
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js +7 -0
- package/dist/controls-options-manager/types.js.map +1 -0
- package/dist/controls-options-manager/util.js +309 -18
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/index.js +110 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +15 -0
- package/dist/interceptors/index.js.map +1 -0
- package/dist/interceptors/locusRetry.js +93 -0
- package/dist/interceptors/locusRetry.js.map +1 -0
- package/dist/interpretation/collection.js +23 -0
- package/dist/interpretation/collection.js.map +1 -0
- package/dist/interpretation/index.js +380 -0
- package/dist/interpretation/index.js.map +1 -0
- package/dist/interpretation/siLanguage.js +25 -0
- package/dist/interpretation/siLanguage.js.map +1 -0
- package/dist/locus-info/controlsUtils.js +91 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +386 -62
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js +7 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js +71 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +249 -72
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js +89 -14
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/index.js +65 -102
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +73 -124
- package/dist/media/properties.js.map +1 -1
- package/dist/mediaQualityMetrics/config.js +135 -330
- package/dist/mediaQualityMetrics/config.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +86 -2
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +4075 -2827
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +292 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -0
- package/dist/meeting/muteState.js +224 -136
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +177 -152
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/util.js +672 -417
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +73 -7
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +192 -51
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +1 -1
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +36 -36
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +39 -0
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +484 -119
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +7 -0
- package/dist/meetings/meetings.types.js.map +1 -0
- package/dist/meetings/request.js +2 -0
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +73 -7
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +58 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +25 -0
- package/dist/member/types.js.map +1 -0
- package/dist/member/util.js +132 -25
- package/dist/member/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 +102 -6
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +106 -38
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js +15 -0
- package/dist/members/types.js.map +1 -0
- package/dist/members/util.js +326 -232
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +18 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +1 -446
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +223 -32
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +10 -0
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +39 -36
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +3 -1
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +76 -5
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +366 -104
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +255 -0
- package/dist/multistream/sendSlotManager.js.map +1 -0
- package/dist/reachability/clusterReachability.js +356 -0
- package/dist/reachability/clusterReachability.js.map +1 -0
- package/dist/reachability/index.js +263 -390
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/request.js +6 -4
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js +29 -0
- package/dist/reachability/util.js.map +1 -0
- package/dist/reconnection-manager/index.js +266 -202
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/index.js +21 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js +9 -8
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +51 -28
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +48 -64
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +220 -70
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/rtcMetrics/constants.js +12 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +179 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/statsAnalyzer/index.js +357 -295
- package/dist/statsAnalyzer/index.js.map +1 -1
- package/dist/statsAnalyzer/mqaUtil.js +296 -156
- package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
- package/dist/types/annotation/annotation.types.d.ts +42 -0
- package/dist/types/annotation/constants.d.ts +31 -0
- package/dist/types/annotation/index.d.ts +117 -0
- package/dist/types/breakouts/events.d.ts +8 -0
- package/dist/types/breakouts/utils.d.ts +14 -0
- package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
- package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
- package/dist/types/common/errors/webex-errors.d.ts +25 -1
- package/dist/types/common/logs/request.d.ts +2 -0
- package/dist/types/common/queue.d.ts +9 -7
- package/dist/types/config.d.ts +2 -7
- package/dist/types/constants.d.ts +203 -31
- package/dist/types/controls-options-manager/enums.d.ts +11 -1
- package/dist/types/controls-options-manager/index.d.ts +17 -1
- package/dist/types/controls-options-manager/types.d.ts +43 -0
- package/dist/types/controls-options-manager/util.d.ts +1 -7
- package/dist/types/index.d.ts +6 -5
- package/dist/types/interceptors/index.d.ts +2 -0
- package/dist/types/interceptors/locusRetry.d.ts +27 -0
- package/dist/types/interpretation/collection.d.ts +5 -0
- package/dist/types/interpretation/index.d.ts +5 -0
- package/dist/types/interpretation/siLanguage.d.ts +5 -0
- package/dist/types/locus-info/index.d.ts +57 -4
- package/dist/types/locus-info/parser.d.ts +66 -6
- package/dist/types/media/index.d.ts +2 -0
- package/dist/types/media/properties.d.ts +34 -49
- package/dist/types/mediaQualityMetrics/config.d.ts +99 -223
- package/dist/types/meeting/in-meeting-actions.d.ts +86 -2
- package/dist/types/meeting/index.d.ts +567 -496
- package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
- package/dist/types/meeting/muteState.d.ts +93 -25
- package/dist/types/meeting/request.d.ts +64 -43
- package/dist/types/meeting/util.d.ts +117 -1
- package/dist/types/meeting-info/index.d.ts +13 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
- package/dist/types/meetings/collection.d.ts +17 -0
- package/dist/types/meetings/index.d.ts +113 -21
- package/dist/types/meetings/meetings.types.d.ts +4 -0
- package/dist/types/member/index.d.ts +14 -0
- package/dist/types/member/types.d.ts +32 -0
- package/dist/types/members/collection.d.ts +5 -0
- package/dist/types/members/index.d.ts +35 -2
- package/dist/types/members/request.d.ts +73 -9
- package/dist/types/members/types.d.ts +25 -0
- package/dist/types/members/util.d.ts +214 -1
- package/dist/types/metrics/constants.d.ts +17 -0
- package/dist/types/metrics/index.d.ts +4 -111
- package/dist/types/multistream/mediaRequestManager.d.ts +72 -3
- package/dist/types/multistream/receiveSlot.d.ts +7 -3
- package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
- package/dist/types/multistream/remoteMedia.d.ts +3 -31
- package/dist/types/multistream/remoteMediaGroup.d.ts +2 -9
- package/dist/types/multistream/remoteMediaManager.d.ts +62 -2
- package/dist/types/multistream/sendSlotManager.d.ts +70 -0
- package/dist/types/reachability/clusterReachability.d.ts +109 -0
- package/dist/types/reachability/index.d.ts +60 -95
- package/dist/types/reachability/request.d.ts +3 -1
- package/dist/types/reachability/util.d.ts +8 -0
- package/dist/types/reconnection-manager/index.d.ts +19 -0
- package/dist/types/recording-controller/index.d.ts +15 -1
- package/dist/types/recording-controller/util.d.ts +5 -4
- package/dist/types/roap/index.d.ts +2 -1
- package/dist/types/roap/request.d.ts +9 -8
- package/dist/types/roap/turnDiscovery.d.ts +39 -5
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +61 -0
- package/dist/types/statsAnalyzer/index.d.ts +34 -12
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +28 -4
- package/dist/types/webinar/collection.d.ts +16 -0
- package/dist/types/webinar/index.d.ts +5 -0
- package/dist/webinar/collection.js +44 -0
- package/dist/webinar/collection.js.map +1 -0
- package/dist/webinar/index.js +69 -0
- package/dist/webinar/index.js.map +1 -0
- package/package.json +22 -19
- package/src/annotation/annotation.types.ts +50 -0
- package/src/annotation/constants.ts +36 -0
- package/src/annotation/index.ts +328 -0
- package/src/breakouts/README.md +35 -11
- package/src/breakouts/breakout.ts +67 -9
- package/src/breakouts/events.ts +56 -0
- package/src/breakouts/index.ts +558 -59
- package/src/breakouts/utils.ts +42 -0
- package/src/common/errors/no-meeting-info.ts +24 -0
- package/src/common/errors/reclaim-host-role-errors.ts +134 -0
- package/src/common/errors/webex-errors.ts +44 -2
- package/src/common/logs/logger-proxy.ts +1 -1
- package/src/common/logs/request.ts +5 -1
- package/src/common/queue.ts +22 -8
- package/src/config.ts +4 -9
- package/src/constants.ts +229 -21
- package/src/controls-options-manager/enums.ts +12 -0
- package/src/controls-options-manager/index.ts +116 -21
- package/src/controls-options-manager/types.ts +59 -0
- package/src/controls-options-manager/util.ts +294 -14
- package/src/index.ts +44 -0
- package/src/interceptors/index.ts +3 -0
- package/src/interceptors/locusRetry.ts +67 -0
- package/src/interpretation/README.md +60 -0
- package/src/interpretation/collection.ts +19 -0
- package/src/interpretation/index.ts +349 -0
- package/src/interpretation/siLanguage.ts +18 -0
- package/src/locus-info/controlsUtils.ts +108 -0
- package/src/locus-info/index.ts +417 -59
- package/src/locus-info/infoUtils.ts +10 -2
- package/src/locus-info/mediaSharesUtils.ts +80 -0
- package/src/locus-info/parser.ts +258 -47
- package/src/locus-info/selfUtils.ts +81 -5
- package/src/media/index.ts +100 -108
- package/src/media/properties.ts +88 -117
- package/src/mediaQualityMetrics/config.ts +103 -238
- package/src/meeting/in-meeting-actions.ts +171 -3
- package/src/meeting/index.ts +3411 -2435
- package/src/meeting/locusMediaRequest.ts +313 -0
- package/src/meeting/muteState.ts +223 -136
- package/src/meeting/request.ts +155 -120
- package/src/meeting/util.ts +685 -395
- package/src/meeting-info/index.ts +81 -8
- package/src/meeting-info/meeting-info-v2.ts +170 -14
- package/src/meeting-info/util.ts +1 -1
- package/src/meeting-info/utilv2.ts +23 -23
- package/src/meetings/collection.ts +33 -0
- package/src/meetings/index.ts +507 -127
- package/src/meetings/meetings.types.ts +12 -0
- package/src/meetings/request.ts +2 -0
- package/src/meetings/util.ts +81 -12
- package/src/member/index.ts +58 -0
- package/src/member/types.ts +38 -0
- package/src/member/util.ts +141 -25
- package/src/members/collection.ts +8 -0
- package/src/members/index.ts +134 -8
- package/src/members/request.ts +97 -17
- package/src/members/types.ts +29 -0
- package/src/members/util.ts +333 -240
- package/src/metrics/constants.ts +17 -0
- package/src/metrics/index.ts +1 -469
- package/src/multistream/mediaRequestManager.ts +271 -56
- package/src/multistream/receiveSlot.ts +11 -4
- package/src/multistream/receiveSlotManager.ts +34 -24
- package/src/multistream/remoteMedia.ts +5 -3
- package/src/multistream/remoteMediaGroup.ts +78 -0
- package/src/multistream/remoteMediaManager.ts +248 -44
- package/src/multistream/sendSlotManager.ts +199 -0
- package/src/reachability/clusterReachability.ts +320 -0
- package/src/reachability/index.ts +229 -346
- package/src/reachability/request.ts +8 -4
- package/src/reachability/util.ts +24 -0
- package/src/reconnection-manager/index.ts +128 -97
- package/src/recording-controller/index.ts +20 -3
- package/src/recording-controller/util.ts +26 -9
- package/src/roap/index.ts +52 -23
- package/src/roap/request.ts +48 -67
- package/src/roap/turnDiscovery.ts +147 -49
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +166 -0
- package/src/statsAnalyzer/index.ts +457 -416
- package/src/statsAnalyzer/mqaUtil.ts +317 -170
- package/src/webinar/collection.ts +31 -0
- package/src/webinar/index.ts +62 -0
- package/test/integration/spec/converged-space-meetings.js +60 -3
- package/test/integration/spec/journey.js +320 -261
- package/test/integration/spec/space-meeting.js +76 -3
- package/test/unit/spec/annotation/index.ts +418 -0
- package/test/unit/spec/breakouts/breakout.ts +118 -28
- package/test/unit/spec/breakouts/events.ts +89 -0
- package/test/unit/spec/breakouts/index.ts +1349 -114
- package/test/unit/spec/breakouts/utils.js +52 -1
- package/test/unit/spec/common/queue.js +31 -2
- package/test/unit/spec/controls-options-manager/index.js +163 -0
- package/test/unit/spec/controls-options-manager/util.js +576 -60
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRetry.ts +131 -0
- package/test/unit/spec/interpretation/collection.ts +15 -0
- package/test/unit/spec/interpretation/index.ts +625 -0
- package/test/unit/spec/interpretation/siLanguage.ts +28 -0
- package/test/unit/spec/locus-info/controlsUtils.js +316 -43
- package/test/unit/spec/locus-info/index.js +1363 -37
- package/test/unit/spec/locus-info/infoUtils.js +37 -15
- package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
- package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
- package/test/unit/spec/locus-info/parser.js +116 -35
- package/test/unit/spec/locus-info/selfConstant.js +27 -4
- package/test/unit/spec/locus-info/selfUtils.js +208 -17
- package/test/unit/spec/media/index.ts +173 -81
- package/test/unit/spec/media/properties.ts +2 -2
- package/test/unit/spec/meeting/in-meeting-actions.ts +85 -3
- package/test/unit/spec/meeting/index.js +6821 -2172
- package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
- package/test/unit/spec/meeting/muteState.js +402 -212
- package/test/unit/spec/meeting/request.js +473 -54
- package/test/unit/spec/meeting/utils.js +773 -67
- package/test/unit/spec/meeting-info/index.js +300 -0
- package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
- package/test/unit/spec/meeting-info/utilv2.js +21 -0
- package/test/unit/spec/meetings/collection.js +26 -0
- package/test/unit/spec/meetings/index.js +1415 -213
- package/test/unit/spec/meetings/utils.js +229 -2
- package/test/unit/spec/member/index.js +61 -6
- package/test/unit/spec/member/util.js +510 -34
- package/test/unit/spec/members/index.js +432 -1
- package/test/unit/spec/members/request.js +206 -27
- package/test/unit/spec/members/utils.js +210 -0
- package/test/unit/spec/metrics/index.js +1 -50
- package/test/unit/spec/multistream/mediaRequestManager.ts +781 -114
- package/test/unit/spec/multistream/receiveSlot.ts +9 -1
- package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
- package/test/unit/spec/multistream/remoteMedia.ts +2 -0
- package/test/unit/spec/multistream/remoteMediaGroup.ts +345 -0
- package/test/unit/spec/multistream/remoteMediaManager.ts +525 -0
- package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
- package/test/unit/spec/reachability/clusterReachability.ts +279 -0
- package/test/unit/spec/reachability/index.ts +551 -14
- package/test/unit/spec/reachability/request.js +3 -1
- package/test/unit/spec/reachability/util.ts +40 -0
- package/test/unit/spec/reconnection-manager/index.js +171 -11
- package/test/unit/spec/recording-controller/index.js +294 -218
- package/test/unit/spec/recording-controller/util.js +223 -96
- package/test/unit/spec/roap/index.ts +180 -83
- package/test/unit/spec/roap/request.ts +100 -62
- package/test/unit/spec/roap/turnDiscovery.ts +388 -96
- package/test/unit/spec/rtcMetrics/index.ts +122 -0
- package/test/unit/spec/stats-analyzer/index.js +1252 -12
- package/test/unit/spec/webinar/collection.ts +13 -0
- package/test/unit/spec/webinar/index.ts +60 -0
- package/test/utils/integrationTestUtils.js +46 -0
- package/test/utils/testUtils.js +0 -57
- package/test/utils/webex-test-users.js +12 -4
- package/dist/metrics/config.js +0 -289
- package/dist/metrics/config.js.map +0 -1
- package/dist/types/metrics/config.d.ts +0 -169
- package/src/index.js +0 -18
- package/src/metrics/config.ts +0 -485
package/src/meetings/index.ts
CHANGED
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
import '@webex/internal-plugin-mercury';
|
|
4
4
|
import '@webex/internal-plugin-conversation';
|
|
5
|
+
import '@webex/internal-plugin-metrics';
|
|
5
6
|
// @ts-ignore
|
|
6
7
|
import {WebexPlugin} from '@webex/webex-core';
|
|
7
8
|
import {setLogger} from '@webex/internal-media-core';
|
|
8
9
|
|
|
10
|
+
import * as mediaHelpersModule from '@webex/media-helpers';
|
|
11
|
+
|
|
9
12
|
import 'webrtc-adapter';
|
|
10
13
|
|
|
11
14
|
import Metrics from '../metrics';
|
|
12
|
-
import {trigger, eventType} from '../metrics/config';
|
|
13
15
|
import LoggerConfig from '../common/logs/logger-config';
|
|
14
16
|
import StaticConfig from '../common/config';
|
|
15
17
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
@@ -40,11 +42,14 @@ import {
|
|
|
40
42
|
MEETING_REMOVED_REASON,
|
|
41
43
|
_CONVERSATION_URL_,
|
|
42
44
|
CONVERSATION_URL,
|
|
45
|
+
MEETINGNUMBER,
|
|
46
|
+
_JOINED_,
|
|
47
|
+
_MOVED_,
|
|
43
48
|
} from '../constants';
|
|
44
49
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
45
50
|
import MeetingInfo from '../meeting-info';
|
|
46
51
|
import MeetingInfoV2 from '../meeting-info/meeting-info-v2';
|
|
47
|
-
import Meeting from '../meeting';
|
|
52
|
+
import Meeting, {CallStateForMetrics} from '../meeting';
|
|
48
53
|
import PersonalMeetingRoom from '../personal-meeting-room';
|
|
49
54
|
import Reachability from '../reachability';
|
|
50
55
|
import Request from './request';
|
|
@@ -53,6 +58,10 @@ import CaptchaError from '../common/errors/captcha-error';
|
|
|
53
58
|
|
|
54
59
|
import MeetingCollection from './collection';
|
|
55
60
|
import MeetingsUtil from './util';
|
|
61
|
+
import PermissionError from '../common/errors/permission';
|
|
62
|
+
import {INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
|
|
63
|
+
import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
|
|
64
|
+
import NoMeetingInfoError from '../common/errors/no-meeting-info';
|
|
56
65
|
|
|
57
66
|
let mediaLogger;
|
|
58
67
|
|
|
@@ -139,12 +148,13 @@ export default class Meetings extends WebexPlugin {
|
|
|
139
148
|
meetingCollection: any;
|
|
140
149
|
personalMeetingRoom: any;
|
|
141
150
|
preferredWebexSite: any;
|
|
142
|
-
reachability:
|
|
151
|
+
reachability: Reachability;
|
|
143
152
|
registered: any;
|
|
144
153
|
request: any;
|
|
145
154
|
geoHintInfo: any;
|
|
146
155
|
meetingInfo: any;
|
|
147
|
-
|
|
156
|
+
mediaHelpers: any;
|
|
157
|
+
breakoutLocusForHandleLater: any;
|
|
148
158
|
namespace = MEETINGS;
|
|
149
159
|
|
|
150
160
|
/**
|
|
@@ -156,6 +166,17 @@ export default class Meetings extends WebexPlugin {
|
|
|
156
166
|
constructor(...args) {
|
|
157
167
|
super(...args);
|
|
158
168
|
|
|
169
|
+
/**
|
|
170
|
+
* The webrtc-core media helpers. This is a temporary solution required for the SDK sample app
|
|
171
|
+
* to be able to call media helper functions.
|
|
172
|
+
*
|
|
173
|
+
* @instance
|
|
174
|
+
* @type {Object}
|
|
175
|
+
* @private
|
|
176
|
+
* @memberof Meetings
|
|
177
|
+
*/
|
|
178
|
+
this.mediaHelpers = mediaHelpersModule;
|
|
179
|
+
|
|
159
180
|
/**
|
|
160
181
|
* The Meetings request to interact with server
|
|
161
182
|
* @instance
|
|
@@ -183,15 +204,17 @@ export default class Meetings extends WebexPlugin {
|
|
|
183
204
|
* @memberof Meetings
|
|
184
205
|
*/
|
|
185
206
|
this.personalMeetingRoom = null;
|
|
207
|
+
|
|
186
208
|
/**
|
|
187
|
-
* The Reachability object to interact with server
|
|
209
|
+
* The Reachability object to interact with server
|
|
188
210
|
* starts as null
|
|
189
211
|
* @instance
|
|
190
212
|
* @type {Object}
|
|
191
213
|
* @private
|
|
192
214
|
* @memberof Meetings
|
|
193
215
|
*/
|
|
194
|
-
|
|
216
|
+
// @ts-ignore
|
|
217
|
+
this.reachability = new Reachability(this.webex);
|
|
195
218
|
|
|
196
219
|
/**
|
|
197
220
|
* If the meetings plugin has been registered and listening via {@link Meetings#register}
|
|
@@ -221,30 +244,137 @@ export default class Meetings extends WebexPlugin {
|
|
|
221
244
|
*/
|
|
222
245
|
this.media = {
|
|
223
246
|
getUserMedia: Media.getUserMedia,
|
|
224
|
-
getSupportedDevice: Media.getSupportedDevice,
|
|
225
247
|
};
|
|
226
248
|
|
|
227
249
|
this.onReady();
|
|
228
250
|
}
|
|
229
251
|
|
|
230
252
|
/**
|
|
231
|
-
*
|
|
253
|
+
* check whether you need to handle this main session's locus data or not
|
|
254
|
+
* @param {Object} meeting current meeting data
|
|
255
|
+
* @param {Object} newLocus new locus data
|
|
256
|
+
* @returns {boolean}
|
|
257
|
+
* @private
|
|
258
|
+
* @memberof Meetings
|
|
259
|
+
*/
|
|
260
|
+
private isNeedHandleMainLocus(meeting: any, newLocus: any) {
|
|
261
|
+
const breakoutUrl = newLocus.controls?.breakout?.url;
|
|
262
|
+
const breakoutLocus = this.meetingCollection.getActiveBreakoutLocus(breakoutUrl);
|
|
263
|
+
|
|
264
|
+
const isSelfJoined = newLocus?.self?.state === _JOINED_;
|
|
265
|
+
const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
|
|
266
|
+
// @ts-ignore
|
|
267
|
+
const deviceFromNewLocus = MeetingsUtil.getThisDevice(newLocus, this.webex.internal.device.url);
|
|
268
|
+
const isResourceMovedOnThisDevice =
|
|
269
|
+
deviceFromNewLocus?.state === _LEFT_ && deviceFromNewLocus?.reason === _MOVED_;
|
|
270
|
+
|
|
271
|
+
const isNewLocusJoinThisDevice = MeetingsUtil.joinedOnThisDevice(
|
|
272
|
+
meeting,
|
|
273
|
+
newLocus,
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
this.webex.internal.device.url
|
|
276
|
+
);
|
|
277
|
+
const isBreakoutLocusJoinThisDevice =
|
|
278
|
+
breakoutLocus?.joinedWith?.correlationId &&
|
|
279
|
+
breakoutLocus.joinedWith.correlationId === meeting?.correlationId;
|
|
280
|
+
|
|
281
|
+
if (isSelfJoined && isNewLocusJoinThisDevice) {
|
|
282
|
+
LoggerProxy.logger.log(
|
|
283
|
+
'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
|
|
284
|
+
);
|
|
285
|
+
if (breakoutLocus?.joinedWith && deviceFromNewLocus) {
|
|
286
|
+
const breakoutReplaceAt =
|
|
287
|
+
breakoutLocus.joinedWith.replaces?.length > 0
|
|
288
|
+
? breakoutLocus.joinedWith.replaces[0].replaceAt
|
|
289
|
+
: '';
|
|
290
|
+
const newLocusReplaceAt =
|
|
291
|
+
deviceFromNewLocus.replaces?.length > 0 ? deviceFromNewLocus.replaces[0].replaceAt : '';
|
|
292
|
+
if (breakoutReplaceAt && newLocusReplaceAt && breakoutReplaceAt > newLocusReplaceAt) {
|
|
293
|
+
LoggerProxy.logger.log(
|
|
294
|
+
`Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt ${newLocusReplaceAt} bo replacedAt ${breakoutReplaceAt}`
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
if (isBreakoutLocusJoinThisDevice) {
|
|
304
|
+
LoggerProxy.logger.log(
|
|
305
|
+
`Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: ${breakoutUrl}`
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
if (isSelfMoved && (newLocus?.self?.removed || isResourceMovedOnThisDevice)) {
|
|
311
|
+
LoggerProxy.logger.log(
|
|
312
|
+
'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
return false;
|
|
316
|
+
}
|
|
317
|
+
if (isSelfJoined && isResourceMovedOnThisDevice) {
|
|
318
|
+
LoggerProxy.logger.log(
|
|
319
|
+
'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
|
|
320
|
+
);
|
|
321
|
+
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
LoggerProxy.logger.log(
|
|
325
|
+
'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
return true;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* check whether you need to handle this locus data or not
|
|
333
|
+
* @param {Object} meeting old locus data
|
|
334
|
+
* @param {Object} newLocus new locus data
|
|
335
|
+
* @returns {boolean}
|
|
336
|
+
* @private
|
|
337
|
+
* @memberof Meetings
|
|
338
|
+
*/
|
|
339
|
+
private isNeedHandleLocusDTO(meeting: any, newLocus: any) {
|
|
340
|
+
if (newLocus) {
|
|
341
|
+
const isNewLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(newLocus);
|
|
342
|
+
const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
|
|
343
|
+
if (!meeting) {
|
|
344
|
+
if (isNewLocusAsBreakout) {
|
|
345
|
+
LoggerProxy.logger.log(
|
|
346
|
+
`Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: ${newLocus.fullState?.active}`
|
|
347
|
+
);
|
|
348
|
+
|
|
349
|
+
return newLocus.self?.state === _JOINED_;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return this.isNeedHandleMainLocus(meeting, newLocus);
|
|
353
|
+
}
|
|
354
|
+
if (!isNewLocusAsBreakout) {
|
|
355
|
+
return this.isNeedHandleMainLocus(meeting, newLocus);
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
return !isSelfMoved;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
return true;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* get corresponding meeting object by locus data
|
|
232
366
|
* @param {Object} data a locus event
|
|
233
367
|
* @param {String} data.locusUrl
|
|
234
368
|
* @param {Object} data.locus
|
|
235
|
-
* @
|
|
236
|
-
* @param {String} data.eventType
|
|
237
|
-
* @returns {undefined}
|
|
369
|
+
* @returns {Object}
|
|
238
370
|
* @private
|
|
239
371
|
* @memberof Meetings
|
|
240
372
|
*/
|
|
241
|
-
|
|
242
|
-
let meeting = null;
|
|
243
|
-
|
|
373
|
+
getCorrespondingMeetingByLocus(data) {
|
|
244
374
|
// getting meeting by correlationId. This will happen for the new event
|
|
245
375
|
// Either the locus
|
|
246
376
|
// TODO : Add check for the callBack Address
|
|
247
|
-
|
|
377
|
+
return (
|
|
248
378
|
this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
|
|
249
379
|
// @ts-ignore
|
|
250
380
|
this.meetingCollection.getByKey(
|
|
@@ -260,7 +390,24 @@ export default class Meetings extends WebexPlugin {
|
|
|
260
390
|
) ||
|
|
261
391
|
(data.locus.info?.isUnifiedSpaceMeeting
|
|
262
392
|
? undefined
|
|
263
|
-
: this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl))
|
|
393
|
+
: this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl)) ||
|
|
394
|
+
this.meetingCollection.getByKey(MEETINGNUMBER, data.locus?.info?.webExMeetingId)
|
|
395
|
+
);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* handle locus events and takes meeting actions with them as they come in
|
|
400
|
+
* @param {Object} data a locus event
|
|
401
|
+
* @param {String} data.locusUrl
|
|
402
|
+
* @param {Object} data.locus
|
|
403
|
+
* @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
|
|
404
|
+
* @param {String} data.eventType
|
|
405
|
+
* @returns {undefined}
|
|
406
|
+
* @private
|
|
407
|
+
* @memberof Meetings
|
|
408
|
+
*/
|
|
409
|
+
private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
|
|
410
|
+
let meeting = this.getCorrespondingMeetingByLocus(data);
|
|
264
411
|
|
|
265
412
|
// Special case when locus has got replaced, This only happend once if a replace locus exists
|
|
266
413
|
// https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
|
|
@@ -273,6 +420,16 @@ export default class Meetings extends WebexPlugin {
|
|
|
273
420
|
);
|
|
274
421
|
}
|
|
275
422
|
|
|
423
|
+
if (meeting && !MeetingsUtil.isBreakoutLocusDTO(data.locus)) {
|
|
424
|
+
meeting.locusInfo.updateMainSessionLocusCache(data.locus);
|
|
425
|
+
}
|
|
426
|
+
if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
|
|
427
|
+
LoggerProxy.logger.log(
|
|
428
|
+
`Meetings:index#handleLocusEvent --> doesn't need to process locus event`
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
276
433
|
if (!meeting) {
|
|
277
434
|
// TODO: create meeting when we get a meeting object
|
|
278
435
|
// const checkForEnded = (locus) => {
|
|
@@ -329,6 +486,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
329
486
|
|
|
330
487
|
// It's a new meeting so initialize the locus data
|
|
331
488
|
meeting.locusInfo.initialSetup(data.locus);
|
|
489
|
+
this.checkHandleBreakoutLocus(data.locus);
|
|
332
490
|
})
|
|
333
491
|
.catch((e) => {
|
|
334
492
|
LoggerProxy.logger.error(e);
|
|
@@ -338,10 +496,15 @@ export default class Meetings extends WebexPlugin {
|
|
|
338
496
|
// because the other user left so before sending 'added' event make sure it exists in the collection
|
|
339
497
|
|
|
340
498
|
if (this.getMeetingByType(_ID_, meeting.id)) {
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
499
|
+
// @ts-ignore
|
|
500
|
+
this.webex.internal.newMetrics.submitClientEvent({
|
|
501
|
+
name: 'client.call.remote-started',
|
|
502
|
+
payload: {
|
|
503
|
+
trigger: 'mercury-event',
|
|
504
|
+
},
|
|
505
|
+
options: {
|
|
506
|
+
meetingId: meeting.id,
|
|
507
|
+
},
|
|
345
508
|
});
|
|
346
509
|
Trigger.trigger(
|
|
347
510
|
this,
|
|
@@ -421,7 +584,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
421
584
|
|
|
422
585
|
// @ts-ignore
|
|
423
586
|
this.webex.internal.mercury.on(ONLINE, () => {
|
|
424
|
-
this.syncMeetings();
|
|
587
|
+
this.syncMeetings({keepOnlyLocusMeetings: false});
|
|
425
588
|
});
|
|
426
589
|
|
|
427
590
|
// @ts-ignore
|
|
@@ -494,7 +657,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
494
657
|
|
|
495
658
|
MeetingsUtil.checkH264Support({disableNotifications: true});
|
|
496
659
|
// @ts-ignore
|
|
497
|
-
Metrics.initialSetup(this.
|
|
660
|
+
Metrics.initialSetup(this.webex);
|
|
498
661
|
});
|
|
499
662
|
}
|
|
500
663
|
|
|
@@ -519,35 +682,38 @@ export default class Meetings extends WebexPlugin {
|
|
|
519
682
|
}
|
|
520
683
|
|
|
521
684
|
/**
|
|
522
|
-
* API to
|
|
523
|
-
* @param {Boolean}
|
|
685
|
+
* API to toggle starting adhoc meeting
|
|
686
|
+
* @param {Boolean} changeState
|
|
524
687
|
* @private
|
|
525
688
|
* @memberof Meetings
|
|
526
689
|
* @returns {undefined}
|
|
527
690
|
*/
|
|
528
|
-
private
|
|
529
|
-
if (typeof
|
|
691
|
+
private _toggleAdhocMeetings(changeState: boolean) {
|
|
692
|
+
if (typeof changeState !== 'boolean') {
|
|
530
693
|
return;
|
|
531
694
|
}
|
|
532
695
|
// @ts-ignore
|
|
533
|
-
this.config
|
|
696
|
+
if (this.config?.experimental?.enableAdhocMeetings !== changeState) {
|
|
697
|
+
// @ts-ignore
|
|
698
|
+
this.config.experimental.enableAdhocMeetings = changeState;
|
|
699
|
+
}
|
|
534
700
|
}
|
|
535
701
|
|
|
536
702
|
/**
|
|
537
|
-
* API to toggle
|
|
538
|
-
* @param {Boolean}
|
|
703
|
+
* API to toggle TCP reachability, needs to be called before webex.meetings.register()
|
|
704
|
+
* @param {Boolean} newValue
|
|
539
705
|
* @private
|
|
540
706
|
* @memberof Meetings
|
|
541
707
|
* @returns {undefined}
|
|
542
708
|
*/
|
|
543
|
-
private
|
|
544
|
-
if (typeof
|
|
709
|
+
private _toggleTcpReachability(newValue: boolean) {
|
|
710
|
+
if (typeof newValue !== 'boolean') {
|
|
545
711
|
return;
|
|
546
712
|
}
|
|
547
713
|
// @ts-ignore
|
|
548
|
-
if (this.config
|
|
714
|
+
if (this.config.experimental.enableTcpReachability !== newValue) {
|
|
549
715
|
// @ts-ignore
|
|
550
|
-
this.config.experimental.
|
|
716
|
+
this.config.experimental.enableTcpReachability = newValue;
|
|
551
717
|
}
|
|
552
718
|
}
|
|
553
719
|
|
|
@@ -663,6 +829,36 @@ export default class Meetings extends WebexPlugin {
|
|
|
663
829
|
);
|
|
664
830
|
}
|
|
665
831
|
|
|
832
|
+
/**
|
|
833
|
+
* Creates a noise reduction effect
|
|
834
|
+
*
|
|
835
|
+
* @param {INoiseReductionEffect} options optional custom effect options
|
|
836
|
+
* @returns {Promise<effect>} noise reduction effect.
|
|
837
|
+
* @public
|
|
838
|
+
* @memberof Meetings
|
|
839
|
+
*/
|
|
840
|
+
createNoiseReductionEffect = async (options?: INoiseReductionEffect) => {
|
|
841
|
+
// @ts-ignore
|
|
842
|
+
const authToken = this.webex.credentials.supertoken.access_token;
|
|
843
|
+
|
|
844
|
+
return new mediaHelpersModule.NoiseReductionEffect({authToken, ...options});
|
|
845
|
+
};
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* Creates a virtual background effect
|
|
849
|
+
*
|
|
850
|
+
* @param {IVirtualBackgroundEffect} options optional custom effect options
|
|
851
|
+
* @returns {Promise<effect>} virtual background effect.
|
|
852
|
+
* @public
|
|
853
|
+
* @memberof Meetings
|
|
854
|
+
*/
|
|
855
|
+
createVirtualBackgroundEffect = async (options?: IVirtualBackgroundEffect) => {
|
|
856
|
+
// @ts-ignore
|
|
857
|
+
const authToken = this.webex.credentials.supertoken.access_token;
|
|
858
|
+
|
|
859
|
+
return new mediaHelpersModule.VirtualBackgroundEffect({authToken, ...options});
|
|
860
|
+
};
|
|
861
|
+
|
|
666
862
|
/**
|
|
667
863
|
* Uploads logs to the webex services for tracking
|
|
668
864
|
* @param {Object} [options={}]
|
|
@@ -677,8 +873,10 @@ export default class Meetings extends WebexPlugin {
|
|
|
677
873
|
*/
|
|
678
874
|
uploadLogs(
|
|
679
875
|
options: {
|
|
876
|
+
autoupload?: boolean;
|
|
680
877
|
callStart?: string;
|
|
681
878
|
feedbackId?: string;
|
|
879
|
+
locussessionid?: string;
|
|
682
880
|
locusId?: string;
|
|
683
881
|
correlationId?: string;
|
|
684
882
|
meetingId?: string;
|
|
@@ -695,6 +893,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
695
893
|
'Meetings:index#uploadLogs --> Upload logs for meeting completed.',
|
|
696
894
|
uploadResult
|
|
697
895
|
);
|
|
896
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_SUCCESS, options);
|
|
698
897
|
Trigger.trigger(
|
|
699
898
|
this,
|
|
700
899
|
{
|
|
@@ -729,8 +928,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
729
928
|
);
|
|
730
929
|
|
|
731
930
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_FAILURE, {
|
|
732
|
-
|
|
733
|
-
meetingId: options.meetingsId,
|
|
931
|
+
...options,
|
|
734
932
|
reason: uploadError.message,
|
|
735
933
|
stack: uploadError.stack,
|
|
736
934
|
code: uploadError.code,
|
|
@@ -738,17 +936,6 @@ export default class Meetings extends WebexPlugin {
|
|
|
738
936
|
});
|
|
739
937
|
}
|
|
740
938
|
|
|
741
|
-
/**
|
|
742
|
-
* initializes the reachability instance for Meetings
|
|
743
|
-
* @returns {undefined}
|
|
744
|
-
* @public
|
|
745
|
-
* @memberof Meetings
|
|
746
|
-
*/
|
|
747
|
-
setReachability() {
|
|
748
|
-
// @ts-ignore
|
|
749
|
-
this.reachability = new Reachability(this.webex);
|
|
750
|
-
}
|
|
751
|
-
|
|
752
939
|
/**
|
|
753
940
|
* gets the reachability instance for Meetings
|
|
754
941
|
* @returns {Reachability}
|
|
@@ -766,10 +953,6 @@ export default class Meetings extends WebexPlugin {
|
|
|
766
953
|
* @memberof Meetings
|
|
767
954
|
*/
|
|
768
955
|
startReachability() {
|
|
769
|
-
if (!this.reachability) {
|
|
770
|
-
this.setReachability();
|
|
771
|
-
}
|
|
772
|
-
|
|
773
956
|
return this.getReachability().gatherReachability();
|
|
774
957
|
}
|
|
775
958
|
|
|
@@ -797,6 +980,29 @@ export default class Meetings extends WebexPlugin {
|
|
|
797
980
|
if (res) {
|
|
798
981
|
this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
|
|
799
982
|
}
|
|
983
|
+
|
|
984
|
+
// fall back to getting the preferred site from the user information
|
|
985
|
+
if (!this.preferredWebexSite) {
|
|
986
|
+
// @ts-ignore
|
|
987
|
+
return this.webex.internal.user
|
|
988
|
+
.get()
|
|
989
|
+
.then((user) => {
|
|
990
|
+
const preferredWebexSite =
|
|
991
|
+
user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
|
|
992
|
+
if (preferredWebexSite) {
|
|
993
|
+
this.preferredWebexSite = preferredWebexSite;
|
|
994
|
+
} else {
|
|
995
|
+
throw new Error('site not found');
|
|
996
|
+
}
|
|
997
|
+
})
|
|
998
|
+
.catch(() => {
|
|
999
|
+
LoggerProxy.logger.error(
|
|
1000
|
+
'Failed to fetch preferred site from user - no site will be set'
|
|
1001
|
+
);
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
return Promise.resolve();
|
|
800
1006
|
});
|
|
801
1007
|
}
|
|
802
1008
|
|
|
@@ -837,29 +1043,55 @@ export default class Meetings extends WebexPlugin {
|
|
|
837
1043
|
}
|
|
838
1044
|
|
|
839
1045
|
/**
|
|
840
|
-
* Create a meeting.
|
|
841
|
-
*
|
|
1046
|
+
* Create a meeting or return an existing meeting.
|
|
1047
|
+
*
|
|
1048
|
+
* When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
|
|
1049
|
+
*
|
|
1050
|
+
* @param {string} destination - sipURL, phonenumber, or locus object}
|
|
842
1051
|
* @param {string} [type] - the optional specified type, such as locusId
|
|
843
1052
|
* @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
|
|
1053
|
+
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
1054
|
+
* @param {string} correlationId - the optional specified correlationId (callStateForMetrics.correlationId can be provided instead)
|
|
1055
|
+
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
1056
|
+
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
1057
|
+
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
|
1058
|
+
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
|
844
1059
|
* @returns {Promise<Meeting>} A new Meeting.
|
|
845
1060
|
* @public
|
|
846
1061
|
* @memberof Meetings
|
|
847
1062
|
*/
|
|
848
|
-
public create(
|
|
1063
|
+
public create(
|
|
1064
|
+
destination: string,
|
|
1065
|
+
type: string = null,
|
|
1066
|
+
useRandomDelayForInfo = false,
|
|
1067
|
+
infoExtraParams = {},
|
|
1068
|
+
correlationId: string = undefined,
|
|
1069
|
+
failOnMissingMeetingInfo = false,
|
|
1070
|
+
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1071
|
+
meetingInfo = undefined,
|
|
1072
|
+
meetingLookupUrl = undefined
|
|
1073
|
+
) {
|
|
849
1074
|
// TODO: type should be from a dictionary
|
|
850
1075
|
|
|
851
1076
|
// Validate meeting information based on the provided destination and
|
|
852
1077
|
// type. This must be performed prior to determining if the meeting is
|
|
853
1078
|
// found in the collection, as we mutate the destination for hydra person
|
|
854
1079
|
// id values.
|
|
1080
|
+
if (correlationId) {
|
|
1081
|
+
callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
|
|
1082
|
+
}
|
|
1083
|
+
|
|
855
1084
|
return (
|
|
856
1085
|
this.meetingInfo
|
|
857
1086
|
.fetchInfoOptions(destination, type)
|
|
858
1087
|
// Catch a failure to fetch info options.
|
|
859
1088
|
.catch((error) => {
|
|
860
|
-
LoggerProxy.logger.
|
|
861
|
-
`Meetings:index#create -->
|
|
1089
|
+
LoggerProxy.logger.error(
|
|
1090
|
+
`Meetings:index#create --> ERROR, unable to determine info options: ${error.message}`
|
|
862
1091
|
);
|
|
1092
|
+
if (error instanceof SpaceIDDeprecatedError) {
|
|
1093
|
+
throw new SpaceIDDeprecatedError();
|
|
1094
|
+
}
|
|
863
1095
|
})
|
|
864
1096
|
.then((options: any = {}) => {
|
|
865
1097
|
// Normalize the destination.
|
|
@@ -890,49 +1122,61 @@ export default class Meetings extends WebexPlugin {
|
|
|
890
1122
|
// Validate if a meeting was found.
|
|
891
1123
|
if (!meeting) {
|
|
892
1124
|
// Create a meeting based on the normalized destination and type.
|
|
893
|
-
return this.createMeeting(
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
1125
|
+
return this.createMeeting(
|
|
1126
|
+
targetDest,
|
|
1127
|
+
type,
|
|
1128
|
+
useRandomDelayForInfo,
|
|
1129
|
+
infoExtraParams,
|
|
1130
|
+
callStateForMetrics,
|
|
1131
|
+
failOnMissingMeetingInfo,
|
|
1132
|
+
meetingInfo,
|
|
1133
|
+
meetingLookupUrl
|
|
1134
|
+
).then((createdMeeting: any) => {
|
|
1135
|
+
// If the meeting was successfully created.
|
|
1136
|
+
if (createdMeeting && createdMeeting.on) {
|
|
1137
|
+
// Create a destruction event for the meeting.
|
|
1138
|
+
createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
|
|
1139
|
+
// @ts-ignore
|
|
1140
|
+
if (this.config.autoUploadLogs) {
|
|
1141
|
+
this.uploadLogs({
|
|
1142
|
+
callStart: createdMeeting.locusInfo?.fullState?.lastActive,
|
|
1143
|
+
locussessionid: createdMeeting.locusInfo?.fullState?.sessionId,
|
|
1144
|
+
correlationId: createdMeeting.correlationId,
|
|
1145
|
+
feedbackId: createdMeeting.correlationId,
|
|
1146
|
+
locusId: createdMeeting.locusId,
|
|
1147
|
+
meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
|
|
1148
|
+
autoupload: true,
|
|
1149
|
+
}).then(() => this.destroy(createdMeeting, payload.reason));
|
|
1150
|
+
} else {
|
|
1151
|
+
this.destroy(createdMeeting, payload.reason);
|
|
1152
|
+
}
|
|
1153
|
+
});
|
|
1154
|
+
|
|
1155
|
+
createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
|
|
1156
|
+
// @ts-ignore
|
|
1157
|
+
if (this.config.autoUploadLogs) {
|
|
1158
|
+
this.uploadLogs({
|
|
1159
|
+
callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
|
|
1160
|
+
locussessionid: meetingInstance?.locusInfo?.fullState?.sessionId,
|
|
1161
|
+
correlationId: meetingInstance.correlationId,
|
|
1162
|
+
feedbackId: meetingInstance.correlationId,
|
|
1163
|
+
locusId: meetingInstance.locusId,
|
|
1164
|
+
meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
|
|
1165
|
+
autoupload: true,
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
});
|
|
1169
|
+
} else {
|
|
1170
|
+
LoggerProxy.logger.error(
|
|
1171
|
+
`Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
|
|
1172
|
+
);
|
|
933
1173
|
}
|
|
934
|
-
|
|
1174
|
+
|
|
1175
|
+
// Return the newly created meeting.
|
|
1176
|
+
return Promise.resolve(createdMeeting);
|
|
1177
|
+
});
|
|
935
1178
|
}
|
|
1179
|
+
meeting.setCallStateForMetrics(callStateForMetrics);
|
|
936
1180
|
|
|
937
1181
|
// Return the existing meeting.
|
|
938
1182
|
return Promise.resolve(meeting);
|
|
@@ -941,9 +1185,18 @@ export default class Meetings extends WebexPlugin {
|
|
|
941
1185
|
}
|
|
942
1186
|
|
|
943
1187
|
/**
|
|
1188
|
+
* Create meeting
|
|
1189
|
+
*
|
|
1190
|
+
* When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
|
|
1191
|
+
*
|
|
944
1192
|
* @param {String} destination see create()
|
|
945
1193
|
* @param {String} type see create()
|
|
946
1194
|
* @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
|
|
1195
|
+
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
1196
|
+
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
1197
|
+
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
1198
|
+
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
|
1199
|
+
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
|
947
1200
|
* @returns {Promise} a new meeting instance complete with meeting info and destination
|
|
948
1201
|
* @private
|
|
949
1202
|
* @memberof Meetings
|
|
@@ -951,7 +1204,12 @@ export default class Meetings extends WebexPlugin {
|
|
|
951
1204
|
private async createMeeting(
|
|
952
1205
|
destination: any,
|
|
953
1206
|
type: string = null,
|
|
954
|
-
useRandomDelayForInfo = false
|
|
1207
|
+
useRandomDelayForInfo = false,
|
|
1208
|
+
infoExtraParams = {},
|
|
1209
|
+
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1210
|
+
failOnMissingMeetingInfo = false,
|
|
1211
|
+
meetingInfo = undefined,
|
|
1212
|
+
meetingLookupUrl = undefined
|
|
955
1213
|
) {
|
|
956
1214
|
const meeting = new Meeting(
|
|
957
1215
|
{
|
|
@@ -965,6 +1223,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
965
1223
|
meetingInfoProvider: this.meetingInfo,
|
|
966
1224
|
destination,
|
|
967
1225
|
destinationType: type,
|
|
1226
|
+
callStateForMetrics,
|
|
968
1227
|
},
|
|
969
1228
|
{
|
|
970
1229
|
// @ts-ignore
|
|
@@ -996,22 +1255,45 @@ export default class Meetings extends WebexPlugin {
|
|
|
996
1255
|
const isMeetingActive = !!destination.fullState?.active;
|
|
997
1256
|
// @ts-ignore
|
|
998
1257
|
const {enableUnifiedMeetings} = this.config.experimental;
|
|
999
|
-
|
|
1000
|
-
|
|
1258
|
+
const meetingInfoOptions = {
|
|
1259
|
+
extraParams: infoExtraParams,
|
|
1260
|
+
sendCAevents: !!callStateForMetrics?.correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
|
|
1261
|
+
};
|
|
1262
|
+
|
|
1263
|
+
if (meetingInfo) {
|
|
1264
|
+
meeting.injectMeetingInfo(meetingInfo, meetingInfoOptions, meetingLookupUrl);
|
|
1265
|
+
} else if (
|
|
1266
|
+
enableUnifiedMeetings &&
|
|
1267
|
+
!isMeetingActive &&
|
|
1268
|
+
useRandomDelayForInfo &&
|
|
1269
|
+
waitingTime > 0
|
|
1270
|
+
) {
|
|
1001
1271
|
meeting.fetchMeetingInfoTimeoutId = setTimeout(
|
|
1002
|
-
() => meeting.fetchMeetingInfo(
|
|
1272
|
+
() => meeting.fetchMeetingInfo(meetingInfoOptions),
|
|
1003
1273
|
waitingTime
|
|
1004
1274
|
);
|
|
1005
1275
|
meeting.parseMeetingInfo(undefined, destination);
|
|
1006
1276
|
} else {
|
|
1007
|
-
await meeting.fetchMeetingInfo(
|
|
1277
|
+
await meeting.fetchMeetingInfo(meetingInfoOptions);
|
|
1008
1278
|
}
|
|
1009
1279
|
} catch (err) {
|
|
1010
|
-
if (
|
|
1011
|
-
|
|
1280
|
+
if (
|
|
1281
|
+
!(err instanceof CaptchaError) &&
|
|
1282
|
+
!(err instanceof PasswordError) &&
|
|
1283
|
+
!(err instanceof PermissionError)
|
|
1284
|
+
) {
|
|
1012
1285
|
LoggerProxy.logger.info(
|
|
1013
1286
|
`Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
|
|
1014
1287
|
);
|
|
1288
|
+
if (failOnMissingMeetingInfo) {
|
|
1289
|
+
LoggerProxy.logger.info(
|
|
1290
|
+
`Meetings:index#createMeeting --> Destroying meeting due to missing meeting info.`
|
|
1291
|
+
);
|
|
1292
|
+
// @ts-ignore
|
|
1293
|
+
this.destroy(meeting, MEETING_REMOVED_REASON.MISSING_MEETING_INFO);
|
|
1294
|
+
throw new NoMeetingInfoError();
|
|
1295
|
+
}
|
|
1296
|
+
// if there is no meeting info and no error should be thrown then we assume its a 1:1 call or wireless share
|
|
1015
1297
|
LoggerProxy.logger.info(
|
|
1016
1298
|
'Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share'
|
|
1017
1299
|
);
|
|
@@ -1064,7 +1346,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1064
1346
|
//
|
|
1065
1347
|
// Our job is to determine the appropriate one
|
|
1066
1348
|
// and its corresponding service so that developers
|
|
1067
|
-
// need only sipURL
|
|
1349
|
+
// need only sipURL to get a meeting
|
|
1068
1350
|
// and its ID, but have the option to use createWithType()
|
|
1069
1351
|
// and specify those types to get meetingInfo
|
|
1070
1352
|
}
|
|
@@ -1102,39 +1384,126 @@ export default class Meetings extends WebexPlugin {
|
|
|
1102
1384
|
}
|
|
1103
1385
|
|
|
1104
1386
|
/**
|
|
1105
|
-
*
|
|
1106
|
-
* @
|
|
1387
|
+
* Syncs all the meetings from server. Does nothing and returns immediately if unverified guest.
|
|
1388
|
+
* @param {boolean} keepOnlyLocusMeetings - whether the sync should keep only locus meetings or any other meeting in meetingCollection
|
|
1389
|
+
* @returns {Promise<void>}
|
|
1107
1390
|
* @public
|
|
1108
1391
|
* @memberof Meetings
|
|
1109
1392
|
*/
|
|
1110
|
-
public syncMeetings() {
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1393
|
+
public syncMeetings({keepOnlyLocusMeetings = true} = {}): Promise<void> {
|
|
1394
|
+
// @ts-ignore
|
|
1395
|
+
if (this.webex.credentials.isUnverifiedGuest) {
|
|
1396
|
+
LoggerProxy.logger.info(
|
|
1397
|
+
'Meetings:index#syncMeetings --> skipping meeting sync as unverified guest'
|
|
1398
|
+
);
|
|
1399
|
+
|
|
1400
|
+
return Promise.resolve();
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
return this.request
|
|
1404
|
+
.getActiveMeetings()
|
|
1405
|
+
.then((locusArray) => {
|
|
1406
|
+
const activeLocusUrl = [];
|
|
1407
|
+
|
|
1408
|
+
if (locusArray?.loci && locusArray.loci.length > 0) {
|
|
1409
|
+
const lociToUpdate = this.sortLocusArrayToUpdate(locusArray.loci);
|
|
1410
|
+
lociToUpdate.forEach((locus) => {
|
|
1411
|
+
activeLocusUrl.push(locus.url);
|
|
1412
|
+
this.handleLocusEvent({
|
|
1413
|
+
locus,
|
|
1414
|
+
locusUrl: locus.url,
|
|
1415
|
+
});
|
|
1120
1416
|
});
|
|
1121
|
-
}
|
|
1122
|
-
|
|
1123
|
-
const meetingsCollection = this.meetingCollection.getAll();
|
|
1417
|
+
}
|
|
1418
|
+
const meetingsCollection = this.meetingCollection.getAll();
|
|
1124
1419
|
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
if (!activeLocusUrl.includes(meeting.locusUrl)) {
|
|
1131
|
-
// destroy function also uploads logs
|
|
1420
|
+
if (Object.keys(meetingsCollection).length > 0) {
|
|
1421
|
+
// Sometimes the mercury events are lost after mercury reconnect
|
|
1422
|
+
// Remove any Locus meetings that are not returned by Locus
|
|
1423
|
+
// (they had a locusUrl previously but are no longer active) in the sync
|
|
1424
|
+
for (const meeting of Object.values(meetingsCollection)) {
|
|
1132
1425
|
// @ts-ignore
|
|
1133
|
-
|
|
1426
|
+
const {locusUrl} = meeting;
|
|
1427
|
+
if ((keepOnlyLocusMeetings || locusUrl) && !activeLocusUrl.includes(locusUrl)) {
|
|
1428
|
+
// destroy function also uploads logs
|
|
1429
|
+
// @ts-ignore
|
|
1430
|
+
this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
|
|
1431
|
+
}
|
|
1134
1432
|
}
|
|
1135
1433
|
}
|
|
1434
|
+
})
|
|
1435
|
+
.catch((error) => {
|
|
1436
|
+
LoggerProxy.logger.error(
|
|
1437
|
+
`Meetings:index#syncMeetings --> failed to sync meetings, ${error}`
|
|
1438
|
+
);
|
|
1439
|
+
throw new Error(error);
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* sort out locus array for initial creating
|
|
1445
|
+
* @param {Array} loci original locus array
|
|
1446
|
+
* @returns {undefined}
|
|
1447
|
+
* @public
|
|
1448
|
+
* @memberof Meetings
|
|
1449
|
+
*/
|
|
1450
|
+
sortLocusArrayToUpdate(loci: any[]) {
|
|
1451
|
+
const mainLoci = loci.filter((locus) => !MeetingsUtil.isBreakoutLocusDTO(locus));
|
|
1452
|
+
const breakoutLoci = loci.filter((locus) => MeetingsUtil.isValidBreakoutLocus(locus));
|
|
1453
|
+
this.breakoutLocusForHandleLater = [];
|
|
1454
|
+
const lociToUpdate = [...mainLoci];
|
|
1455
|
+
breakoutLoci.forEach((breakoutLocus) => {
|
|
1456
|
+
const associateMainLocus = mainLoci.find(
|
|
1457
|
+
(mainLocus) => mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url
|
|
1458
|
+
);
|
|
1459
|
+
const existCorrespondingMeeting = this.getCorrespondingMeetingByLocus({
|
|
1460
|
+
locus: breakoutLocus,
|
|
1461
|
+
locusUrl: breakoutLocus.url,
|
|
1462
|
+
});
|
|
1463
|
+
|
|
1464
|
+
if (associateMainLocus && !existCorrespondingMeeting) {
|
|
1465
|
+
// if exists both main session and breakout session locus of the same non-exist meeting, handle main locus first,
|
|
1466
|
+
// after meeting create with main locus, then handle the associate breakout locus.
|
|
1467
|
+
// if only handle breakout locus, will miss some date
|
|
1468
|
+
this.breakoutLocusForHandleLater.push(breakoutLocus);
|
|
1469
|
+
} else {
|
|
1470
|
+
lociToUpdate.push(breakoutLocus);
|
|
1136
1471
|
}
|
|
1137
1472
|
});
|
|
1473
|
+
|
|
1474
|
+
return lociToUpdate;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/**
|
|
1478
|
+
* check breakout locus which waiting for main locus's meeting to be created, then handle the breakout locus
|
|
1479
|
+
* @param {Object} newCreatedLocus the locus which just create meeting object of it
|
|
1480
|
+
* @returns {undefined}
|
|
1481
|
+
* @public
|
|
1482
|
+
* @memberof Meetings
|
|
1483
|
+
*/
|
|
1484
|
+
checkHandleBreakoutLocus(newCreatedLocus) {
|
|
1485
|
+
if (
|
|
1486
|
+
!newCreatedLocus ||
|
|
1487
|
+
!this.breakoutLocusForHandleLater ||
|
|
1488
|
+
!this.breakoutLocusForHandleLater.length
|
|
1489
|
+
) {
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
if (MeetingsUtil.isBreakoutLocusDTO(newCreatedLocus)) {
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
const existIndex = this.breakoutLocusForHandleLater.findIndex(
|
|
1496
|
+
(breakoutLocus) =>
|
|
1497
|
+
breakoutLocus.controls?.breakout?.url === newCreatedLocus.controls?.breakout?.url
|
|
1498
|
+
);
|
|
1499
|
+
|
|
1500
|
+
if (existIndex < 0) {
|
|
1501
|
+
return;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1504
|
+
const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
|
|
1505
|
+
this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
|
|
1506
|
+
this.breakoutLocusForHandleLater.splice(existIndex, 1);
|
|
1138
1507
|
}
|
|
1139
1508
|
|
|
1140
1509
|
/**
|
|
@@ -1156,4 +1525,15 @@ export default class Meetings extends WebexPlugin {
|
|
|
1156
1525
|
getLogger() {
|
|
1157
1526
|
return LoggerProxy.get();
|
|
1158
1527
|
}
|
|
1528
|
+
|
|
1529
|
+
/**
|
|
1530
|
+
* Returns the first meeting it finds that has the webrtc media connection created.
|
|
1531
|
+
* Useful for debugging in the console.
|
|
1532
|
+
*
|
|
1533
|
+
* @private
|
|
1534
|
+
* @returns {Meeting} Meeting object that has a webrtc media connection, else undefined
|
|
1535
|
+
*/
|
|
1536
|
+
getActiveWebrtcMeeting() {
|
|
1537
|
+
return this.meetingCollection.getActiveWebrtcMeeting();
|
|
1538
|
+
}
|
|
1159
1539
|
}
|