@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.
Files changed (126) hide show
  1. package/dist/breakouts/breakout.js +1 -1
  2. package/dist/breakouts/index.js +7 -2
  3. package/dist/breakouts/index.js.map +1 -1
  4. package/dist/constants.js +11 -4
  5. package/dist/constants.js.map +1 -1
  6. package/dist/interpretation/index.js +1 -1
  7. package/dist/interpretation/siLanguage.js +1 -1
  8. package/dist/locus-info/selfUtils.js +0 -5
  9. package/dist/locus-info/selfUtils.js.map +1 -1
  10. package/dist/media/MediaConnectionAwaiter.js +70 -15
  11. package/dist/media/MediaConnectionAwaiter.js.map +1 -1
  12. package/dist/media/index.js +12 -0
  13. package/dist/media/index.js.map +1 -1
  14. package/dist/meeting/connectionStateHandler.js +67 -0
  15. package/dist/meeting/connectionStateHandler.js.map +1 -0
  16. package/dist/meeting/index.js +552 -357
  17. package/dist/meeting/index.js.map +1 -1
  18. package/dist/meeting/locusMediaRequest.js +7 -0
  19. package/dist/meeting/locusMediaRequest.js.map +1 -1
  20. package/dist/meeting/muteState.js +6 -1
  21. package/dist/meeting/muteState.js.map +1 -1
  22. package/dist/meeting/util.js +1 -0
  23. package/dist/meeting/util.js.map +1 -1
  24. package/dist/meeting-info/index.js +4 -4
  25. package/dist/meeting-info/index.js.map +1 -1
  26. package/dist/meeting-info/meeting-info-v2.js +2 -2
  27. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  28. package/dist/meeting-info/util.js +17 -17
  29. package/dist/meeting-info/util.js.map +1 -1
  30. package/dist/meeting-info/utilv2.js +16 -16
  31. package/dist/meeting-info/utilv2.js.map +1 -1
  32. package/dist/meetings/collection.js +1 -1
  33. package/dist/meetings/collection.js.map +1 -1
  34. package/dist/meetings/index.js +37 -33
  35. package/dist/meetings/index.js.map +1 -1
  36. package/dist/meetings/meetings.types.js +8 -0
  37. package/dist/meetings/meetings.types.js.map +1 -1
  38. package/dist/meetings/util.js +3 -2
  39. package/dist/meetings/util.js.map +1 -1
  40. package/dist/metrics/constants.js +2 -1
  41. package/dist/metrics/constants.js.map +1 -1
  42. package/dist/metrics/index.js +57 -0
  43. package/dist/metrics/index.js.map +1 -1
  44. package/dist/personal-meeting-room/index.js +1 -1
  45. package/dist/personal-meeting-room/index.js.map +1 -1
  46. package/dist/reachability/clusterReachability.js +108 -53
  47. package/dist/reachability/clusterReachability.js.map +1 -1
  48. package/dist/reachability/index.js +415 -56
  49. package/dist/reachability/index.js.map +1 -1
  50. package/dist/types/constants.d.ts +11 -3
  51. package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
  52. package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
  53. package/dist/types/meeting/index.d.ts +27 -7
  54. package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
  55. package/dist/types/meeting-info/index.d.ts +3 -2
  56. package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
  57. package/dist/types/meeting-info/util.d.ts +5 -4
  58. package/dist/types/meeting-info/utilv2.d.ts +3 -2
  59. package/dist/types/meetings/collection.d.ts +3 -2
  60. package/dist/types/meetings/index.d.ts +4 -3
  61. package/dist/types/meetings/meetings.types.d.ts +9 -0
  62. package/dist/types/metrics/constants.d.ts +1 -0
  63. package/dist/types/metrics/index.d.ts +15 -0
  64. package/dist/types/reachability/clusterReachability.d.ts +31 -3
  65. package/dist/types/reachability/index.d.ts +93 -2
  66. package/dist/webinar/index.js +1 -1
  67. package/package.json +23 -23
  68. package/src/breakouts/index.ts +7 -1
  69. package/src/constants.ts +13 -17
  70. package/src/locus-info/selfUtils.ts +0 -5
  71. package/src/media/MediaConnectionAwaiter.ts +89 -14
  72. package/src/media/index.ts +13 -0
  73. package/src/meeting/connectionStateHandler.ts +65 -0
  74. package/src/meeting/index.ts +526 -292
  75. package/src/meeting/locusMediaRequest.ts +5 -0
  76. package/src/meeting/muteState.ts +6 -1
  77. package/src/meeting/util.ts +1 -0
  78. package/src/meeting-info/index.ts +9 -6
  79. package/src/meeting-info/meeting-info-v2.ts +4 -4
  80. package/src/meeting-info/util.ts +23 -28
  81. package/src/meeting-info/utilv2.ts +18 -24
  82. package/src/meetings/collection.ts +3 -3
  83. package/src/meetings/index.ts +39 -40
  84. package/src/meetings/meetings.types.ts +11 -0
  85. package/src/meetings/util.ts +5 -4
  86. package/src/metrics/constants.ts +1 -0
  87. package/src/metrics/index.ts +44 -0
  88. package/src/personal-meeting-room/index.ts +2 -2
  89. package/src/reachability/clusterReachability.ts +86 -25
  90. package/src/reachability/index.ts +316 -27
  91. package/test/unit/spec/breakouts/index.ts +51 -32
  92. package/test/unit/spec/locus-info/selfUtils.js +25 -23
  93. package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
  94. package/test/unit/spec/media/index.ts +42 -27
  95. package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
  96. package/test/unit/spec/meeting/index.js +758 -179
  97. package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
  98. package/test/unit/spec/meeting/muteState.js +24 -0
  99. package/test/unit/spec/meeting-info/index.js +4 -4
  100. package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
  101. package/test/unit/spec/meeting-info/request.js +2 -2
  102. package/test/unit/spec/meeting-info/utilv2.js +41 -49
  103. package/test/unit/spec/meetings/index.js +14 -0
  104. package/test/unit/spec/metrics/index.js +126 -0
  105. package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
  106. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
  107. package/test/unit/spec/reachability/clusterReachability.ts +116 -22
  108. package/test/unit/spec/reachability/index.ts +1153 -84
  109. package/test/unit/spec/rtcMetrics/index.ts +1 -0
  110. package/dist/mediaQualityMetrics/config.js +0 -321
  111. package/dist/mediaQualityMetrics/config.js.map +0 -1
  112. package/dist/statsAnalyzer/global.js +0 -44
  113. package/dist/statsAnalyzer/global.js.map +0 -1
  114. package/dist/statsAnalyzer/index.js +0 -1072
  115. package/dist/statsAnalyzer/index.js.map +0 -1
  116. package/dist/statsAnalyzer/mqaUtil.js +0 -368
  117. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  118. package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
  119. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  120. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  121. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  122. package/src/mediaQualityMetrics/config.ts +0 -255
  123. package/src/statsAnalyzer/global.ts +0 -37
  124. package/src/statsAnalyzer/index.ts +0 -1318
  125. package/src/statsAnalyzer/mqaUtil.ts +0 -463
  126. 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
  }
