@webex/plugin-meetings 3.11.0 → 3.12.0-next.1
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 +1138 -866
- 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 +48 -6
- 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 +260 -90
- 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 +238 -44
- 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 +162 -5
- 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 +716 -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 +348 -36
- 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: {
|
|
@@ -6161,6 +6266,49 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6161
6266
|
}
|
|
6162
6267
|
}
|
|
6163
6268
|
|
|
6269
|
+
/**
|
|
6270
|
+
* Disconnects and cleans up the default LLM session listeners/timers.
|
|
6271
|
+
* @param {Object} options
|
|
6272
|
+
* @param {boolean} [options.removeOnlineListener=true] removes the one-time online listener
|
|
6273
|
+
* @param {boolean} [options.throwOnError=true] rethrows disconnect errors when true
|
|
6274
|
+
* @returns {Promise<void>}
|
|
6275
|
+
*/
|
|
6276
|
+
private cleanupLLMConneciton = async ({
|
|
6277
|
+
removeOnlineListener = true,
|
|
6278
|
+
throwOnError = true,
|
|
6279
|
+
}: {
|
|
6280
|
+
removeOnlineListener?: boolean;
|
|
6281
|
+
throwOnError?: boolean;
|
|
6282
|
+
} = {}): Promise<void> => {
|
|
6283
|
+
try {
|
|
6284
|
+
// @ts-ignore - Fix type
|
|
6285
|
+
await this.webex.internal.llm.disconnectLLM({
|
|
6286
|
+
code: 3050,
|
|
6287
|
+
reason: 'done (permanent)',
|
|
6288
|
+
});
|
|
6289
|
+
} catch (error) {
|
|
6290
|
+
LoggerProxy.logger.error(
|
|
6291
|
+
'Meeting:index#cleanupLLMConneciton --> Failed to disconnect default LLM session',
|
|
6292
|
+
error
|
|
6293
|
+
);
|
|
6294
|
+
|
|
6295
|
+
if (throwOnError) {
|
|
6296
|
+
throw error;
|
|
6297
|
+
}
|
|
6298
|
+
} finally {
|
|
6299
|
+
if (removeOnlineListener) {
|
|
6300
|
+
// @ts-ignore - Fix type
|
|
6301
|
+
this.webex.internal.llm.off('online', this.handleLLMOnline);
|
|
6302
|
+
}
|
|
6303
|
+
// @ts-ignore - fix types
|
|
6304
|
+
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
6305
|
+
// @ts-ignore - Fix type
|
|
6306
|
+
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
6307
|
+
|
|
6308
|
+
this.clearLLMHealthCheckTimer();
|
|
6309
|
+
}
|
|
6310
|
+
};
|
|
6311
|
+
|
|
6164
6312
|
/**
|
|
6165
6313
|
* Connects to low latency mercury and reconnects if the address has changed
|
|
6166
6314
|
* It will also disconnect if called when the meeting has ended
|
|
@@ -6169,15 +6317,26 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6169
6317
|
*/
|
|
6170
6318
|
async updateLLMConnection() {
|
|
6171
6319
|
// @ts-ignore - Fix type
|
|
6172
|
-
const {
|
|
6320
|
+
const {
|
|
6321
|
+
url = undefined,
|
|
6322
|
+
info: {datachannelUrl = undefined} = {},
|
|
6323
|
+
self: {datachannelToken = undefined} = {},
|
|
6324
|
+
} = this.locusInfo || {};
|
|
6173
6325
|
|
|
6174
6326
|
const isJoined = this.isJoined();
|
|
6175
6327
|
|
|
6328
|
+
// @ts-ignore
|
|
6329
|
+
const currentToken = this.webex.internal.llm.getDatachannelToken(DataChannelTokenType.Default);
|
|
6330
|
+
|
|
6331
|
+
const finalToken = currentToken ?? datachannelToken;
|
|
6332
|
+
|
|
6333
|
+
if (!currentToken && datachannelToken) {
|
|
6334
|
+
// @ts-ignore
|
|
6335
|
+
this.webex.internal.llm.setDatachannelToken(datachannelToken, DataChannelTokenType.Default);
|
|
6336
|
+
}
|
|
6337
|
+
|
|
6176
6338
|
// webinar panelist should use new data channel in practice session
|
|
6177
|
-
const dataChannelUrl =
|
|
6178
|
-
this.webinar.isJoinPracticeSessionDataChannel() && practiceSessionDatachannelUrl
|
|
6179
|
-
? practiceSessionDatachannelUrl
|
|
6180
|
-
: datachannelUrl;
|
|
6339
|
+
const dataChannelUrl = datachannelUrl;
|
|
6181
6340
|
|
|
6182
6341
|
// @ts-ignore - Fix type
|
|
6183
6342
|
if (this.webex.internal.llm.isConnected()) {
|
|
@@ -6190,21 +6349,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6190
6349
|
) {
|
|
6191
6350
|
return undefined;
|
|
6192
6351
|
}
|
|
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();
|
|
6352
|
+
await this.cleanupLLMConneciton({removeOnlineListener: false});
|
|
6208
6353
|
}
|
|
6209
6354
|
|
|
6210
6355
|
if (!isJoined) {
|
|
@@ -6213,7 +6358,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6213
6358
|
|
|
6214
6359
|
// @ts-ignore - Fix type
|
|
6215
6360
|
return this.webex.internal.llm
|
|
6216
|
-
.registerAndConnect(url, dataChannelUrl)
|
|
6361
|
+
.registerAndConnect(url, dataChannelUrl, finalToken)
|
|
6217
6362
|
.then((registerAndConnectResult) => {
|
|
6218
6363
|
// @ts-ignore - Fix type
|
|
6219
6364
|
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
@@ -7417,7 +7562,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7417
7562
|
*/
|
|
7418
7563
|
private async waitForMediaConnectionConnected(): Promise<void> {
|
|
7419
7564
|
try {
|
|
7420
|
-
await this.mediaProperties.waitForMediaConnectionConnected();
|
|
7565
|
+
await this.mediaProperties.waitForMediaConnectionConnected(this.correlationId);
|
|
7421
7566
|
} catch (error) {
|
|
7422
7567
|
const {iceConnected} = error;
|
|
7423
7568
|
|
|
@@ -8010,6 +8155,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8010
8155
|
remoteMediaManagerConfig,
|
|
8011
8156
|
bundlePolicy = 'max-bundle',
|
|
8012
8157
|
additionalMediaOptions = {},
|
|
8158
|
+
allowPublishMediaInLobby = false,
|
|
8013
8159
|
} = options;
|
|
8014
8160
|
|
|
8015
8161
|
const {
|
|
@@ -8030,7 +8176,6 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8030
8176
|
const ipver = MeetingUtil.getIpVersion(this.webex); // used just for metrics
|
|
8031
8177
|
|
|
8032
8178
|
// If the user is unjoined or guest waiting in lobby dont allow the user to addMedia
|
|
8033
|
-
// @ts-ignore - isUserUnadmitted coming from SelfUtil
|
|
8034
8179
|
if (this.isUserUnadmitted && !this.wirelessShare && !this.allowMediaInLobby) {
|
|
8035
8180
|
throw new UserInLobbyError();
|
|
8036
8181
|
}
|
|
@@ -8075,7 +8220,13 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8075
8220
|
this.brbState = createBrbState(this, false);
|
|
8076
8221
|
|
|
8077
8222
|
try {
|
|
8078
|
-
|
|
8223
|
+
// if we're in a lobby and allowPublishMediaInLobby==false, we don't want to
|
|
8224
|
+
// setup local streams for publishing, because if we ever end up admitted to the meeting
|
|
8225
|
+
// but Locus event about it for us is delayed or missed, others could see/hear our user's video/audio
|
|
8226
|
+
// while the user would still think they're in the lobby
|
|
8227
|
+
if (allowPublishMediaInLobby || !this.isUserUnadmitted) {
|
|
8228
|
+
await this.setUpLocalStreamReferences(localStreams);
|
|
8229
|
+
}
|
|
8079
8230
|
|
|
8080
8231
|
this.setMercuryListener();
|
|
8081
8232
|
|
|
@@ -8543,12 +8694,12 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8543
8694
|
LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
|
|
8544
8695
|
|
|
8545
8696
|
return MeetingUtil.leaveMeeting(this, options)
|
|
8546
|
-
.then((leave) => {
|
|
8697
|
+
.then(async (leave) => {
|
|
8547
8698
|
// CA team recommends submitting this *after* locus /leave
|
|
8548
8699
|
submitLeaveMetric();
|
|
8549
8700
|
|
|
8550
8701
|
this.meetingFiniteStateMachine.leave();
|
|
8551
|
-
this.clearMeetingData();
|
|
8702
|
+
await this.clearMeetingData();
|
|
8552
8703
|
|
|
8553
8704
|
// upload logs on leave irrespective of meeting delete
|
|
8554
8705
|
Trigger.trigger(
|
|
@@ -9407,10 +9558,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9407
9558
|
});
|
|
9408
9559
|
|
|
9409
9560
|
return MeetingUtil.endMeetingForAll(this)
|
|
9410
|
-
.then((end) => {
|
|
9561
|
+
.then(async (end) => {
|
|
9411
9562
|
this.meetingFiniteStateMachine.end();
|
|
9412
9563
|
|
|
9413
|
-
this.clearMeetingData();
|
|
9564
|
+
await this.clearMeetingData();
|
|
9414
9565
|
// upload logs on leave irrespective of meeting delete
|
|
9415
9566
|
Trigger.trigger(
|
|
9416
9567
|
this,
|
|
@@ -9458,7 +9609,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9458
9609
|
* @public
|
|
9459
9610
|
* @memberof Meeting
|
|
9460
9611
|
*/
|
|
9461
|
-
clearMeetingData = () => {
|
|
9612
|
+
clearMeetingData = async () => {
|
|
9462
9613
|
this.audio = null;
|
|
9463
9614
|
this.video = null;
|
|
9464
9615
|
this.screenShareFloorState = ScreenShareFloorStatus.RELEASED;
|
|
@@ -9474,12 +9625,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
9474
9625
|
|
|
9475
9626
|
this.annotation.deregisterEvents();
|
|
9476
9627
|
|
|
9477
|
-
|
|
9478
|
-
this.webex.internal.llm.off('event:relay.event', this.processRelayEvent);
|
|
9479
|
-
// @ts-ignore - Fix type
|
|
9480
|
-
this.webex.internal.llm.off(LOCUS_LLM_EVENT, this.processLocusLLMEvent);
|
|
9481
|
-
|
|
9482
|
-
this.clearLLMHealthCheckTimer();
|
|
9628
|
+
await this.cleanupLLMConneciton({throwOnError: false});
|
|
9483
9629
|
};
|
|
9484
9630
|
|
|
9485
9631
|
/**
|
|
@@ -10179,4 +10325,52 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
10179
10325
|
cancelSipCallOut(participantId: string) {
|
|
10180
10326
|
return this.meetingRequest.cancelSipCallOut(participantId);
|
|
10181
10327
|
}
|
|
10328
|
+
|
|
10329
|
+
/**
|
|
10330
|
+
* Method to get new data
|
|
10331
|
+
* @returns {Promise}
|
|
10332
|
+
*/
|
|
10333
|
+
public async refreshDataChannelToken() {
|
|
10334
|
+
const isPracticeSession = this.webinar.isJoinPracticeSessionDataChannel();
|
|
10335
|
+
const dataChannelTokenType = this.getDataChannelTokenType();
|
|
10336
|
+
|
|
10337
|
+
try {
|
|
10338
|
+
const res = await this.meetingRequest.fetchDatachannelToken({
|
|
10339
|
+
locusUrl: this.locusUrl,
|
|
10340
|
+
requestingParticipantId: this.members.selfId,
|
|
10341
|
+
isPracticeSession,
|
|
10342
|
+
});
|
|
10343
|
+
|
|
10344
|
+
return {
|
|
10345
|
+
body: {
|
|
10346
|
+
datachannelToken: res.body.datachannelToken,
|
|
10347
|
+
dataChannelTokenType,
|
|
10348
|
+
},
|
|
10349
|
+
};
|
|
10350
|
+
} catch (e) {
|
|
10351
|
+
const msg = e?.message || String(e);
|
|
10352
|
+
|
|
10353
|
+
LoggerProxy.logger.warn(
|
|
10354
|
+
`Meeting:index#refreshDataChannelToken --> DataChannel token refresh failed (likely locus changed or participant left): ${msg}`,
|
|
10355
|
+
{statusCode: e?.statusCode}
|
|
10356
|
+
);
|
|
10357
|
+
|
|
10358
|
+
return null;
|
|
10359
|
+
}
|
|
10360
|
+
}
|
|
10361
|
+
|
|
10362
|
+
/**
|
|
10363
|
+
* Determines the current data channel token type based on the meeting state.
|
|
10364
|
+
*
|
|
10365
|
+
* variant should be used when connecting to the LLM data channel.
|
|
10366
|
+
*
|
|
10367
|
+
* @returns {DataChannelTokenType} The token type representing the current session mode.
|
|
10368
|
+
*/
|
|
10369
|
+
public getDataChannelTokenType(): DataChannelTokenType {
|
|
10370
|
+
if (this.webinar.isJoinPracticeSessionDataChannel()) {
|
|
10371
|
+
return DataChannelTokenType.PracticeSession;
|
|
10372
|
+
}
|
|
10373
|
+
|
|
10374
|
+
return DataChannelTokenType.Default;
|
|
10375
|
+
}
|
|
10182
10376
|
}
|
package/src/meeting/request.ts
CHANGED
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
ToggleReactionsOptions,
|
|
34
34
|
PostMeetingDataConsentOptions,
|
|
35
35
|
SynchronizeVideoLayout,
|
|
36
|
+
fetchDataChannelTokenOptions,
|
|
36
37
|
} from './request.type';
|
|
37
38
|
import MeetingUtil from './util';
|
|
38
39
|
import {AnnotationInfo} from '../annotation/annotation.types';
|
|
@@ -1126,4 +1127,45 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
1126
1127
|
throw err;
|
|
1127
1128
|
}
|
|
1128
1129
|
}
|
|
1130
|
+
|
|
1131
|
+
/**
|
|
1132
|
+
* Sends a request to retrieve the datachannel authorization token for a participant.
|
|
1133
|
+
*
|
|
1134
|
+
* For regular meeting data channel:
|
|
1135
|
+
* GET /locus/api/v1/loci/{uuid:lid}/participant/{uuid:pid}/datachannel/token
|
|
1136
|
+
*
|
|
1137
|
+
* For practice session data channel:
|
|
1138
|
+
* GET /locus/api/v1/loci/{uuid:lid}/participant/{uuid:pid}/practiceSession/datachannel/token
|
|
1139
|
+
*
|
|
1140
|
+
* @param {string} locusUrl - The locus url.
|
|
1141
|
+
* @param {string} requestingParticipantId - The participant UUID.
|
|
1142
|
+
* @param {boolean} [isPracticeSession=false] - Whether to get the practice session token.
|
|
1143
|
+
* @returns {Promise<{datachannelToken: string}>}
|
|
1144
|
+
*/
|
|
1145
|
+
public async fetchDatachannelToken({
|
|
1146
|
+
locusUrl,
|
|
1147
|
+
requestingParticipantId,
|
|
1148
|
+
isPracticeSession = false,
|
|
1149
|
+
}: fetchDataChannelTokenOptions) {
|
|
1150
|
+
if (!locusUrl || !requestingParticipantId) {
|
|
1151
|
+
return Promise.reject(new Error('locusUrl and participantId are required'));
|
|
1152
|
+
}
|
|
1153
|
+
const practicePrefix = isPracticeSession ? '/practiceSession' : '';
|
|
1154
|
+
|
|
1155
|
+
const uri = `${locusUrl}/${PARTICIPANT}/${requestingParticipantId}${practicePrefix}/datachannel/token`;
|
|
1156
|
+
|
|
1157
|
+
// @ts-ignore
|
|
1158
|
+
return this.locusDeltaRequest({
|
|
1159
|
+
method: HTTP_VERBS.GET,
|
|
1160
|
+
uri,
|
|
1161
|
+
}).catch((err) => {
|
|
1162
|
+
LoggerProxy.logger.warn(
|
|
1163
|
+
`Meeting:request#fetchDatachannelToken --> Failed to retrieve ${
|
|
1164
|
+
isPracticeSession ? 'practice session ' : ''
|
|
1165
|
+
}datachannel token: ${err?.message || err}`
|
|
1166
|
+
);
|
|
1167
|
+
|
|
1168
|
+
return null;
|
|
1169
|
+
});
|
|
1170
|
+
}
|
|
1129
1171
|
}
|
|
@@ -88,4 +88,10 @@ export type UnsetStageVideoLayout = {
|
|
|
88
88
|
overrideDefault: false;
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
+
export type fetchDataChannelTokenOptions = {
|
|
92
|
+
locusUrl: string;
|
|
93
|
+
requestingParticipantId: string;
|
|
94
|
+
isPracticeSession: boolean;
|
|
95
|
+
};
|
|
96
|
+
|
|
91
97
|
export type SynchronizeVideoLayout = SetStageVideoLayout | UnsetStageVideoLayout;
|