@webex/plugin-meetings 3.0.0-beta.31 → 3.0.0-beta.310

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 (378) hide show
  1. package/README.md +46 -8
  2. package/dist/annotation/annotation.types.js +7 -0
  3. package/dist/annotation/annotation.types.js.map +1 -0
  4. package/dist/annotation/constants.js +49 -0
  5. package/dist/annotation/constants.js.map +1 -0
  6. package/dist/annotation/index.js +342 -0
  7. package/dist/annotation/index.js.map +1 -0
  8. package/dist/breakouts/breakout.js +94 -15
  9. package/dist/breakouts/breakout.js.map +1 -1
  10. package/dist/breakouts/edit-lock-error.js +52 -0
  11. package/dist/breakouts/edit-lock-error.js.map +1 -0
  12. package/dist/breakouts/events.js +45 -0
  13. package/dist/breakouts/events.js.map +1 -0
  14. package/dist/breakouts/index.js +709 -35
  15. package/dist/breakouts/index.js.map +1 -1
  16. package/dist/breakouts/utils.js +45 -1
  17. package/dist/breakouts/utils.js.map +1 -1
  18. package/dist/common/errors/no-meeting-info.js +51 -0
  19. package/dist/common/errors/no-meeting-info.js.map +1 -0
  20. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  21. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  22. package/dist/common/errors/webex-errors.js +48 -7
  23. package/dist/common/errors/webex-errors.js.map +1 -1
  24. package/dist/common/logs/logger-proxy.js +1 -1
  25. package/dist/common/logs/logger-proxy.js.map +1 -1
  26. package/dist/common/logs/request.js +5 -1
  27. package/dist/common/logs/request.js.map +1 -1
  28. package/dist/common/queue.js +24 -9
  29. package/dist/common/queue.js.map +1 -1
  30. package/dist/config.js +5 -11
  31. package/dist/config.js.map +1 -1
  32. package/dist/constants.js +233 -29
  33. package/dist/constants.js.map +1 -1
  34. package/dist/controls-options-manager/enums.js +14 -2
  35. package/dist/controls-options-manager/enums.js.map +1 -1
  36. package/dist/controls-options-manager/index.js +109 -15
  37. package/dist/controls-options-manager/index.js.map +1 -1
  38. package/dist/controls-options-manager/types.js +7 -0
  39. package/dist/controls-options-manager/types.js.map +1 -0
  40. package/dist/controls-options-manager/util.js +309 -18
  41. package/dist/controls-options-manager/util.js.map +1 -1
  42. package/dist/index.js +112 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/interpretation/collection.js +23 -0
  45. package/dist/interpretation/collection.js.map +1 -0
  46. package/dist/interpretation/index.js +366 -0
  47. package/dist/interpretation/index.js.map +1 -0
  48. package/dist/interpretation/siLanguage.js +25 -0
  49. package/dist/interpretation/siLanguage.js.map +1 -0
  50. package/dist/locus-info/controlsUtils.js +91 -2
  51. package/dist/locus-info/controlsUtils.js.map +1 -1
  52. package/dist/locus-info/index.js +383 -62
  53. package/dist/locus-info/index.js.map +1 -1
  54. package/dist/locus-info/infoUtils.js +7 -1
  55. package/dist/locus-info/infoUtils.js.map +1 -1
  56. package/dist/locus-info/mediaSharesUtils.js +57 -1
  57. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  58. package/dist/locus-info/parser.js +249 -72
  59. package/dist/locus-info/parser.js.map +1 -1
  60. package/dist/locus-info/selfUtils.js +89 -14
  61. package/dist/locus-info/selfUtils.js.map +1 -1
  62. package/dist/media/index.js +61 -116
  63. package/dist/media/index.js.map +1 -1
  64. package/dist/media/properties.js +73 -124
  65. package/dist/media/properties.js.map +1 -1
  66. package/dist/meeting/in-meeting-actions.js +82 -2
  67. package/dist/meeting/in-meeting-actions.js.map +1 -1
  68. package/dist/meeting/index.js +3777 -2929
  69. package/dist/meeting/index.js.map +1 -1
  70. package/dist/meeting/locusMediaRequest.js +292 -0
  71. package/dist/meeting/locusMediaRequest.js.map +1 -0
  72. package/dist/meeting/muteState.js +230 -124
  73. package/dist/meeting/muteState.js.map +1 -1
  74. package/dist/meeting/request.js +260 -196
  75. package/dist/meeting/request.js.map +1 -1
  76. package/dist/meeting/util.js +601 -417
  77. package/dist/meeting/util.js.map +1 -1
  78. package/dist/meeting-info/index.js +73 -7
  79. package/dist/meeting-info/index.js.map +1 -1
  80. package/dist/meeting-info/meeting-info-v2.js +192 -51
  81. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  82. package/dist/meeting-info/util.js +1 -1
  83. package/dist/meeting-info/util.js.map +1 -1
  84. package/dist/meeting-info/utilv2.js +36 -36
  85. package/dist/meeting-info/utilv2.js.map +1 -1
  86. package/dist/meetings/collection.js +39 -0
  87. package/dist/meetings/collection.js.map +1 -1
  88. package/dist/meetings/index.js +415 -115
  89. package/dist/meetings/index.js.map +1 -1
  90. package/dist/meetings/meetings.types.js +7 -0
  91. package/dist/meetings/meetings.types.js.map +1 -0
  92. package/dist/meetings/request.js +2 -0
  93. package/dist/meetings/request.js.map +1 -1
  94. package/dist/meetings/util.js +72 -6
  95. package/dist/meetings/util.js.map +1 -1
  96. package/dist/member/index.js +58 -0
  97. package/dist/member/index.js.map +1 -1
  98. package/dist/member/types.js +25 -0
  99. package/dist/member/types.js.map +1 -0
  100. package/dist/member/util.js +132 -25
  101. package/dist/member/util.js.map +1 -1
  102. package/dist/members/collection.js +10 -0
  103. package/dist/members/collection.js.map +1 -1
  104. package/dist/members/index.js +102 -6
  105. package/dist/members/index.js.map +1 -1
  106. package/dist/members/request.js +106 -38
  107. package/dist/members/request.js.map +1 -1
  108. package/dist/members/types.js +15 -0
  109. package/dist/members/types.js.map +1 -0
  110. package/dist/members/util.js +326 -232
  111. package/dist/members/util.js.map +1 -1
  112. package/dist/metrics/constants.js +13 -5
  113. package/dist/metrics/constants.js.map +1 -1
  114. package/dist/metrics/index.js +1 -468
  115. package/dist/metrics/index.js.map +1 -1
  116. package/dist/multistream/mediaRequestManager.js +238 -49
  117. package/dist/multistream/mediaRequestManager.js.map +1 -1
  118. package/dist/multistream/receiveSlot.js +29 -16
  119. package/dist/multistream/receiveSlot.js.map +1 -1
  120. package/dist/multistream/receiveSlotManager.js +39 -36
  121. package/dist/multistream/receiveSlotManager.js.map +1 -1
  122. package/dist/multistream/remoteMedia.js +44 -18
  123. package/dist/multistream/remoteMedia.js.map +1 -1
  124. package/dist/multistream/remoteMediaGroup.js +60 -3
  125. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  126. package/dist/multistream/remoteMediaManager.js +209 -59
  127. package/dist/multistream/remoteMediaManager.js.map +1 -1
  128. package/dist/multistream/sendSlotManager.js +233 -0
  129. package/dist/multistream/sendSlotManager.js.map +1 -0
  130. package/dist/reachability/index.js +225 -59
  131. package/dist/reachability/index.js.map +1 -1
  132. package/dist/reachability/request.js +17 -8
  133. package/dist/reachability/request.js.map +1 -1
  134. package/dist/reconnection-manager/index.js +201 -156
  135. package/dist/reconnection-manager/index.js.map +1 -1
  136. package/dist/recording-controller/index.js +21 -2
  137. package/dist/recording-controller/index.js.map +1 -1
  138. package/dist/recording-controller/util.js +9 -8
  139. package/dist/recording-controller/util.js.map +1 -1
  140. package/dist/roap/index.js +62 -32
  141. package/dist/roap/index.js.map +1 -1
  142. package/dist/roap/request.js +112 -97
  143. package/dist/roap/request.js.map +1 -1
  144. package/dist/roap/turnDiscovery.js +95 -36
  145. package/dist/roap/turnDiscovery.js.map +1 -1
  146. package/dist/rtcMetrics/constants.js +12 -0
  147. package/dist/rtcMetrics/constants.js.map +1 -0
  148. package/dist/rtcMetrics/index.js +117 -0
  149. package/dist/rtcMetrics/index.js.map +1 -0
  150. package/dist/statsAnalyzer/index.js +86 -78
  151. package/dist/statsAnalyzer/index.js.map +1 -1
  152. package/dist/statsAnalyzer/mqaUtil.js +11 -10
  153. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  154. package/dist/types/annotation/annotation.types.d.ts +42 -0
  155. package/dist/types/annotation/constants.d.ts +31 -0
  156. package/dist/types/annotation/index.d.ts +117 -0
  157. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  158. package/dist/types/breakouts/events.d.ts +8 -0
  159. package/dist/types/breakouts/utils.d.ts +14 -0
  160. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  161. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  162. package/dist/types/common/errors/webex-errors.d.ts +25 -1
  163. package/dist/types/common/logs/request.d.ts +2 -0
  164. package/dist/types/common/queue.d.ts +9 -7
  165. package/dist/types/config.d.ts +1 -7
  166. package/dist/types/constants.d.ts +194 -24
  167. package/dist/types/controls-options-manager/enums.d.ts +11 -1
  168. package/dist/types/controls-options-manager/index.d.ts +17 -1
  169. package/dist/types/controls-options-manager/types.d.ts +43 -0
  170. package/dist/types/controls-options-manager/util.d.ts +1 -7
  171. package/dist/types/index.d.ts +6 -4
  172. package/dist/types/interpretation/collection.d.ts +5 -0
  173. package/dist/types/interpretation/index.d.ts +5 -0
  174. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  175. package/dist/types/locus-info/index.d.ts +57 -4
  176. package/dist/types/locus-info/parser.d.ts +67 -6
  177. package/dist/types/media/index.d.ts +2 -0
  178. package/dist/types/media/properties.d.ts +34 -48
  179. package/dist/types/meeting/in-meeting-actions.d.ts +82 -2
  180. package/dist/types/meeting/index.d.ts +463 -510
  181. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  182. package/dist/types/meeting/muteState.d.ts +99 -23
  183. package/dist/types/meeting/request.d.ts +72 -43
  184. package/dist/types/meeting/util.d.ts +101 -1
  185. package/dist/types/meeting-info/index.d.ts +13 -1
  186. package/dist/types/meeting-info/meeting-info-v2.d.ts +31 -1
  187. package/dist/types/meetings/collection.d.ts +17 -0
  188. package/dist/types/meetings/index.d.ts +98 -20
  189. package/dist/types/meetings/meetings.types.d.ts +4 -0
  190. package/dist/types/member/index.d.ts +14 -0
  191. package/dist/types/member/types.d.ts +32 -0
  192. package/dist/types/members/collection.d.ts +5 -0
  193. package/dist/types/members/index.d.ts +35 -2
  194. package/dist/types/members/request.d.ts +73 -9
  195. package/dist/types/members/types.d.ts +25 -0
  196. package/dist/types/members/util.d.ts +214 -1
  197. package/dist/types/metrics/constants.d.ts +12 -4
  198. package/dist/types/metrics/index.d.ts +4 -119
  199. package/dist/types/multistream/mediaRequestManager.d.ts +73 -5
  200. package/dist/types/multistream/receiveSlot.d.ts +13 -11
  201. package/dist/types/multistream/receiveSlotManager.d.ts +14 -4
  202. package/dist/types/multistream/remoteMedia.d.ts +8 -29
  203. package/dist/types/multistream/remoteMediaGroup.d.ts +0 -9
  204. package/dist/types/multistream/remoteMediaManager.d.ts +46 -2
  205. package/dist/types/multistream/sendSlotManager.d.ts +61 -0
  206. package/dist/types/reachability/index.d.ts +61 -7
  207. package/dist/types/reachability/request.d.ts +7 -3
  208. package/dist/types/reconnection-manager/index.d.ts +9 -0
  209. package/dist/types/recording-controller/index.d.ts +15 -1
  210. package/dist/types/recording-controller/util.d.ts +5 -4
  211. package/dist/types/roap/index.d.ts +2 -1
  212. package/dist/types/roap/request.d.ts +15 -11
  213. package/dist/types/roap/turnDiscovery.d.ts +21 -3
  214. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  215. package/dist/types/rtcMetrics/index.d.ts +47 -0
  216. package/dist/types/statsAnalyzer/index.d.ts +7 -1
  217. package/dist/types/webinar/collection.d.ts +16 -0
  218. package/dist/types/webinar/index.d.ts +5 -0
  219. package/dist/webinar/collection.js +44 -0
  220. package/dist/webinar/collection.js.map +1 -0
  221. package/dist/webinar/index.js +69 -0
  222. package/dist/webinar/index.js.map +1 -0
  223. package/package.json +23 -20
  224. package/src/annotation/annotation.types.ts +50 -0
  225. package/src/annotation/constants.ts +36 -0
  226. package/src/annotation/index.ts +328 -0
  227. package/src/breakouts/README.md +42 -12
  228. package/src/breakouts/breakout.ts +67 -9
  229. package/src/breakouts/edit-lock-error.ts +25 -0
  230. package/src/breakouts/events.ts +56 -0
  231. package/src/breakouts/index.ts +592 -20
  232. package/src/breakouts/utils.ts +42 -0
  233. package/src/common/errors/no-meeting-info.ts +24 -0
  234. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  235. package/src/common/errors/webex-errors.ts +44 -2
  236. package/src/common/logs/logger-proxy.ts +1 -1
  237. package/src/common/logs/request.ts +5 -1
  238. package/src/common/queue.ts +22 -8
  239. package/src/config.ts +4 -10
  240. package/src/constants.ts +221 -19
  241. package/src/controls-options-manager/enums.ts +12 -0
  242. package/src/controls-options-manager/index.ts +116 -21
  243. package/src/controls-options-manager/types.ts +59 -0
  244. package/src/controls-options-manager/util.ts +294 -14
  245. package/src/index.ts +40 -0
  246. package/src/interpretation/README.md +60 -0
  247. package/src/interpretation/collection.ts +19 -0
  248. package/src/interpretation/index.ts +332 -0
  249. package/src/interpretation/siLanguage.ts +18 -0
  250. package/src/locus-info/controlsUtils.ts +108 -0
  251. package/src/locus-info/index.ts +413 -59
  252. package/src/locus-info/infoUtils.ts +10 -2
  253. package/src/locus-info/mediaSharesUtils.ts +64 -0
  254. package/src/locus-info/parser.ts +258 -47
  255. package/src/locus-info/selfUtils.ts +81 -5
  256. package/src/media/index.ts +102 -122
  257. package/src/media/properties.ts +87 -110
  258. package/src/meeting/in-meeting-actions.ts +163 -3
  259. package/src/meeting/index.ts +3132 -2541
  260. package/src/meeting/locusMediaRequest.ts +313 -0
  261. package/src/meeting/muteState.ts +229 -131
  262. package/src/meeting/request.ts +177 -121
  263. package/src/meeting/util.ts +588 -394
  264. package/src/meeting-info/index.ts +81 -8
  265. package/src/meeting-info/meeting-info-v2.ts +170 -14
  266. package/src/meeting-info/util.ts +1 -1
  267. package/src/meeting-info/utilv2.ts +23 -23
  268. package/src/meetings/collection.ts +33 -0
  269. package/src/meetings/index.ts +445 -123
  270. package/src/meetings/meetings.types.ts +12 -0
  271. package/src/meetings/request.ts +2 -0
  272. package/src/meetings/util.ts +80 -11
  273. package/src/member/index.ts +58 -0
  274. package/src/member/types.ts +38 -0
  275. package/src/member/util.ts +141 -25
  276. package/src/members/collection.ts +8 -0
  277. package/src/members/index.ts +134 -8
  278. package/src/members/request.ts +97 -17
  279. package/src/members/types.ts +29 -0
  280. package/src/members/util.ts +333 -240
  281. package/src/metrics/constants.ts +12 -4
  282. package/src/metrics/index.ts +1 -490
  283. package/src/multistream/mediaRequestManager.ts +289 -79
  284. package/src/multistream/receiveSlot.ts +31 -17
  285. package/src/multistream/receiveSlotManager.ts +34 -24
  286. package/src/multistream/remoteMedia.ts +27 -2
  287. package/src/multistream/remoteMediaGroup.ts +59 -0
  288. package/src/multistream/remoteMediaManager.ts +148 -30
  289. package/src/multistream/sendSlotManager.ts +170 -0
  290. package/src/reachability/index.ts +228 -37
  291. package/src/reachability/request.ts +17 -8
  292. package/src/reconnection-manager/index.ts +83 -56
  293. package/src/recording-controller/index.ts +20 -3
  294. package/src/recording-controller/util.ts +26 -9
  295. package/src/roap/index.ts +63 -32
  296. package/src/roap/request.ts +100 -104
  297. package/src/roap/turnDiscovery.ts +48 -26
  298. package/src/rtcMetrics/constants.ts +3 -0
  299. package/src/rtcMetrics/index.ts +100 -0
  300. package/src/statsAnalyzer/index.ts +105 -91
  301. package/src/statsAnalyzer/mqaUtil.ts +13 -14
  302. package/src/webinar/collection.ts +31 -0
  303. package/src/webinar/index.ts +62 -0
  304. package/test/integration/spec/converged-space-meetings.js +60 -3
  305. package/test/integration/spec/journey.js +320 -261
  306. package/test/integration/spec/space-meeting.js +76 -3
  307. package/test/unit/spec/annotation/index.ts +418 -0
  308. package/test/unit/spec/breakouts/breakout.ts +118 -28
  309. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  310. package/test/unit/spec/breakouts/events.ts +89 -0
  311. package/test/unit/spec/breakouts/index.ts +1395 -69
  312. package/test/unit/spec/breakouts/utils.js +52 -1
  313. package/test/unit/spec/common/queue.js +31 -2
  314. package/test/unit/spec/controls-options-manager/index.js +163 -0
  315. package/test/unit/spec/controls-options-manager/util.js +576 -60
  316. package/test/unit/spec/fixture/locus.js +1 -0
  317. package/test/unit/spec/interpretation/collection.ts +15 -0
  318. package/test/unit/spec/interpretation/index.ts +589 -0
  319. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  320. package/test/unit/spec/locus-info/controlsUtils.js +316 -43
  321. package/test/unit/spec/locus-info/index.js +1304 -33
  322. package/test/unit/spec/locus-info/infoUtils.js +37 -15
  323. package/test/unit/spec/locus-info/lib/SeqCmp.json +16 -0
  324. package/test/unit/spec/locus-info/mediaSharesUtils.ts +32 -0
  325. package/test/unit/spec/locus-info/parser.js +116 -35
  326. package/test/unit/spec/locus-info/selfConstant.js +27 -4
  327. package/test/unit/spec/locus-info/selfUtils.js +208 -17
  328. package/test/unit/spec/media/index.ts +104 -37
  329. package/test/unit/spec/media/properties.ts +2 -2
  330. package/test/unit/spec/meeting/in-meeting-actions.ts +81 -3
  331. package/test/unit/spec/meeting/index.js +5216 -1956
  332. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  333. package/test/unit/spec/meeting/muteState.js +408 -208
  334. package/test/unit/spec/meeting/request.js +483 -49
  335. package/test/unit/spec/meeting/utils.js +679 -64
  336. package/test/unit/spec/meeting-info/index.js +300 -0
  337. package/test/unit/spec/meeting-info/meetinginfov2.js +526 -5
  338. package/test/unit/spec/meeting-info/utilv2.js +21 -0
  339. package/test/unit/spec/meetings/collection.js +26 -0
  340. package/test/unit/spec/meetings/index.js +1011 -205
  341. package/test/unit/spec/meetings/utils.js +202 -2
  342. package/test/unit/spec/member/index.js +61 -6
  343. package/test/unit/spec/member/util.js +510 -34
  344. package/test/unit/spec/members/index.js +432 -1
  345. package/test/unit/spec/members/request.js +206 -27
  346. package/test/unit/spec/members/utils.js +210 -0
  347. package/test/unit/spec/metrics/index.js +1 -50
  348. package/test/unit/spec/multistream/mediaRequestManager.ts +803 -162
  349. package/test/unit/spec/multistream/receiveSlot.ts +28 -20
  350. package/test/unit/spec/multistream/receiveSlotManager.ts +32 -30
  351. package/test/unit/spec/multistream/remoteMedia.ts +30 -0
  352. package/test/unit/spec/multistream/remoteMediaGroup.ts +266 -0
  353. package/test/unit/spec/multistream/remoteMediaManager.ts +326 -0
  354. package/test/unit/spec/multistream/sendSlotManager.ts +242 -0
  355. package/test/unit/spec/reachability/index.ts +549 -9
  356. package/test/unit/spec/reachability/request.js +68 -0
  357. package/test/unit/spec/reconnection-manager/index.js +85 -9
  358. package/test/unit/spec/recording-controller/index.js +294 -218
  359. package/test/unit/spec/recording-controller/util.js +223 -96
  360. package/test/unit/spec/roap/index.ts +178 -64
  361. package/test/unit/spec/roap/request.ts +203 -85
  362. package/test/unit/spec/roap/turnDiscovery.ts +82 -36
  363. package/test/unit/spec/rtcMetrics/index.ts +73 -0
  364. package/test/unit/spec/stats-analyzer/index.js +136 -2
  365. package/test/unit/spec/webinar/collection.ts +13 -0
  366. package/test/unit/spec/webinar/index.ts +60 -0
  367. package/test/utils/integrationTestUtils.js +46 -0
  368. package/test/utils/testUtils.js +0 -52
  369. package/dist/meeting/effectsState.js +0 -262
  370. package/dist/meeting/effectsState.js.map +0 -1
  371. package/dist/metrics/config.js +0 -299
  372. package/dist/metrics/config.js.map +0 -1
  373. package/dist/types/meeting/effectsState.d.ts +0 -42
  374. package/dist/types/metrics/config.d.ts +0 -178
  375. package/src/index.js +0 -16
  376. package/src/meeting/effectsState.ts +0 -211
  377. package/src/metrics/config.ts +0 -495
  378. package/test/unit/spec/meeting/effectsState.js +0 -285