@@ -379,7 +379,12 @@ export class MuteState {
379
379
  }
380
380
  if (muted !== undefined) {
381
381
  this.state.server.remoteMute = muted;
382
- this.muteLocalStream(meeting, muted, 'remotelyMuted');
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
 
@@ -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 {_MEETING_LINK_, _SIP_URI_, _PERSONAL_ROOM_} from '../constants';
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 {String} [type] to match up with the destination value
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: string = null,
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 === _PERSONAL_ROOM_ && !destination) {
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 === _MEETING_LINK_) {
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(MeetingInfoUtil.convertLinkToSip(destination), _SIP_URI_),
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
- _CONVERSATION_URL_,
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 {String} [type] to match up with the destination value
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: string = null,
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 === _CONVERSATION_URL_ &&
287
+ destinationType.type === DESTINATION_TYPE.CONVERSATION_URL &&
288
288
  this.webex.config.meetings.experimental.enableAdhocMeetings &&
289
289
  this.webex.meetings.preferredWebexSite
290
290
  ) {
@@ -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
- _SIP_URI_,
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 === _LOCUS_ID_) {
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 = _MEETING_LINK_;
198
+ options.type = DESTINATION_TYPE.MEETING_LINK;
204
199
  options.destination = destination;
205
200
  } else if (this.isSipUri(destination)) {
206
- options.type = _SIP_URI_;
201
+ options.type = DESTINATION_TYPE.SIP_URI;
207
202
  options.destination = destination;
208
203
  } else if (this.isPhoneNumber(destination)) {
209
- options.type = _SIP_URI_;
204
+ options.type = DESTINATION_TYPE.SIP_URI;
210
205
  options.destination = destination;
211
206
  } else if (this.isConversationUrl(destination, webex)) {
212
- options.type = _CONVERSATION_URL_;
207
+ options.type = DESTINATION_TYPE.CONVERSATION_URL;
213
208
  options.destination = destination;
214
209
  } else if (hydraId.people) {
215
- options.type = _SIP_URI_;
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 = _CONVERSATION_URL_;
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 {String} type One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
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: string, value: any) {
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 _SIP_URI_:
268
- case _PERSONAL_ROOM_:
269
- case _MEETING_ID_:
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 _CONVERSATION_URL_:
269
+ case DESTINATION_TYPE.CONVERSATION_URL:
275
270
  method = HTTP_VERBS.PUT;
276
271
  break;
277
- case _LOCUS_ID_:
272
+ case DESTINATION_TYPE.LOCUS_ID:
278
273
  uri = `${value}/${MEETINGINFO}`;
279
274
  method = HTTP_VERBS.PUT;
280
275
  break;
281
- case _MEETING_LINK_:
282
- resource = `$/${LOCI}/${MEETINGINFO}/${btoa(
283
- value
284
- )}?${TYPE}=${_MEETING_LINK_}&${USE_URI_LOOKUP_FALSE}`;
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 !== _LOCUS_ID_) {
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 === _LOCUS_ID_) {
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
- _SIP_URI_,
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 === _PERSONAL_ROOM_) {
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 = _MEETING_LINK_;
182
+ options.type = DESTINATION_TYPE.MEETING_LINK;
189
183
  options.destination = destination;
190
184
  } else if (this.isSipUri(destination)) {
191
- options.type = _SIP_URI_;
185
+ options.type = DESTINATION_TYPE.SIP_URI;
192
186
  options.destination = destination;
193
187
  } else if (this.isPhoneNumber(destination)) {
194
- options.type = _SIP_URI_;
188
+ options.type = DESTINATION_TYPE.SIP_URI;
195
189
  options.destination = destination;
196
190
  } else if (this.isConversationUrl(destination, webex)) {
197
- options.type = _CONVERSATION_URL_;
191
+ options.type = DESTINATION_TYPE.CONVERSATION_URL;
198
192
  options.destination = destination;
199
193
  } else if (hydraId && hydraId.people) {
200
- options.type = _SIP_URI_;
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 {String} options.type One of [SIP_URI, PERSONAL_ROOM, MEETING_ID, CONVERSATION_URL, LOCUS_ID, MEETING_LINK]
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: string; destination: object} | any) {
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 _SIP_URI_:
237
+ case DESTINATION_TYPE.SIP_URI:
244
238
  body.sipUrl = destination;
245
239
  break;
246
- case _PERSONAL_ROOM_:
240
+ case DESTINATION_TYPE.PERSONAL_ROOM:
247
241
  body.userId = destination.userId;
248
242
  body.orgId = destination.orgId;
249
243
  break;
250
- case _MEETING_ID_:
244
+ case DESTINATION_TYPE.MEETING_ID:
251
245
  body.meetingKey = destination;
252
246
  break;
253
- case _CONVERSATION_URL_:
247
+ case DESTINATION_TYPE.CONVERSATION_URL:
254
248
  body.conversationUrl = destination;
255
249
  break;
256
- case _LOCUS_ID_:
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 _MEETING_LINK_:
258
+ case DESTINATION_TYPE.MEETING_LINK:
265
259
  body.meetingUrl = destination;
266
260
  break;
267
- case _MEETING_UUID_: {
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 _SIP_URI_:
314
+ case DESTINATION_TYPE.SIP_URI:
321
315
  preferredWebexSite = this.getWebexSite(destination);
322
316
  break;
323
- case _LOCUS_ID_:
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 {String} key
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: string, value: any) {
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);
@@ -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(CONVERSATION_URL, data.locus.conversationUrl)) ||
399
- this.meetingCollection.getByKey(MEETINGNUMBER, data.locus?.info?.webExMeetingId)
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, _LOCUS_ID_, useRandomDelayForInfo)
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 {string} [type] - the optional specified type, such as locusId
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: string = null,
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 (type === _CONVERSATION_URL_ || options.type === _CONVERSATION_URL_) {
1132
- const foundMeeting = this.meetingCollection.getByKey(CONVERSATION_URL, targetDest);
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 {String} type see create()
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: string = null,
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 === _LOCUS_ID_ ? destination : null, // pass the locus object if present
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
- enableUnifiedMeetings &&
1295
- !isMeetingActive &&
1296
- useRandomDelayForInfo &&
1297
- waitingTime > 0
1298
- ) {
1299
- meeting.fetchMeetingInfoTimeoutId = setTimeout(
1300
- () => meeting.fetchMeetingInfo(meetingInfoOptions),
1301
- waitingTime
1302
- );
1303
- meeting.parseMeetingInfo(undefined, destination);
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 !== _LOCUS_ID_) {
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>;
@@ -5,10 +5,9 @@ import {
5
5
  _INCOMING_,
6
6
  _JOINED_,
7
7
  _LEFT_,
8
- _LOCUS_ID_,
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) => (type === _LOCUS_ID_ ? _INCOMING_ : _CREATED_);
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;