@webex/plugin-meetings 3.3.1 → 3.4.0-next.10

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 (138) 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 +18 -9
  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 +576 -374
  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 +41 -35
  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 +546 -115
  49. package/dist/reachability/index.js.map +1 -1
  50. package/dist/reconnection-manager/index.js +1 -1
  51. package/dist/reconnection-manager/index.js.map +1 -1
  52. package/dist/rtcMetrics/index.js +26 -6
  53. package/dist/rtcMetrics/index.js.map +1 -1
  54. package/dist/types/constants.d.ts +11 -3
  55. package/dist/types/media/MediaConnectionAwaiter.d.ts +24 -4
  56. package/dist/types/meeting/connectionStateHandler.d.ts +30 -0
  57. package/dist/types/meeting/index.d.ts +28 -8
  58. package/dist/types/meeting/locusMediaRequest.d.ts +2 -0
  59. package/dist/types/meeting-info/index.d.ts +3 -2
  60. package/dist/types/meeting-info/meeting-info-v2.d.ts +3 -2
  61. package/dist/types/meeting-info/util.d.ts +5 -4
  62. package/dist/types/meeting-info/utilv2.d.ts +3 -2
  63. package/dist/types/meetings/collection.d.ts +3 -2
  64. package/dist/types/meetings/index.d.ts +6 -4
  65. package/dist/types/meetings/meetings.types.d.ts +9 -0
  66. package/dist/types/metrics/constants.d.ts +1 -0
  67. package/dist/types/metrics/index.d.ts +15 -0
  68. package/dist/types/reachability/clusterReachability.d.ts +31 -3
  69. package/dist/types/reachability/index.d.ts +107 -4
  70. package/dist/types/rtcMetrics/index.d.ts +11 -1
  71. package/dist/webinar/index.js +1 -1
  72. package/package.json +23 -23
  73. package/src/breakouts/index.ts +7 -1
  74. package/src/constants.ts +13 -17
  75. package/src/locus-info/selfUtils.ts +0 -5
  76. package/src/media/MediaConnectionAwaiter.ts +89 -14
  77. package/src/media/index.ts +18 -9
  78. package/src/meeting/connectionStateHandler.ts +65 -0
  79. package/src/meeting/index.ts +541 -298
  80. package/src/meeting/locusMediaRequest.ts +5 -0
  81. package/src/meeting/muteState.ts +6 -1
  82. package/src/meeting/util.ts +1 -0
  83. package/src/meeting-info/index.ts +9 -6
  84. package/src/meeting-info/meeting-info-v2.ts +4 -4
  85. package/src/meeting-info/util.ts +23 -28
  86. package/src/meeting-info/utilv2.ts +18 -24
  87. package/src/meetings/collection.ts +3 -3
  88. package/src/meetings/index.ts +43 -43
  89. package/src/meetings/meetings.types.ts +11 -0
  90. package/src/meetings/util.ts +5 -4
  91. package/src/metrics/constants.ts +1 -0
  92. package/src/metrics/index.ts +44 -0
  93. package/src/personal-meeting-room/index.ts +2 -2
  94. package/src/reachability/clusterReachability.ts +86 -25
  95. package/src/reachability/index.ts +364 -30
  96. package/src/reconnection-manager/index.ts +1 -1
  97. package/src/rtcMetrics/index.ts +25 -5
  98. package/test/unit/spec/breakouts/index.ts +51 -32
  99. package/test/unit/spec/locus-info/selfUtils.js +25 -23
  100. package/test/unit/spec/media/MediaConnectionAwaiter.ts +131 -32
  101. package/test/unit/spec/media/index.ts +75 -34
  102. package/test/unit/spec/meeting/connectionStateHandler.ts +102 -0
  103. package/test/unit/spec/meeting/index.js +807 -185
  104. package/test/unit/spec/meeting/locusMediaRequest.ts +7 -0
  105. package/test/unit/spec/meeting/muteState.js +24 -0
  106. package/test/unit/spec/meeting-info/index.js +4 -4
  107. package/test/unit/spec/meeting-info/meetinginfov2.js +24 -28
  108. package/test/unit/spec/meeting-info/request.js +2 -2
  109. package/test/unit/spec/meeting-info/utilv2.js +41 -49
  110. package/test/unit/spec/meetings/index.js +44 -3
  111. package/test/unit/spec/metrics/index.js +126 -0
  112. package/test/unit/spec/multistream/mediaRequestManager.ts +2 -2
  113. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -2
  114. package/test/unit/spec/reachability/clusterReachability.ts +116 -22
  115. package/test/unit/spec/reachability/index.ts +1398 -131
  116. package/test/unit/spec/rtcMetrics/index.ts +32 -0
  117. package/dist/mediaQualityMetrics/config.js +0 -321
  118. package/dist/mediaQualityMetrics/config.js.map +0 -1
  119. package/dist/networkQualityMonitor/index.js +0 -227
  120. package/dist/networkQualityMonitor/index.js.map +0 -1
  121. package/dist/statsAnalyzer/global.js +0 -44
  122. package/dist/statsAnalyzer/global.js.map +0 -1
  123. package/dist/statsAnalyzer/index.js +0 -1072
  124. package/dist/statsAnalyzer/index.js.map +0 -1
  125. package/dist/statsAnalyzer/mqaUtil.js +0 -368
  126. package/dist/statsAnalyzer/mqaUtil.js.map +0 -1
  127. package/dist/types/mediaQualityMetrics/config.d.ts +0 -247
  128. package/dist/types/networkQualityMonitor/index.d.ts +0 -70
  129. package/dist/types/statsAnalyzer/global.d.ts +0 -36
  130. package/dist/types/statsAnalyzer/index.d.ts +0 -217
  131. package/dist/types/statsAnalyzer/mqaUtil.d.ts +0 -48
  132. package/src/mediaQualityMetrics/config.ts +0 -255
  133. package/src/networkQualityMonitor/index.ts +0 -211
  134. package/src/statsAnalyzer/global.ts +0 -37
  135. package/src/statsAnalyzer/index.ts +0 -1318
  136. package/src/statsAnalyzer/mqaUtil.ts +0 -463
  137. package/test/unit/spec/networkQualityMonitor/index.js +0 -99
  138. 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
 