@@ -2,14 +2,16 @@
2
2
 
3
3
  import '@webex/internal-plugin-mercury';
4
4
  import '@webex/internal-plugin-conversation';
5
+ import '@webex/internal-plugin-metrics';
5
6
  // @ts-ignore
6
7
  import {WebexPlugin} from '@webex/webex-core';
7
8
  import {setLogger} from '@webex/internal-media-core';
8
9
 
10
+ import * as mediaHelpersModule from '@webex/media-helpers';
11
+
9
12
  import 'webrtc-adapter';
10
13
 
11
14
  import Metrics from '../metrics';
12
- import {trigger, eventType} from '../metrics/config';
13
15
  import LoggerConfig from '../common/logs/logger-config';
14
16
  import StaticConfig from '../common/config';
15
17
  import LoggerProxy from '../common/logs/logger-proxy';
@@ -40,6 +42,9 @@ import {
40
42
  MEETING_REMOVED_REASON,
41
43
  _CONVERSATION_URL_,
42
44
  CONVERSATION_URL,
45
+ MEETINGNUMBER,
46
+ _JOINED_,
47
+ _MOVED_,
43
48
  } from '../constants';
44
49
  import BEHAVIORAL_METRICS from '../metrics/constants';
45
50
  import MeetingInfo from '../meeting-info';
