@webex/plugin-meetings 3.11.0 → 3.12.0-next.2
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/aiEnableRequest/index.js +184 -0
- package/dist/aiEnableRequest/index.js.map +1 -0
- package/dist/aiEnableRequest/utils.js +36 -0
- package/dist/aiEnableRequest/utils.js.map +1 -0
- package/dist/annotation/index.js +14 -5
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/config.js +7 -2
- package/dist/config.js.map +1 -1
- package/dist/constants.js +28 -6
- package/dist/constants.js.map +1 -1
- package/dist/hashTree/constants.js +3 -1
- package/dist/hashTree/constants.js.map +1 -1
- package/dist/hashTree/hashTree.js +18 -0
- package/dist/hashTree/hashTree.js.map +1 -1
- package/dist/hashTree/hashTreeParser.js +850 -410
- package/dist/hashTree/hashTreeParser.js.map +1 -1
- package/dist/hashTree/types.js +4 -2
- package/dist/hashTree/types.js.map +1 -1
- package/dist/hashTree/utils.js +10 -0
- package/dist/hashTree/utils.js.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/constant.js +12 -0
- package/dist/interceptors/constant.js.map +1 -0
- package/dist/interceptors/dataChannelAuthToken.js +290 -0
- package/dist/interceptors/dataChannelAuthToken.js.map +1 -0
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/utils.js +27 -0
- package/dist/interceptors/utils.js.map +1 -0
- package/dist/interpretation/index.js +2 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +5 -3
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +522 -131
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/selfUtils.js +1 -0
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +57 -1
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/properties.js +4 -2
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +7 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1173 -877
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +50 -0
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/util.js +133 -3
- package/dist/meeting/util.js.map +1 -1
- package/dist/meetings/index.js +117 -48
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +10 -0
- package/dist/member/index.js.map +1 -1
- package/dist/member/util.js +10 -0
- package/dist/member/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +9 -60
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +11 -0
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/reachability/index.js +18 -10
- package/dist/reachability/index.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +0 -1
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/types/aiEnableRequest/index.d.ts +5 -0
- package/dist/types/aiEnableRequest/utils.d.ts +2 -0
- package/dist/types/config.d.ts +4 -0
- package/dist/types/constants.d.ts +23 -1
- package/dist/types/hashTree/constants.d.ts +1 -0
- package/dist/types/hashTree/hashTree.d.ts +7 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +122 -14
- package/dist/types/hashTree/types.d.ts +3 -0
- package/dist/types/hashTree/utils.d.ts +6 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/interceptors/constant.d.ts +5 -0
- package/dist/types/interceptors/dataChannelAuthToken.d.ts +43 -0
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/interceptors/utils.d.ts +1 -0
- package/dist/types/locus-info/index.d.ts +60 -8
- package/dist/types/locus-info/types.d.ts +7 -0
- package/dist/types/media/MediaConnectionAwaiter.d.ts +10 -1
- package/dist/types/media/properties.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +6 -0
- package/dist/types/meeting/index.d.ts +61 -7
- package/dist/types/meeting/request.d.ts +16 -1
- package/dist/types/meeting/request.type.d.ts +5 -0
- package/dist/types/meeting/util.d.ts +31 -0
- package/dist/types/meetings/index.d.ts +4 -2
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/mediaRequestManager.d.ts +0 -23
- package/dist/types/reactions/reactions.type.d.ts +1 -0
- package/dist/types/webinar/utils.d.ts +6 -0
- package/dist/webinar/index.js +291 -91
- package/dist/webinar/index.js.map +1 -1
- package/dist/webinar/utils.js +25 -0
- package/dist/webinar/utils.js.map +1 -0
- package/package.json +24 -23
- package/src/aiEnableRequest/README.md +84 -0
- package/src/aiEnableRequest/index.ts +170 -0
- package/src/aiEnableRequest/utils.ts +25 -0
- package/src/annotation/index.ts +27 -7
- package/src/config.ts +4 -0
- package/src/constants.ts +29 -1
- package/src/hashTree/constants.ts +1 -0
- package/src/hashTree/hashTree.ts +17 -0
- package/src/hashTree/hashTreeParser.ts +745 -252
- package/src/hashTree/types.ts +4 -0
- package/src/hashTree/utils.ts +9 -0
- package/src/index.ts +8 -1
- package/src/interceptors/constant.ts +6 -0
- package/src/interceptors/dataChannelAuthToken.ts +170 -0
- package/src/interceptors/index.ts +2 -1
- package/src/interceptors/utils.ts +16 -0
- package/src/interpretation/index.ts +2 -2
- package/src/locus-info/controlsUtils.ts +11 -0
- package/src/locus-info/index.ts +579 -113
- package/src/locus-info/selfUtils.ts +1 -0
- package/src/locus-info/types.ts +8 -0
- package/src/media/MediaConnectionAwaiter.ts +41 -1
- package/src/media/properties.ts +3 -1
- package/src/meeting/in-meeting-actions.ts +12 -0
- package/src/meeting/index.ts +291 -76
- package/src/meeting/request.ts +42 -0
- package/src/meeting/request.type.ts +6 -0
- package/src/meeting/util.ts +160 -2
- package/src/meetings/index.ts +157 -44
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +12 -0
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +4 -54
- package/src/multistream/remoteMediaManager.ts +13 -0
- package/src/reachability/index.ts +9 -0
- package/src/reactions/reactions.type.ts +1 -0
- package/src/reconnection-manager/index.ts +0 -1
- package/src/webinar/index.ts +191 -6
- package/src/webinar/utils.ts +16 -0
- package/test/unit/spec/aiEnableRequest/index.ts +981 -0
- package/test/unit/spec/aiEnableRequest/utils.ts +130 -0
- package/test/unit/spec/annotation/index.ts +69 -7
- package/test/unit/spec/hashTree/hashTree.ts +66 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +2225 -189
- package/test/unit/spec/interceptors/dataChannelAuthToken.ts +210 -0
- package/test/unit/spec/interceptors/utils.ts +75 -0
- package/test/unit/spec/locus-info/controlsUtils.js +29 -0
- package/test/unit/spec/locus-info/index.js +1134 -55
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +41 -1
- package/test/unit/spec/media/properties.ts +12 -3
- package/test/unit/spec/meeting/in-meeting-actions.ts +8 -2
- package/test/unit/spec/meeting/index.js +829 -115
- package/test/unit/spec/meeting/request.js +70 -0
- package/test/unit/spec/meeting/utils.js +438 -26
- package/test/unit/spec/meetings/index.js +653 -32
- package/test/unit/spec/member/index.js +28 -4
- package/test/unit/spec/member/util.js +65 -27
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -85
- package/test/unit/spec/multistream/remoteMediaManager.ts +30 -0
- package/test/unit/spec/reachability/index.ts +23 -0
- package/test/unit/spec/reconnection-manager/index.js +4 -8
- package/test/unit/spec/webinar/index.ts +474 -37
- package/test/unit/spec/webinar/utils.ts +39 -0
package/src/meeting/index.ts
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
CALL_DIAGNOSTIC_CONFIG,
|
|
14
14
|
RtcMetrics,
|
|
15
15
|
} from '@webex/internal-plugin-metrics';
|
|
16
|
-
import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
|
|
16
|
+
import type {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
|
|
17
17
|
|
|
18
18
|
import {
|
|
19
19
|
ConnectionState,
|
|
@@ -33,6 +33,8 @@ import {
|
|
|
33
33
|
InboundAudioIssueSubTypes,
|
|
34
34
|
} from '@webex/internal-media-core';
|
|
35
35
|
|
|
36
|
+
import {DataChannelTokenType} from '@webex/internal-plugin-llm';
|
|
37
|
+
|
|
36
38
|
import {
|
|
37
39
|
LocalStream,
|
|
38
40
|
LocalCameraStream,
|
|
@@ -55,6 +57,7 @@ import {
|
|
|
55
57
|
isBrowserMediaError,
|
|
56
58
|
isBrowserMediaErrorName,
|
|
57
59
|
} from '@webex/internal-plugin-metrics/src/call-diagnostic/call-diagnostic-metrics.util';
|
|
60
|
+
import {CapabilityState, WebCapabilities} from '@webex/web-capabilities';
|
|
58
61
|
import {processNewCaptions} from './voicea-meeting';
|
|
59
62
|
|
|
60
63
|
import {
|
|
@@ -178,8 +181,9 @@ import JoinForbiddenError from '../common/errors/join-forbidden-error';
|
|
|
178
181
|
import {ReachabilityMetrics} from '../reachability/reachability.types';
|
|
179
182
|
import {SetStageOptions, SetStageVideoLayout, UnsetStageVideoLayout} from './request.type';
|
|
180
183
|
import {Invitee} from './type';
|
|
181
|
-
import {DataSet} from '../hashTree/hashTreeParser';
|
|
184
|
+
import {DataSet, HashTreeMessage, Metadata} from '../hashTree/hashTreeParser';
|
|
182
185
|
import {LocusDTO} from '../locus-info/types';
|
|
186
|
+
import AIEnableRequest from '../aiEnableRequest';
|
|
183
187
|
|
|
184
188
|
// default callback so we don't call an undefined function, but in practice it should never be used
|
|
185
189
|
const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
|
|
@@ -249,6 +253,7 @@ export type AddMediaOptions = {
|
|
|
249
253
|
remoteMediaManagerConfig?: RemoteMediaManagerConfiguration; // applies only to multistream meetings
|
|
250
254
|
bundlePolicy?: BundlePolicy; // applies only to multistream meetings
|
|
251
255
|
allowMediaInLobby?: boolean; // allows adding media when in the lobby
|
|
256
|
+
allowPublishMediaInLobby?: boolean; // allows publishing media when in the lobby, if not specified, default value false is used
|
|
252
257
|
additionalMediaOptions?: AdditionalMediaOptions; // allows adding additional options like send/receive audio/video
|
|
253
258
|
};
|
|
254
259
|
|
|
@@ -563,6 +568,34 @@ type MediaReachabilityMetrics = ReachabilityMetrics & {
|
|
|
563
568
|
* @memberof Meeting
|
|
564
569
|
*/
|
|
565
570
|
|
|
571
|
+
/**
|
|
572
|
+
* Stores an event so all events can be later retrieved via a console command for debugging.
|
|
573
|
+
* @param {string} type
|
|
574
|
+
* @param {Object} data
|
|
575
|
+
* @returns {void}
|
|
576
|
+
*/
|
|
577
|
+
export function storeEventForDebugging(
|
|
578
|
+
type: string,
|
|
579
|
+
data: {
|
|
580
|
+
eventType: any;
|
|
581
|
+
stateElementsMessage?: HashTreeMessage;
|
|
582
|
+
}
|
|
583
|
+
) {
|
|
584
|
+
if ((window as any)?.locusEvents) {
|
|
585
|
+
// only store non-heartbeat hash tree messages
|
|
586
|
+
if (
|
|
587
|
+
data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED &&
|
|
588
|
+
data.stateElementsMessage?.locusStateElements
|
|
589
|
+
) {
|
|
590
|
+
(window as any).locusEvents.push({
|
|
591
|
+
...data,
|
|
592
|
+
timestamp: new Date().toLocaleString(),
|
|
593
|
+
type,
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
|
|
566
599
|
/**
|
|
567
600
|
* @description Meeting is the crux of the plugin
|
|
568
601
|
* @export
|
|
@@ -574,6 +607,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
574
607
|
breakouts: any;
|
|
575
608
|
simultaneousInterpretation: any;
|
|
576
609
|
annotation: any;
|
|
610
|
+
aiEnableRequest: any;
|
|
577
611
|
webinar: any;
|
|
578
612
|
conversationUrl: string;
|
|
579
613
|
callStateForMetrics: CallStateForMetrics;
|
|
@@ -622,6 +656,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
622
656
|
keepAliveTimerId: NodeJS.Timeout;
|
|
623
657
|
lastVideoLayoutInfo: any;
|
|
624
658
|
locusInfo: any;
|
|
659
|
+
// this group of properties is populated via updateMeetingObject() that's registered as a callback with LocusInfo
|
|
660
|
+
isUserUnadmitted?: boolean;
|
|
661
|
+
joinedWith?: any;
|
|
662
|
+
selfId?: string;
|
|
663
|
+
roles: any[];
|
|
664
|
+
// ... there is more ... see SelfUtils.parse()
|
|
665
|
+
// end of the group
|
|
625
666
|
locusMediaRequest?: LocusMediaRequest;
|
|
626
667
|
mediaProperties: MediaProperties;
|
|
627
668
|
mediaRequestManagers: {
|
|
@@ -656,7 +697,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
656
697
|
endCallInitJoinReq: any;
|
|
657
698
|
endJoinReqResp: any;
|
|
658
699
|
endLocalSDPGenRemoteSDPRecvDelay: any;
|
|
659
|
-
joinedWith: any;
|
|
660
700
|
locusId: any;
|
|
661
701
|
startCallInitJoinReq: any;
|
|
662
702
|
startJoinReqResp: any;
|
|
@@ -671,12 +711,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
671
711
|
permissionTokenReceivedLocalTime: number;
|
|
672
712
|
resourceId: any;
|
|
673
713
|
resourceUrl: string;
|
|
674
|
-
selfId: string;
|
|
675
714
|
state: any;
|
|
676
715
|
localAudioStreamMuteStateHandler: () => void;
|
|
677
716
|
localVideoStreamMuteStateHandler: () => void;
|
|
678
717
|
localOutputTrackChangeHandler: () => void;
|
|
679
|
-
|
|
718
|
+
localConstraintsChangeHandler: () => void;
|
|
680
719
|
environment: string;
|
|
681
720
|
namespace = MEETINGS;
|
|
682
721
|
allowMediaInLobby: boolean;
|
|
@@ -893,6 +932,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
893
932
|
*/
|
|
894
933
|
// @ts-ignore
|
|
895
934
|
this.simultaneousInterpretation = new SimultaneousInterpretation({}, {parent: this.webex});
|
|
935
|
+
|
|
936
|
+
// @ts-ignore
|
|
937
|
+
this.aiEnableRequest = new AIEnableRequest({}, {parent: this.webex});
|
|
938
|
+
|
|
896
939
|
/**
|
|
897
940
|
* @instance
|
|
898
941
|
* @type {Annotation}
|
|
@@ -1542,6 +1585,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1542
1585
|
}
|
|
1543
1586
|
};
|
|
1544
1587
|
|
|
1588
|
+
this.localConstraintsChangeHandler = () => {
|
|
1589
|
+
if (!this.isMultistream) {
|
|
1590
|
+
this.mediaProperties.webrtcMediaConnection?.updatePreferredBitrateKbps();
|
|
1591
|
+
}
|
|
1592
|
+
};
|
|
1593
|
+
|
|
1545
1594
|
/**
|
|
1546
1595
|
* Promise that exists if SDP offer has been generated, and resolves once sdp answer is received.
|
|
1547
1596
|
* @instance
|
|
@@ -2951,6 +3000,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2951
3000
|
);
|
|
2952
3001
|
});
|
|
2953
3002
|
|
|
3003
|
+
this.locusInfo.on(
|
|
3004
|
+
LOCUSINFO.EVENTS.CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED,
|
|
3005
|
+
({aiSummaryNotification}) => {
|
|
3006
|
+
Trigger.trigger(
|
|
3007
|
+
this,
|
|
3008
|
+
{file: 'meeting/index', function: 'setupLocusControlsListener'},
|
|
3009
|
+
EVENT_TRIGGERS.MEETING_CONTROLS_AI_SUMMARY_NOTIFICATION_UPDATED,
|
|
3010
|
+
{aiSummaryNotification}
|
|
3011
|
+
);
|
|
3012
|
+
}
|
|
3013
|
+
);
|
|
3014
|
+
|
|
2954
3015
|
this.locusInfo.on(LOCUSINFO.EVENTS.CONTROLS_WEBCAST_CHANGED, ({state}) => {
|
|
2955
3016
|
Trigger.trigger(
|
|
2956
3017
|
this,
|
|
@@ -3402,6 +3463,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3402
3463
|
this.recordingController.setLocusUrl(this.locusUrl);
|
|
3403
3464
|
this.controlsOptionsManager.setLocusUrl(this.locusUrl, !!isMainLocus);
|
|
3404
3465
|
this.webinar.locusUrlUpdate(url);
|
|
3466
|
+
// @ts-ignore
|
|
3467
|
+
this.webex.internal.llm.setRefreshHandler(() => this.refreshDataChannelToken());
|
|
3405
3468
|
|
|
3406
3469
|
Trigger.trigger(
|
|
3407
3470
|
this,
|
|
@@ -3432,6 +3495,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3432
3495
|
this.breakouts.breakoutServiceUrlUpdate(payload?.services?.breakout?.url);
|
|
3433
3496
|
this.annotation.approvalUrlUpdate(payload?.services?.approval?.url);
|
|
3434
3497
|
this.simultaneousInterpretation.approvalUrlUpdate(payload?.services?.approval?.url);
|
|
3498
|
+
this.aiEnableRequest.approvalUrlUpdate(payload?.services?.approval?.url);
|
|
3435
3499
|
});
|
|
3436
3500
|
}
|
|
3437
3501
|
|
|
@@ -3529,6 +3593,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3529
3593
|
// @ts-ignore - config coming from registerPlugin
|
|
3530
3594
|
if (datachannelUrl && this.config.enableAutomaticLLM) {
|
|
3531
3595
|
this.updateLLMConnection();
|
|
3596
|
+
if (this.webinar.isJoinPracticeSessionDataChannel()) {
|
|
3597
|
+
this.webinar.updatePSDataChannel();
|
|
3598
|
+
}
|
|
3532
3599
|
}
|
|
3533
3600
|
}
|
|
3534
3601
|
|
|
@@ -3761,6 +3828,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3761
3828
|
);
|
|
3762
3829
|
});
|
|
3763
3830
|
|
|
3831
|
+
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_ID_CHANGED, (payload) => {
|
|
3832
|
+
this.aiEnableRequest.selfParticipantIdUpdate(payload.selfId);
|
|
3833
|
+
});
|
|
3834
|
+
|
|
3764
3835
|
this.locusInfo.on(LOCUSINFO.EVENTS.SELF_MEETING_INTERPRETATION_CHANGED, (payload) => {
|
|
3765
3836
|
const targetChanged = this.simultaneousInterpretation.updateSelfInterpretation(payload);
|
|
3766
3837
|
Trigger.trigger(
|
|
@@ -4263,6 +4334,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4263
4334
|
bothLeaveAndEndMeetingAvailable: MeetingUtil.bothLeaveAndEndMeetingAvailable(
|
|
4264
4335
|
this.userDisplayHints
|
|
4265
4336
|
),
|
|
4337
|
+
requireHostEndMeetingBeforeLeave: MeetingUtil.requireHostEndMeetingBeforeLeave(
|
|
4338
|
+
this.userDisplayHints
|
|
4339
|
+
),
|
|
4266
4340
|
canEnableClosedCaption: MeetingUtil.canEnableClosedCaption(this.userDisplayHints),
|
|
4267
4341
|
canStartTranscribing: MeetingUtil.canStartTranscribing(this.userDisplayHints),
|
|
4268
4342
|
canStopTranscribing: MeetingUtil.canStopTranscribing(this.userDisplayHints),
|
|
@@ -4521,6 +4595,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4521
4595
|
requiredHints: [DISPLAY_HINTS.DISABLE_ATTENDEE_START_POLLING_QA],
|
|
4522
4596
|
displayHints: this.userDisplayHints,
|
|
4523
4597
|
}),
|
|
4598
|
+
canAttendeeRequestAiAssistantEnabled: MeetingUtil.canAttendeeRequestAiAssistantEnabled(
|
|
4599
|
+
this.userDisplayHints,
|
|
4600
|
+
this.roles
|
|
4601
|
+
),
|
|
4602
|
+
isAttendeeRequestAiAssistantDeclinedAll:
|
|
4603
|
+
MeetingUtil.attendeeRequestAiAssistantDeclinedAll(this.userDisplayHints),
|
|
4524
4604
|
}) || changed;
|
|
4525
4605
|
}
|
|
4526
4606
|
if (changed) {
|
|
@@ -4592,7 +4672,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4592
4672
|
mediaId: string;
|
|
4593
4673
|
host: object;
|
|
4594
4674
|
selfId: string;
|
|
4595
|
-
dataSets: DataSet[];
|
|
4675
|
+
dataSets: DataSet[]; // only sent by Locus when hash trees are used
|
|
4676
|
+
metadata: Metadata; // only sent by Locus when hash trees are used
|
|
4596
4677
|
}) {
|
|
4597
4678
|
const mtgLocus: any = data.locus;
|
|
4598
4679
|
|
|
@@ -4608,6 +4689,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4608
4689
|
trigger: 'join-response',
|
|
4609
4690
|
locus: mtgLocus,
|
|
4610
4691
|
dataSets: data.dataSets,
|
|
4692
|
+
metadata: data.metadata,
|
|
4611
4693
|
});
|
|
4612
4694
|
}
|
|
4613
4695
|
|
|
@@ -4817,6 +4899,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4817
4899
|
this.localVideoStreamMuteStateHandler
|
|
4818
4900
|
);
|
|
4819
4901
|
oldStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
4902
|
+
oldStream?.off(LocalStreamEventNames.ConstraintsChange, this.localConstraintsChangeHandler);
|
|
4820
4903
|
|
|
4821
4904
|
// we don't update this.mediaProperties.mediaDirection.sendVideo, because we always keep it as true to avoid extra SDP exchanges
|
|
4822
4905
|
this.mediaProperties.setLocalVideoStream(localStream);
|
|
@@ -4832,6 +4915,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4832
4915
|
this.localVideoStreamMuteStateHandler
|
|
4833
4916
|
);
|
|
4834
4917
|
localStream?.on(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
4918
|
+
localStream?.on(LocalStreamEventNames.ConstraintsChange, this.localConstraintsChangeHandler);
|
|
4835
4919
|
|
|
4836
4920
|
if (!this.isMultistream || !localStream) {
|
|
4837
4921
|
// for multistream WCME automatically un-publishes the old stream when we publish a new one
|
|
@@ -4966,6 +5050,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4966
5050
|
this.localVideoStreamMuteStateHandler
|
|
4967
5051
|
);
|
|
4968
5052
|
videoStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
5053
|
+
videoStream?.off(LocalStreamEventNames.ConstraintsChange, this.localConstraintsChangeHandler);
|
|
4969
5054
|
|
|
4970
5055
|
shareAudioStream?.off(StreamEventNames.Ended, this.handleShareAudioStreamEnded);
|
|
4971
5056
|
shareAudioStream?.off(
|
|
@@ -5379,6 +5464,18 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5379
5464
|
let joined = false;
|
|
5380
5465
|
let joinResponse = prevJoinResponse;
|
|
5381
5466
|
|
|
5467
|
+
/* Before we do anything, check if RTCPeerConnection is available. Normally this is checked
|
|
5468
|
+
by addMediaInternal() itself when creating the media connection, but since joinWithMedia()
|
|
5469
|
+
is a convenience method that does both join() and addMedia(), we want to fail fast here
|
|
5470
|
+
in case WebRTC is not available at all.
|
|
5471
|
+
*/
|
|
5472
|
+
if (WebCapabilities.supportsRTCPeerConnection() === CapabilityState.NOT_CAPABLE) {
|
|
5473
|
+
// throw the same error that would be thrown by addMediaInternal()
|
|
5474
|
+
throw new Errors.WebrtcApiNotAvailableError(
|
|
5475
|
+
'RTCPeerConnection API is not available in this environment'
|
|
5476
|
+
);
|
|
5477
|
+
}
|
|
5478
|
+
|
|
5382
5479
|
try {
|
|
5383
5480
|
let turnServerInfo;
|
|
5384
5481
|
let turnDiscoverySkippedReason;
|
|
@@ -5449,7 +5546,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5449
5546
|
// if this was the first attempt, let's do a retry
|
|
5450
5547
|
let shouldRetry = !isRetry;
|
|
5451
5548
|
|
|
5452
|
-
if (
|
|
5549
|
+
if (
|
|
5550
|
+
CallDiagnosticUtils.isSdpOfferCreationError(error) ||
|
|
5551
|
+
CallDiagnosticUtils.isWebrtcApiNotAvailableError(error)
|
|
5552
|
+
) {
|
|
5453
5553
|
// errors related to offer creation (for example missing H264 codec) will happen again no matter how many times we try,
|
|
5454
5554
|
// so there is no point doing a retry
|
|
5455
5555
|
shouldRetry = false;
|
|
@@ -5742,6 +5842,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5742
5842
|
*/
|
|
5743
5843
|
private processLocusLLMEvent = (event: LocusLLMEvent): void => {
|
|
5744
5844
|
if (event.data.eventType === LOCUSEVENT.HASH_TREE_DATA_UPDATED) {
|
|
5845
|
+
// @ts-ignore
|
|
5846
|
+
if (this.config.experimental.storeLocusHashTreeEventsForDebugging) {
|
|
5847
|
+
storeEventForDebugging('llm', event.data);
|
|
5848
|
+
}
|
|
5849
|
+
|
|
5745
5850
|
this.locusInfo.parse(this, event.data);
|
|
5746
5851
|
} else {
|
|
5747
5852
|
LoggerProxy.logger.warn(
|
|
@@ -5765,7 +5870,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5765
5870
|
this.isReactionsSupported()
|
|
5766
5871
|
) {
|
|
5767
5872
|
const member = this.members.membersCollection.get(e.data.sender.participantId);
|
|
5768
|
-
if (!member) {
|
|
5873
|
+
if (!member && !this.locusInfo?.info?.isWebinar) {
|
|
5769
5874
|
// @ts-ignore -- fix type
|
|
5770
5875
|
LoggerProxy.logger.warn(
|
|
5771
5876
|
`Meeting:index#processRelayEvent --> Skipping handling of ${REACTION_RELAY_TYPES.REACTION} for ${this.id}. participantId ${e.data.sender.participantId} does not exist in membersCollection.`
|
|
@@ -5773,7 +5878,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5773
5878
|
break;
|
|
5774
5879
|
}
|
|
5775
5880
|
|
|
5776
|
-
const
|
|
5881
|
+
const name = (member && member.name) || e.data.sender.displayName;
|
|
5777
5882
|
const processedReaction: ProcessedReaction = {
|
|
5778
5883
|
reaction: e.data.reaction,
|
|
5779
5884
|
sender: {
|
|
@@ -5802,37 +5907,35 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
5802
5907
|
* @returns {void}
|
|
5803
5908
|
*/
|
|
5804
5909
|
stopTranscription() {
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
);
|
|
5910
|
+
// @ts-ignore
|
|
5911
|
+
this.webex.internal.voicea.off(
|
|
5912
|
+
VOICEAEVENTS.VOICEA_ANNOUNCEMENT,
|
|
5913
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.VOICEA_ANNOUNCEMENT]
|
|
5914
|
+
);
|
|
5811
5915
|
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5916
|
+
// @ts-ignore
|
|
5917
|
+
this.webex.internal.voicea.off(
|
|
5918
|
+
VOICEAEVENTS.CAPTIONS_TURNED_ON,
|
|
5919
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.CAPTIONS_TURNED_ON]
|
|
5920
|
+
);
|
|
5817
5921
|
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5922
|
+
// @ts-ignore
|
|
5923
|
+
this.webex.internal.voicea.off(
|
|
5924
|
+
VOICEAEVENTS.EVA_COMMAND,
|
|
5925
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.EVA_COMMAND]
|
|
5926
|
+
);
|
|
5823
5927
|
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5928
|
+
// @ts-ignore
|
|
5929
|
+
this.webex.internal.voicea.off(
|
|
5930
|
+
VOICEAEVENTS.NEW_CAPTION,
|
|
5931
|
+
this.voiceaListenerCallbacks[VOICEAEVENTS.NEW_CAPTION]
|
|
5932
|
+
);
|
|
5829
5933
|
|
|
5830
|
-
|
|
5831
|
-
|
|
5934
|
+
// @ts-ignore
|
|
5935
|
+
this.webex.internal.voicea.deregisterEvents();
|
|
5832
5936
|
|
|
5833
|
-
|
|
5834
|
-
|
|
5835
|
-
}
|
|
5937
|
+
this.areVoiceaEventsSetup = false;
|
|
5938
|
+
this.triggerStopReceivingTranscriptionEvent();
|
|
5836
5939
|
}
|
|
5837
5940
|
|
|
5838
5941
|
/**
|
|
@@ -6093,6 +6196,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6093
6196
|
return Promise.reject(error);
|
|
6094
6197
|
})
|
|
6095
6198
|
.then((join) => {
|
|
6199
|
+
this.saveDataChannelToken(join);
|
|
6096
6200
|
// @ts-ignore - config coming from registerPlugin
|
|
6097
6201
|
if (this.config.enableAutomaticLLM) {
|
|
6098
6202
|
// @ts-ignore
|
|
@@ -6161,23 +6265,100 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6161
6265
|
}
|
|
6162
6266
|
}
|
|
6163
6267
|
|
|
6268
|
+
/**
|
|
6269
|
+
* Disconnects and cleans up the default LLM session listeners/timers.
|
|
6270
|
+
* @param {Object} options
|
|
6271
|
+
* @param {boolean} [options.removeOnlineListener=true] removes the one-time online listener
|
|
6272
|
+
* @param {boolean} [options.throwOnError=true] rethrows disconnect errors when true
|
|
6273
|
+
* @returns {Promise<void>}
|
|
6274
|
+
*/
|
|
6275
|
+
private cleanupLLMConneciton = async ({
|
|
6276
|
+
removeOnlineListener = true,
|
|
6277
|
+
throwOnError = true,
|
|
6278
|
+
}: {
|
|
6279
|
+
removeOnlineListener?: boolean;
|
|
6280
|
+
throwOnError?: boolean;
|
|
6281
|
+
} = {}): Promise<void> => {
|
|
6282
|
+
try {
|
|
6283
|
+
// @ts-ignore - Fix type
|
|
6284
|
+
await this.webex.internal.llm.disconnectLLM({
|
|
6285
|
+
code: 3050,
|
|
6286
|
+
reason: 'done (permanent)',
|
|
6287
|
+
});
|
|
6288
|
+
} catch (error) {
|
|
6289
|
+
LoggerProxy.logger.error(
|
|
6290
|
+
'Meeting:index#cleanupLLMConneciton --> Failed to disconnect default LLM session',
|
|
6291
|
+
error
|
|
6292
|
+
);
|
|
6293
|
+
|
|
6294
|
+
if (throwOnError) {
|
|
6295
|
+
throw error;
|
|
6296
|
+
}
|
|
6297
|
+
} finally {
|
|
6298
|
+
if (removeOnlineListener) {
|
|
6299
|
+
// @ts-ignore - Fix type
|
|
6300
|
+
this.webex.internal.llm.off('online', this.handleLLMOnline);
|
|
6301
|
+
}
|
|
6302
|
+
// @ts-ignore - fix types
|
|
6303
|
+
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6304
|
+
// @ts-ignore - Fix type
|
|
6305
|
+
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
6306
|
+
|
|
6307
|
+
this.clearLLMHealthCheckTimer();
|
|
6308
|
+
}
|
|
6309
|
+
};
|
|
6310
|
+
|
|
6311
|
+
/**
|
|
6312
|
+
* Clears all data channel tokens stored in LLM.
|
|
6313
|
+
* Called during meeting cleanup to ensure stale tokens are not reused.
|
|
6314
|
+
* @returns {void}
|
|
6315
|
+
*/
|
|
6316
|
+
clearDataChannelToken(): void {
|
|
6317
|
+
// @ts-ignore
|
|
6318
|
+
this.webex.internal.llm.resetDatachannelTokens();
|
|
6319
|
+
}
|
|
6320
|
+
|
|
6321
|
+
/**
|
|
6322
|
+
* Saves the data channel tokens from the join response into LLM so that
|
|
6323
|
+
* updateLLMConnection / updatePSDataChannel don't need to fetch them from locusInfo.
|
|
6324
|
+
* @param {Object} join - The parsed join response (from MeetingUtil.parseLocusJoin)
|
|
6325
|
+
* @returns {void}
|
|
6326
|
+
*/
|
|
6327
|
+
saveDataChannelToken(join: any): void {
|
|
6328
|
+
const datachannelToken = join?.locus?.self?.datachannelToken;
|
|
6329
|
+
const practiceSessionDatachannelToken = join?.locus?.self?.practiceSessionDatachannelToken;
|
|
6330
|
+
|
|
6331
|
+
if (datachannelToken) {
|
|
6332
|
+
// @ts-ignore
|
|
6333
|
+
this.webex.internal.llm.setDatachannelToken(datachannelToken, DataChannelTokenType.Default);
|
|
6334
|
+
}
|
|
6335
|
+
|
|
6336
|
+
if (practiceSessionDatachannelToken) {
|
|
6337
|
+
// @ts-ignore
|
|
6338
|
+
this.webex.internal.llm.setDatachannelToken(
|
|
6339
|
+
practiceSessionDatachannelToken,
|
|
6340
|
+
DataChannelTokenType.PracticeSession
|
|
6341
|
+
);
|
|
6342
|
+
}
|
|
6343
|
+
}
|
|
6344
|
+
|
|
6164
6345
|
/**
|
|
6165
6346
|
* Connects to low latency mercury and reconnects if the address has changed
|
|
6166
6347
|
* It will also disconnect if called when the meeting has ended
|
|
6167
|
-
* @param {String} datachannelUrl
|
|
6168
6348
|
* @returns {Promise}
|
|
6169
6349
|
*/
|
|
6170
6350
|
async updateLLMConnection() {
|
|
6171
6351
|
// @ts-ignore - Fix type
|
|
6172
|
-
const {url, info: {datachannelUrl
|
|
6352
|
+
const {url = undefined, info: {datachannelUrl = undefined} = {}} = this.locusInfo || {};
|
|
6173
6353
|
|
|
6174
6354
|
const isJoined = this.isJoined();
|
|
6175
6355
|
|
|
6176
|
-
//
|
|
6177
|
-
const
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6356
|
+
// @ts-ignore
|
|
6357
|
+
const datachannelToken = this.webex.internal.llm.getDatachannelToken(
|
|
6358
|
+
DataChannelTokenType.Default
|
|
6359
|
+
);
|
|
6360
|
+
|
|
6361
|
+
const dataChannelUrl = datachannelUrl;
|
|
6181
6362
|
|
|
6182
6363
|
// @ts-ignore - Fix type
|
|
6183
6364
|
if (this.webex.internal.llm.isConnected()) {
|
|
@@ -6190,21 +6371,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6190
6371
|
) {
|
|
6191
6372
|
return undefined;
|
|
6192
6373
|
}
|
|
6193
|
-
|
|
6194
|
-
await this.webex.internal.llm.disconnectLLM(
|
|
6195
|
-
isJoined
|
|
6196
|
-
? {
|
|
6197
|
-
code: 3050,
|
|
6198
|
-
reason: 'done (permanent)',
|
|
6199
|
-
}
|
|
6200
|
-
: undefined
|
|
6201
|
-
);
|
|
6202
|
-
// @ts-ignore - Fix type
|
|
6203
|
-
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6204
|
-
// @ts-ignore - Fix type
|
|
6205
|
-
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
6206
|
-
|
|
6207
|
-
this.clearLLMHealthCheckTimer();
|
|
6374
|
+
await this.cleanupLLMConneciton({removeOnlineListener: false});
|
|
6208
6375
|
}
|
|
6209
6376
|
|
|
6210
6377
|
if (!isJoined) {
|
|
@@ -6213,7 +6380,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6213
6380
|
|
|
6214
6381
|
// @ts-ignore - Fix type
|
|
6215
6382
|
return this.webex.internal.llm
|
|
6216
|
-
.registerAndConnect(url, dataChannelUrl)
|
|
6383
|
+
.registerAndConnect(url, dataChannelUrl, datachannelToken)
|
|
6217
6384
|
.then((registerAndConnectResult) => {
|
|
6218
6385
|
// @ts-ignore - Fix type
|
|
6219
6386
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
@@ -7417,7 +7584,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7417
7584
|
*/
|
|
7418
7585
|
private async waitForMediaConnectionConnected(): Promise<void> {
|
|
7419
7586
|
try {
|
|
7420
|
-
await this.mediaProperties.waitForMediaConnectionConnected();
|
|
7587
|
+
await this.mediaProperties.waitForMediaConnectionConnected(this.correlationId);
|
|
7421
7588
|
} catch (error) {
|
|
7422
7589
|
const {iceConnected} = error;
|
|
7423
7590
|
|
|
@@ -8010,6 +8177,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8010
8177
|
remoteMediaManagerConfig,
|
|
8011
8178
|
bundlePolicy = 'max-bundle',
|
|
8012
8179
|
additionalMediaOptions = {},
|
|
8180
|
+
allowPublishMediaInLobby = false,
|
|
8013
8181
|
} = options;
|
|
8014
8182
|
|
|
8015
8183
|
const {
|
|
@@ -8030,7 +8198,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8030
8198
|
const ipver = MeetingUtil.getIpVersion(this.webex); // used just for metrics
|
|
8031
8199
|
|
|
8032
8200
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
|
8033
|
-
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
|
8034
8201
|
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
|
8035
8202
|
throw new UserInLobbyError();
|
|
8036
8203
|
}
|
|
@@ -8075,7 +8242,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8075
8242
|
this.brbState = createBrbState(this, false);
|
|
8076
8243
|
|
|
8077
8244
|
try {
|
|
8078
|
-
|
|
8245
|
+
// if we're in a lobby and allowPublishMediaInLobby==false, we don't want to
|
|
8246
|
+
// setup local streams for publishing, because if we ever end up admitted to the meeting
|
|
8247
|
+
// but Locus event about it for us is delayed or missed, others could see/hear our user's video/audio
|
|
8248
|
+
// while the user would still think they're in the lobby
|
|
8249
|
+
if (allowPublishMediaInLobby || !this.isUserUnadmitted) {
|
|
8250
|
+
await this.setUpLocalStreamReferences(localStreams);
|
|
8251
|
+
}
|
|
8079
8252
|
|
|
8080
8253
|
this.setMercuryListener();
|
|
8081
8254
|
|
|
@@ -8543,12 +8716,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8543
8716
|
LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
|
|
8544
8717
|
|
|
8545
8718
|
return MeetingUtil.leaveMeeting(this, options)
|
|
8546
|
-
.then((leave) => {
|
|
8719
|
+
.then(async (leave) => {
|
|
8547
8720
|
// CA team recommends submitting this *after* locus /leave
|
|
8548
8721
|
submitLeaveMetric();
|
|
8549
8722
|
|
|
8550
8723
|
this.meetingFiniteStateMachine.leave();
|
|
8551
|
-
this.clearMeetingData();
|
|
8724
|
+
await this.clearMeetingData();
|
|
8552
8725
|
|
|
8553
8726
|
// upload logs on leave irrespective of meeting delete
|
|
8554
8727
|
Trigger.trigger(
|
|
@@ -9407,10 +9580,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9407
9580
|
});
|
|
9408
9581
|
|
|
9409
9582
|
return MeetingUtil.endMeetingForAll(this)
|
|
9410
|
-
.then((end) => {
|
|
9583
|
+
.then(async (end) => {
|
|
9411
9584
|
this.meetingFiniteStateMachine.end();
|
|
9412
9585
|
|
|
9413
|
-
this.clearMeetingData();
|
|
9586
|
+
await this.clearMeetingData();
|
|
9414
9587
|
// upload logs on leave irrespective of meeting delete
|
|
9415
9588
|
Trigger.trigger(
|
|
9416
9589
|
this,
|
|
@@ -9458,7 +9631,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9458
9631
|
* @public
|
|
9459
9632
|
* @memberof Meeting
|
|
9460
9633
|
*/
|
|
9461
|
-
clearMeetingData = () => {
|
|
9634
|
+
clearMeetingData = async () => {
|
|
9462
9635
|
this.audio = null;
|
|
9463
9636
|
this.video = null;
|
|
9464
9637
|
this.screenShareFloorState = ScreenShareFloorStatus.RELEASED;
|
|
@@ -9467,19 +9640,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9467
9640
|
}
|
|
9468
9641
|
this.queuedMediaUpdates = [];
|
|
9469
9642
|
|
|
9470
|
-
|
|
9471
|
-
|
|
9472
|
-
this.transcription = undefined;
|
|
9473
|
-
}
|
|
9643
|
+
this.stopTranscription();
|
|
9644
|
+
this.transcription = undefined;
|
|
9474
9645
|
|
|
9475
9646
|
this.annotation.deregisterEvents();
|
|
9476
9647
|
|
|
9477
|
-
|
|
9478
|
-
this.
|
|
9479
|
-
// @ts-ignore - Fix type
|
|
9480
|
-
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
9481
|
-
|
|
9482
|
-
this.clearLLMHealthCheckTimer();
|
|
9648
|
+
this.clearDataChannelToken();
|
|
9649
|
+
await this.cleanupLLMConneciton({throwOnError: false});
|
|
9483
9650
|
};
|
|
9484
9651
|
|
|
9485
9652
|
/**
|
|
@@ -10179,4 +10346,52 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
10179
10346
|
cancelSipCallOut(participantId: string) {
|
|
10180
10347
|
return this.meetingRequest.cancelSipCallOut(participantId);
|
|
10181
10348
|
}
|
|
10349
|
+
|
|
10350
|
+
/**
|
|
10351
|
+
* Method to get new data
|
|
10352
|
+
* @returns {Promise}
|
|
10353
|
+
*/
|
|
10354
|
+
public async refreshDataChannelToken() {
|
|
10355
|
+
const isPracticeSession = this.webinar.isJoinPracticeSessionDataChannel();
|
|
10356
|
+
const dataChannelTokenType = this.getDataChannelTokenType();
|
|
10357
|
+
|
|
10358
|
+
try {
|
|
10359
|
+
const res = await this.meetingRequest.fetchDatachannelToken({
|
|
10360
|
+
locusUrl: this.locusUrl,
|
|
10361
|
+
requestingParticipantId: this.members.selfId,
|
|
10362
|
+
isPracticeSession,
|
|
10363
|
+
});
|
|
10364
|
+
|
|
10365
|
+
return {
|
|
10366
|
+
body: {
|
|
10367
|
+
datachannelToken: res.body.datachannelToken,
|
|
10368
|
+
dataChannelTokenType,
|
|
10369
|
+
},
|
|
10370
|
+
};
|
|
10371
|
+
} catch (e) {
|
|
10372
|
+
const msg = e?.message || String(e);
|
|
10373
|
+
|
|
10374
|
+
LoggerProxy.logger.warn(
|
|
10375
|
+
`Meeting:index#refreshDataChannelToken --> DataChannel token refresh failed (likely locus changed or participant left): ${msg}`,
|
|
10376
|
+
{statusCode: e?.statusCode}
|
|
10377
|
+
);
|
|
10378
|
+
|
|
10379
|
+
return null;
|
|
10380
|
+
}
|
|
10381
|
+
}
|
|
10382
|
+
|
|
10383
|
+
/**
|
|
10384
|
+
* Determines the current data channel token type based on the meeting state.
|
|
10385
|
+
*
|
|
10386
|
+
* variant should be used when connecting to the LLM data channel.
|
|
10387
|
+
*
|
|
10388
|
+
* @returns {DataChannelTokenType} The token type representing the current session mode.
|
|
10389
|
+
*/
|
|
10390
|
+
public getDataChannelTokenType(): DataChannelTokenType {
|
|
10391
|
+
if (this.webinar.isJoinPracticeSessionDataChannel()) {
|
|
10392
|
+
return DataChannelTokenType.PracticeSession;
|
|
10393
|
+
}
|
|
10394
|
+
|
|
10395
|
+
return DataChannelTokenType.Default;
|
|
10396
|
+
}
|
|
10182
10397
|
}
|