@@ -769,7 +765,7 @@ export default class Meetings extends WebexPlugin {
769
765
  return Promise.all([
770
766
  this.fetchUserPreferredWebexSite(),
771
767
  this.getGeoHint(),
772
- this.startReachability().catch((error) => {
768
+ this.startReachability('registration').catch((error) => {
773
769
  LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
774
770
  }),
775
771
  // @ts-ignore
@@ -971,12 +967,13 @@ export default class Meetings extends WebexPlugin {
971
967
 
972
968
  /**
973
969
  * initializes and starts gathering reachability for Meetings
970
+ * @param {string} trigger - explains the reason for starting reachability
974
971
  * @returns {Promise}
975
972
  * @public
976
973
  * @memberof Meetings
977
974
  */
978
- startReachability() {
979
- return this.getReachability().gatherReachability();
975
+ startReachability(trigger = 'client') {
976
+ return this.getReachability().gatherReachability(trigger);
980
977
  }
981
978
 
982
979
  /**
@@ -1076,7 +1073,7 @@ export default class Meetings extends WebexPlugin {
1076
1073
  * When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
1077
1074
  *
1078
1075
  * @param {string} destination - sipURL, phonenumber, or locus object}
1079
- * @param {string} [type] - the optional specified type, such as locusId
1076
+ * @param {DESTINATION_TYPE} [type] - the optional specified type, such as locusId
1080
1077
  * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
1081
1078
  * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1082
1079
  * @param {string} correlationId - the optional specified correlationId (callStateForMetrics.correlationId can be provided instead)
@@ -1090,7 +1087,7 @@ export default class Meetings extends WebexPlugin {
1090
1087
  */
1091
1088
  public create(
1092
1089
  destination: string,
1093
- type: string = null,
1090
+ type: DESTINATION_TYPE = null,
1094
1091
  useRandomDelayForInfo = false,
1095
1092
  infoExtraParams = {},
1096
1093
  correlationId: string = undefined,
@@ -1099,12 +1096,11 @@ export default class Meetings extends WebexPlugin {
1099
1096
  meetingInfo = undefined,
1100
1097
  meetingLookupUrl = undefined
1101
1098
  ) {
1102
- // TODO: type should be from a dictionary
1103
-
1104
1099
  // Validate meeting information based on the provided destination and
1105
1100
  // type. This must be performed prior to determining if the meeting is
1106
1101
  // found in the collection, as we mutate the destination for hydra person
1107
1102
  // id values.
1103
+
1108
1104
  if (correlationId) {
1109
1105
  callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
1110
1106
  }
@@ -1128,8 +1124,14 @@ export default class Meetings extends WebexPlugin {
1128
1124
  // check for the conversation URL then sip Url
1129
1125
  let meeting = null;
1130
1126
 
1131
- if (type === _CONVERSATION_URL_ || options.type === _CONVERSATION_URL_) {
1132
- const foundMeeting = this.meetingCollection.getByKey(CONVERSATION_URL, targetDest);
1127
+ if (
1128
+ type === DESTINATION_TYPE.CONVERSATION_URL ||
1129
+ options.type === DESTINATION_TYPE.CONVERSATION_URL
1130
+ ) {
1131
+ const foundMeeting = this.meetingCollection.getByKey(
1132
+ MEETING_KEY.CONVERSATION_URL,
1133
+ targetDest
1134
+ );
1133
1135
 
1134
1136
  if (foundMeeting) {
1135
1137
  const foundMeetingIsNotCalendarMeeting = !foundMeeting.locusInfo.scheduledMeeting;
@@ -1144,7 +1146,7 @@ export default class Meetings extends WebexPlugin {
1144
1146
 
1145
1147
  // Attempt to collect the meeting if it exists.
1146
1148
  if (!meeting) {
1147
- meeting = this.meetingCollection.getByKey(SIP_URI, targetDest);
1149
+ meeting = this.meetingCollection.getByKey(MEETING_KEY.SIP_URI, targetDest);
1148
1150
  }
1149
1151
 
1150
1152
  // Validate if a meeting was found.
@@ -1218,7 +1220,7 @@ export default class Meetings extends WebexPlugin {
1218
1220
  * When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
1219
1221
  *
1220
1222
  * @param {String} destination see create()
1221
- * @param {String} type see create()
1223
+ * @param {DESTINATION_TYPE} type see create()
1222
1224
  * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1223
1225
  * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1224
1226
  * @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
@@ -1231,7 +1233,7 @@ export default class Meetings extends WebexPlugin {
1231
1233
  */
1232
1234
  private async createMeeting(
1233
1235
  destination: any,
1234
- type: string = null,
1236
+ type: DESTINATION_TYPE = null,
1235
1237
  useRandomDelayForInfo = false,
1236
1238
  infoExtraParams = {},
1237
1239
  callStateForMetrics: CallStateForMetrics = undefined,
@@ -1247,7 +1249,7 @@ export default class Meetings extends WebexPlugin {
1247
1249
  deviceUrl: this.webex.internal.device.url,
1248
1250
  // @ts-ignore
1249
1251
  orgId: this.webex.internal.device.orgId,
1250
- locus: type === _LOCUS_ID_ ? destination : null, // pass the locus object if present
1252
+ locus: type === DESTINATION_TYPE.LOCUS_ID ? destination : null, // pass the locus object if present
1251
1253
  meetingInfoProvider: this.meetingInfo,
1252
1254
  destination,
1253
1255
  destinationType: type,
@@ -1290,19 +1292,17 @@ export default class Meetings extends WebexPlugin {
1290
1292
 
1291
1293
  if (meetingInfo) {
1292
1294
  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);
1295
+ } else if (type !== DESTINATION_TYPE.ONE_ON_ONE_CALL) {
1296
+ // ignore fetchMeetingInfo for 1:1 meetings
1297
+ if (enableUnifiedMeetings && !isMeetingActive && useRandomDelayForInfo && waitingTime > 0) {
1298
+ meeting.fetchMeetingInfoTimeoutId = setTimeout(
1299
+ () => meeting.fetchMeetingInfo(meetingInfoOptions),
1300
+ waitingTime
1301
+ );
1302
+ meeting.parseMeetingInfo(undefined, destination);
1303
+ } else {
1304
+ await meeting.fetchMeetingInfo(meetingInfoOptions);
1305
+ }
1306
1306
  }
1307
1307
  } catch (err) {
1308
1308
  if (
@@ -1333,7 +1333,7 @@ export default class Meetings extends WebexPlugin {
1333
1333
  // For type LOCUS_ID we need to parse the locus object to get the information
1334
1334
  // about the caller and callee
1335
1335
  // Meeting Added event will be created in `handleLocusEvent`
1336
- if (type !== _LOCUS_ID_) {
1336
+ if (type !== DESTINATION_TYPE.LOCUS_ID) {
1337
1337
  if (!meeting.sipUri) {
1338
1338
  meeting.setSipUri(destination);
1339
1339
  }
@@ -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>;