@@ -53,6 +58,10 @@ import CaptchaError from '../common/errors/captcha-error';
53
58
 
54
59
  import MeetingCollection from './collection';
55
60
  import MeetingsUtil from './util';
61
+ import PermissionError from '../common/errors/permission';
62
+ import {INoiseReductionEffect, IVirtualBackgroundEffect} from './meetings.types';
63
+ import {SpaceIDDeprecatedError} from '../common/errors/webex-errors';
64
+ import NoMeetingInfoError from '../common/errors/no-meeting-info';
56
65
 
57
66
  let mediaLogger;
58
67
 
@@ -139,12 +148,13 @@ export default class Meetings extends WebexPlugin {
139
148
  meetingCollection: any;
140
149
  personalMeetingRoom: any;
141
150
  preferredWebexSite: any;
142
- reachability: any;
151
+ reachability: Reachability;
143
152
  registered: any;
144
153
  request: any;
145
154
  geoHintInfo: any;
146
155
  meetingInfo: any;
147
-
156
+ mediaHelpers: any;
157
+ breakoutLocusForHandleLater: any;
148
158
  namespace = MEETINGS;
149
159
 
150
160
  /**
@@ -156,6 +166,17 @@ export default class Meetings extends WebexPlugin {
156
166
  constructor(...args) {
157
167
  super(...args);
158
168
 
169
+ /**
170
+ * The webrtc-core media helpers. This is a temporary solution required for the SDK sample app
171
+ * to be able to call media helper functions.
172
+ *
173
+ * @instance
174
+ * @type {Object}
175
+ * @private
176
+ * @memberof Meetings
177
+ */
178
+ this.mediaHelpers = mediaHelpersModule;
179
+
159
180
  /**
160
181
  * The Meetings request to interact with server
161
182
  * @instance
@@ -183,15 +204,17 @@ export default class Meetings extends WebexPlugin {
183
204
  * @memberof Meetings
184
205
  */
185
206
  this.personalMeetingRoom = null;
207
+
186
208
  /**
187
- * The Reachability object to interact with server, starts as null until {@link Meeting#setReachability} is called
209
+ * The Reachability object to interact with server
188
210
  * starts as null
189
211
  * @instance
190
212
  * @type {Object}
191
213
  * @private
192
214
  * @memberof Meetings
193
215
  */
194
- this.reachability = null;
216
+ // @ts-ignore
217
+ this.reachability = new Reachability(this.webex);
195
218
 
196
219
  /**
197
220
  * If the meetings plugin has been registered and listening via {@link Meetings#register}
@@ -221,30 +244,137 @@ export default class Meetings extends WebexPlugin {
221
244
  */
222
245
  this.media = {
223
246
  getUserMedia: Media.getUserMedia,
224
- getSupportedDevice: Media.getSupportedDevice,
225
247
  };
226
248
 
227
249
  this.onReady();
228
250
  }
