@webex/plugin-meetings 3.9.0-webinar5k.1 → 3.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/constants.js +24 -0
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/index.js +22 -5
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js +7 -0
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +116 -0
- package/dist/interceptors/locusRouteToken.js.map +1 -0
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/controlsUtils.js +11 -2
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/index.js +76 -322
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/parser.js +4 -1
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/properties.js +53 -5
- package/dist/media/properties.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +14 -0
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +467 -277
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/request.js +177 -14
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/type.js +7 -0
- package/dist/meeting/type.js.map +1 -0
- package/dist/meeting/util.js +100 -3
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +29 -21
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +20 -16
- package/dist/meetings/index.js.map +1 -1
- package/dist/member/index.js +9 -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/members/index.js +10 -7
- package/dist/members/index.js.map +1 -1
- package/dist/members/util.js +7 -2
- package/dist/members/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 +1 -1
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +34 -5
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +42 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/reachability/index.js +3 -3
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/constants.d.ts +23 -0
- package/dist/types/controls-options-manager/index.d.ts +9 -1
- package/dist/types/interceptors/index.d.ts +2 -1
- package/dist/types/interceptors/locusRouteToken.d.ts +38 -0
- package/dist/types/locus-info/index.d.ts +9 -54
- package/dist/types/media/properties.d.ts +21 -0
- package/dist/types/meeting/in-meeting-actions.d.ts +14 -0
- package/dist/types/meeting/index.d.ts +64 -29
- package/dist/types/meeting/request.d.ts +42 -0
- package/dist/types/meeting/type.d.ts +9 -0
- package/dist/types/meeting/util.d.ts +13 -0
- package/dist/types/meeting-info/meeting-info-v2.d.ts +6 -3
- package/dist/types/meetings/index.d.ts +3 -1
- package/dist/types/member/index.d.ts +1 -0
- package/dist/types/member/util.d.ts +5 -0
- package/dist/types/members/index.d.ts +12 -11
- package/dist/types/members/util.d.ts +8 -4
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/remoteMedia.d.ts +20 -1
- package/dist/types/multistream/remoteMediaGroup.d.ts +11 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +25 -27
- package/src/constants.ts +26 -2
- package/src/controls-options-manager/index.ts +26 -5
- package/src/index.ts +2 -1
- package/src/interceptors/index.ts +2 -1
- package/src/interceptors/locusRouteToken.ts +80 -0
- package/src/locus-info/controlsUtils.ts +18 -0
- package/src/locus-info/index.ts +69 -357
- package/src/locus-info/parser.ts +5 -1
- package/src/media/properties.ts +43 -0
- package/src/meeting/in-meeting-actions.ts +29 -0
- package/src/meeting/index.ts +296 -87
- package/src/meeting/request.ts +141 -0
- package/src/meeting/type.ts +9 -0
- package/src/meeting/util.ts +107 -3
- package/src/meeting-info/meeting-info-v2.ts +24 -5
- package/src/meetings/index.ts +15 -22
- package/src/member/index.ts +10 -0
- package/src/member/util.ts +14 -0
- package/src/members/index.ts +20 -10
- package/src/members/util.ts +20 -3
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/mediaRequestManager.ts +7 -7
- package/src/multistream/remoteMedia.ts +34 -4
- package/src/multistream/remoteMediaGroup.ts +37 -2
- package/src/reachability/index.ts +3 -3
- package/test/unit/spec/common/browser-detection.js +0 -24
- package/test/unit/spec/controls-options-manager/index.js +47 -0
- package/test/unit/spec/fixture/locus.js +1 -0
- package/test/unit/spec/interceptors/locusRouteToken.ts +87 -0
- package/test/unit/spec/locus-info/index.js +80 -361
- package/test/unit/spec/locus-info/parser.js +3 -2
- package/test/unit/spec/media/properties.ts +137 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +14 -0
- package/test/unit/spec/meeting/index.js +637 -53
- package/test/unit/spec/meeting/muteState.js +32 -6
- package/test/unit/spec/meeting/request.js +21 -0
- package/test/unit/spec/meeting/utils.js +171 -18
- package/test/unit/spec/meeting-info/meetinginfov2.js +8 -3
- package/test/unit/spec/meetings/index.js +12 -5
- package/test/unit/spec/member/util.js +24 -0
- package/test/unit/spec/members/collection.js +120 -0
- package/test/unit/spec/members/index.js +107 -2
- package/test/unit/spec/members/request.js +55 -0
- package/test/unit/spec/members/utils.js +116 -14
- package/test/unit/spec/multistream/mediaRequestManager.ts +19 -6
- package/test/unit/spec/multistream/remoteMedia.ts +66 -2
- package/test/unit/spec/reachability/index.ts +158 -3
- package/test/unit/spec/roap/turnDiscovery.ts +3 -3
- package/dist/hashTree/constants.js +0 -23
- package/dist/hashTree/constants.js.map +0 -1
- package/dist/hashTree/hashTree.js +0 -516
- package/dist/hashTree/hashTree.js.map +0 -1
- package/dist/hashTree/hashTreeParser.js +0 -521
- package/dist/hashTree/hashTreeParser.js.map +0 -1
- package/dist/types/hashTree/constants.d.ts +0 -8
- package/dist/types/hashTree/hashTree.d.ts +0 -128
- package/dist/types/hashTree/hashTreeParser.d.ts +0 -152
- package/src/hashTree/constants.ts +0 -12
- package/src/hashTree/hashTree.ts +0 -460
- package/src/hashTree/hashTreeParser.ts +0 -556
- package/test/unit/spec/hashTree/hashTree.ts +0 -394
- package/test/unit/spec/hashTree/hashTreeParser.ts +0 -156
package/src/meeting/request.ts
CHANGED
|
@@ -886,6 +886,44 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
886
886
|
});
|
|
887
887
|
}
|
|
888
888
|
|
|
889
|
+
/**
|
|
890
|
+
* Extend the current meeting duration.
|
|
891
|
+
*
|
|
892
|
+
* @param {Object} params - Parameters for extending the meeting.
|
|
893
|
+
* @param {string} params.meetingInstanceId - The unique ID of the meeting instance.
|
|
894
|
+
* @param {string} params.participantId - The ID of the participant requesting the extension.
|
|
895
|
+
* @param {number} params.extensionMinutes - The number of minutes to extend the meeting by.
|
|
896
|
+
* @param {string} params.meetingPolicyUrl - The base URL for meeting policy service (dynamic, from locus links)
|
|
897
|
+
* @returns {Promise<any>} A promise that resolves with the server response.
|
|
898
|
+
*/
|
|
899
|
+
extendMeeting({
|
|
900
|
+
meetingInstanceId,
|
|
901
|
+
participantId,
|
|
902
|
+
extensionMinutes,
|
|
903
|
+
meetingPolicyUrl,
|
|
904
|
+
}: {
|
|
905
|
+
meetingInstanceId: string;
|
|
906
|
+
participantId: string;
|
|
907
|
+
extensionMinutes: number;
|
|
908
|
+
meetingPolicyUrl: string;
|
|
909
|
+
}) {
|
|
910
|
+
if (!meetingPolicyUrl) {
|
|
911
|
+
return Promise.reject(new Error('meetingPolicyUrl is required'));
|
|
912
|
+
}
|
|
913
|
+
const uri = `${meetingPolicyUrl}/continueMeeting`;
|
|
914
|
+
|
|
915
|
+
// @ts-ignore
|
|
916
|
+
return this.request({
|
|
917
|
+
method: HTTP_VERBS.POST,
|
|
918
|
+
uri,
|
|
919
|
+
body: {
|
|
920
|
+
meetingInstanceId,
|
|
921
|
+
requestParticipantId: participantId,
|
|
922
|
+
extensionMinutes,
|
|
923
|
+
},
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
|
|
889
927
|
/**
|
|
890
928
|
* Make a network request to enable or disable reactions.
|
|
891
929
|
* @param {boolean} options.enable - determines if we need to enable or disable.
|
|
@@ -985,4 +1023,107 @@ export default class MeetingRequest extends StatelessWebexPlugin {
|
|
|
985
1023
|
body: {videoLayout},
|
|
986
1024
|
});
|
|
987
1025
|
}
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* Sends a request to notify the host of a meeting.
|
|
1029
|
+
* @param {string} siteFullUrl - The site URL.
|
|
1030
|
+
* @param {string} locusId - The locus ID.
|
|
1031
|
+
* @param {string} meetingUuid - The meeting UUID.
|
|
1032
|
+
* @param {Array<string>} displayName - The display names to notify the host about.
|
|
1033
|
+
* @returns {Promise}
|
|
1034
|
+
*/
|
|
1035
|
+
notifyHost(siteFullUrl: string, locusId: string, meetingUuid: string, displayName: string[]) {
|
|
1036
|
+
// @ts-ignore
|
|
1037
|
+
return this.request({
|
|
1038
|
+
method: HTTP_VERBS.POST,
|
|
1039
|
+
uri: `https://${siteFullUrl}/wbxappapi/v1/meetings/${meetingUuid}/notifyhost`,
|
|
1040
|
+
body: {
|
|
1041
|
+
displayName,
|
|
1042
|
+
size: displayName?.length,
|
|
1043
|
+
},
|
|
1044
|
+
headers: {
|
|
1045
|
+
locusId,
|
|
1046
|
+
},
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* Call out to a SIP participant
|
|
1052
|
+
*
|
|
1053
|
+
* @param {any} meetingId - The meeting ID.
|
|
1054
|
+
* @param {any} meetingNumber - The meeting number.
|
|
1055
|
+
* @param {string} address - The SIP address to call out.
|
|
1056
|
+
* @param {string} displayName - The display name for the participant.
|
|
1057
|
+
* @returns {Promise} The API response
|
|
1058
|
+
*/
|
|
1059
|
+
public async sipCallOut(meetingId, meetingNumber, address, displayName) {
|
|
1060
|
+
const body: any = {
|
|
1061
|
+
meetingId,
|
|
1062
|
+
meetingNumber,
|
|
1063
|
+
address,
|
|
1064
|
+
displayName,
|
|
1065
|
+
};
|
|
1066
|
+
try {
|
|
1067
|
+
// @ts-ignore
|
|
1068
|
+
const response = await this.request({
|
|
1069
|
+
method: HTTP_VERBS.POST,
|
|
1070
|
+
service: 'hydra',
|
|
1071
|
+
resource: 'meetingParticipants/callout',
|
|
1072
|
+
body,
|
|
1073
|
+
headers: {
|
|
1074
|
+
Accept: 'application/json',
|
|
1075
|
+
},
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
LoggerProxy.logger.info('Meetings:request#sipCallOut --> SIP call-out successful', response);
|
|
1079
|
+
|
|
1080
|
+
return response.body;
|
|
1081
|
+
} catch (err) {
|
|
1082
|
+
LoggerProxy.logger.error(
|
|
1083
|
+
`Meetings:request#sipCallOut --> Error calling out SIP participant, error ${JSON.stringify(
|
|
1084
|
+
err
|
|
1085
|
+
)}`
|
|
1086
|
+
);
|
|
1087
|
+
throw err;
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
/**
|
|
1092
|
+
* Cancel an ongoing SIP call-out
|
|
1093
|
+
*
|
|
1094
|
+
* @param {string} participantId - The ID of the participant whose SIP call-out should be cancelled.
|
|
1095
|
+
* @returns {Promise} The API response
|
|
1096
|
+
*/
|
|
1097
|
+
public async cancelSipCallOut(participantId) {
|
|
1098
|
+
const body = {
|
|
1099
|
+
participantId,
|
|
1100
|
+
};
|
|
1101
|
+
|
|
1102
|
+
try {
|
|
1103
|
+
// @ts-ignore
|
|
1104
|
+
const response = await this.request({
|
|
1105
|
+
method: HTTP_VERBS.POST,
|
|
1106
|
+
service: 'hydra',
|
|
1107
|
+
resource: 'meetingParticipants/cancelCallout',
|
|
1108
|
+
body,
|
|
1109
|
+
headers: {
|
|
1110
|
+
Accept: 'application/json',
|
|
1111
|
+
},
|
|
1112
|
+
});
|
|
1113
|
+
|
|
1114
|
+
LoggerProxy.logger.info(
|
|
1115
|
+
'Meetings:request#cancelSipCallOut --> SIP call-out cancelled successfully',
|
|
1116
|
+
response
|
|
1117
|
+
);
|
|
1118
|
+
|
|
1119
|
+
return response.body;
|
|
1120
|
+
} catch (err) {
|
|
1121
|
+
LoggerProxy.logger.error(
|
|
1122
|
+
`Meetings:request#cancelSipCallOut --> Error cancelling SIP participant call-out, error ${JSON.stringify(
|
|
1123
|
+
err
|
|
1124
|
+
)}`
|
|
1125
|
+
);
|
|
1126
|
+
throw err;
|
|
1127
|
+
}
|
|
1128
|
+
}
|
|
988
1129
|
}
|
package/src/meeting/util.ts
CHANGED
|
@@ -31,7 +31,6 @@ const MeetingUtil = {
|
|
|
31
31
|
|
|
32
32
|
// First todo: add check for existance
|
|
33
33
|
parsed.locus = response.body.locus;
|
|
34
|
-
parsed.dataSets = response.body.dataSets;
|
|
35
34
|
parsed.mediaConnections = response.body.mediaConnections;
|
|
36
35
|
parsed.locusUrl = parsed.locus.url;
|
|
37
36
|
parsed.locusId = parsed.locus.url.split('/').pop();
|
|
@@ -114,6 +113,28 @@ const MeetingUtil = {
|
|
|
114
113
|
return IP_VERSION.unknown;
|
|
115
114
|
},
|
|
116
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Returns CA event labels related to Orpheus ipver parameter that can be sent to CA with any CA event
|
|
118
|
+
* @param {any} webex instance
|
|
119
|
+
* @returns {Array<string>|undefined} array of CA event labels or undefined if no labels should be sent
|
|
120
|
+
*/
|
|
121
|
+
getCaEventLabelsForIpVersion(webex: any): Array<string> | undefined {
|
|
122
|
+
const ipver = MeetingUtil.getIpVersion(webex);
|
|
123
|
+
|
|
124
|
+
switch (ipver) {
|
|
125
|
+
case IP_VERSION.unknown:
|
|
126
|
+
return undefined;
|
|
127
|
+
case IP_VERSION.only_ipv4:
|
|
128
|
+
return ['hasIpv4_true'];
|
|
129
|
+
case IP_VERSION.only_ipv6:
|
|
130
|
+
return ['hasIpv6_true'];
|
|
131
|
+
case IP_VERSION.ipv4_and_ipv6:
|
|
132
|
+
return ['hasIpv4_true', 'hasIpv6_true'];
|
|
133
|
+
default:
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
|
|
117
138
|
joinMeeting: async (meeting, options) => {
|
|
118
139
|
if (!meeting) {
|
|
119
140
|
return Promise.reject(new ParameterError('You need a meeting object.'));
|
|
@@ -196,6 +217,17 @@ const MeetingUtil = {
|
|
|
196
217
|
});
|
|
197
218
|
|
|
198
219
|
return parsed;
|
|
220
|
+
})
|
|
221
|
+
.catch((err) => {
|
|
222
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
223
|
+
name: 'client.locus.join.response',
|
|
224
|
+
payload: {
|
|
225
|
+
identifiers: {meetingLookupUrl: meeting.meetingInfo?.meetingLookupUrl},
|
|
226
|
+
},
|
|
227
|
+
options: {meetingId: meeting.id, rawError: err},
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
throw err;
|
|
199
231
|
});
|
|
200
232
|
},
|
|
201
233
|
|
|
@@ -207,6 +239,10 @@ const MeetingUtil = {
|
|
|
207
239
|
meeting.simultaneousInterpretation.cleanUp();
|
|
208
240
|
meeting.locusMediaRequest = undefined;
|
|
209
241
|
|
|
242
|
+
meeting.webex?.internal?.newMetrics?.callDiagnosticMetrics?.clearEventLimitsForCorrelationId(
|
|
243
|
+
meeting.correlationId
|
|
244
|
+
);
|
|
245
|
+
|
|
210
246
|
// make sure we send last metrics before we close the peerconnection
|
|
211
247
|
const stopStatsAnalyzer = meeting.statsAnalyzer
|
|
212
248
|
? meeting.statsAnalyzer.stopAnalyzer()
|
|
@@ -327,10 +363,57 @@ const MeetingUtil = {
|
|
|
327
363
|
meeting.resourceId = meeting.resourceId || options.resourceId;
|
|
328
364
|
|
|
329
365
|
if (meeting.requiredCaptcha) {
|
|
330
|
-
|
|
366
|
+
const errorToThrow = new CaptchaError();
|
|
367
|
+
|
|
368
|
+
// @ts-ignore
|
|
369
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
370
|
+
name: 'client.meetinginfo.response',
|
|
371
|
+
options: {
|
|
372
|
+
meetingId: meeting.id,
|
|
373
|
+
},
|
|
374
|
+
payload: {
|
|
375
|
+
errors: [
|
|
376
|
+
{
|
|
377
|
+
fatal: false,
|
|
378
|
+
category: 'expected',
|
|
379
|
+
name: 'other',
|
|
380
|
+
shownToUser: false,
|
|
381
|
+
errorCode: errorToThrow.code,
|
|
382
|
+
errorDescription: errorToThrow.name,
|
|
383
|
+
rawErrorMessage: errorToThrow.sdkMessage,
|
|
384
|
+
},
|
|
385
|
+
],
|
|
386
|
+
},
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
return Promise.reject(errorToThrow);
|
|
331
390
|
}
|
|
391
|
+
|
|
332
392
|
if (meeting.passwordStatus === PASSWORD_STATUS.REQUIRED) {
|
|
333
|
-
|
|
393
|
+
const errorToThrow = new PasswordError();
|
|
394
|
+
|
|
395
|
+
// @ts-ignore
|
|
396
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
397
|
+
name: 'client.meetinginfo.response',
|
|
398
|
+
options: {
|
|
399
|
+
meetingId: meeting.id,
|
|
400
|
+
},
|
|
401
|
+
payload: {
|
|
402
|
+
errors: [
|
|
403
|
+
{
|
|
404
|
+
fatal: false,
|
|
405
|
+
category: 'expected',
|
|
406
|
+
name: 'other',
|
|
407
|
+
shownToUser: false,
|
|
408
|
+
errorCode: errorToThrow.code,
|
|
409
|
+
errorDescription: errorToThrow.name,
|
|
410
|
+
rawErrorMessage: errorToThrow.sdkMessage,
|
|
411
|
+
},
|
|
412
|
+
],
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
return Promise.reject(errorToThrow);
|
|
334
417
|
}
|
|
335
418
|
|
|
336
419
|
if (options.pin) {
|
|
@@ -541,11 +624,29 @@ const MeetingUtil = {
|
|
|
541
624
|
canStartManualCaption: (displayHints) =>
|
|
542
625
|
displayHints.includes(DISPLAY_HINTS.MANUAL_CAPTION_START),
|
|
543
626
|
|
|
627
|
+
isLocalRecordingStarted: (displayHints) =>
|
|
628
|
+
displayHints.includes(DISPLAY_HINTS.LOCAL_RECORDING_STATUS_STARTED),
|
|
629
|
+
|
|
630
|
+
isLocalRecordingStopped: (displayHints) =>
|
|
631
|
+
displayHints.includes(DISPLAY_HINTS.LOCAL_RECORDING_STATUS_STOPPED),
|
|
632
|
+
|
|
633
|
+
isLocalRecordingPaused: (displayHints) =>
|
|
634
|
+
displayHints.includes(DISPLAY_HINTS.LOCAL_RECORDING_STATUS_PAUSED),
|
|
635
|
+
|
|
636
|
+
isLocalStreamingStarted: (displayHints) =>
|
|
637
|
+
displayHints.includes(DISPLAY_HINTS.STREAMING_STATUS_STARTED),
|
|
638
|
+
|
|
639
|
+
isLocalStreamingStopped: (displayHints) =>
|
|
640
|
+
displayHints.includes(DISPLAY_HINTS.STREAMING_STATUS_STOPPED),
|
|
641
|
+
|
|
544
642
|
canStopManualCaption: (displayHints) => displayHints.includes(DISPLAY_HINTS.MANUAL_CAPTION_STOP),
|
|
545
643
|
|
|
546
644
|
isManualCaptionActive: (displayHints) =>
|
|
547
645
|
displayHints.includes(DISPLAY_HINTS.MANUAL_CAPTION_STATUS_ACTIVE),
|
|
548
646
|
|
|
647
|
+
isSpokenLanguageAutoDetectionEnabled: (displayHints) =>
|
|
648
|
+
displayHints.includes(DISPLAY_HINTS.SPOKEN_LANGUAGE_AUTO_DETECTION_ENABLED),
|
|
649
|
+
|
|
549
650
|
isWebexAssistantActive: (displayHints) =>
|
|
550
651
|
displayHints.includes(DISPLAY_HINTS.WEBEX_ASSISTANT_STATUS_ACTIVE),
|
|
551
652
|
|
|
@@ -559,6 +660,9 @@ const MeetingUtil = {
|
|
|
559
660
|
|
|
560
661
|
waitingForOthersToJoin: (displayHints) => displayHints.includes(DISPLAY_HINTS.WAITING_FOR_OTHERS),
|
|
561
662
|
|
|
663
|
+
showAutoEndMeetingWarning: (displayHints) =>
|
|
664
|
+
displayHints.includes(DISPLAY_HINTS.SHOW_AUTO_END_MEETING_WARNING),
|
|
665
|
+
|
|
562
666
|
canSendReactions: (originalValue, displayHints) => {
|
|
563
667
|
if (displayHints.includes(DISPLAY_HINTS.REACTIONS_ACTIVE)) {
|
|
564
668
|
return true;
|
|
@@ -371,6 +371,7 @@ export default class MeetingInfoV2 {
|
|
|
371
371
|
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
|
|
372
372
|
* @param {String} installedOrgID org ID of user's machine
|
|
373
373
|
* @param {Boolean} enableStaticMeetingLink whether or not to enable static meeting link
|
|
374
|
+
* @param {String} classificationId need it to start adhoc meeting if space support classification
|
|
374
375
|
* @returns {Promise} returns a meeting info object
|
|
375
376
|
* @public
|
|
376
377
|
* @memberof MeetingInfo
|
|
@@ -379,7 +380,8 @@ export default class MeetingInfoV2 {
|
|
|
379
380
|
conversationUrl: string,
|
|
380
381
|
installedOrgID?: string,
|
|
381
382
|
// setting this to true enables static meeting link
|
|
382
|
-
enableStaticMeetingLink = false
|
|
383
|
+
enableStaticMeetingLink = false,
|
|
384
|
+
classificationId = undefined
|
|
383
385
|
) {
|
|
384
386
|
const getInvitees = (particpants = []) => {
|
|
385
387
|
const invitees = [];
|
|
@@ -407,6 +409,7 @@ export default class MeetingInfoV2 {
|
|
|
407
409
|
invitees: getInvitees(conversation.participants?.items),
|
|
408
410
|
installedOrgID,
|
|
409
411
|
schedule: enableStaticMeetingLink,
|
|
412
|
+
classificationId,
|
|
410
413
|
};
|
|
411
414
|
|
|
412
415
|
if (installedOrgID) {
|
|
@@ -429,16 +432,26 @@ export default class MeetingInfoV2 {
|
|
|
429
432
|
* Creates adhoc space meetings for a space by fetching the conversation infomation
|
|
430
433
|
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
|
|
431
434
|
* @param {String} installedOrgID org ID of user's machine
|
|
435
|
+
* @param {String} classificationId if space is support classification, it needs provide it during start instant meeting
|
|
432
436
|
* @returns {Promise} returns a meeting info object
|
|
433
437
|
* @public
|
|
434
438
|
* @memberof MeetingInfo
|
|
435
439
|
*/
|
|
436
|
-
async createAdhocSpaceMeeting(
|
|
440
|
+
async createAdhocSpaceMeeting(
|
|
441
|
+
conversationUrl: string,
|
|
442
|
+
installedOrgID?: string,
|
|
443
|
+
classificationId?: string
|
|
444
|
+
) {
|
|
437
445
|
if (!this.webex.meetings.preferredWebexSite) {
|
|
438
446
|
throw Error('No preferred webex site found');
|
|
439
447
|
}
|
|
440
448
|
|
|
441
|
-
return this.createAdhocSpaceMeetingOrEnableStaticMeetingLink(
|
|
449
|
+
return this.createAdhocSpaceMeetingOrEnableStaticMeetingLink(
|
|
450
|
+
conversationUrl,
|
|
451
|
+
installedOrgID,
|
|
452
|
+
false,
|
|
453
|
+
classificationId
|
|
454
|
+
)
|
|
442
455
|
.then((requestResult) => {
|
|
443
456
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS);
|
|
444
457
|
|
|
@@ -618,6 +631,7 @@ export default class MeetingInfoV2 {
|
|
|
618
631
|
* @param {Object} options
|
|
619
632
|
* @param {String} registrationId
|
|
620
633
|
* @param {String} fullSiteUrl
|
|
634
|
+
* @param {String} classificationId
|
|
621
635
|
* @returns {Promise} returns a meeting info object
|
|
622
636
|
* @public
|
|
623
637
|
* @memberof MeetingInfo
|
|
@@ -635,7 +649,8 @@ export default class MeetingInfoV2 {
|
|
|
635
649
|
extraParams: object = {},
|
|
636
650
|
options: {meetingId?: string; sendCAevents?: boolean} = {},
|
|
637
651
|
registrationId: string = null,
|
|
638
|
-
fullSiteUrl: string = null
|
|
652
|
+
fullSiteUrl: string = null,
|
|
653
|
+
classificationId: string = null
|
|
639
654
|
) {
|
|
640
655
|
const {meetingId, sendCAevents} = options;
|
|
641
656
|
|
|
@@ -650,7 +665,11 @@ export default class MeetingInfoV2 {
|
|
|
650
665
|
this.webex.config.meetings.experimental.enableAdhocMeetings &&
|
|
651
666
|
this.webex.meetings.preferredWebexSite
|
|
652
667
|
) {
|
|
653
|
-
return this.createAdhocSpaceMeeting(
|
|
668
|
+
return this.createAdhocSpaceMeeting(
|
|
669
|
+
destinationType.destination,
|
|
670
|
+
installedOrgID,
|
|
671
|
+
classificationId
|
|
672
|
+
);
|
|
654
673
|
}
|
|
655
674
|
|
|
656
675
|
const body = await MeetingInfoUtil.getRequestBody({
|
package/src/meetings/index.ts
CHANGED
|
@@ -66,7 +66,6 @@ import JoinWebinarError from '../common/errors/join-webinar-error';
|
|
|
66
66
|
import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
|
|
67
67
|
import NoMeetingInfoError from '../common/errors/no-meeting-info';
|
|
68
68
|
import JoinForbiddenError from '../common/errors/join-forbidden-error';
|
|
69
|
-
import {DataSet} from '../hashTree/hashTreeParser';
|
|
70
69
|
|
|
71
70
|
let mediaLogger;
|
|
72
71
|
|
|
@@ -408,13 +407,6 @@ export default class Meetings extends WebexPlugin {
|
|
|
408
407
|
* @memberof Meetings
|
|
409
408
|
*/
|
|
410
409
|
getCorrespondingMeetingByLocus(data) {
|
|
411
|
-
if (data.eventType === 'locus.state_message' && data.stateElementsMessage?.locusUrl) {
|
|
412
|
-
return this.meetingCollection.getByKey(
|
|
413
|
-
MEETING_KEY.LOCUS_URL,
|
|
414
|
-
data.stateElementsMessage.locusUrl
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
|
|
418
410
|
// getting meeting by correlationId. This will happen for the new event
|
|
419
411
|
// Either the locus
|
|
420
412
|
// TODO : Add check for the callBack Address
|
|
@@ -453,10 +445,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
453
445
|
* @private
|
|
454
446
|
* @memberof Meetings
|
|
455
447
|
*/
|
|
456
|
-
private handleLocusEvent(
|
|
457
|
-
data: {locusUrl: string; locus: any; dataSets?: DataSet[]},
|
|
458
|
-
useRandomDelayForInfo = false
|
|
459
|
-
) {
|
|
448
|
+
private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
|
|
460
449
|
let meeting = this.getCorrespondingMeetingByLocus(data);
|
|
461
450
|
|
|
462
451
|
// Special case when locus has got replaced, This only happend once if a replace locus exists
|
|
@@ -535,7 +524,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
535
524
|
meeting = newMeeting;
|
|
536
525
|
|
|
537
526
|
// It's a new meeting so initialize the locus data
|
|
538
|
-
meeting.locusInfo.initialSetup(data.locus
|
|
527
|
+
meeting.locusInfo.initialSetup(data.locus);
|
|
539
528
|
this.checkHandleBreakoutLocus(data.locus);
|
|
540
529
|
})
|
|
541
530
|
.catch((e) => {
|
|
@@ -1342,6 +1331,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1342
1331
|
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
|
1343
1332
|
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
|
1344
1333
|
* @param {string} sessionCorrelationId - the optional specified sessionCorrelationId (callStateForMetrics.sessionCorrelationId) can be provided instead
|
|
1334
|
+
* @param {String} classificationId - If space support classification, it will provide it while start instant meeting
|
|
1345
1335
|
* @returns {Promise<Meeting>} A new Meeting.
|
|
1346
1336
|
* @public
|
|
1347
1337
|
* @memberof Meetings
|
|
@@ -1356,7 +1346,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1356
1346
|
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1357
1347
|
meetingInfo = undefined,
|
|
1358
1348
|
meetingLookupUrl = undefined,
|
|
1359
|
-
sessionCorrelationId: string = undefined
|
|
1349
|
+
sessionCorrelationId: string = undefined,
|
|
1350
|
+
classificationId: string = undefined
|
|
1360
1351
|
) {
|
|
1361
1352
|
// Validate meeting information based on the provided destination and
|
|
1362
1353
|
// type. This must be performed prior to determining if the meeting is
|
|
@@ -1426,7 +1417,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1426
1417
|
callStateForMetrics,
|
|
1427
1418
|
failOnMissingMeetingInfo,
|
|
1428
1419
|
meetingInfo,
|
|
1429
|
-
meetingLookupUrl
|
|
1420
|
+
meetingLookupUrl,
|
|
1421
|
+
classificationId
|
|
1430
1422
|
).then((createdMeeting: any) => {
|
|
1431
1423
|
// If the meeting was successfully created.
|
|
1432
1424
|
if (createdMeeting && createdMeeting.on) {
|
|
@@ -1540,6 +1532,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1540
1532
|
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
1541
1533
|
* @param {Object} [meetingInfo] - Pre-fetched complete meeting info
|
|
1542
1534
|
* @param {String} [meetingLookupUrl] - meeting info prefetch url
|
|
1535
|
+
* @param {String} classificationId see create()
|
|
1543
1536
|
* @returns {Promise} a new meeting instance complete with meeting info and destination
|
|
1544
1537
|
* @private
|
|
1545
1538
|
* @memberof Meetings
|
|
@@ -1552,7 +1545,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1552
1545
|
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1553
1546
|
failOnMissingMeetingInfo = false,
|
|
1554
1547
|
meetingInfo = undefined,
|
|
1555
|
-
meetingLookupUrl = undefined
|
|
1548
|
+
meetingLookupUrl = undefined,
|
|
1549
|
+
classificationId = undefined
|
|
1556
1550
|
) {
|
|
1557
1551
|
const meeting = new Meeting(
|
|
1558
1552
|
{
|
|
@@ -1571,11 +1565,12 @@ export default class Meetings extends WebexPlugin {
|
|
|
1571
1565
|
{
|
|
1572
1566
|
// @ts-ignore
|
|
1573
1567
|
parent: this.webex,
|
|
1568
|
+
},
|
|
1569
|
+
(newMeeting) => {
|
|
1570
|
+
this.meetingCollection.set(newMeeting);
|
|
1574
1571
|
}
|
|
1575
1572
|
);
|
|
1576
1573
|
|
|
1577
|
-
this.meetingCollection.set(meeting);
|
|
1578
|
-
|
|
1579
1574
|
try {
|
|
1580
1575
|
// if no participant has joined the scheduled meeting (meaning meeting is not active) and we get a locusEvent,
|
|
1581
1576
|
// it means the meeting will start in 5-6 min. In that case, we want to fetchMeetingInfo
|
|
@@ -1599,6 +1594,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1599
1594
|
// @ts-ignore
|
|
1600
1595
|
const {enableUnifiedMeetings} = this.config.experimental;
|
|
1601
1596
|
const meetingInfoOptions = {
|
|
1597
|
+
classificationId,
|
|
1602
1598
|
extraParams: infoExtraParams,
|
|
1603
1599
|
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
|
|
1604
1600
|
};
|
|
@@ -1835,10 +1831,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1835
1831
|
}
|
|
1836
1832
|
|
|
1837
1833
|
const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
|
|
1838
|
-
this.handleLocusEvent({
|
|
1839
|
-
locus: associateBreakoutLocus,
|
|
1840
|
-
locusUrl: associateBreakoutLocus.url,
|
|
1841
|
-
});
|
|
1834
|
+
this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
|
|
1842
1835
|
this.breakoutLocusForHandleLater.splice(existIndex, 1);
|
|
1843
1836
|
}
|
|
1844
1837
|
|
package/src/member/index.ts
CHANGED
|
@@ -42,6 +42,7 @@ export default class Member {
|
|
|
42
42
|
status: any;
|
|
43
43
|
supportsBreakouts: boolean;
|
|
44
44
|
supportsInterpretation: boolean;
|
|
45
|
+
supportsSingleUserAutoEndMeeting: boolean;
|
|
45
46
|
supportLiveAnnotation: boolean;
|
|
46
47
|
type: any;
|
|
47
48
|
namespace = MEETINGS;
|
|
@@ -130,6 +131,13 @@ export default class Member {
|
|
|
130
131
|
* @memberof Member
|
|
131
132
|
*/
|
|
132
133
|
this.supportsBreakouts = null;
|
|
134
|
+
/**
|
|
135
|
+
* @instance
|
|
136
|
+
* @type {Boolean}
|
|
137
|
+
* @public
|
|
138
|
+
* @memberof Member
|
|
139
|
+
*/
|
|
140
|
+
this.supportsSingleUserAutoEndMeeting = null;
|
|
133
141
|
/**
|
|
134
142
|
* @instance
|
|
135
143
|
* @type {Boolean}
|
|
@@ -339,6 +347,8 @@ export default class Member {
|
|
|
339
347
|
this.isVideoMuted = MemberUtil.isVideoMuted(participant);
|
|
340
348
|
this.isHandRaised = MemberUtil.isHandRaised(participant);
|
|
341
349
|
this.supportsBreakouts = MemberUtil.isBreakoutsSupported(participant);
|
|
350
|
+
this.supportsSingleUserAutoEndMeeting =
|
|
351
|
+
MemberUtil.isSupportsSingleUserAutoEndMeeting(participant);
|
|
342
352
|
this.supportsInterpretation = MemberUtil.isInterpretationSupported(participant);
|
|
343
353
|
this.supportLiveAnnotation = MemberUtil.isLiveAnnotationSupported(participant);
|
|
344
354
|
this.isGuest = MemberUtil.isGuest(participant);
|
package/src/member/util.ts
CHANGED
|
@@ -207,6 +207,20 @@ const MemberUtil = {
|
|
|
207
207
|
return !participant.doesNotSupportBreakouts;
|
|
208
208
|
},
|
|
209
209
|
|
|
210
|
+
/**
|
|
211
|
+
* @param {Object} participant - The locus participant object.
|
|
212
|
+
* @returns {Boolean}
|
|
213
|
+
*/
|
|
214
|
+
isSupportsSingleUserAutoEndMeeting: (participant) => {
|
|
215
|
+
if (!participant) {
|
|
216
|
+
throw new ParameterError(
|
|
217
|
+
'Single user auto end meeting support could not be processed, participant is undefined.'
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return !participant.doesNotSupportSingleUserAutoEndMeeting;
|
|
222
|
+
},
|
|
223
|
+
|
|
210
224
|
/**
|
|
211
225
|
* @param {Object} participant - The locus participant object.
|
|
212
226
|
* @returns {Boolean}
|
package/src/members/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ import MembersUtil from './util';
|
|
|
30
30
|
import {ReceiveSlotManager} from '../multistream/receiveSlotManager';
|
|
31
31
|
import {MediaRequestManager} from '../multistream/mediaRequestManager';
|
|
32
32
|
import {ServerRoleShape} from './types';
|
|
33
|
+
import {Invitee} from '../meeting/type';
|
|
33
34
|
|
|
34
35
|
/**
|
|
35
36
|
* Members Update Event
|
|
@@ -387,7 +388,9 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
387
388
|
* when new participant updates come in, both delta and full participants, update them in members collection
|
|
388
389
|
* delta object in the event will have {updated, added} and full will be the full membersCollection
|
|
389
390
|
* @param {Object} payload
|
|
390
|
-
* @param {Object} payload.participants
|
|
391
|
+
* @param {Object} payload.participants new/updated participants
|
|
392
|
+
* @param {Boolean} payload.isReplace whether to replace the whole members collection
|
|
393
|
+
* @param {Object} payload.removedParticipantIds ids of the removed participants
|
|
391
394
|
* @returns {undefined}
|
|
392
395
|
* @private
|
|
393
396
|
* @memberof Members
|
|
@@ -824,18 +827,18 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
824
827
|
|
|
825
828
|
/**
|
|
826
829
|
* Adds a guest Member to the associated meeting
|
|
827
|
-
* @param {
|
|
830
|
+
* @param {Invitee} invitee
|
|
828
831
|
* @param {Boolean} [alertIfActive]
|
|
829
832
|
* @returns {Promise}
|
|
830
833
|
* @memberof Members
|
|
831
834
|
*/
|
|
832
|
-
addMember(invitee:
|
|
835
|
+
addMember(invitee: Invitee, alertIfActive?: boolean) {
|
|
833
836
|
if (!this.locusUrl) {
|
|
834
837
|
return Promise.reject(
|
|
835
838
|
new ParameterError('The associated locus url for this meeting object must be defined.')
|
|
836
839
|
);
|
|
837
840
|
}
|
|
838
|
-
if (MembersUtil.isInvalidInvitee(invitee)) {
|
|
841
|
+
if (invitee?.skipEmailValidation !== true && MembersUtil.isInvalidInvitee(invitee)) {
|
|
839
842
|
return Promise.reject(
|
|
840
843
|
new ParameterError(
|
|
841
844
|
'The invitee must be defined with either a valid email, emailAddress or phoneNumber property.'
|
|
@@ -849,11 +852,11 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
849
852
|
|
|
850
853
|
/**
|
|
851
854
|
* Cancels an outgoing PSTN call to the associated meeting
|
|
852
|
-
* @param {
|
|
855
|
+
* @param {Invitee} invitee
|
|
853
856
|
* @returns {Promise}
|
|
854
857
|
* @memberof Members
|
|
855
858
|
*/
|
|
856
|
-
cancelPhoneInvite(invitee:
|
|
859
|
+
cancelPhoneInvite(invitee: Invitee) {
|
|
857
860
|
if (!this.locusUrl) {
|
|
858
861
|
return Promise.reject(
|
|
859
862
|
new ParameterError('The associated locus url for this meeting object must be defined.')
|
|
@@ -871,13 +874,13 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
871
874
|
|
|
872
875
|
/**
|
|
873
876
|
* Cancels an SIP/phone call to the associated meeting
|
|
874
|
-
* @param {
|
|
877
|
+
* @param {Invitee} invitee
|
|
875
878
|
* @param {String} invitee.memberId - The memberId of the invitee
|
|
876
879
|
* @param {Boolean} [invitee.isInternalNumber] - When cancel phone invitation, if the number is internal
|
|
877
880
|
* @returns {Promise}
|
|
878
881
|
* @memberof Members
|
|
879
882
|
*/
|
|
880
|
-
cancelInviteByMemberId(invitee:
|
|
883
|
+
cancelInviteByMemberId(invitee: Invitee) {
|
|
881
884
|
if (!this.locusUrl) {
|
|
882
885
|
return Promise.reject(
|
|
883
886
|
new ParameterError('The associated locus url for this meeting object must be defined.')
|
|
@@ -1204,11 +1207,17 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
1204
1207
|
* @param {string} memberId - id of the participant who is receiving request
|
|
1205
1208
|
* @param {string} requestingParticipantId - id of the participant who is sending request (optional)
|
|
1206
1209
|
* @param {string} [alias] - alias name
|
|
1210
|
+
* @param {string} [suffix] - name suffix (optional)
|
|
1207
1211
|
* @returns {Promise}
|
|
1208
1212
|
* @public
|
|
1209
1213
|
* @memberof Members
|
|
1210
1214
|
*/
|
|
1211
|
-
public editDisplayName(
|
|
1215
|
+
public editDisplayName(
|
|
1216
|
+
memberId: string,
|
|
1217
|
+
requestingParticipantId: string,
|
|
1218
|
+
alias: string,
|
|
1219
|
+
suffix?: string
|
|
1220
|
+
) {
|
|
1212
1221
|
if (!this.locusUrl) {
|
|
1213
1222
|
return Promise.reject(
|
|
1214
1223
|
new ParameterError(
|
|
@@ -1228,7 +1237,8 @@ export default class Members extends StatelessWebexPlugin {
|
|
|
1228
1237
|
memberId,
|
|
1229
1238
|
requestingParticipantId,
|
|
1230
1239
|
alias,
|
|
1231
|
-
locusUrl
|
|
1240
|
+
locusUrl,
|
|
1241
|
+
suffix
|
|
1232
1242
|
);
|
|
1233
1243
|
|
|
1234
1244
|
return this.membersRequest.editDisplayNameMember(options);
|