@webex/plugin-meetings 3.3.1 → 3.4.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 +7 -2
- package/dist/breakouts/index.js.map +1 -1
- package/dist/constants.js +11 -4
- package/dist/constants.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/selfUtils.js +0 -5
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/media/MediaConnectionAwaiter.js +70 -15
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/index.js +12 -0
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +67 -0
- package/dist/meeting/connectionStateHandler.js.map +1 -0
- package/dist/meeting/index.js +552 -357
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +7 -0
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +6 -1
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/util.js +1 -0
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/index.js +4 -4
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +2 -2
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/util.js +17 -17
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +16 -16
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +1 -1
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +37 -33
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js +8 -0
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/util.js +3 -2
- package/dist/meetings/util.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +57 -0
- package/dist/metrics/index.js.map +1 -1
- package/dist/personal-meeting-room/index.js +1 -1
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/reachability/clusterReachability.js +108 -53
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +415 -56
- package/dist/reachability/index.js.map +1 -1
- package/dist/types/constants.d.ts +11 -3
- package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
- package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
- package/dist/types/meeting/index.d.ts +27 -7
- package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
- package/dist/types/meeting-info/index.d.ts +3 -2
- package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
- package/dist/types/meeting-info/util.d.ts +5 -4
- package/dist/types/meeting-info/utilv2.d.ts +3 -2
- package/dist/types/meetings/collection.d.ts +3 -2
- package/dist/types/meetings/index.d.ts +4 -3
- package/dist/types/meetings/meetings.types.d.ts +9 -0
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/metrics/index.d.ts +15 -0
- package/dist/types/reachability/clusterReachability.d.ts +31 -3
- package/dist/types/reachability/index.d.ts +93 -2
- package/dist/webinar/index.js +1 -1
- package/package.json +23 -23
- package/src/breakouts/index.ts +7 -1
- package/src/constants.ts +13 -17
- package/src/locus-info/selfUtils.ts +0 -5
- package/src/media/MediaConnectionAwaiter.ts +89 -14
- package/src/media/index.ts +13 -0
- package/src/meeting/connectionStateHandler.ts +65 -0
- package/src/meeting/index.ts +526 -292
- package/src/meeting/locusMediaRequest.ts +5 -0
- package/src/meeting/muteState.ts +6 -1
- package/src/meeting/util.ts +1 -0
- package/src/meeting-info/index.ts +9 -6
- package/src/meeting-info/meeting-info-v2.ts +4 -4
- package/src/meeting-info/util.ts +23 -28
- package/src/meeting-info/utilv2.ts +18 -24
- package/src/meetings/collection.ts +3 -3
- package/src/meetings/index.ts +39 -40
- package/src/meetings/meetings.types.ts +11 -0
- package/src/meetings/util.ts +5 -4
- package/src/metrics/constants.ts +1 -0
- package/src/metrics/index.ts +44 -0
- package/src/personal-meeting-room/index.ts +2 -2
- package/src/reachability/clusterReachability.ts +86 -25
- package/src/reachability/index.ts +316 -27
- package/test/unit/spec/breakouts/index.ts +51 -32
- package/test/unit/spec/locus-info/selfUtils.js +25 -23
- package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
- package/test/unit/spec/media/index.ts +42 -27
- package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
- package/test/unit/spec/meeting/index.js +758 -179
- package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
- package/test/unit/spec/meeting/muteState.js +24 -0
- package/test/unit/spec/meeting-info/index.js +4 -4
- package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
- package/test/unit/spec/meeting-info/request.js +2 -2
- package/test/unit/spec/meeting-info/utilv2.js +41 -49
- package/test/unit/spec/meetings/index.js +14 -0
- package/test/unit/spec/metrics/index.js +126 -0
- package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
- package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
- package/test/unit/spec/reachability/clusterReachability.ts +116 -22
- package/test/unit/spec/reachability/index.ts +1153 -84
- package/test/unit/spec/rtcMetrics/index.ts +1 -0
- package/dist/mediaQualityMetrics/config.js +0 -321
- package/dist/mediaQualityMetrics/config.js.map +0 -1
- package/dist/statsAnalyzer/global.js +0 -44
- package/dist/statsAnalyzer/global.js.map +0 -1
- package/dist/statsAnalyzer/index.js +0 -1072
- package/dist/statsAnalyzer/index.js.map +0 -1
- package/dist/statsAnalyzer/mqaUtil.js +0 -368
- package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
- package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
- package/dist/types/statsAnalyzer/global.d.ts +0 -36
- package/dist/types/statsAnalyzer/index.d.ts +0 -217
- package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
- package/src/mediaQualityMetrics/config.ts +0 -255
- package/src/statsAnalyzer/global.ts +0 -37
- package/src/statsAnalyzer/index.ts +0 -1318
- package/src/statsAnalyzer/mqaUtil.ts +0 -463
- package/test/unit/spec/stats-analyzer/index.js +0 -1819
|
@@ -341,4 +341,9 @@ export class LocusMediaRequest extends WebexPlugin {
|
|
|
341
341
|
|
|
342
342
|
return pendingPromise.promise;
|
|
343
343
|
}
|
|
344
|
+
|
|
345
|
+
/** Returns true if a confluence on the server is already created */
|
|
346
|
+
public isConfluenceCreated() {
|
|
347
|
+
return this.confluenceState === 'created';
|
|
348
|
+
}
|
|
344
349
|
}
|
package/src/meeting/muteState.ts
CHANGED
|
@@ -379,7 +379,12 @@ export class MuteState {
|
|
|
379
379
|
}
|
|
380
380
|
if (muted !== undefined) {
|
|
381
381
|
this.state.server.remoteMute = muted;
|
|
382
|
-
|
|
382
|
+
|
|
383
|
+
// We never want to unmute the local stream from a server remote mute update.
|
|
384
|
+
// Moderated unmute is handled by a different function.
|
|
385
|
+
if (muted) {
|
|
386
|
+
this.muteLocalStream(meeting, muted, 'remotelyMuted');
|
|
387
|
+
}
|
|
383
388
|
}
|
|
384
389
|
}
|
|
385
390
|
|
package/src/meeting/util.ts
CHANGED
|
@@ -172,6 +172,7 @@ const MeetingUtil = {
|
|
|
172
172
|
cleanUp: (meeting) => {
|
|
173
173
|
meeting.breakouts.cleanUp();
|
|
174
174
|
meeting.simultaneousInterpretation.cleanUp();
|
|
175
|
+
meeting.locusMediaRequest = undefined;
|
|
175
176
|
|
|
176
177
|
// make sure we send last metrics before we close the peerconnection
|
|
177
178
|
const stopStatsAnalyzer = meeting.statsAnalyzer
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {DESTINATION_TYPE} from '../constants';
|
|
6
6
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
7
7
|
|
|
8
8
|
import MeetingInfoCollection from './collection';
|
|
@@ -157,7 +157,7 @@ export default class MeetingInfo {
|
|
|
157
157
|
/**
|
|
158
158
|
* Fetches meeting info from the server
|
|
159
159
|
* @param {String} destination one of many different types of destinations to look up info for
|
|
160
|
-
* @param {
|
|
160
|
+
* @param {DESTINATION_TYPE} [type] to match up with the destination value
|
|
161
161
|
* @param {String} [password] meeting password
|
|
162
162
|
* @param {Object} [captchaInfo] captcha code and id
|
|
163
163
|
* @param {String} [installedOrgID]
|
|
@@ -170,7 +170,7 @@ export default class MeetingInfo {
|
|
|
170
170
|
*/
|
|
171
171
|
public fetchMeetingInfo(
|
|
172
172
|
destination: string,
|
|
173
|
-
type:
|
|
173
|
+
type: DESTINATION_TYPE = null,
|
|
174
174
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
175
175
|
password: string = null,
|
|
176
176
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -186,7 +186,7 @@ export default class MeetingInfo {
|
|
|
186
186
|
extraParams: object = {},
|
|
187
187
|
options: {meetingId?: string; sendCAevents?: boolean} = {}
|
|
188
188
|
) {
|
|
189
|
-
if (type ===
|
|
189
|
+
if (type === DESTINATION_TYPE.PERSONAL_ROOM && !destination) {
|
|
190
190
|
destination = this.webex.internal.device.userId;
|
|
191
191
|
}
|
|
192
192
|
|
|
@@ -195,10 +195,13 @@ export default class MeetingInfo {
|
|
|
195
195
|
// fetch meeting info
|
|
196
196
|
this.requestFetchInfo({...infoOptions, ...options}).catch((error) => {
|
|
197
197
|
// if it failed the first time as meeting link
|
|
198
|
-
if (infoOptions.type ===
|
|
198
|
+
if (infoOptions.type === DESTINATION_TYPE.MEETING_LINK) {
|
|
199
199
|
// convert the meeting link to sip URI and retry
|
|
200
200
|
return this.requestFetchInfo({
|
|
201
|
-
...this.fetchInfoOptions(
|
|
201
|
+
...this.fetchInfoOptions(
|
|
202
|
+
MeetingInfoUtil.convertLinkToSip(destination),
|
|
203
|
+
DESTINATION_TYPE.SIP_URI
|
|
204
|
+
),
|
|
202
205
|
...options,
|
|
203
206
|
});
|
|
204
207
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import lodash from 'lodash';
|
|
2
2
|
import {
|
|
3
3
|
HTTP_VERBS,
|
|
4
|
-
|
|
4
|
+
DESTINATION_TYPE,
|
|
5
5
|
WBXAPPAPI_SERVICE,
|
|
6
6
|
DEFAULT_MEETING_INFO_REQUEST_BODY,
|
|
7
7
|
} from '../constants';
|
|
@@ -249,7 +249,7 @@ export default class MeetingInfoV2 {
|
|
|
249
249
|
/**
|
|
250
250
|
* Fetches meeting info from the server
|
|
251
251
|
* @param {String} destination one of many different types of destinations to look up info for
|
|
252
|
-
* @param {
|
|
252
|
+
* @param {DESTINATION_TYPE} [type] to match up with the destination value
|
|
253
253
|
* @param {String} password
|
|
254
254
|
* @param {Object} captchaInfo
|
|
255
255
|
* @param {String} captchaInfo.code
|
|
@@ -264,7 +264,7 @@ export default class MeetingInfoV2 {
|
|
|
264
264
|
*/
|
|
265
265
|
async fetchMeetingInfo(
|
|
266
266
|
destination: string,
|
|
267
|
-
type:
|
|
267
|
+
type: DESTINATION_TYPE = null,
|
|
268
268
|
password: string = null,
|
|
269
269
|
captchaInfo: {
|
|
270
270
|
code: string;
|
|
@@ -284,7 +284,7 @@ export default class MeetingInfoV2 {
|
|
|
284
284
|
});
|
|
285
285
|
|
|
286
286
|
if (
|
|
287
|
-
destinationType.type ===
|
|
287
|
+
destinationType.type === DESTINATION_TYPE.CONVERSATION_URL &&
|
|
288
288
|
this.webex.config.meetings.experimental.enableAdhocMeetings &&
|
|
289
289
|
this.webex.meetings.preferredWebexSite
|
|
290
290
|
) {
|
package/src/meeting-info/util.ts
CHANGED
|
@@ -8,12 +8,7 @@ import ParameterError from '../common/errors/parameter';
|
|
|
8
8
|
import LoggerProxy from '../common/logs/logger-proxy';
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
|
-
|
|
12
|
-
_PERSONAL_ROOM_,
|
|
13
|
-
_MEETING_ID_,
|
|
14
|
-
_CONVERSATION_URL_,
|
|
15
|
-
_LOCUS_ID_,
|
|
16
|
-
_MEETING_LINK_,
|
|
11
|
+
DESTINATION_TYPE,
|
|
17
12
|
_PEOPLE_,
|
|
18
13
|
_ROOM_,
|
|
19
14
|
HTTP_VERBS,
|
|
@@ -37,10 +32,10 @@ import {
|
|
|
37
32
|
* @class MeetingInfoUtil
|
|
38
33
|
*/
|
|
39
34
|
export default class MeetingInfoUtil {
|
|
40
|
-
static extractDestination(destination, type) {
|
|
35
|
+
static extractDestination(destination, type: DESTINATION_TYPE) {
|
|
41
36
|
let dest = destination;
|
|
42
37
|
|
|
43
|
-
if (type ===
|
|
38
|
+
if (type === DESTINATION_TYPE.LOCUS_ID) {
|
|
44
39
|
if (!(destination && destination.url)) {
|
|
45
40
|
throw new ParameterError(
|
|
46
41
|
'You cannot create a meeting by locus without a locus.url defined'
|
|
@@ -200,19 +195,19 @@ export default class MeetingInfoUtil {
|
|
|
200
195
|
'Meeting-info:util#generateOptions --> WARN, use of Meeting Link is deprecated, please use a SIP URI instead'
|
|
201
196
|
);
|
|
202
197
|
|
|
203
|
-
options.type =
|
|
198
|
+
options.type = DESTINATION_TYPE.MEETING_LINK;
|
|
204
199
|
options.destination = destination;
|
|
205
200
|
} else if (this.isSipUri(destination)) {
|
|
206
|
-
options.type =
|
|
201
|
+
options.type = DESTINATION_TYPE.SIP_URI;
|
|
207
202
|
options.destination = destination;
|
|
208
203
|
} else if (this.isPhoneNumber(destination)) {
|
|
209
|
-
options.type =
|
|
204
|
+
options.type = DESTINATION_TYPE.SIP_URI;
|
|
210
205
|
options.destination = destination;
|
|
211
206
|
} else if (this.isConversationUrl(destination, webex)) {
|
|
212
|
-
options.type =
|
|
207
|
+
options.type = DESTINATION_TYPE.CONVERSATION_URL;
|
|
213
208
|
options.destination = destination;
|
|
214
209
|
} else if (hydraId.people) {
|
|
215
|
-
options.type =
|
|
210
|
+
options.type = DESTINATION_TYPE.SIP_URI;
|
|
216
211
|
|
|
217
212
|
return this.getSipUriFromHydraPersonId(hydraId.destination, webex).then((res) => {
|
|
218
213
|
options.destination = res;
|
|
@@ -225,7 +220,7 @@ export default class MeetingInfoUtil {
|
|
|
225
220
|
return Promise.resolve(options);
|
|
226
221
|
});
|
|
227
222
|
} else if (hydraId.room) {
|
|
228
|
-
options.type =
|
|
223
|
+
options.type = DESTINATION_TYPE.CONVERSATION_URL;
|
|
229
224
|
try {
|
|
230
225
|
await webex.internal.services.waitForCatalog('postauth');
|
|
231
226
|
|
|
@@ -254,34 +249,34 @@ export default class MeetingInfoUtil {
|
|
|
254
249
|
|
|
255
250
|
/**
|
|
256
251
|
* Helper function to build up a correct locus url depending on the value passed
|
|
257
|
-
* @param {
|
|
252
|
+
* @param {DESTINATION_TYPE} type One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
|
|
258
253
|
* @param {Object} value ?? value.value
|
|
259
254
|
* @returns {Object} returns an object with {resource, method}
|
|
260
255
|
*/
|
|
261
|
-
static getResourceUrl(type:
|
|
256
|
+
static getResourceUrl(type: DESTINATION_TYPE, value: any) {
|
|
262
257
|
let resource = `/${LOCI}/${MEETINGINFO}`;
|
|
263
258
|
let method = HTTP_VERBS.GET;
|
|
264
259
|
let uri = null;
|
|
265
260
|
|
|
266
261
|
switch (type) {
|
|
267
|
-
case
|
|
268
|
-
case
|
|
269
|
-
case
|
|
262
|
+
case DESTINATION_TYPE.SIP_URI:
|
|
263
|
+
case DESTINATION_TYPE.PERSONAL_ROOM:
|
|
264
|
+
case DESTINATION_TYPE.MEETING_ID:
|
|
270
265
|
resource = `/${LOCI}/${MEETINGINFO}/${encodeURIComponent(
|
|
271
266
|
value
|
|
272
267
|
)}?${TYPE}=${type}&${USE_URI_LOOKUP_FALSE}`;
|
|
273
268
|
break;
|
|
274
|
-
case
|
|
269
|
+
case DESTINATION_TYPE.CONVERSATION_URL:
|
|
275
270
|
method = HTTP_VERBS.PUT;
|
|
276
271
|
break;
|
|
277
|
-
case
|
|
272
|
+
case DESTINATION_TYPE.LOCUS_ID:
|
|
278
273
|
uri = `${value}/${MEETINGINFO}`;
|
|
279
274
|
method = HTTP_VERBS.PUT;
|
|
280
275
|
break;
|
|
281
|
-
case
|
|
282
|
-
resource = `$/${LOCI}/${MEETINGINFO}/${btoa(
|
|
283
|
-
|
|
284
|
-
|
|
276
|
+
case DESTINATION_TYPE.MEETING_LINK:
|
|
277
|
+
resource = `$/${LOCI}/${MEETINGINFO}/${btoa(value)}?${TYPE}=${
|
|
278
|
+
DESTINATION_TYPE.MEETING_LINK
|
|
279
|
+
}&${USE_URI_LOOKUP_FALSE}`;
|
|
285
280
|
break;
|
|
286
281
|
default:
|
|
287
282
|
}
|
|
@@ -293,7 +288,7 @@ export default class MeetingInfoUtil {
|
|
|
293
288
|
};
|
|
294
289
|
}
|
|
295
290
|
|
|
296
|
-
static getRequestParams(resourceOptions, type, value, api) {
|
|
291
|
+
static getRequestParams(resourceOptions, type: DESTINATION_TYPE, value, api) {
|
|
297
292
|
let requestParams: any = {
|
|
298
293
|
method: resourceOptions.method,
|
|
299
294
|
api,
|
|
@@ -303,14 +298,14 @@ export default class MeetingInfoUtil {
|
|
|
303
298
|
if (resourceOptions.method === HTTP_VERBS.GET) {
|
|
304
299
|
// for handling URL redirections
|
|
305
300
|
requestParams.resource = requestParams.resource.concat(`&${ALTERNATE_REDIRECT_TRUE}`);
|
|
306
|
-
} else if (type !==
|
|
301
|
+
} else if (type !== DESTINATION_TYPE.LOCUS_ID) {
|
|
307
302
|
// locus id check is a PUT not sure why
|
|
308
303
|
requestParams.resource = requestParams.resource.concat(`?${ALTERNATE_REDIRECT_TRUE}`);
|
|
309
304
|
requestParams.body = {
|
|
310
305
|
value,
|
|
311
306
|
lookupType: type,
|
|
312
307
|
};
|
|
313
|
-
} else if (type ===
|
|
308
|
+
} else if (type === DESTINATION_TYPE.LOCUS_ID) {
|
|
314
309
|
requestParams = {
|
|
315
310
|
method: resourceOptions.method,
|
|
316
311
|
uri: resourceOptions.uri,
|
|
@@ -4,15 +4,9 @@ import url from 'url';
|
|
|
4
4
|
import {deconstructHydraId} from '@webex/common';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
|
|
8
|
-
_PERSONAL_ROOM_,
|
|
9
|
-
_MEETING_ID_,
|
|
10
|
-
_CONVERSATION_URL_,
|
|
11
|
-
_LOCUS_ID_,
|
|
12
|
-
_MEETING_LINK_,
|
|
7
|
+
DESTINATION_TYPE,
|
|
13
8
|
_PEOPLE_,
|
|
14
9
|
_ROOM_,
|
|
15
|
-
_MEETING_UUID_,
|
|
16
10
|
DIALER_REGEX,
|
|
17
11
|
WEBEX_DOT_COM,
|
|
18
12
|
CONVERSATION_SERVICE,
|
|
@@ -144,7 +138,7 @@ export default class MeetingInfoUtil {
|
|
|
144
138
|
const {type, webex} = from;
|
|
145
139
|
let {destination} = from;
|
|
146
140
|
|
|
147
|
-
if (type ===
|
|
141
|
+
if (type === DESTINATION_TYPE.PERSONAL_ROOM) {
|
|
148
142
|
// this case checks if your type is personal room
|
|
149
143
|
if (!destination) {
|
|
150
144
|
// if we are not getting anything in desination we fetch org and user ids from webex instance
|
|
@@ -185,19 +179,19 @@ export default class MeetingInfoUtil {
|
|
|
185
179
|
'Meeting-info:util#generateOptions --> WARN, use of Meeting Link is deprecated, please use a SIP URI instead'
|
|
186
180
|
);
|
|
187
181
|
|
|
188
|
-
options.type =
|
|
182
|
+
options.type = DESTINATION_TYPE.MEETING_LINK;
|
|
189
183
|
options.destination = destination;
|
|
190
184
|
} else if (this.isSipUri(destination)) {
|
|
191
|
-
options.type =
|
|
185
|
+
options.type = DESTINATION_TYPE.SIP_URI;
|
|
192
186
|
options.destination = destination;
|
|
193
187
|
} else if (this.isPhoneNumber(destination)) {
|
|
194
|
-
options.type =
|
|
188
|
+
options.type = DESTINATION_TYPE.SIP_URI;
|
|
195
189
|
options.destination = destination;
|
|
196
190
|
} else if (this.isConversationUrl(destination, webex)) {
|
|
197
|
-
options.type =
|
|
191
|
+
options.type = DESTINATION_TYPE.CONVERSATION_URL;
|
|
198
192
|
options.destination = destination;
|
|
199
193
|
} else if (hydraId && hydraId.people) {
|
|
200
|
-
options.type =
|
|
194
|
+
options.type = DESTINATION_TYPE.SIP_URI;
|
|
201
195
|
|
|
202
196
|
return this.getSipUriFromHydraPersonId(hydraId && hydraId.destination, webex).then((res) => {
|
|
203
197
|
options.destination = res;
|
|
@@ -226,12 +220,12 @@ export default class MeetingInfoUtil {
|
|
|
226
220
|
/**
|
|
227
221
|
* Helper function to build up a correct locus url depending on the value passed
|
|
228
222
|
* @param {Object} options type and value to fetch meeting info
|
|
229
|
-
* @param {
|
|
223
|
+
* @param {DESTINATION_TYPE} options.type One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
|
|
230
224
|
* @param {String} options.installedOrgID org ID of user's machine
|
|
231
225
|
* @param {Object} options.destination ?? value.value
|
|
232
226
|
* @returns {Object} returns an object with {resource, method}
|
|
233
227
|
*/
|
|
234
|
-
static getRequestBody(options: {type:
|
|
228
|
+
static getRequestBody(options: {type: DESTINATION_TYPE; destination: object} | any) {
|
|
235
229
|
const {type, destination, password, captchaInfo, installedOrgID, locusId, extraParams} =
|
|
236
230
|
options;
|
|
237
231
|
const body: any = {
|
|
@@ -240,20 +234,20 @@ export default class MeetingInfoUtil {
|
|
|
240
234
|
};
|
|
241
235
|
|
|
242
236
|
switch (type) {
|
|
243
|
-
case
|
|
237
|
+
case DESTINATION_TYPE.SIP_URI:
|
|
244
238
|
body.sipUrl = destination;
|
|
245
239
|
break;
|
|
246
|
-
case
|
|
240
|
+
case DESTINATION_TYPE.PERSONAL_ROOM:
|
|
247
241
|
body.userId = destination.userId;
|
|
248
242
|
body.orgId = destination.orgId;
|
|
249
243
|
break;
|
|
250
|
-
case
|
|
244
|
+
case DESTINATION_TYPE.MEETING_ID:
|
|
251
245
|
body.meetingKey = destination;
|
|
252
246
|
break;
|
|
253
|
-
case
|
|
247
|
+
case DESTINATION_TYPE.CONVERSATION_URL:
|
|
254
248
|
body.conversationUrl = destination;
|
|
255
249
|
break;
|
|
256
|
-
case
|
|
250
|
+
case DESTINATION_TYPE.LOCUS_ID:
|
|
257
251
|
// use meetingID for the completer meeting info for the already started meeting
|
|
258
252
|
if (destination.info?.webExMeetingId) {
|
|
259
253
|
body.meetingKey = destination.info.webExMeetingId;
|
|
@@ -261,10 +255,10 @@ export default class MeetingInfoUtil {
|
|
|
261
255
|
body.sipUrl = destination.info.sipUri;
|
|
262
256
|
}
|
|
263
257
|
break;
|
|
264
|
-
case
|
|
258
|
+
case DESTINATION_TYPE.MEETING_LINK:
|
|
265
259
|
body.meetingUrl = destination;
|
|
266
260
|
break;
|
|
267
|
-
case
|
|
261
|
+
case DESTINATION_TYPE.MEETING_UUID: {
|
|
268
262
|
body.meetingUUID = destination;
|
|
269
263
|
break;
|
|
270
264
|
}
|
|
@@ -317,10 +311,10 @@ export default class MeetingInfoUtil {
|
|
|
317
311
|
let preferredWebexSite = null;
|
|
318
312
|
|
|
319
313
|
switch (type) {
|
|
320
|
-
case
|
|
314
|
+
case DESTINATION_TYPE.SIP_URI:
|
|
321
315
|
preferredWebexSite = this.getWebexSite(destination);
|
|
322
316
|
break;
|
|
323
|
-
case
|
|
317
|
+
case DESTINATION_TYPE.LOCUS_ID:
|
|
324
318
|
preferredWebexSite = destination.info?.webExSite;
|
|
325
319
|
break;
|
|
326
320
|
default:
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {find} from 'lodash';
|
|
2
2
|
|
|
3
3
|
import Collection from '../common/collection';
|
|
4
|
-
|
|
4
|
+
import {MEETING_KEY} from './meetings.types';
|
|
5
5
|
/**
|
|
6
6
|
* @export
|
|
7
7
|
* @class MeetingCollection
|
|
@@ -26,13 +26,13 @@ export default class MeetingCollection extends Collection {
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* get a specific meeting searching for key
|
|
29
|
-
* @param {
|
|
29
|
+
* @param {MEETING_KEY} key
|
|
30
30
|
* @param {Any} value
|
|
31
31
|
* @returns {Meeting} if found, else returns null
|
|
32
32
|
* @public
|
|
33
33
|
* @memberof MeetingCollection
|
|
34
34
|
*/
|
|
35
|
-
public getByKey(key:
|
|
35
|
+
public getByKey(key: MEETING_KEY, value: any) {
|
|
36
36
|
if (key && value) {
|
|
37
37
|
// @ts-ignore
|
|
38
38
|
return find(this.meetings, (meeting) => meeting[key] === value);
|
package/src/meetings/index.ts
CHANGED
|
@@ -25,28 +25,22 @@ import {
|
|
|
25
25
|
EVENT_TRIGGERS,
|
|
26
26
|
READY,
|
|
27
27
|
LOCUSEVENT,
|
|
28
|
-
LOCUS_URL,
|
|
29
28
|
MAX_RANDOM_DELAY_FOR_MEETING_INFO,
|
|
30
29
|
ROAP,
|
|
31
30
|
ONLINE,
|
|
32
31
|
OFFLINE,
|
|
33
32
|
_MEETING_,
|
|
34
33
|
_JOIN_,
|
|
35
|
-
_LOCUS_ID_,
|
|
36
34
|
_INCOMING_,
|
|
37
35
|
LOCUS,
|
|
38
|
-
CORRELATION_ID,
|
|
39
|
-
SIP_URI,
|
|
40
36
|
_LEFT_,
|
|
41
37
|
_ID_,
|
|
42
38
|
MEETING_REMOVED_REASON,
|
|
43
|
-
_CONVERSATION_URL_,
|
|
44
|
-
CONVERSATION_URL,
|
|
45
|
-
MEETINGNUMBER,
|
|
46
39
|
_JOINED_,
|
|
47
40
|
_MOVED_,
|
|
48
41
|
_ON_HOLD_LOBBY_,
|
|
49
42
|
_WAIT_,
|
|
43
|
+
DESTINATION_TYPE,
|
|
50
44
|
} from '../constants';
|
|
51
45
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
52
46
|
import MeetingInfo from '../meeting-info';
|
|
@@ -57,11 +51,10 @@ import Reachability from '../reachability';
|
|
|
57
51
|
import Request from './request';
|
|
58
52
|
import PasswordError from '../common/errors/password-error';
|
|
59
53
|
import CaptchaError from '../common/errors/captcha-error';
|
|
60
|
-
|
|
61
54
|
import MeetingCollection from './collection';
|
|
55
|
+
import {MEETING_KEY, INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
|
|
62
56
|
import MeetingsUtil from './util';
|
|
63
57
|
import PermissionError from '../common/errors/permission';
|
|
64
|
-
import {INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
|
|
65
58
|
import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
|
|
66
59
|
import NoMeetingInfoError from '../common/errors/no-meeting-info';
|
|
67
60
|
|
|
@@ -380,23 +373,26 @@ export default class Meetings extends WebexPlugin {
|
|
|
380
373
|
// Either the locus
|
|
381
374
|
// TODO : Add check for the callBack Address
|
|
382
375
|
return (
|
|
383
|
-
this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
|
|
376
|
+
this.meetingCollection.getByKey(MEETING_KEY.LOCUS_URL, data.locusUrl) ||
|
|
384
377
|
// @ts-ignore
|
|
385
378
|
this.meetingCollection.getByKey(
|
|
386
|
-
CORRELATION_ID,
|
|
379
|
+
MEETING_KEY.CORRELATION_ID,
|
|
387
380
|
// @ts-ignore
|
|
388
381
|
MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)
|
|
389
382
|
) ||
|
|
390
383
|
this.meetingCollection.getByKey(
|
|
391
|
-
SIP_URI,
|
|
384
|
+
MEETING_KEY.SIP_URI,
|
|
392
385
|
data.locus.self &&
|
|
393
386
|
data.locus.self.callbackInfo &&
|
|
394
387
|
data.locus.self.callbackInfo.callbackAddress
|
|
395
388
|
) ||
|
|
396
389
|
(data.locus.info?.isUnifiedSpaceMeeting
|
|
397
390
|
? undefined
|
|
398
|
-
: this.meetingCollection.getByKey(
|
|
399
|
-
|
|
391
|
+
: this.meetingCollection.getByKey(
|
|
392
|
+
MEETING_KEY.CONVERSATION_URL,
|
|
393
|
+
data.locus.conversationUrl
|
|
394
|
+
)) ||
|
|
395
|
+
this.meetingCollection.getByKey(MEETING_KEY.MEETINGNUMBER, data.locus?.info?.webExMeetingId)
|
|
400
396
|
);
|
|
401
397
|
}
|
|
402
398
|
|
|
@@ -420,7 +416,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
420
416
|
if (!meeting && data.locus?.replaces?.length > 0) {
|
|
421
417
|
// Always the last element in the replace is the active one
|
|
422
418
|
meeting = this.meetingCollection.getByKey(
|
|
423
|
-
LOCUS_URL,
|
|
419
|
+
MEETING_KEY.LOCUS_URL,
|
|
424
420
|
data.locus.replaces[data.locus.replaces.length - 1].locusUrl
|
|
425
421
|
);
|
|
426
422
|
}
|
|
@@ -485,7 +481,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
485
481
|
return;
|
|
486
482
|
}
|
|
487
483
|
|
|
488
|
-
this.create(data.locus,
|
|
484
|
+
this.create(data.locus, DESTINATION_TYPE.LOCUS_ID, useRandomDelayForInfo)
|
|
489
485
|
.then((newMeeting) => {
|
|
490
486
|
meeting = newMeeting;
|
|
491
487
|
|
|
@@ -1076,7 +1072,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1076
1072
|
* When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
|
|
1077
1073
|
*
|
|
1078
1074
|
* @param {string} destination - sipURL, phonenumber, or locus object}
|
|
1079
|
-
* @param {
|
|
1075
|
+
* @param {DESTINATION_TYPE} [type] - the optional specified type, such as locusId
|
|
1080
1076
|
* @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
|
|
1081
1077
|
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
1082
1078
|
* @param {string} correlationId - the optional specified correlationId (callStateForMetrics.correlationId can be provided instead)
|
|
@@ -1090,7 +1086,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1090
1086
|
*/
|
|
1091
1087
|
public create(
|
|
1092
1088
|
destination: string,
|
|
1093
|
-
type:
|
|
1089
|
+
type: DESTINATION_TYPE = null,
|
|
1094
1090
|
useRandomDelayForInfo = false,
|
|
1095
1091
|
infoExtraParams = {},
|
|
1096
1092
|
correlationId: string = undefined,
|
|
@@ -1099,12 +1095,11 @@ export default class Meetings extends WebexPlugin {
|
|
|
1099
1095
|
meetingInfo = undefined,
|
|
1100
1096
|
meetingLookupUrl = undefined
|
|
1101
1097
|
) {
|
|
1102
|
-
// TODO: type should be from a dictionary
|
|
1103
|
-
|
|
1104
1098
|
// Validate meeting information based on the provided destination and
|
|
1105
1099
|
// type. This must be performed prior to determining if the meeting is
|
|
1106
1100
|
// found in the collection, as we mutate the destination for hydra person
|
|
1107
1101
|
// id values.
|
|
1102
|
+
|
|
1108
1103
|
if (correlationId) {
|
|
1109
1104
|
callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
|
|
1110
1105
|
}
|
|
@@ -1128,8 +1123,14 @@ export default class Meetings extends WebexPlugin {
|
|
|
1128
1123
|
// check for the conversation URL then sip Url
|
|
1129
1124
|
let meeting = null;
|
|
1130
1125
|
|
|
1131
|
-
if (
|
|
1132
|
-
|
|
1126
|
+
if (
|
|
1127
|
+
type === DESTINATION_TYPE.CONVERSATION_URL ||
|
|
1128
|
+
options.type === DESTINATION_TYPE.CONVERSATION_URL
|
|
1129
|
+
) {
|
|
1130
|
+
const foundMeeting = this.meetingCollection.getByKey(
|
|
1131
|
+
MEETING_KEY.CONVERSATION_URL,
|
|
1132
|
+
targetDest
|
|
1133
|
+
);
|
|
1133
1134
|
|
|
1134
1135
|
if (foundMeeting) {
|
|
1135
1136
|
const foundMeetingIsNotCalendarMeeting = !foundMeeting.locusInfo.scheduledMeeting;
|
|
@@ -1144,7 +1145,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1144
1145
|
|
|
1145
1146
|
// Attempt to collect the meeting if it exists.
|
|
1146
1147
|
if (!meeting) {
|
|
1147
|
-
meeting = this.meetingCollection.getByKey(SIP_URI, targetDest);
|
|
1148
|
+
meeting = this.meetingCollection.getByKey(MEETING_KEY.SIP_URI, targetDest);
|
|
1148
1149
|
}
|
|
1149
1150
|
|
|
1150
1151
|
// Validate if a meeting was found.
|
|
@@ -1218,7 +1219,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1218
1219
|
* When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
|
|
1219
1220
|
*
|
|
1220
1221
|
* @param {String} destination see create()
|
|
1221
|
-
* @param {
|
|
1222
|
+
* @param {DESTINATION_TYPE} type see create()
|
|
1222
1223
|
* @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
|
|
1223
1224
|
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
1224
1225
|
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
@@ -1231,7 +1232,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1231
1232
|
*/
|
|
1232
1233
|
private async createMeeting(
|
|
1233
1234
|
destination: any,
|
|
1234
|
-
type:
|
|
1235
|
+
type: DESTINATION_TYPE = null,
|
|
1235
1236
|
useRandomDelayForInfo = false,
|
|
1236
1237
|
infoExtraParams = {},
|
|
1237
1238
|
callStateForMetrics: CallStateForMetrics = undefined,
|
|
@@ -1247,7 +1248,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1247
1248
|
deviceUrl: this.webex.internal.device.url,
|
|
1248
1249
|
// @ts-ignore
|
|
1249
1250
|
orgId: this.webex.internal.device.orgId,
|
|
1250
|
-
locus: type ===
|
|
1251
|
+
locus: type === DESTINATION_TYPE.LOCUS_ID ? destination : null, // pass the locus object if present
|
|
1251
1252
|
meetingInfoProvider: this.meetingInfo,
|
|
1252
1253
|
destination,
|
|
1253
1254
|
destinationType: type,
|
|
@@ -1290,19 +1291,17 @@ export default class Meetings extends WebexPlugin {
|
|
|
1290
1291
|
|
|
1291
1292
|
if (meetingInfo) {
|
|
1292
1293
|
meeting.injectMeetingInfo(meetingInfo, meetingInfoOptions, meetingLookupUrl);
|
|
1293
|
-
} else if (
|
|
1294
|
-
|
|
1295
|
-
!isMeetingActive &&
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
} else {
|
|
1305
|
-
await meeting.fetchMeetingInfo(meetingInfoOptions);
|
|
1294
|
+
} else if (type !== DESTINATION_TYPE.ONE_ON_ONE_CALL) {
|
|
1295
|
+
// ignore fetchMeetingInfo for 1:1 meetings
|
|
1296
|
+
if (enableUnifiedMeetings && !isMeetingActive && useRandomDelayForInfo && waitingTime > 0) {
|
|
1297
|
+
meeting.fetchMeetingInfoTimeoutId = setTimeout(
|
|
1298
|
+
() => meeting.fetchMeetingInfo(meetingInfoOptions),
|
|
1299
|
+
waitingTime
|
|
1300
|
+
);
|
|
1301
|
+
meeting.parseMeetingInfo(undefined, destination);
|
|
1302
|
+
} else {
|
|
1303
|
+
await meeting.fetchMeetingInfo(meetingInfoOptions);
|
|
1304
|
+
}
|
|
1306
1305
|
}
|
|
1307
1306
|
} catch (err) {
|
|
1308
1307
|
if (
|
|
@@ -1333,7 +1332,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1333
1332
|
// For type LOCUS_ID we need to parse the locus object to get the information
|
|
1334
1333
|
// about the caller and callee
|
|
1335
1334
|
// Meeting Added event will be created in `handleLocusEvent`
|
|
1336
|
-
if (type !==
|
|
1335
|
+
if (type !== DESTINATION_TYPE.LOCUS_ID) {
|
|
1337
1336
|
if (!meeting.sipUri) {
|
|
1338
1337
|
meeting.setSipUri(destination);
|
|
1339
1338
|
}
|
|
@@ -2,6 +2,7 @@ import type {
|
|
|
2
2
|
NoiseReductionEffectOptions,
|
|
3
3
|
VirtualBackgroundEffectOptions,
|
|
4
4
|
} from '@webex/media-helpers';
|
|
5
|
+
import {Enum} from '../constants';
|
|
5
6
|
|
|
6
7
|
type INoiseReductionEffect = Omit<
|
|
7
8
|
NoiseReductionEffectOptions,
|
|
@@ -10,3 +11,13 @@ type INoiseReductionEffect = Omit<
|
|
|
10
11
|
type IVirtualBackgroundEffect = Omit<VirtualBackgroundEffectOptions, 'authToken'>;
|
|
11
12
|
|
|
12
13
|
export type {INoiseReductionEffect, IVirtualBackgroundEffect};
|
|
14
|
+
|
|
15
|
+
export const MEETING_KEY = {
|
|
16
|
+
CONVERSATION_URL: 'conversationUrl',
|
|
17
|
+
SIP_URI: 'sipUri',
|
|
18
|
+
LOCUS_URL: 'locusUrl',
|
|
19
|
+
MEETINGNUMBER: 'meetingNumber',
|
|
20
|
+
CORRELATION_ID: 'correlationId',
|
|
21
|
+
} as const;
|
|
22
|
+
|
|
23
|
+
export type MEETING_KEY = Enum<typeof MEETING_KEY>;
|
package/src/meetings/util.ts
CHANGED
|
@@ -5,10 +5,9 @@ import {
|
|
|
5
5
|
_INCOMING_,
|
|
6
6
|
_JOINED_,
|
|
7
7
|
_LEFT_,
|
|
8
|
-
|
|
8
|
+
DESTINATION_TYPE,
|
|
9
9
|
_MOVED_,
|
|
10
10
|
BREAKOUTS,
|
|
11
|
-
CORRELATION_ID,
|
|
12
11
|
EVENT_TRIGGERS,
|
|
13
12
|
LOCUS,
|
|
14
13
|
LOCUSEVENT,
|
|
@@ -18,6 +17,7 @@ import LoggerProxy from '../common/logs/logger-proxy';
|
|
|
18
17
|
import Trigger from '../common/events/trigger-proxy';
|
|
19
18
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
20
19
|
import Metrics from '../metrics';
|
|
20
|
+
import {MEETING_KEY} from './meetings.types';
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Meetings Media Codec Missing Event
|
|
@@ -39,14 +39,15 @@ import Metrics from '../metrics';
|
|
|
39
39
|
|
|
40
40
|
const MeetingsUtil: any = {};
|
|
41
41
|
|
|
42
|
-
MeetingsUtil.getMeetingAddedType = (type) =>
|
|
42
|
+
MeetingsUtil.getMeetingAddedType = (type: DESTINATION_TYPE) =>
|
|
43
|
+
type === DESTINATION_TYPE.LOCUS_ID ? _INCOMING_ : _CREATED_;
|
|
43
44
|
|
|
44
45
|
MeetingsUtil.handleRoapMercury = (envelope, meetingCollection) => {
|
|
45
46
|
const {data} = envelope;
|
|
46
47
|
const {eventType} = data;
|
|
47
48
|
|
|
48
49
|
if (eventType === LOCUSEVENT.MESSAGE_ROAP) {
|
|
49
|
-
const meeting = meetingCollection.getByKey(CORRELATION_ID, data.correlationId);
|
|
50
|
+
const meeting = meetingCollection.getByKey(MEETING_KEY.CORRELATION_ID, data.correlationId);
|
|
50
51
|
|
|
51
52
|
if (meeting) {
|
|
52
53
|
const {seq, messageType, tieBreaker, errorType, errorCause} = data.message;
|