229
251
 
230
252
  /**
231
- * handle locus events and takes meeting actions with them as they come in
253
+ * check whether you need to handle this main session's locus data or not
254
+ * @param {Object} meeting current meeting data
255
+ * @param {Object} newLocus new locus data
256
+ * @returns {boolean}
257
+ * @private
258
+ * @memberof Meetings
259
+ */
260
+ private isNeedHandleMainLocus(meeting: any, newLocus: any) {
261
+ const breakoutUrl = newLocus.controls?.breakout?.url;
262
+ const breakoutLocus = this.meetingCollection.getActiveBreakoutLocus(breakoutUrl);
263
+
264
+ const isSelfJoined = newLocus?.self?.state === _JOINED_;
265
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
266
+ // @ts-ignore
267
+ const deviceFromNewLocus = MeetingsUtil.getThisDevice(newLocus, this.webex.internal.device.url);
268
+ const isResourceMovedOnThisDevice =
269
+ deviceFromNewLocus?.state === _LEFT_ && deviceFromNewLocus?.reason === _MOVED_;
270
+
271
+ const isNewLocusJoinThisDevice = MeetingsUtil.joinedOnThisDevice(
272
+ meeting,
273
+ newLocus,
274
+ // @ts-ignore
275
+ this.webex.internal.device.url
276
+ );
277
+ const isBreakoutLocusJoinThisDevice =
278
+ breakoutLocus?.joinedWith?.correlationId &&
279
+ breakoutLocus.joinedWith.correlationId === meeting?.correlationId;
280
+
281
+ if (isSelfJoined && isNewLocusJoinThisDevice) {
282
+ LoggerProxy.logger.log(
283
+ 'Meetings:index#isNeedHandleMainLocus --> self this device shown as JOINED in the main session'
284
+ );
285
+ if (breakoutLocus?.joinedWith && deviceFromNewLocus) {
286
+ const breakoutReplaceAt =
287
+ breakoutLocus.joinedWith.replaces?.length > 0
288
+ ? breakoutLocus.joinedWith.replaces[0].replaceAt
289
+ : '';
290
+ const newLocusReplaceAt =
291
+ deviceFromNewLocus.replaces?.length > 0 ? deviceFromNewLocus.replaces[0].replaceAt : '';
292
+ if (breakoutReplaceAt && newLocusReplaceAt && breakoutReplaceAt > newLocusReplaceAt) {
293
+ LoggerProxy.logger.log(
294
+ `Meetings:index#isNeedHandleMainLocus --> this is expired main joined status locus_dto replacedAt ${newLocusReplaceAt} bo replacedAt ${breakoutReplaceAt}`
295
+ );
296
+
297
+ return false;
298
+ }
299
+ }
300
+
301
+ return true;
302
+ }
303
+ if (isBreakoutLocusJoinThisDevice) {
304
+ LoggerProxy.logger.log(
305
+ `Meetings:index#isNeedHandleMainLocus --> there is active breakout session and joined on this device, and don't need to handle main session: ${breakoutUrl}`
306
+ );
307
+
308
+ return false;
309
+ }
310
+ if (isSelfMoved && (newLocus?.self?.removed || isResourceMovedOnThisDevice)) {
311
+ LoggerProxy.logger.log(
312
+ 'Meetings:index#isNeedHandleMainLocus --> self moved main locus with self removed status or with device resource moved, not need to handle'
313
+ );
314
+
315
+ return false;
316
+ }
317
+ if (isSelfJoined && isResourceMovedOnThisDevice) {
318
+ LoggerProxy.logger.log(
319
+ 'Meetings:index#isNeedHandleMainLocus --> self device left&moved in main locus with self joined status, not need to handle'
320
+ );
321
+
322
+ return false;
323
+ }
324
+ LoggerProxy.logger.log(
325
+ 'Meetings:index#isNeedHandleMainLocus --> this is a normal main session locusDTO update case'
326
+ );
327
+
328
+ return true;
329
+ }
330
+
331
+ /**
332
+ * check whether you need to handle this locus data or not
333
+ * @param {Object} meeting old locus data
334
+ * @param {Object} newLocus new locus data
335
+ * @returns {boolean}
336
+ * @private
337
+ * @memberof Meetings
338
+ */
339
+ private isNeedHandleLocusDTO(meeting: any, newLocus: any) {
340
+ if (newLocus) {
341
+ const isNewLocusAsBreakout = MeetingsUtil.isBreakoutLocusDTO(newLocus);
342
+ const isSelfMoved = newLocus?.self?.state === _LEFT_ && newLocus?.self?.reason === _MOVED_;
343
+ if (!meeting) {
344
+ if (isNewLocusAsBreakout) {
345
+ LoggerProxy.logger.log(
346
+ `Meetings:index#isNeedHandleLocusDTO --> the first breakout session locusDTO active status: ${newLocus.fullState?.active}`
347
+ );
348
+
349
+ return newLocus.self?.state === _JOINED_;
350
+ }
351
+
352
+ return this.isNeedHandleMainLocus(meeting, newLocus);
353
+ }
354
+ if (!isNewLocusAsBreakout) {
355
+ return this.isNeedHandleMainLocus(meeting, newLocus);
356
+ }
357
+
358
+ return !isSelfMoved;
359
+ }
360
+
361
+ return true;
362
+ }
363
+
364
+ /**
365
+ * get corresponding meeting object by locus data
232
366
  * @param {Object} data a locus event
233
367
  * @param {String} data.locusUrl
234
368
  * @param {Object} data.locus
235
- * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
236
- * @param {String} data.eventType
237
- * @returns {undefined}
369
+ * @returns {Object}
238
370
  * @private
239
371
  * @memberof Meetings
240
372
  */
241
- private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
242
- let meeting = null;
243
-
373
+ getCorrespondingMeetingByLocus(data) {
244
374
  // getting meeting by correlationId. This will happen for the new event
245
375
  // Either the locus
246
376
  // TODO : Add check for the callBack Address
247
- meeting =
377
+ return (
248
378
  this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
249
379
  // @ts-ignore
250
380
  this.meetingCollection.getByKey(
@@ -260,7 +390,24 @@ export default class Meetings extends WebexPlugin {
260
390
  ) ||
261
391
  (data.locus.info?.isUnifiedSpaceMeeting
262
392
  ? undefined
263
- : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl));
393
+ : this.meetingCollection.getByKey(CONVERSATION_URL, data.locus.conversationUrl)) ||
394
+ this.meetingCollection.getByKey(MEETINGNUMBER, data.locus?.info?.webExMeetingId)
395
+ );
396
+ }
397
+
398
+ /**
399
+ * handle locus events and takes meeting actions with them as they come in
400
+ * @param {Object} data a locus event
401
+ * @param {String} data.locusUrl
402
+ * @param {Object} data.locus
403
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
404
+ * @param {String} data.eventType
405
+ * @returns {undefined}
406
+ * @private
407
+ * @memberof Meetings
408
+ */
409
+ private handleLocusEvent(data: {locusUrl: string; locus: any}, useRandomDelayForInfo = false) {
410
+ let meeting = this.getCorrespondingMeetingByLocus(data);
264
411
 
265
412
  // Special case when locus has got replaced, This only happend once if a replace locus exists
266
413
  // https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
@@ -273,6 +420,16 @@ export default class Meetings extends WebexPlugin {
273
420
  );
274
421
  }
275
422
 
423
+ if (meeting && !MeetingsUtil.isBreakoutLocusDTO(data.locus)) {
424
+ meeting.locusInfo.updateMainSessionLocusCache(data.locus);
425
+ }
426
+ if (!this.isNeedHandleLocusDTO(meeting, data.locus)) {
427
+ LoggerProxy.logger.log(
428
+ `Meetings:index#handleLocusEvent --> doesn't need to process locus event`
429
+ );
430
+
431
+ return;
432
+ }
276
433
  if (!meeting) {
277
434
  // TODO: create meeting when we get a meeting object
278
435
  // const checkForEnded = (locus) => {
@@ -329,6 +486,7 @@ export default class Meetings extends WebexPlugin {
329
486
 
330
487
  // It's a new meeting so initialize the locus data
331
488
  meeting.locusInfo.initialSetup(data.locus);
489
+ this.checkHandleBreakoutLocus(data.locus);
332
490
  })
333
491
  .catch((e) => {
334
492
  LoggerProxy.logger.error(e);
@@ -338,10 +496,15 @@ export default class Meetings extends WebexPlugin {
338
496
  // because the other user left so before sending 'added' event make sure it exists in the collection
339
497
 
340
498
  if (this.getMeetingByType(_ID_, meeting.id)) {
341
- Metrics.postEvent({
342
- event: eventType.REMOTE_STARTED,
343
- meeting,
344
- data: {trigger: trigger.MERCURY_EVENT},
499
+ // @ts-ignore
500
+ this.webex.internal.newMetrics.submitClientEvent({
501
+ name: 'client.call.remote-started',
502
+ payload: {
503
+ trigger: 'mercury-event',
504
+ },
505
+ options: {
506
+ meetingId: meeting.id,
507
+ },
345
508
  });
346
509
  Trigger.trigger(
347
510
  this,
@@ -494,7 +657,7 @@ export default class Meetings extends WebexPlugin {
494
657
 
495
658
  MeetingsUtil.checkH264Support({disableNotifications: true});
496
659
  // @ts-ignore
497
- Metrics.initialSetup(this.meetingCollection, this.webex);
660
+ Metrics.initialSetup(this.webex);
498
661
  });
499
662
  }
500
663
 
@@ -518,21 +681,6 @@ export default class Meetings extends WebexPlugin {
518
681
  }
519
682
  }
520
683
 
521
- /**
522
- * API to enable or disable TURN discovery
523
- * @param {Boolean} enable
524
- * @private
525
- * @memberof Meetings
526
- * @returns {undefined}
527
- */
528
- private _toggleTurnDiscovery(enable: boolean) {
529
- if (typeof enable !== 'boolean') {
530
- return;
531
- }
532
- // @ts-ignore
533
- this.config.experimental.enableTurnDiscovery = enable;
534
- }
535
-
536
684
  /**
537
685
  * API to toggle starting adhoc meeting
538
686
  * @param {Boolean} changeState
@@ -663,6 +811,36 @@ export default class Meetings extends WebexPlugin {
663
811
  );
664
812
  }
665
813
 
814
+ /**
815
+ * Creates a noise reduction effect
816
+ *
817
+ * @param {INoiseReductionEffect} options optional custom effect options
818
+ * @returns {Promise<effect>} noise reduction effect.
819
+ * @public
820
+ * @memberof Meetings
821
+ */
822
+ createNoiseReductionEffect = async (options?: INoiseReductionEffect) => {
823
+ // @ts-ignore
824
+ const authToken = this.webex.credentials.supertoken.access_token;
825
+
826
+ return new mediaHelpersModule.NoiseReductionEffect({authToken, ...options});
827
+ };
828
+
829
+ /**
830
+ * Creates a virtual background effect
831
+ *
832
+ * @param {IVirtualBackgroundEffect} options optional custom effect options
833
+ * @returns {Promise<effect>} virtual background effect.
834
+ * @public
835
+ * @memberof Meetings
836
+ */
837
+ createVirtualBackgroundEffect = async (options?: IVirtualBackgroundEffect) => {
838
+ // @ts-ignore
839
+ const authToken = this.webex.credentials.supertoken.access_token;
840
+
841
+ return new mediaHelpersModule.VirtualBackgroundEffect({authToken, ...options});
842
+ };
843
+
666
844
  /**
667
845
  * Uploads logs to the webex services for tracking
668
846
  * @param {Object} [options={}]
@@ -677,8 +855,10 @@ export default class Meetings extends WebexPlugin {
677
855
  */
678
856
  uploadLogs(
679
857
  options: {
858
+ autoupload?: boolean;
680
859
  callStart?: string;
681
860
  feedbackId?: string;
861
+ locussessionid?: string;
682
862
  locusId?: string;
683
863
  correlationId?: string;
684
864
  meetingId?: string;
@@ -695,6 +875,7 @@ export default class Meetings extends WebexPlugin {
695
875
  'Meetings:index#uploadLogs --> Upload logs for meeting completed.',
696
876
  uploadResult
697
877
  );
878
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_SUCCESS, options);
698
879
  Trigger.trigger(
699
880
  this,
700
881
  {
@@ -729,8 +910,7 @@ export default class Meetings extends WebexPlugin {
729
910
  );
730
911
 
731
912
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_FAILURE, {
732
- // @ts-ignore - seems like typo
733
- meetingId: options.meetingsId,
913
+ ...options,
734
914
  reason: uploadError.message,
735
915
  stack: uploadError.stack,
736
916
  code: uploadError.code,
@@ -738,17 +918,6 @@ export default class Meetings extends WebexPlugin {
738
918
  });
739
919
  }
740
920
 
741
- /**
742
- * initializes the reachability instance for Meetings
743
- * @returns {undefined}
744
- * @public
745
- * @memberof Meetings
746
- */
747
- setReachability() {
748
- // @ts-ignore
749
- this.reachability = new Reachability(this.webex);
750
- }
751
-
752
921
  /**
753
922
  * gets the reachability instance for Meetings
754
923
  * @returns {Reachability}
@@ -766,10 +935,6 @@ export default class Meetings extends WebexPlugin {
766
935
  * @memberof Meetings
767
936
  */
768
937
  startReachability() {
769
- if (!this.reachability) {
770
- this.setReachability();
771
- }
772
-
773
938
  return this.getReachability().gatherReachability();
774
939
  }
775
940
 
@@ -797,6 +962,29 @@ export default class Meetings extends WebexPlugin {
797
962
  if (res) {
798
963
  this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
799
964
  }
965
+
966
+ // fall back to getting the preferred site from the user information
967
+ if (!this.preferredWebexSite) {
968
+ // @ts-ignore
969
+ return this.webex.internal.user
970
+ .get()
971
+ .then((user) => {
972
+ const preferredWebexSite =
973
+ user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
974
+ if (preferredWebexSite) {
975
+ this.preferredWebexSite = preferredWebexSite;
976
+ } else {
977
+ throw new Error('site not found');
978
+ }
979
+ })
980
+ .catch(() => {
981
+ LoggerProxy.logger.error(
982
+ 'Failed to fetch preferred site from user - no site will be set'
983
+ );
984
+ });
985
+ }
986
+
987
+ return Promise.resolve();
800
988
  });
801
989
  }
802
990
 
@@ -838,14 +1026,24 @@ export default class Meetings extends WebexPlugin {
838
1026
 
839
1027
  /**
840
1028
  * Create a meeting.
841
- * @param {string} destination - sipURL, spaceId, phonenumber, or locus object}
1029
+ * @param {string} destination - sipURL, phonenumber, or locus object}
842
1030
  * @param {string} [type] - the optional specified type, such as locusId
843
1031
  * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
1032
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1033
+ * @param {string} correlationId - the optional specified correlationId
1034
+ * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
844
1035
  * @returns {Promise<Meeting>} A new Meeting.
845
1036
  * @public
846
1037
  * @memberof Meetings
847
1038
  */
848
- public create(destination: string, type: string = null, useRandomDelayForInfo = false) {
1039
+ public create(
1040
+ destination: string,
1041
+ type: string = null,
1042
+ useRandomDelayForInfo = false,
1043
+ infoExtraParams = {},
1044
+ correlationId: string = undefined,
1045
+ failOnMissingMeetingInfo = false
1046
+ ) {
849
1047
  // TODO: type should be from a dictionary
850
1048
 
851
1049
  // Validate meeting information based on the provided destination and
@@ -857,9 +1055,12 @@ export default class Meetings extends WebexPlugin {
857
1055
  .fetchInfoOptions(destination, type)
858
1056
  // Catch a failure to fetch info options.
859
1057
  .catch((error) => {
860
- LoggerProxy.logger.info(
861
- `Meetings:index#create --> INFO, unable to determine info options: ${error.message}`
1058
+ LoggerProxy.logger.error(
1059
+ `Meetings:index#create --> ERROR, unable to determine info options: ${error.message}`
862
1060
  );
1061
+ if (error instanceof SpaceIDDeprecatedError) {
1062
+ throw new SpaceIDDeprecatedError();
1063
+ }
863
1064
  })
864
1065
  .then((options: any = {}) => {
865
1066
  // Normalize the destination.
@@ -890,48 +1091,57 @@ export default class Meetings extends WebexPlugin {
890
1091
  // Validate if a meeting was found.
891
1092
  if (!meeting) {
892
1093
  // Create a meeting based on the normalized destination and type.
893
- return this.createMeeting(targetDest, type, useRandomDelayForInfo).then(
894
- (createdMeeting: any) => {
895
- // If the meeting was successfully created.
896
- if (createdMeeting && createdMeeting.on) {
897
- // Create a destruction event for the meeting.
898
- createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
899
- // @ts-ignore
900
- if (this.config.autoUploadLogs) {
901
- this.uploadLogs({
902
- callStart: createdMeeting.locusInfo?.fullState?.lastActive,
903
- correlationId: createdMeeting.correlationId,
904
- feedbackId: createdMeeting.correlationId,
905
- locusId: createdMeeting.locusId,
906
- meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
907
- }).then(() => this.destroy(createdMeeting, payload.reason));
908
- } else {
909
- this.destroy(createdMeeting, payload.reason);
910
- }
911
- });
912
-
913
- createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
914
- // @ts-ignore
915
- if (this.config.autoUploadLogs) {
916
- this.uploadLogs({
917
- callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
918
- correlationId: meetingInstance.correlationId,
919
- feedbackId: meetingInstance.correlationId,
920
- locusId: meetingInstance.locusId,
921
- meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
922
- });
923
- }
924
- });
925
- } else {
926
- LoggerProxy.logger.error(
927
- `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
928
- );
929
- }
930
-
931
- // Return the newly created meeting.
932
- return Promise.resolve(createdMeeting);
1094
+ return this.createMeeting(
1095
+ targetDest,
1096
+ type,
1097
+ useRandomDelayForInfo,
1098
+ infoExtraParams,
1099
+ correlationId,
1100
+ failOnMissingMeetingInfo
1101
+ ).then((createdMeeting: any) => {
1102
+ // If the meeting was successfully created.
1103
+ if (createdMeeting && createdMeeting.on) {
1104
+ // Create a destruction event for the meeting.
1105
+ createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
1106
+ // @ts-ignore
1107
+ if (this.config.autoUploadLogs) {
1108
+ this.uploadLogs({
1109
+ callStart: createdMeeting.locusInfo?.fullState?.lastActive,
1110
+ locussessionid: createdMeeting.locusInfo?.fullState?.sessionId,
1111
+ correlationId: createdMeeting.correlationId,
1112
+ feedbackId: createdMeeting.correlationId,
1113
+ locusId: createdMeeting.locusId,
1114
+ meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
1115
+ autoupload: true,
1116
+ }).then(() => this.destroy(createdMeeting, payload.reason));
1117
+ } else {
1118
+ this.destroy(createdMeeting, payload.reason);
1119
+ }
1120
+ });
1121
+
1122
+ createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
1123
+ // @ts-ignore
1124
+ if (this.config.autoUploadLogs) {
1125
+ this.uploadLogs({
1126
+ callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
1127
+ locussessionid: meetingInstance?.locusInfo?.fullState?.sessionId,
1128
+ correlationId: meetingInstance.correlationId,
1129
+ feedbackId: meetingInstance.correlationId,
1130
+ locusId: meetingInstance.locusId,
1131
+ meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
1132
+ autoupload: true,
1133
+ });
1134
+ }
1135
+ });
1136
+ } else {
1137
+ LoggerProxy.logger.error(
1138
+ `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
1139
+ );
933
1140
  }
934
- );
1141
+
1142
+ // Return the newly created meeting.
1143
+ return Promise.resolve(createdMeeting);
1144
+ });
935
1145
  }
936
1146
 
937
1147
  // Return the existing meeting.
@@ -944,6 +1154,9 @@ export default class Meetings extends WebexPlugin {
944
1154
  * @param {String} destination see create()
945
1155
  * @param {String} type see create()
946
1156
  * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1157
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1158
+ * @param {String} correlationId the optional specified correlationId
1159
+ * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
947
1160
  * @returns {Promise} a new meeting instance complete with meeting info and destination
948
1161
  * @private
949
1162
  * @memberof Meetings
@@ -951,7 +1164,10 @@ export default class Meetings extends WebexPlugin {
951
1164
  private async createMeeting(
952
1165
  destination: any,
953
1166
  type: string = null,
954
- useRandomDelayForInfo = false
1167
+ useRandomDelayForInfo = false,
1168
+ infoExtraParams = {},
1169
+ correlationId: string = undefined,
1170
+ failOnMissingMeetingInfo = false
955
1171
  ) {
956
1172
  const meeting = new Meeting(
957
1173
  {
@@ -965,6 +1181,7 @@ export default class Meetings extends WebexPlugin {
965
1181
  meetingInfoProvider: this.meetingInfo,
966
1182
  destination,
967
1183
  destinationType: type,
1184
+ correlationId,
968
1185
  },
969
1186
  {
970
1187
  // @ts-ignore
@@ -999,19 +1216,38 @@ export default class Meetings extends WebexPlugin {
999
1216
 
1000
1217
  if (enableUnifiedMeetings && !isMeetingActive && useRandomDelayForInfo && waitingTime > 0) {
1001
1218
  meeting.fetchMeetingInfoTimeoutId = setTimeout(
1002
- () => meeting.fetchMeetingInfo({}),
1219
+ () =>
1220
+ meeting.fetchMeetingInfo({
1221
+ extraParams: infoExtraParams,
1222
+ sendCAevents: !!correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
1223
+ }),
1003
1224
  waitingTime
1004
1225
  );
1005
1226
  meeting.parseMeetingInfo(undefined, destination);
1006
1227
  } else {
1007
- await meeting.fetchMeetingInfo({});
1228
+ await meeting.fetchMeetingInfo({
1229
+ extraParams: infoExtraParams,
1230
+ sendCAevents: !!correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
1231
+ });
1008
1232
  }
1009
1233
  } catch (err) {
1010
- if (!(err instanceof CaptchaError) && !(err instanceof PasswordError)) {
1011
- // if there is no meeting info we assume its a 1:1 call or wireless share
1234
+ if (
1235
+ !(err instanceof CaptchaError) &&
1236
+ !(err instanceof PasswordError) &&
1237
+ !(err instanceof PermissionError)
1238
+ ) {
1012
1239
  LoggerProxy.logger.info(
1013
1240
  `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
1014
1241
  );
1242
+ if (failOnMissingMeetingInfo) {
1243
+ LoggerProxy.logger.info(
1244
+ `Meetings:index#createMeeting --> Destroying meeting due to missing meeting info.`
1245
+ );
1246
+ // @ts-ignore
1247
+ this.destroy(meeting, MEETING_REMOVED_REASON.MISSING_MEETING_INFO);
1248
+ throw new NoMeetingInfoError();
1249
+ }
1250
+ // if there is no meeting info and no error should be thrown then we assume its a 1:1 call or wireless share
1015
1251
  LoggerProxy.logger.info(
1016
1252
  'Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share'
1017
1253
  );
@@ -1064,7 +1300,7 @@ export default class Meetings extends WebexPlugin {
1064
1300
  //
1065
1301
  // Our job is to determine the appropriate one
1066
1302
  // and its corresponding service so that developers
1067
- // need only sipURL or spaceID to get a meeting
1303
+ // need only sipURL to get a meeting
1068
1304
  // and its ID, but have the option to use createWithType()
1069
1305
  // and specify those types to get meetingInfo
1070
1306
  }
@@ -1108,33 +1344,108 @@ export default class Meetings extends WebexPlugin {
1108
1344
  * @memberof Meetings
1109
1345
  */
1110
1346
  public syncMeetings() {
1111
- return this.request.getActiveMeetings().then((locusArray) => {
1112
- const activeLocusUrl = [];
1113
-
1114
- if (locusArray?.loci && locusArray.loci.length > 0) {
1115
- locusArray.loci.forEach((locus) => {
1116
- activeLocusUrl.push(locus.url);
1117
- this.handleLocusEvent({
1118
- locus,
1119
- locusUrl: locus.url,
1347
+ return this.request
1348
+ .getActiveMeetings()
1349
+ .then((locusArray) => {
1350
+ const activeLocusUrl = [];
1351
+
1352
+ if (locusArray?.loci && locusArray.loci.length > 0) {
1353
+ const lociToUpdate = this.sortLocusArrayToUpdate(locusArray.loci);
1354
+ lociToUpdate.forEach((locus) => {
1355
+ activeLocusUrl.push(locus.url);
1356
+ this.handleLocusEvent({
1357
+ locus,
1358
+ locusUrl: locus.url,
1359
+ });
1120
1360
  });
1121
- });
1122
- }
1123
- const meetingsCollection = this.meetingCollection.getAll();
1361
+ }
1362
+ const meetingsCollection = this.meetingCollection.getAll();
1124
1363
 
1125
- if (Object.keys(meetingsCollection).length > 0) {
1126
- // Some time the mercury event is missed after mercury reconnect
1127
- // if sync returns no locus then clear all the meetings
1128
- for (const meeting of Object.values(meetingsCollection)) {
1129
- // @ts-ignore
1130
- if (!activeLocusUrl.includes(meeting.locusUrl)) {
1131
- // destroy function also uploads logs
1364
+ if (Object.keys(meetingsCollection).length > 0) {
1365
+ // Some time the mercury event is missed after mercury reconnect
1366
+ // if sync returns no locus then clear all the meetings
1367
+ for (const meeting of Object.values(meetingsCollection)) {
1132
1368
  // @ts-ignore
1133
- this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1369
+ if (!activeLocusUrl.includes(meeting.locusUrl)) {
1370
+ // destroy function also uploads logs
1371
+ // @ts-ignore
1372
+ this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1373
+ }
1134
1374
  }
1135
1375
  }
1376
+ })
1377
+ .catch((error) => {
1378
+ LoggerProxy.logger.error(
1379
+ `Meetings:index#syncMeetings --> failed to sync meetings, ${error}`
1380
+ );
1381
+ throw new Error(error);
1382
+ });
1383
+ }
1384
+
1385
+ /**
1386
+ * sort out locus array for initial creating
1387
+ * @param {Array} loci original locus array
1388
+ * @returns {undefined}
1389
+ * @public
1390
+ * @memberof Meetings
1391
+ */
1392
+ sortLocusArrayToUpdate(loci: any[]) {
1393
+ const mainLoci = loci.filter((locus) => !MeetingsUtil.isBreakoutLocusDTO(locus));
1394
+ const breakoutLoci = loci.filter((locus) => MeetingsUtil.isValidBreakoutLocus(locus));
1395
+ this.breakoutLocusForHandleLater = [];
1396
+ const lociToUpdate = [...mainLoci];
1397
+ breakoutLoci.forEach((breakoutLocus) => {
1398
+ const associateMainLocus = mainLoci.find(
1399
+ (mainLocus) => mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url
1400
+ );
1401
+ const existCorrespondingMeeting = this.getCorrespondingMeetingByLocus({
1402
+ locus: breakoutLocus,
1403
+ locusUrl: breakoutLocus.url,
1404
+ });
1405
+
1406
+ if (associateMainLocus && !existCorrespondingMeeting) {
1407
+ // if exists both main session and breakout session locus of the same non-exist meeting, handle main locus first,
1408
+ // after meeting create with main locus, then handle the associate breakout locus.
1409
+ // if only handle breakout locus, will miss some date
1410
+ this.breakoutLocusForHandleLater.push(breakoutLocus);
1411
+ } else {
1412
+ lociToUpdate.push(breakoutLocus);
1136
1413
  }
1137
1414
  });
1415
+
1416
+ return lociToUpdate;
1417
+ }
1418
+
1419
+ /**
1420
+ * check breakout locus which waiting for main locus's meeting to be created, then handle the breakout locus
1421
+ * @param {Object} newCreatedLocus the locus which just create meeting object of it
1422
+ * @returns {undefined}
1423
+ * @public
1424
+ * @memberof Meetings
1425
+ */
1426
+ checkHandleBreakoutLocus(newCreatedLocus) {
1427
+ if (
1428
+ !newCreatedLocus ||
1429
+ !this.breakoutLocusForHandleLater ||
1430
+ !this.breakoutLocusForHandleLater.length
1431
+ ) {
1432
+ return;
1433
+ }
1434
+ if (MeetingsUtil.isBreakoutLocusDTO(newCreatedLocus)) {
1435
+ return;
1436
+ }
1437
+ const existIndex = this.breakoutLocusForHandleLater.findIndex(
1438
+ (breakoutLocus) =>
1439
+ breakoutLocus.controls?.breakout?.url === newCreatedLocus.controls?.breakout?.url
1440
+ );
1441
+
1442
+ if (existIndex < 0) {
1443
+ return;
1444
+ }
1445
+
1446
+ const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
1447
+ this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
1448
+ this.breakoutLocusForHandleLater.splice(existIndex, 1);
1138
1449
  }
1139
1450
 
1140
1451
  /**
@@ -1156,4 +1467,15 @@ export default class Meetings extends WebexPlugin {
1156
1467
  getLogger() {
1157
1468
  return LoggerProxy.get();
1158
1469
  }
1470
+
1471
+ /**
1472
+ * Returns the first meeting it finds that has the webrtc media connection created.
1473
+ * Useful for debugging in the console.
1474
+ *
1475
+ * @private
1476
+ * @returns {Meeting} Meeting object that has a webrtc media connection, else undefined
1477
+ */
1478
+ getActiveWebrtcMeeting() {
1479
+ return this.meetingCollection.getActiveWebrtcMeeting();
1480
+ }
1159
1481
  }