@webex/plugin-meetings 3.0.0-beta.4 → 3.0.0-beta.400

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 (629) hide show
  1. package/README.md +58 -8
  2. package/UPGRADING.md +9 -9
  3. package/browsers.js +19 -24
  4. package/dist/annotation/annotation.types.js +7 -0
  5. package/dist/annotation/annotation.types.js.map +1 -0
  6. package/dist/annotation/constants.js +49 -0
  7. package/dist/annotation/constants.js.map +1 -0
  8. package/dist/annotation/index.js +342 -0
  9. package/dist/annotation/index.js.map +1 -0
  10. package/dist/breakouts/breakout.js +216 -0
  11. package/dist/breakouts/breakout.js.map +1 -0
  12. package/dist/breakouts/collection.js +23 -0
  13. package/dist/breakouts/collection.js.map +1 -0
  14. package/dist/breakouts/edit-lock-error.js +52 -0
  15. package/dist/breakouts/edit-lock-error.js.map +1 -0
  16. package/dist/breakouts/events.js +45 -0
  17. package/dist/breakouts/events.js.map +1 -0
  18. package/dist/breakouts/index.js +1048 -0
  19. package/dist/breakouts/index.js.map +1 -0
  20. package/dist/breakouts/request.js +78 -0
  21. package/dist/breakouts/request.js.map +1 -0
  22. package/dist/breakouts/utils.js +67 -0
  23. package/dist/breakouts/utils.js.map +1 -0
  24. package/dist/common/browser-detection.js +1 -20
  25. package/dist/common/browser-detection.js.map +1 -1
  26. package/dist/common/collection.js +5 -20
  27. package/dist/common/collection.js.map +1 -1
  28. package/dist/common/config.js +0 -7
  29. package/dist/common/config.js.map +1 -1
  30. package/dist/common/errors/captcha-error.js +10 -24
  31. package/dist/common/errors/captcha-error.js.map +1 -1
  32. package/dist/common/errors/intent-to-join.js +11 -24
  33. package/dist/common/errors/intent-to-join.js.map +1 -1
  34. package/dist/common/errors/join-meeting.js +12 -25
  35. package/dist/common/errors/join-meeting.js.map +1 -1
  36. package/dist/common/errors/media.js +10 -24
  37. package/dist/common/errors/media.js.map +1 -1
  38. package/dist/common/errors/no-meeting-info.js +51 -0
  39. package/dist/common/errors/no-meeting-info.js.map +1 -0
  40. package/dist/common/errors/parameter.js +5 -33
  41. package/dist/common/errors/parameter.js.map +1 -1
  42. package/dist/common/errors/password-error.js +10 -24
  43. package/dist/common/errors/password-error.js.map +1 -1
  44. package/dist/common/errors/permission.js +9 -23
  45. package/dist/common/errors/permission.js.map +1 -1
  46. package/dist/common/errors/reclaim-host-role-errors.js +158 -0
  47. package/dist/common/errors/reclaim-host-role-errors.js.map +1 -0
  48. package/dist/common/errors/reconnection-in-progress.js +0 -17
  49. package/dist/common/errors/reconnection-in-progress.js.map +1 -1
  50. package/dist/common/errors/reconnection.js +10 -24
  51. package/dist/common/errors/reconnection.js.map +1 -1
  52. package/dist/common/errors/stats.js +10 -24
  53. package/dist/common/errors/stats.js.map +1 -1
  54. package/dist/common/errors/webex-errors.js +54 -48
  55. package/dist/common/errors/webex-errors.js.map +1 -1
  56. package/dist/common/errors/webex-meetings-error.js +5 -25
  57. package/dist/common/errors/webex-meetings-error.js.map +1 -1
  58. package/dist/common/events/events-scope.js +0 -22
  59. package/dist/common/events/events-scope.js.map +1 -1
  60. package/dist/common/events/events.js +0 -23
  61. package/dist/common/events/events.js.map +1 -1
  62. package/dist/common/events/trigger-proxy.js +0 -12
  63. package/dist/common/events/trigger-proxy.js.map +1 -1
  64. package/dist/common/events/util.js +0 -15
  65. package/dist/common/events/util.js.map +1 -1
  66. package/dist/common/logs/logger-config.js +0 -4
  67. package/dist/common/logs/logger-config.js.map +1 -1
  68. package/dist/common/logs/logger-proxy.js +1 -8
  69. package/dist/common/logs/logger-proxy.js.map +1 -1
  70. package/dist/common/logs/request.js +41 -60
  71. package/dist/common/logs/request.js.map +1 -1
  72. package/dist/common/queue.js +28 -23
  73. package/dist/common/queue.js.map +1 -1
  74. package/dist/config.js +11 -15
  75. package/dist/config.js.map +1 -1
  76. package/dist/constants.js +347 -74
  77. package/dist/constants.js.map +1 -1
  78. package/dist/controls-options-manager/constants.js +14 -0
  79. package/dist/controls-options-manager/constants.js.map +1 -0
  80. package/dist/controls-options-manager/enums.js +27 -0
  81. package/dist/controls-options-manager/enums.js.map +1 -0
  82. package/dist/controls-options-manager/index.js +297 -0
  83. package/dist/controls-options-manager/index.js.map +1 -0
  84. package/dist/controls-options-manager/types.js +7 -0
  85. package/dist/controls-options-manager/types.js.map +1 -0
  86. package/dist/controls-options-manager/util.js +319 -0
  87. package/dist/controls-options-manager/util.js.map +1 -0
  88. package/dist/index.js +125 -18
  89. package/dist/index.js.map +1 -1
  90. package/dist/interceptors/index.js +15 -0
  91. package/dist/interceptors/index.js.map +1 -0
  92. package/dist/interceptors/locusRetry.js +93 -0
  93. package/dist/interceptors/locusRetry.js.map +1 -0
  94. package/dist/interpretation/collection.js +23 -0
  95. package/dist/interpretation/collection.js.map +1 -0
  96. package/dist/interpretation/index.js +380 -0
  97. package/dist/interpretation/index.js.map +1 -0
  98. package/dist/interpretation/siLanguage.js +25 -0
  99. package/dist/interpretation/siLanguage.js.map +1 -0
  100. package/dist/locus-info/controlsUtils.js +101 -29
  101. package/dist/locus-info/controlsUtils.js.map +1 -1
  102. package/dist/locus-info/embeddedAppsUtils.js +3 -26
  103. package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
  104. package/dist/locus-info/fullState.js +0 -15
  105. package/dist/locus-info/fullState.js.map +1 -1
  106. package/dist/locus-info/hostUtils.js +4 -12
  107. package/dist/locus-info/hostUtils.js.map +1 -1
  108. package/dist/locus-info/index.js +564 -246
  109. package/dist/locus-info/index.js.map +1 -1
  110. package/dist/locus-info/infoUtils.js +10 -38
  111. package/dist/locus-info/infoUtils.js.map +1 -1
  112. package/dist/locus-info/mediaSharesUtils.js +82 -38
  113. package/dist/locus-info/mediaSharesUtils.js.map +1 -1
  114. package/dist/locus-info/parser.js +314 -163
  115. package/dist/locus-info/parser.js.map +1 -1
  116. package/dist/locus-info/selfUtils.js +110 -92
  117. package/dist/locus-info/selfUtils.js.map +1 -1
  118. package/dist/media/index.js +107 -231
  119. package/dist/media/index.js.map +1 -1
  120. package/dist/media/properties.js +137 -222
  121. package/dist/media/properties.js.map +1 -1
  122. package/dist/media/util.js +2 -9
  123. package/dist/media/util.js.map +1 -1
  124. package/dist/mediaQualityMetrics/config.js +316 -501
  125. package/dist/mediaQualityMetrics/config.js.map +1 -1
  126. package/dist/meeting/in-meeting-actions.js +97 -14
  127. package/dist/meeting/in-meeting-actions.js.map +1 -1
  128. package/dist/meeting/index.js +5311 -3871
  129. package/dist/meeting/index.js.map +1 -1
  130. package/dist/meeting/locusMediaRequest.js +292 -0
  131. package/dist/meeting/locusMediaRequest.js.map +1 -0
  132. package/dist/meeting/muteState.js +260 -183
  133. package/dist/meeting/muteState.js.map +1 -1
  134. package/dist/meeting/request.js +421 -347
  135. package/dist/meeting/request.js.map +1 -1
  136. package/dist/meeting/request.type.js +7 -0
  137. package/dist/meeting/request.type.js.map +1 -0
  138. package/dist/meeting/state.js +21 -31
  139. package/dist/meeting/state.js.map +1 -1
  140. package/dist/meeting/util.js +672 -585
  141. package/dist/meeting/util.js.map +1 -1
  142. package/dist/meeting/voicea-meeting.js +172 -0
  143. package/dist/meeting/voicea-meeting.js.map +1 -0
  144. package/dist/meeting-info/collection.js +6 -25
  145. package/dist/meeting-info/collection.js.map +1 -1
  146. package/dist/meeting-info/index.js +87 -39
  147. package/dist/meeting-info/index.js.map +1 -1
  148. package/dist/meeting-info/meeting-info-v2.js +352 -283
  149. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  150. package/dist/meeting-info/request.js +3 -15
  151. package/dist/meeting-info/request.js.map +1 -1
  152. package/dist/meeting-info/util.js +99 -183
  153. package/dist/meeting-info/util.js.map +1 -1
  154. package/dist/meeting-info/utilv2.js +147 -234
  155. package/dist/meeting-info/utilv2.js.map +1 -1
  156. package/dist/meetings/collection.js +43 -19
  157. package/dist/meetings/collection.js.map +1 -1
  158. package/dist/meetings/index.js +895 -600
  159. package/dist/meetings/index.js.map +1 -1
  160. package/dist/meetings/meetings.types.js +7 -0
  161. package/dist/meetings/meetings.types.js.map +1 -0
  162. package/dist/meetings/request.js +26 -41
  163. package/dist/meetings/request.js.map +1 -1
  164. package/dist/meetings/util.js +184 -157
  165. package/dist/meetings/util.js.map +1 -1
  166. package/dist/member/index.js +134 -85
  167. package/dist/member/index.js.map +1 -1
  168. package/dist/member/types.js +25 -0
  169. package/dist/member/types.js.map +1 -0
  170. package/dist/member/util.js +158 -88
  171. package/dist/member/util.js.map +1 -1
  172. package/dist/members/collection.js +13 -12
  173. package/dist/members/collection.js.map +1 -1
  174. package/dist/members/index.js +194 -204
  175. package/dist/members/index.js.map +1 -1
  176. package/dist/members/request.js +113 -68
  177. package/dist/members/request.js.map +1 -1
  178. package/dist/members/types.js +15 -0
  179. package/dist/members/types.js.map +1 -0
  180. package/dist/members/util.js +324 -259
  181. package/dist/members/util.js.map +1 -1
  182. package/dist/metrics/constants.js +19 -7
  183. package/dist/metrics/constants.js.map +1 -1
  184. package/dist/metrics/index.js +11 -558
  185. package/dist/metrics/index.js.map +1 -1
  186. package/dist/multistream/mediaRequestManager.js +263 -50
  187. package/dist/multistream/mediaRequestManager.js.map +1 -1
  188. package/dist/multistream/receiveSlot.js +58 -65
  189. package/dist/multistream/receiveSlot.js.map +1 -1
  190. package/dist/multistream/receiveSlotManager.js +76 -95
  191. package/dist/multistream/receiveSlotManager.js.map +1 -1
  192. package/dist/multistream/remoteMedia.js +62 -76
  193. package/dist/multistream/remoteMedia.js.map +1 -1
  194. package/dist/multistream/remoteMediaGroup.js +82 -45
  195. package/dist/multistream/remoteMediaGroup.js.map +1 -1
  196. package/dist/multistream/remoteMediaManager.js +657 -448
  197. package/dist/multistream/remoteMediaManager.js.map +1 -1
  198. package/dist/multistream/sendSlotManager.js +255 -0
  199. package/dist/multistream/sendSlotManager.js.map +1 -0
  200. package/dist/networkQualityMonitor/index.js +40 -59
  201. package/dist/networkQualityMonitor/index.js.map +1 -1
  202. package/dist/personal-meeting-room/index.js +21 -45
  203. package/dist/personal-meeting-room/index.js.map +1 -1
  204. package/dist/personal-meeting-room/request.js +1 -31
  205. package/dist/personal-meeting-room/request.js.map +1 -1
  206. package/dist/personal-meeting-room/util.js +0 -13
  207. package/dist/personal-meeting-room/util.js.map +1 -1
  208. package/dist/reachability/clusterReachability.js +356 -0
  209. package/dist/reachability/clusterReachability.js.map +1 -0
  210. package/dist/reachability/index.js +297 -460
  211. package/dist/reachability/index.js.map +1 -1
  212. package/dist/reachability/request.js +20 -26
  213. package/dist/reachability/request.js.map +1 -1
  214. package/dist/reachability/util.js +29 -0
  215. package/dist/reachability/util.js.map +1 -0
  216. package/dist/reactions/constants.js +13 -0
  217. package/dist/reactions/constants.js.map +1 -0
  218. package/dist/reactions/reactions.js +109 -0
  219. package/dist/reactions/reactions.js.map +1 -0
  220. package/dist/reactions/reactions.type.js +36 -0
  221. package/dist/reactions/reactions.type.js.map +1 -0
  222. package/dist/reconnection-manager/index.js +413 -483
  223. package/dist/reconnection-manager/index.js.map +1 -1
  224. package/dist/recording-controller/enums.js +17 -0
  225. package/dist/recording-controller/enums.js.map +1 -0
  226. package/dist/recording-controller/index.js +362 -0
  227. package/dist/recording-controller/index.js.map +1 -0
  228. package/dist/recording-controller/util.js +64 -0
  229. package/dist/recording-controller/util.js.map +1 -0
  230. package/dist/roap/index.js +102 -86
  231. package/dist/roap/index.js.map +1 -1
  232. package/dist/roap/request.js +131 -135
  233. package/dist/roap/request.js.map +1 -1
  234. package/dist/roap/turnDiscovery.js +437 -116
  235. package/dist/roap/turnDiscovery.js.map +1 -1
  236. package/dist/rtcMetrics/constants.js +12 -0
  237. package/dist/rtcMetrics/constants.js.map +1 -0
  238. package/dist/rtcMetrics/index.js +179 -0
  239. package/dist/rtcMetrics/index.js.map +1 -0
  240. package/dist/statsAnalyzer/global.js +1 -95
  241. package/dist/statsAnalyzer/global.js.map +1 -1
  242. package/dist/statsAnalyzer/index.js +557 -583
  243. package/dist/statsAnalyzer/index.js.map +1 -1
  244. package/dist/statsAnalyzer/mqaUtil.js +326 -130
  245. package/dist/statsAnalyzer/mqaUtil.js.map +1 -1
  246. package/dist/transcription/index.js +22 -47
  247. package/dist/transcription/index.js.map +1 -1
  248. package/dist/types/annotation/annotation.types.d.ts +42 -0
  249. package/dist/types/annotation/constants.d.ts +31 -0
  250. package/dist/types/annotation/index.d.ts +117 -0
  251. package/dist/types/breakouts/breakout.d.ts +8 -0
  252. package/dist/types/breakouts/collection.d.ts +5 -0
  253. package/dist/types/breakouts/edit-lock-error.d.ts +15 -0
  254. package/dist/types/breakouts/events.d.ts +8 -0
  255. package/dist/types/breakouts/index.d.ts +5 -0
  256. package/dist/types/breakouts/request.d.ts +22 -0
  257. package/dist/types/breakouts/utils.d.ts +15 -0
  258. package/dist/types/common/browser-detection.d.ts +9 -0
  259. package/dist/types/common/collection.d.ts +48 -0
  260. package/dist/types/common/config.d.ts +2 -0
  261. package/dist/types/common/errors/captcha-error.d.ts +15 -0
  262. package/dist/types/common/errors/intent-to-join.d.ts +16 -0
  263. package/dist/types/common/errors/join-meeting.d.ts +17 -0
  264. package/dist/types/common/errors/media.d.ts +15 -0
  265. package/dist/types/common/errors/no-meeting-info.d.ts +14 -0
  266. package/dist/types/common/errors/parameter.d.ts +15 -0
  267. package/dist/types/common/errors/password-error.d.ts +15 -0
  268. package/dist/types/common/errors/permission.d.ts +14 -0
  269. package/dist/types/common/errors/reclaim-host-role-errors.d.ts +60 -0
  270. package/dist/types/common/errors/reconnection-in-progress.d.ts +9 -0
  271. package/dist/types/common/errors/reconnection.d.ts +15 -0
  272. package/dist/types/common/errors/stats.d.ts +15 -0
  273. package/dist/types/common/errors/webex-errors.d.ts +93 -0
  274. package/dist/types/common/errors/webex-meetings-error.d.ts +20 -0
  275. package/dist/types/common/events/events-scope.d.ts +17 -0
  276. package/dist/types/common/events/events.d.ts +12 -0
  277. package/dist/types/common/events/trigger-proxy.d.ts +2 -0
  278. package/dist/types/common/events/util.d.ts +2 -0
  279. package/dist/types/common/logs/logger-config.d.ts +2 -0
  280. package/dist/types/common/logs/logger-proxy.d.ts +2 -0
  281. package/dist/types/common/logs/request.d.ts +36 -0
  282. package/dist/types/common/queue.d.ts +34 -0
  283. package/dist/types/config.d.ts +72 -0
  284. package/dist/types/constants.d.ts +1088 -0
  285. package/dist/types/controls-options-manager/constants.d.ts +4 -0
  286. package/dist/types/controls-options-manager/enums.d.ts +15 -0
  287. package/dist/types/controls-options-manager/index.d.ts +136 -0
  288. package/dist/types/controls-options-manager/types.d.ts +43 -0
  289. package/dist/types/controls-options-manager/util.d.ts +1 -0
  290. package/dist/types/index.d.ts +7 -0
  291. package/dist/types/interceptors/index.d.ts +2 -0
  292. package/dist/types/interceptors/locusRetry.d.ts +27 -0
  293. package/dist/types/interpretation/collection.d.ts +5 -0
  294. package/dist/types/interpretation/index.d.ts +5 -0
  295. package/dist/types/interpretation/siLanguage.d.ts +5 -0
  296. package/dist/types/locus-info/controlsUtils.d.ts +2 -0
  297. package/dist/types/locus-info/embeddedAppsUtils.d.ts +2 -0
  298. package/dist/types/locus-info/fullState.d.ts +2 -0
  299. package/dist/types/locus-info/hostUtils.d.ts +2 -0
  300. package/dist/types/locus-info/index.d.ts +322 -0
  301. package/dist/types/locus-info/infoUtils.d.ts +2 -0
  302. package/dist/types/locus-info/mediaSharesUtils.d.ts +2 -0
  303. package/dist/types/locus-info/parser.d.ts +272 -0
  304. package/dist/types/locus-info/selfUtils.d.ts +2 -0
  305. package/dist/types/media/index.d.ts +34 -0
  306. package/dist/types/media/properties.d.ts +93 -0
  307. package/dist/types/media/util.d.ts +2 -0
  308. package/dist/types/mediaQualityMetrics/config.d.ts +241 -0
  309. package/dist/types/meeting/in-meeting-actions.d.ts +167 -0
  310. package/dist/types/meeting/index.d.ts +1824 -0
  311. package/dist/types/meeting/locusMediaRequest.d.ts +74 -0
  312. package/dist/types/meeting/muteState.d.ts +178 -0
  313. package/dist/types/meeting/request.d.ts +293 -0
  314. package/dist/types/meeting/request.type.d.ts +11 -0
  315. package/dist/types/meeting/state.d.ts +9 -0
  316. package/dist/types/meeting/util.d.ts +118 -0
  317. package/dist/types/meeting/voicea-meeting.d.ts +16 -0
  318. package/dist/types/meeting-info/collection.d.ts +20 -0
  319. package/dist/types/meeting-info/index.d.ts +69 -0
  320. package/dist/types/meeting-info/meeting-info-v2.d.ts +123 -0
  321. package/dist/types/meeting-info/request.d.ts +22 -0
  322. package/dist/types/meeting-info/util.d.ts +2 -0
  323. package/dist/types/meeting-info/utilv2.d.ts +2 -0
  324. package/dist/types/meetings/collection.d.ts +40 -0
  325. package/dist/types/meetings/index.d.ts +389 -0
  326. package/dist/types/meetings/meetings.types.d.ts +4 -0
  327. package/dist/types/meetings/request.d.ts +27 -0
  328. package/dist/types/meetings/util.d.ts +18 -0
  329. package/dist/types/member/index.d.ts +160 -0
  330. package/dist/types/member/types.d.ts +32 -0
  331. package/dist/types/member/util.d.ts +2 -0
  332. package/dist/types/members/collection.d.ts +29 -0
  333. package/dist/types/members/index.d.ts +353 -0
  334. package/dist/types/members/request.d.ts +114 -0
  335. package/dist/types/members/types.d.ts +25 -0
  336. package/dist/types/members/util.d.ts +215 -0
  337. package/dist/types/metrics/constants.d.ts +70 -0
  338. package/dist/types/metrics/index.d.ts +45 -0
  339. package/dist/types/multistream/mediaRequestManager.d.ts +120 -0
  340. package/dist/types/multistream/receiveSlot.d.ts +68 -0
  341. package/dist/types/multistream/receiveSlotManager.d.ts +56 -0
  342. package/dist/types/multistream/remoteMedia.d.ts +72 -0
  343. package/dist/types/multistream/remoteMediaGroup.d.ts +49 -0
  344. package/dist/types/multistream/remoteMediaManager.d.ts +301 -0
  345. package/dist/types/multistream/sendSlotManager.d.ts +70 -0
  346. package/dist/types/networkQualityMonitor/index.d.ts +70 -0
  347. package/dist/types/personal-meeting-room/index.d.ts +47 -0
  348. package/dist/types/personal-meeting-room/request.d.ts +14 -0
  349. package/dist/types/personal-meeting-room/util.d.ts +2 -0
  350. package/dist/types/reachability/clusterReachability.d.ts +109 -0
  351. package/dist/types/reachability/index.d.ts +105 -0
  352. package/dist/types/reachability/request.d.ts +39 -0
  353. package/dist/types/reachability/util.d.ts +8 -0
  354. package/dist/types/reactions/constants.d.ts +3 -0
  355. package/dist/types/reactions/reactions.d.ts +4 -0
  356. package/dist/types/reactions/reactions.type.d.ts +52 -0
  357. package/dist/types/reconnection-manager/index.d.ts +136 -0
  358. package/dist/types/recording-controller/enums.d.ts +7 -0
  359. package/dist/types/recording-controller/index.d.ts +207 -0
  360. package/dist/types/recording-controller/util.d.ts +14 -0
  361. package/dist/types/roap/index.d.ts +86 -0
  362. package/dist/types/roap/request.d.ts +39 -0
  363. package/dist/types/roap/turnDiscovery.d.ts +155 -0
  364. package/dist/types/rtcMetrics/constants.d.ts +4 -0
  365. package/dist/types/rtcMetrics/index.d.ts +61 -0
  366. package/dist/types/statsAnalyzer/global.d.ts +36 -0
  367. package/dist/types/statsAnalyzer/index.d.ts +217 -0
  368. package/dist/types/statsAnalyzer/mqaUtil.d.ts +48 -0
  369. package/dist/types/transcription/index.d.ts +64 -0
  370. package/dist/types/webinar/collection.d.ts +16 -0
  371. package/dist/types/webinar/index.d.ts +5 -0
  372. package/dist/webinar/collection.js +44 -0
  373. package/dist/webinar/collection.js.map +1 -0
  374. package/dist/webinar/index.js +69 -0
  375. package/dist/webinar/index.js.map +1 -0
  376. package/internal-README.md +7 -6
  377. package/package.json +30 -21
  378. package/src/annotation/annotation.types.ts +50 -0
  379. package/src/annotation/constants.ts +36 -0
  380. package/src/annotation/index.ts +328 -0
  381. package/src/breakouts/README.md +220 -0
  382. package/src/breakouts/breakout.ts +188 -0
  383. package/src/breakouts/collection.ts +19 -0
  384. package/src/breakouts/edit-lock-error.ts +25 -0
  385. package/src/breakouts/events.ts +56 -0
  386. package/src/breakouts/index.ts +925 -0
  387. package/src/breakouts/request.ts +55 -0
  388. package/src/breakouts/utils.ts +57 -0
  389. package/src/common/{browser-detection.js → browser-detection.ts} +9 -6
  390. package/src/common/collection.ts +9 -7
  391. package/src/common/{config.js → config.ts} +1 -1
  392. package/src/common/errors/{captcha-error.js → captcha-error.ts} +11 -7
  393. package/src/common/errors/{intent-to-join.js → intent-to-join.ts} +12 -7
  394. package/src/common/errors/{join-meeting.js → join-meeting.ts} +17 -8
  395. package/src/common/errors/{media.js → media.ts} +11 -7
  396. package/src/common/errors/no-meeting-info.ts +24 -0
  397. package/src/common/errors/parameter.ts +11 -7
  398. package/src/common/errors/{password-error.js → password-error.ts} +11 -7
  399. package/src/common/errors/{permission.js → permission.ts} +10 -6
  400. package/src/common/errors/reclaim-host-role-errors.ts +134 -0
  401. package/src/common/errors/{reconnection.js → reconnection.ts} +11 -7
  402. package/src/common/errors/{stats.js → stats.ts} +11 -7
  403. package/src/common/errors/{webex-errors.js → webex-errors.ts} +51 -8
  404. package/src/common/errors/{webex-meetings-error.js → webex-meetings-error.ts} +4 -2
  405. package/src/common/events/{events-scope.js → events-scope.ts} +6 -2
  406. package/src/common/events/{events.js → events.ts} +5 -1
  407. package/src/common/events/{trigger-proxy.js → trigger-proxy.ts} +9 -5
  408. package/src/common/events/{util.js → util.ts} +2 -3
  409. package/src/common/logs/{logger-config.js → logger-config.ts} +1 -2
  410. package/src/common/logs/logger-proxy.ts +44 -0
  411. package/src/common/logs/{request.js → request.ts} +26 -9
  412. package/src/common/queue.ts +22 -9
  413. package/src/{config.js → config.ts} +19 -21
  414. package/src/constants.ts +296 -27
  415. package/src/controls-options-manager/constants.ts +5 -0
  416. package/src/controls-options-manager/enums.ts +18 -0
  417. package/src/controls-options-manager/index.ts +278 -0
  418. package/src/controls-options-manager/types.ts +59 -0
  419. package/src/controls-options-manager/util.ts +300 -0
  420. package/src/index.ts +45 -0
  421. package/src/interceptors/index.ts +3 -0
  422. package/src/interceptors/locusRetry.ts +67 -0
  423. package/src/interpretation/README.md +60 -0
  424. package/src/interpretation/collection.ts +19 -0
  425. package/src/interpretation/index.ts +349 -0
  426. package/src/interpretation/siLanguage.ts +18 -0
  427. package/src/locus-info/controlsUtils.ts +222 -0
  428. package/src/locus-info/{embeddedAppsUtils.js → embeddedAppsUtils.ts} +5 -6
  429. package/src/locus-info/{fullState.js → fullState.ts} +16 -12
  430. package/src/locus-info/{hostUtils.js → hostUtils.ts} +9 -8
  431. package/src/locus-info/{index.js → index.ts} +561 -119
  432. package/src/locus-info/{infoUtils.js → infoUtils.ts} +29 -10
  433. package/src/locus-info/{mediaSharesUtils.js → mediaSharesUtils.ts} +97 -17
  434. package/src/locus-info/{parser.js → parser.ts} +303 -104
  435. package/src/locus-info/{selfUtils.js → selfUtils.ts} +199 -68
  436. package/src/media/index.ts +460 -0
  437. package/src/media/properties.ts +283 -0
  438. package/src/media/{util.js → util.ts} +2 -2
  439. package/src/mediaQualityMetrics/config.ts +249 -0
  440. package/src/meeting/in-meeting-actions.ts +199 -3
  441. package/src/meeting/index.ts +8494 -0
  442. package/src/meeting/locusMediaRequest.ts +313 -0
  443. package/src/meeting/muteState.ts +465 -0
  444. package/src/meeting/request.ts +912 -0
  445. package/src/meeting/request.type.ts +13 -0
  446. package/src/meeting/{state.js → state.ts} +50 -35
  447. package/src/meeting/util.ts +799 -0
  448. package/src/meeting/voicea-meeting.ts +122 -0
  449. package/src/meeting-info/{collection.js → collection.ts} +6 -2
  450. package/src/meeting-info/index.ts +210 -0
  451. package/src/meeting-info/meeting-info-v2.ts +423 -0
  452. package/src/meeting-info/{request.js → request.ts} +14 -4
  453. package/src/meeting-info/{util.js → util.ts} +70 -58
  454. package/src/meeting-info/{utilv2.js → utilv2.ts} +99 -82
  455. package/src/meetings/collection.ts +76 -0
  456. package/src/meetings/index.ts +1539 -0
  457. package/src/meetings/meetings.types.ts +12 -0
  458. package/src/meetings/{request.js → request.ts} +34 -25
  459. package/src/meetings/{util.js → util.ts} +133 -38
  460. package/src/member/{index.js → index.ts} +159 -56
  461. package/src/member/types.ts +38 -0
  462. package/src/member/util.ts +397 -0
  463. package/src/members/{collection.js → collection.ts} +10 -2
  464. package/src/members/{index.js → index.ts} +351 -146
  465. package/src/members/request.ts +255 -0
  466. package/src/members/types.ts +29 -0
  467. package/src/members/util.ts +353 -0
  468. package/src/metrics/{constants.js → constants.ts} +17 -6
  469. package/src/metrics/index.ts +73 -0
  470. package/src/multistream/mediaRequestManager.ts +341 -64
  471. package/src/multistream/receiveSlot.ts +69 -26
  472. package/src/multistream/receiveSlotManager.ts +66 -42
  473. package/src/multistream/remoteMedia.ts +40 -5
  474. package/src/multistream/remoteMediaGroup.ts +82 -3
  475. package/src/multistream/remoteMediaManager.ts +401 -81
  476. package/src/multistream/sendSlotManager.ts +199 -0
  477. package/src/networkQualityMonitor/{index.js → index.ts} +41 -29
  478. package/src/personal-meeting-room/{index.js → index.ts} +28 -19
  479. package/src/personal-meeting-room/{request.js → request.ts} +13 -4
  480. package/src/personal-meeting-room/{util.js → util.ts} +4 -4
  481. package/src/reachability/clusterReachability.ts +320 -0
  482. package/src/reachability/index.ts +371 -0
  483. package/src/reachability/request.ts +50 -35
  484. package/src/reachability/util.ts +24 -0
  485. package/src/reactions/constants.ts +4 -0
  486. package/src/reactions/reactions.ts +104 -0
  487. package/src/reactions/reactions.type.ts +62 -0
  488. package/src/reconnection-manager/index.ts +643 -0
  489. package/src/recording-controller/enums.ts +8 -0
  490. package/src/recording-controller/index.ts +332 -0
  491. package/src/recording-controller/util.ts +75 -0
  492. package/src/roap/index.ts +288 -0
  493. package/src/roap/request.ts +153 -0
  494. package/src/roap/turnDiscovery.ts +374 -70
  495. package/src/rtcMetrics/constants.ts +3 -0
  496. package/src/rtcMetrics/index.ts +166 -0
  497. package/src/statsAnalyzer/global.ts +37 -0
  498. package/src/statsAnalyzer/index.ts +1275 -0
  499. package/src/statsAnalyzer/mqaUtil.ts +440 -0
  500. package/src/transcription/{index.js → index.ts} +46 -39
  501. package/src/webinar/collection.ts +31 -0
  502. package/src/webinar/index.ts +62 -0
  503. package/test/integration/spec/converged-space-meetings.js +233 -0
  504. package/test/integration/spec/journey.js +791 -531
  505. package/test/integration/spec/space-meeting.js +391 -204
  506. package/test/integration/spec/transcription.js +7 -8
  507. package/test/unit/spec/annotation/index.ts +418 -0
  508. package/test/unit/spec/breakouts/breakout.ts +238 -0
  509. package/test/unit/spec/breakouts/collection.ts +15 -0
  510. package/test/unit/spec/breakouts/edit-lock-error.ts +30 -0
  511. package/test/unit/spec/breakouts/events.ts +89 -0
  512. package/test/unit/spec/breakouts/index.ts +1793 -0
  513. package/test/unit/spec/breakouts/request.ts +104 -0
  514. package/test/unit/spec/breakouts/utils.js +72 -0
  515. package/test/unit/spec/common/browser-detection.js +9 -28
  516. package/test/unit/spec/common/queue.js +31 -2
  517. package/test/unit/spec/controls-options-manager/index.js +287 -0
  518. package/test/unit/spec/controls-options-manager/util.js +582 -0
  519. package/test/unit/spec/fixture/locus.js +93 -90
  520. package/test/unit/spec/interceptors/locusRetry.ts +131 -0
  521. package/test/unit/spec/interpretation/collection.ts +15 -0
  522. package/test/unit/spec/interpretation/index.ts +625 -0
  523. package/test/unit/spec/interpretation/siLanguage.ts +28 -0
  524. package/test/unit/spec/locus-info/controlsUtils.js +325 -32
  525. package/test/unit/spec/locus-info/embeddedAppsUtils.js +8 -6
  526. package/test/unit/spec/locus-info/index.js +1458 -21
  527. package/test/unit/spec/locus-info/infoUtils.js +71 -40
  528. package/test/unit/spec/locus-info/lib/BasicSeqCmp.json +88 -430
  529. package/test/unit/spec/locus-info/lib/SeqCmp.json +529 -685
  530. package/test/unit/spec/locus-info/mediaSharesUtils.ts +41 -0
  531. package/test/unit/spec/locus-info/parser.js +119 -44
  532. package/test/unit/spec/locus-info/selfConstant.js +120 -103
  533. package/test/unit/spec/locus-info/selfUtils.js +291 -12
  534. package/test/unit/spec/media/index.ts +194 -111
  535. package/test/unit/spec/media/properties.ts +11 -11
  536. package/test/unit/spec/meeting/in-meeting-actions.ts +96 -3
  537. package/test/unit/spec/meeting/index.js +8616 -1921
  538. package/test/unit/spec/meeting/locusMediaRequest.ts +442 -0
  539. package/test/unit/spec/meeting/muteState.js +568 -207
  540. package/test/unit/spec/meeting/request.js +602 -82
  541. package/test/unit/spec/meeting/utils.js +867 -179
  542. package/test/unit/spec/meeting/voicea-meeting.ts +266 -0
  543. package/test/unit/spec/meeting-info/index.js +300 -0
  544. package/test/unit/spec/meeting-info/meetinginfov2.js +631 -78
  545. package/test/unit/spec/meeting-info/request.js +7 -9
  546. package/test/unit/spec/meeting-info/util.js +11 -12
  547. package/test/unit/spec/meeting-info/utilv2.js +131 -74
  548. package/test/unit/spec/meetings/collection.js +27 -1
  549. package/test/unit/spec/meetings/index.js +1826 -374
  550. package/test/unit/spec/meetings/utils.js +243 -14
  551. package/test/unit/spec/member/index.js +61 -7
  552. package/test/unit/spec/member/util.js +526 -26
  553. package/test/unit/spec/members/index.js +536 -55
  554. package/test/unit/spec/members/request.js +228 -40
  555. package/test/unit/spec/members/utils.js +217 -4
  556. package/test/unit/spec/metrics/index.js +13 -68
  557. package/test/unit/spec/multistream/mediaRequestManager.ts +1032 -110
  558. package/test/unit/spec/multistream/receiveSlot.ts +77 -18
  559. package/test/unit/spec/multistream/receiveSlotManager.ts +69 -39
  560. package/test/unit/spec/multistream/remoteMedia.ts +40 -2
  561. package/test/unit/spec/multistream/remoteMediaGroup.ts +350 -5
  562. package/test/unit/spec/multistream/remoteMediaManager.ts +937 -65
  563. package/test/unit/spec/multistream/sendSlotManager.ts +274 -0
  564. package/test/unit/spec/networkQualityMonitor/index.js +24 -18
  565. package/test/unit/spec/personal-meeting-room/personal-meeting-room.js +2 -7
  566. package/test/unit/spec/reachability/clusterReachability.ts +279 -0
  567. package/test/unit/spec/reachability/index.ts +606 -26
  568. package/test/unit/spec/reachability/request.js +68 -0
  569. package/test/unit/spec/reachability/util.ts +40 -0
  570. package/test/unit/spec/reconnection-manager/index.js +222 -34
  571. package/test/unit/spec/recording-controller/index.js +306 -0
  572. package/test/unit/spec/recording-controller/util.js +229 -0
  573. package/test/unit/spec/roap/index.ts +238 -82
  574. package/test/unit/spec/roap/request.ts +255 -0
  575. package/test/unit/spec/roap/turnDiscovery.ts +707 -110
  576. package/test/unit/spec/rtcMetrics/index.ts +122 -0
  577. package/test/unit/spec/stats-analyzer/index.js +1331 -62
  578. package/test/unit/spec/webinar/collection.ts +13 -0
  579. package/test/unit/spec/webinar/index.ts +60 -0
  580. package/test/utils/cmr.js +44 -42
  581. package/test/utils/constants.js +9 -0
  582. package/test/utils/integrationTestUtils.js +46 -0
  583. package/test/utils/testUtils.js +63 -99
  584. package/test/utils/webex-config.js +22 -18
  585. package/test/utils/webex-test-users.js +65 -50
  586. package/tsconfig.json +6 -0
  587. package/dist/media/internal-media-core-wrapper.js +0 -22
  588. package/dist/media/internal-media-core-wrapper.js.map +0 -1
  589. package/dist/meeting/effectsState.js +0 -327
  590. package/dist/meeting/effectsState.js.map +0 -1
  591. package/dist/metrics/config.js +0 -301
  592. package/dist/metrics/config.js.map +0 -1
  593. package/dist/multistream/multistreamMedia.js +0 -116
  594. package/dist/multistream/multistreamMedia.js.map +0 -1
  595. package/dist/peer-connection-manager/util.js +0 -124
  596. package/dist/peer-connection-manager/util.js.map +0 -1
  597. package/src/common/logs/logger-proxy.js +0 -33
  598. package/src/index.js +0 -15
  599. package/src/locus-info/controlsUtils.js +0 -102
  600. package/src/media/index.js +0 -459
  601. package/src/media/internal-media-core-wrapper.ts +0 -9
  602. package/src/media/properties.js +0 -289
  603. package/src/mediaQualityMetrics/config.js +0 -382
  604. package/src/meeting/effectsState.js +0 -205
  605. package/src/meeting/index.js +0 -6284
  606. package/src/meeting/muteState.js +0 -318
  607. package/src/meeting/request.js +0 -684
  608. package/src/meeting/util.js +0 -506
  609. package/src/meeting-info/index.js +0 -131
  610. package/src/meeting-info/meeting-info-v2.js +0 -255
  611. package/src/meetings/collection.js +0 -40
  612. package/src/meetings/index.js +0 -1015
  613. package/src/member/util.js +0 -254
  614. package/src/members/request.js +0 -131
  615. package/src/members/util.js +0 -258
  616. package/src/metrics/config.js +0 -324
  617. package/src/metrics/index.js +0 -530
  618. package/src/multistream/multistreamMedia.ts +0 -92
  619. package/src/peer-connection-manager/util.ts +0 -117
  620. package/src/reachability/index.js +0 -464
  621. package/src/reconnection-manager/index.js +0 -519
  622. package/src/roap/index.js +0 -220
  623. package/src/roap/request.js +0 -127
  624. package/src/statsAnalyzer/global.js +0 -133
  625. package/src/statsAnalyzer/index.js +0 -1006
  626. package/src/statsAnalyzer/mqaUtil.js +0 -173
  627. package/test/unit/spec/meeting/effectsState.js +0 -291
  628. package/test/unit/spec/peerconnection-manager/utils.test-fixtures.ts +0 -389
  629. /package/src/common/errors/{reconnection-in-progress.js → reconnection-in-progress.ts} +0 -0
@@ -0,0 +1,1539 @@
1
+ /* eslint no-shadow: ["error", { "allow": ["eventType"] }] */
2
+
3
+ import '@webex/internal-plugin-mercury';
4
+ import '@webex/internal-plugin-conversation';
5
+ import '@webex/internal-plugin-metrics';
6
+ // @ts-ignore
7
+ import {WebexPlugin} from '@webex/webex-core';
8
+ import {setLogger} from '@webex/internal-media-core';
9
+
10
+ import * as mediaHelpersModule from '@webex/media-helpers';
11
+
12
+ import 'webrtc-adapter';
13
+
14
+ import Metrics from '../metrics';
15
+ import LoggerConfig from '../common/logs/logger-config';
16
+ import StaticConfig from '../common/config';
17
+ import LoggerProxy from '../common/logs/logger-proxy';
18
+ import LoggerRequest from '../common/logs/request';
19
+ import Trigger from '../common/events/trigger-proxy';
20
+ import Media from '../media';
21
+ import MeetingUtil from '../meeting/util';
22
+ import {
23
+ MEETINGS,
24
+ EVENTS,
25
+ EVENT_TRIGGERS,
26
+ READY,
27
+ LOCUSEVENT,
28
+ LOCUS_URL,
29
+ MAX_RANDOM_DELAY_FOR_MEETING_INFO,
30
+ ROAP,
31
+ ONLINE,
32
+ OFFLINE,
33
+ _MEETING_,
34
+ _JOIN_,
35
+ _LOCUS_ID_,
36
+ _INCOMING_,
37
+ LOCUS,
38
+ CORRELATION_ID,
39
+ SIP_URI,
40
+ _LEFT_,
41
+ _ID_,
42
+ MEETING_REMOVED_REASON,
43
+ _CONVERSATION_URL_,
44
+ CONVERSATION_URL,
45
+ MEETINGNUMBER,
46
+ _JOINED_,
47
+ _MOVED_,
48
+ } from '../constants';
49
+ import BEHAVIORAL_METRICS from '../metrics/constants';
50
+ import MeetingInfo from '../meeting-info';
51
+ import MeetingInfoV2 from '../meeting-info/meeting-info-v2';
52
+ import Meeting, {CallStateForMetrics} from '../meeting';
53
+ import PersonalMeetingRoom from '../personal-meeting-room';
54
+ import Reachability from '../reachability';
55
+ import Request from './request';
56
+ import PasswordError from '../common/errors/password-error';
57
+ import CaptchaError from '../common/errors/captcha-error';
58
+
59
+ import MeetingCollection from './collection';
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';
65
+
66
+ let mediaLogger;
67
+
68
+ class MediaLogger {
69
+ info(...args) {
70
+ LoggerProxy.logger.info(...args);
71
+ }
72
+
73
+ log(...args) {
74
+ LoggerProxy.logger.log(...args);
75
+ }
76
+
77
+ error(...args) {
78
+ LoggerProxy.logger.error(...args);
79
+ }
80
+
81
+ warn(...args) {
82
+ LoggerProxy.logger.warn(...args);
83
+ }
84
+
85
+ trace(...args) {
86
+ LoggerProxy.logger.trace(...args);
87
+ }
88
+
89
+ debug(...args) {
90
+ LoggerProxy.logger.debug(...args);
91
+ }
92
+ }
93
+ /**
94
+ * Meetings Ready Event
95
+ * Emitted when the meetings instance on webex is ready
96
+ * @event meetings:ready
97
+ * @instance
98
+ * @memberof Meetings
99
+ */
100
+
101
+ /**
102
+ * Meetings Network Disconnected Event
103
+ * Emitted when the meetings instance is disconnected from
104
+ * the internal mercury server
105
+ * @event network:disconnected
106
+ * @instance
107
+ * @memberof Meetings
108
+ */
109
+
110
+ /**
111
+ * Meetings Registered Event
112
+ * Emitted when the meetings instance has been registered and listening
113
+ * @event meetings:registered
114
+ * @instance
115
+ * @memberof Meetings
116
+ */
117
+
118
+ /**
119
+ * Meeting Removed Event
120
+ * Emitted when a meeting was removed from the cache of meetings
121
+ * @event meeting:removed
122
+ * @instance
123
+ * @type {Object}
124
+ * @property {String} meetingId the removed meeting
125
+ * @property {Object} response the server response
126
+ * @property {String} type what type of meeting it was
127
+ * @memberof Meetings
128
+ */
129
+
130
+ /**
131
+ * Meeting Added Event
132
+ * Emitted when a meeting was added to the cache of meetings
133
+ * @event meeting:added
134
+ * @instance
135
+ * @type {Object}
136
+ * @property {String} meetingId the added meeting
137
+ * @property {String} type what type of meeting it was
138
+ * @memberof Meetings
139
+ */
140
+
141
+ /**
142
+ * Maintain a cache of meetings and sync with services.
143
+ * @class
144
+ */
145
+ export default class Meetings extends WebexPlugin {
146
+ loggerRequest: any;
147
+ media: any;
148
+ meetingCollection: any;
149
+ personalMeetingRoom: any;
150
+ preferredWebexSite: any;
151
+ reachability: Reachability;
152
+ registered: any;
153
+ request: any;
154
+ geoHintInfo: any;
155
+ meetingInfo: any;
156
+ mediaHelpers: any;
157
+ breakoutLocusForHandleLater: any;
158
+ namespace = MEETINGS;
159
+
160
+ /**
161
+ * Initializes the Meetings Plugin
162
+ * @constructor
163
+ * @public
164
+ * @memberof Meetings
165
+ */
166
+ constructor(...args) {
167
+ super(...args);
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
+
180
+ /**
181
+ * The Meetings request to interact with server
182
+ * @instance
183
+ * @type {Object}
184
+ * @private
185
+ * @memberof Meetings
186
+ */
187
+ // @ts-ignore
188
+ this.request = new Request({}, {parent: this.webex});
189
+ /**
190
+ * Log upload request helper
191
+ * @instance
192
+ * @type {Object}
193
+ * @private
194
+ * @memberof Meetings
195
+ */
196
+ // @ts-ignore
197
+ this.loggerRequest = new LoggerRequest({webex: this.webex});
198
+ this.meetingCollection = new MeetingCollection();
199
+ /**
200
+ * The PersonalMeetingRoom object to interact with server
201
+ * @instance
202
+ * @type {Object}
203
+ * @public
204
+ * @memberof Meetings
205
+ */
206
+ this.personalMeetingRoom = null;
207
+
208
+ /**
209
+ * The Reachability object to interact with server
210
+ * starts as null
211
+ * @instance
212
+ * @type {Object}
213
+ * @private
214
+ * @memberof Meetings
215
+ */
216
+ // @ts-ignore
217
+ this.reachability = new Reachability(this.webex);
218
+
219
+ /**
220
+ * If the meetings plugin has been registered and listening via {@link Meetings#register}
221
+ * @instance
222
+ * @type {Boolean}
223
+ * @public
224
+ * @memberof Meetings
225
+ */
226
+ this.registered = false;
227
+
228
+ /**
229
+ * This values indicates the preferred webex site the user will start there meeting, getsits value from {@link Meetings#register}
230
+ * @instance
231
+ * @type {String}
232
+ * @private
233
+ * @memberof Meetings
234
+ */
235
+ this.preferredWebexSite = '';
236
+
237
+ /**
238
+ * The public interface for the internal Media util files. These are helpful to expose outside the context
239
+ * of a meeting so that a user can access media without creating a meeting instance.
240
+ * @instance
241
+ * @type {Object}
242
+ * @private
243
+ * @memberof Meetings
244
+ */
245
+ this.media = {
246
+ getUserMedia: Media.getUserMedia,
247
+ };
248
+
249
+ this.onReady();
250
+ }
251
+
252
+ /**
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
366
+ * @param {Object} data a locus event
367
+ * @param {String} data.locusUrl
368
+ * @param {Object} data.locus
369
+ * @returns {Object}
370
+ * @private
371
+ * @memberof Meetings
372
+ */
373
+ getCorrespondingMeetingByLocus(data) {
374
+ // getting meeting by correlationId. This will happen for the new event
375
+ // Either the locus
376
+ // TODO : Add check for the callBack Address
377
+ return (
378
+ this.meetingCollection.getByKey(LOCUS_URL, data.locusUrl) ||
379
+ // @ts-ignore
380
+ this.meetingCollection.getByKey(
381
+ CORRELATION_ID,
382
+ // @ts-ignore
383
+ MeetingsUtil.checkForCorrelationId(this.webex.internal.device.url, data.locus)
384
+ ) ||
385
+ this.meetingCollection.getByKey(
386
+ SIP_URI,
387
+ data.locus.self &&
388
+ data.locus.self.callbackInfo &&
389
+ data.locus.self.callbackInfo.callbackAddress
390
+ ) ||
391
+ (data.locus.info?.isUnifiedSpaceMeeting
392
+ ? undefined
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);
411
+
412
+ // Special case when locus has got replaced, This only happend once if a replace locus exists
413
+ // https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-changing-mid-call
414
+
415
+ if (!meeting && data.locus?.replaces?.length > 0) {
416
+ // Always the last element in the replace is the active one
417
+ meeting = this.meetingCollection.getByKey(
418
+ LOCUS_URL,
419
+ data.locus.replaces[data.locus.replaces.length - 1].locusUrl
420
+ );
421
+ }
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
+ }
433
+ if (!meeting) {
434
+ // TODO: create meeting when we get a meeting object
435
+ // const checkForEnded = (locus) => {
436
+ // TODO: you already ended the meeting but you got an event later
437
+ // Mainly for 1:1 Callsor meeting
438
+ // Happens mainly after refresh
439
+
440
+ // 1:1 Meeting
441
+ // 1) You ended a call before but you got a mercury event
442
+ // Make sure end the call and cleanup the meeting only if the mercury
443
+ // event says so
444
+ // 2) Maintain lastSync time in the meetings object which helps to compare
445
+ // If the meeting came befor or after the sync . ANy meeting start time before the sync time is invalid
446
+
447
+ // For space Meeting
448
+ // Check the locus object and see who has joined
449
+
450
+ // };
451
+ // rather then locus object change to locus url
452
+
453
+ if (
454
+ data.locus &&
455
+ data.locus.fullState &&
456
+ data.locus.fullState.state === LOCUS.STATE.INACTIVE
457
+ ) {
458
+ // just ignore the event as its already ended and not active
459
+ LoggerProxy.logger.warn(
460
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
461
+ );
462
+
463
+ return;
464
+ }
465
+
466
+ // When its wireless share or guest and user leaves the meeting we dont have to keep the meeting object
467
+ // Any future events will be neglected
468
+
469
+ if (
470
+ data.locus &&
471
+ data.locus.self &&
472
+ data.locus.self.state === _LEFT_ &&
473
+ data.locus.self.removed === true
474
+ ) {
475
+ // just ignore the event as its already ended and not active
476
+ LoggerProxy.logger.warn(
477
+ 'Meetings:index#handleLocusEvent --> Locus event received for meeting, after it was ended.'
478
+ );
479
+
480
+ return;
481
+ }
482
+
483
+ this.create(data.locus, _LOCUS_ID_, useRandomDelayForInfo)
484
+ .then((newMeeting) => {
485
+ meeting = newMeeting;
486
+
487
+ // It's a new meeting so initialize the locus data
488
+ meeting.locusInfo.initialSetup(data.locus);
489
+ this.checkHandleBreakoutLocus(data.locus);
490
+ })
491
+ .catch((e) => {
492
+ LoggerProxy.logger.error(e);
493
+ })
494
+ .finally(() => {
495
+ // There will be cases where locus event comes in gets created and deleted because its a 1:1 and meeting gets deleted
496
+ // because the other user left so before sending 'added' event make sure it exists in the collection
497
+
498
+ if (this.getMeetingByType(_ID_, meeting.id)) {
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
+ },
508
+ });
509
+ Trigger.trigger(
510
+ this,
511
+ {
512
+ file: 'meetings',
513
+ function: 'handleLocusEvent',
514
+ },
515
+ EVENT_TRIGGERS.MEETING_ADDED,
516
+ {
517
+ meeting,
518
+ type: meeting.type === _MEETING_ ? _JOIN_ : _INCOMING_,
519
+ }
520
+ );
521
+ } else {
522
+ // Meeting got added but was not found in the collection. It might have got destroyed
523
+ LoggerProxy.logger.warn(
524
+ 'Meetings:index#handleLocusEvent --> Created and destroyed meeting object before sending an event'
525
+ );
526
+ }
527
+ });
528
+ } else {
529
+ meeting.locusInfo.parse(meeting, data);
530
+ }
531
+ }
532
+
533
+ /**
534
+ * handles locus events through mercury that are not roap
535
+ * @param {Object} envelope
536
+ * @param {Object} envelope.data
537
+ * @param {String} envelope.data.eventType
538
+ * @returns {undefined}
539
+ * @private
540
+ * @memberof Meetings
541
+ */
542
+ private handleLocusMercury(envelope: {data: any}) {
543
+ const {data} = envelope;
544
+ // eslint-disable-next-line @typescript-eslint/no-shadow
545
+ const {eventType} = data;
546
+
547
+ if (eventType && eventType !== LOCUSEVENT.MESSAGE_ROAP) {
548
+ this.handleLocusEvent(data, true);
549
+ }
550
+ }
551
+
552
+ /**
553
+ * handles mecury offline event
554
+ * @returns {undefined}
555
+ * @private
556
+ * @memberof Meetings
557
+ */
558
+ private handleMercuryOffline() {
559
+ Trigger.trigger(
560
+ this,
561
+ {
562
+ file: 'meetings/index',
563
+ function: 'handleMercuryOffline',
564
+ },
565
+ EVENT_TRIGGERS.MEETINGS_NETWORK_DISCONNECTED
566
+ );
567
+ }
568
+
569
+ /**
570
+ * registers for locus and roap mercury events
571
+ * @returns {undefined}
572
+ * @private
573
+ * @memberof Meetings
574
+ */
575
+ private listenForEvents() {
576
+ // @ts-ignore
577
+ this.webex.internal.mercury.on(LOCUSEVENT.LOCUS_MERCURY, (envelope) => {
578
+ this.handleLocusMercury(envelope);
579
+ });
580
+ // @ts-ignore
581
+ this.webex.internal.mercury.on(ROAP.ROAP_MERCURY, (envelope) => {
582
+ MeetingsUtil.handleRoapMercury(envelope, this.meetingCollection);
583
+ });
584
+
585
+ // @ts-ignore
586
+ this.webex.internal.mercury.on(ONLINE, () => {
587
+ this.syncMeetings({keepOnlyLocusMeetings: false});
588
+ });
589
+
590
+ // @ts-ignore
591
+ this.webex.internal.mercury.on(OFFLINE, () => {
592
+ this.handleMercuryOffline();
593
+ });
594
+ }
595
+
596
+ /**
597
+ * stops listening for locus and roap mercury events
598
+ * @returns {undefined}
599
+ * @private
600
+ * @memberof Meetings
601
+ */
602
+ private stopListeningForEvents() {
603
+ // @ts-ignore
604
+ this.webex.internal.mercury.off(LOCUSEVENT.LOCUS_MERCURY);
605
+ // @ts-ignore
606
+ this.webex.internal.mercury.off(ROAP.ROAP_MERCURY);
607
+ // @ts-ignore
608
+ this.webex.internal.mercury.off(ONLINE);
609
+ }
610
+
611
+ /**
612
+ * @returns {undefined}
613
+ * @private
614
+ * @memberof Meetings
615
+ */
616
+ private onReady() {
617
+ // @ts-ignore
618
+ this.webex.once(READY, () => {
619
+ // @ts-ignore
620
+ StaticConfig.set(this.config);
621
+ // @ts-ignore
622
+ LoggerConfig.set(this.config.logging);
623
+ // @ts-ignore
624
+ LoggerProxy.set(this.webex.logger);
625
+
626
+ mediaLogger = new MediaLogger();
627
+ setLogger(mediaLogger);
628
+
629
+ /**
630
+ * The MeetingInfo object to interact with server
631
+ * @instance
632
+ * @type {Object}
633
+ * @private
634
+ * @memberof Meetings
635
+ */
636
+ // @ts-ignore
637
+ this.meetingInfo = this.config.experimental.enableUnifiedMeetings
638
+ ? // @ts-ignore
639
+ new MeetingInfoV2(this.webex)
640
+ : // @ts-ignore
641
+ new MeetingInfo(this.webex);
642
+ // @ts-ignore
643
+ this.personalMeetingRoom = new PersonalMeetingRoom(
644
+ {meetingInfo: this.meetingInfo},
645
+ // @ts-ignore
646
+ {parent: this.webex}
647
+ );
648
+
649
+ Trigger.trigger(
650
+ this,
651
+ {
652
+ file: 'meetings',
653
+ function: 'onReady',
654
+ },
655
+ EVENT_TRIGGERS.MEETINGS_READY
656
+ );
657
+
658
+ MeetingsUtil.checkH264Support({disableNotifications: true});
659
+ // @ts-ignore
660
+ Metrics.initialSetup(this.webex);
661
+ });
662
+ }
663
+
664
+ /**
665
+ * API to toggle unified meetings
666
+ * @param {Boolean} changeState
667
+ * @private
668
+ * @memberof Meetings
669
+ * @returns {undefined}
670
+ */
671
+ private _toggleUnifiedMeetings(changeState: boolean) {
672
+ if (typeof changeState !== 'boolean') {
673
+ return;
674
+ }
675
+ // @ts-ignore
676
+ if (this.config?.experimental?.enableUnifiedMeetings !== changeState) {
677
+ // @ts-ignore
678
+ this.config.experimental.enableUnifiedMeetings = changeState;
679
+ // @ts-ignore
680
+ this.meetingInfo = changeState ? new MeetingInfoV2(this.webex) : new MeetingInfo(this.webex);
681
+ }
682
+ }
683
+
684
+ /**
685
+ * API to toggle starting adhoc meeting
686
+ * @param {Boolean} changeState
687
+ * @private
688
+ * @memberof Meetings
689
+ * @returns {undefined}
690
+ */
691
+ private _toggleAdhocMeetings(changeState: boolean) {
692
+ if (typeof changeState !== 'boolean') {
693
+ return;
694
+ }
695
+ // @ts-ignore
696
+ if (this.config?.experimental?.enableAdhocMeetings !== changeState) {
697
+ // @ts-ignore
698
+ this.config.experimental.enableAdhocMeetings = changeState;
699
+ }
700
+ }
701
+
702
+ /**
703
+ * API to toggle TCP reachability, needs to be called before webex.meetings.register()
704
+ * @param {Boolean} newValue
705
+ * @private
706
+ * @memberof Meetings
707
+ * @returns {undefined}
708
+ */
709
+ private _toggleTcpReachability(newValue: boolean) {
710
+ if (typeof newValue !== 'boolean') {
711
+ return;
712
+ }
713
+ // @ts-ignore
714
+ if (this.config.experimental.enableTcpReachability !== newValue) {
715
+ // @ts-ignore
716
+ this.config.experimental.enableTcpReachability = newValue;
717
+ }
718
+ }
719
+
720
+ /**
721
+ * Explicitly sets up the meetings plugin by registering
722
+ * the device, connecting to mercury, and listening for locus events.
723
+ *
724
+ * @returns {Promise}
725
+ * @public
726
+ * @memberof Meetings
727
+ */
728
+ public register() {
729
+ // @ts-ignore
730
+ if (!this.webex.canAuthorize) {
731
+ LoggerProxy.logger.error(
732
+ 'Meetings:index#register --> ERROR, Unable to register, SDK cannot authorize'
733
+ );
734
+
735
+ return Promise.reject(new Error('SDK cannot authorize'));
736
+ }
737
+
738
+ if (this.registered) {
739
+ LoggerProxy.logger.info(
740
+ 'Meetings:index#register --> INFO, Meetings plugin already registered'
741
+ );
742
+
743
+ return Promise.resolve();
744
+ }
745
+
746
+ return Promise.all([
747
+ this.fetchUserPreferredWebexSite(),
748
+ this.getGeoHint(),
749
+ this.startReachability().catch((error) => {
750
+ LoggerProxy.logger.error(`Meetings:index#register --> GDM error, ${error.message}`);
751
+ }),
752
+ // @ts-ignore
753
+ this.webex.internal.device
754
+ .register()
755
+ // @ts-ignore
756
+ .then(() =>
757
+ LoggerProxy.logger.info(
758
+ // @ts-ignore
759
+ `Meetings:index#register --> INFO, Device registered ${this.webex.internal.device.url}`
760
+ )
761
+ )
762
+ // @ts-ignore
763
+ .then(() => this.webex.internal.mercury.connect()),
764
+ MeetingsUtil.checkH264Support.call(this),
765
+ ])
766
+ .then(() => {
767
+ this.listenForEvents();
768
+ Trigger.trigger(
769
+ this,
770
+ {
771
+ file: 'meetings',
772
+ function: 'register',
773
+ },
774
+ EVENT_TRIGGERS.MEETINGS_REGISTERED
775
+ );
776
+ this.registered = true;
777
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_SUCCESS);
778
+ })
779
+ .catch((error) => {
780
+ LoggerProxy.logger.error(
781
+ `Meetings:index#register --> ERROR, Unable to register, ${error.message}`
782
+ );
783
+
784
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETINGS_REGISTRATION_FAILED, {
785
+ reason: error.message,
786
+ stack: error.stack,
787
+ });
788
+
789
+ return Promise.reject(error);
790
+ });
791
+ }
792
+
793
+ /**
794
+ * Explicitly tears down the meetings plugin by deregistering
795
+ * the device, disconnecting from mercury, and stops listening to locus events
796
+ *
797
+ * @returns {Promise}
798
+ * @public
799
+ * @memberof Meetings
800
+ */
801
+ unregister() {
802
+ if (!this.registered) {
803
+ LoggerProxy.logger.info(
804
+ 'Meetings:index#unregister --> INFO, Meetings plugin already unregistered'
805
+ );
806
+
807
+ return Promise.resolve();
808
+ }
809
+
810
+ this.stopListeningForEvents();
811
+
812
+ return (
813
+ // @ts-ignore
814
+ this.webex.internal.mercury
815
+ .disconnect()
816
+ // @ts-ignore
817
+ .then(() => this.webex.internal.device.unregister())
818
+ .then(() => {
819
+ Trigger.trigger(
820
+ this,
821
+ {
822
+ file: 'meetings',
823
+ function: 'unregister',
824
+ },
825
+ EVENT_TRIGGERS.MEETINGS_UNREGISTERED
826
+ );
827
+ this.registered = false;
828
+ })
829
+ );
830
+ }
831
+
832
+ /**
833
+ * Creates a noise reduction effect
834
+ *
835
+ * @param {INoiseReductionEffect} options optional custom effect options
836
+ * @returns {Promise<effect>} noise reduction effect.
837
+ * @public
838
+ * @memberof Meetings
839
+ */
840
+ createNoiseReductionEffect = async (options?: INoiseReductionEffect) => {
841
+ // @ts-ignore
842
+ const authToken = this.webex.credentials.supertoken.access_token;
843
+
844
+ return new mediaHelpersModule.NoiseReductionEffect({authToken, ...options});
845
+ };
846
+
847
+ /**
848
+ * Creates a virtual background effect
849
+ *
850
+ * @param {IVirtualBackgroundEffect} options optional custom effect options
851
+ * @returns {Promise<effect>} virtual background effect.
852
+ * @public
853
+ * @memberof Meetings
854
+ */
855
+ createVirtualBackgroundEffect = async (options?: IVirtualBackgroundEffect) => {
856
+ // @ts-ignore
857
+ const authToken = this.webex.credentials.supertoken.access_token;
858
+
859
+ return new mediaHelpersModule.VirtualBackgroundEffect({authToken, ...options});
860
+ };
861
+
862
+ /**
863
+ * Uploads logs to the webex services for tracking
864
+ * @param {Object} [options={}]
865
+ * @param {String} [options.callStart] Call Start Time
866
+ * @param {String} [options.feedbackId] ID used for tracking
867
+ * @param {String} [options.locusId]
868
+ * @param {String} [options.correlationId]
869
+ * @param {String} [options.meetingId] webex meeting ID
870
+ * @param {String} [options.userId] userId
871
+ * @param {String} [options.orgId] org id
872
+ * @returns {String} feedback ID logs were submitted under
873
+ */
874
+ uploadLogs(
875
+ options: {
876
+ autoupload?: boolean;
877
+ callStart?: string;
878
+ feedbackId?: string;
879
+ locussessionid?: string;
880
+ locusId?: string;
881
+ correlationId?: string;
882
+ meetingId?: string;
883
+ userId?: string;
884
+ orgId?: string;
885
+ } = {}
886
+ ) {
887
+ LoggerProxy.logger.info('Meetings:index#uploadLogs --> uploading logs');
888
+
889
+ return this.loggerRequest
890
+ .uploadLogs(options)
891
+ .then((uploadResult) => {
892
+ LoggerProxy.logger.info(
893
+ 'Meetings:index#uploadLogs --> Upload logs for meeting completed.',
894
+ uploadResult
895
+ );
896
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_SUCCESS, options);
897
+ Trigger.trigger(
898
+ this,
899
+ {
900
+ file: 'meetings',
901
+ function: 'uploadLogs',
902
+ },
903
+ EVENT_TRIGGERS.MEETING_LOG_UPLOAD_SUCCESS,
904
+ {
905
+ meetingId: options.meetingId,
906
+ details: uploadResult,
907
+ }
908
+ );
909
+
910
+ return uploadResult;
911
+ })
912
+ .catch((uploadError) => {
913
+ LoggerProxy.logger.error(
914
+ 'Meetings:index#uploadLogs --> Unable to upload logs for meeting',
915
+ uploadError
916
+ );
917
+ Trigger.trigger(
918
+ this,
919
+ {
920
+ file: 'meetings',
921
+ function: 'uploadLogs',
922
+ },
923
+ EVENT_TRIGGERS.MEETING_LOG_UPLOAD_FAILURE,
924
+ {
925
+ meetingId: options.meetingId,
926
+ reason: uploadError,
927
+ }
928
+ );
929
+
930
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UPLOAD_LOGS_FAILURE, {
931
+ ...options,
932
+ reason: uploadError.message,
933
+ stack: uploadError.stack,
934
+ code: uploadError.code,
935
+ });
936
+ });
937
+ }
938
+
939
+ /**
940
+ * gets the reachability instance for Meetings
941
+ * @returns {Reachability}
942
+ * @public
943
+ * @memberof Meetings
944
+ */
945
+ getReachability() {
946
+ return this.reachability;
947
+ }
948
+
949
+ /**
950
+ * initializes and starts gathering reachability for Meetings
951
+ * @returns {Promise}
952
+ * @public
953
+ * @memberof Meetings
954
+ */
955
+ startReachability() {
956
+ return this.getReachability().gatherReachability();
957
+ }
958
+
959
+ /**
960
+ * Get geoHint for info for meetings
961
+ * @returns {Promise}
962
+ * @private
963
+ * @memberof Meetings
964
+ */
965
+ getGeoHint() {
966
+ return this.request.fetchGeoHint().then((res) => {
967
+ this.geoHintInfo = res;
968
+ });
969
+ }
970
+
971
+ /**
972
+ * Fetch user preferred webex site information
973
+ * This also has other infomation about the user
974
+ * @returns {Promise}
975
+ * @private
976
+ * @memberof Meetings
977
+ */
978
+ fetchUserPreferredWebexSite() {
979
+ return this.request.getMeetingPreferences().then((res) => {
980
+ if (res) {
981
+ this.preferredWebexSite = MeetingsUtil.parseDefaultSiteFromMeetingPreferences(res);
982
+ }
983
+
984
+ // fall back to getting the preferred site from the user information
985
+ if (!this.preferredWebexSite) {
986
+ // @ts-ignore
987
+ return this.webex.internal.user
988
+ .get()
989
+ .then((user) => {
990
+ const preferredWebexSite =
991
+ user?.userPreferences?.userPreferencesItems?.preferredWebExSite;
992
+ if (preferredWebexSite) {
993
+ this.preferredWebexSite = preferredWebexSite;
994
+ } else {
995
+ throw new Error('site not found');
996
+ }
997
+ })
998
+ .catch(() => {
999
+ LoggerProxy.logger.error(
1000
+ 'Failed to fetch preferred site from user - no site will be set'
1001
+ );
1002
+ });
1003
+ }
1004
+
1005
+ return Promise.resolve();
1006
+ });
1007
+ }
1008
+
1009
+ /**
1010
+ * gets the personal meeting room instance, for saved PMR values for this user
1011
+ * @returns {PersonalMeetingRoom}
1012
+ * @public
1013
+ * @memberof Meetings
1014
+ */
1015
+
1016
+ getPersonalMeetingRoom() {
1017
+ return this.personalMeetingRoom;
1018
+ }
1019
+
1020
+ /**
1021
+ * @param {Meeting} meeting
1022
+ * @param {Object} reason
1023
+ * @param {String} type
1024
+ * @returns {Undefined}
1025
+ * @private
1026
+ * @memberof Meetings
1027
+ */
1028
+ private destroy(meeting: Meeting, reason: object) {
1029
+ MeetingUtil.cleanUp(meeting);
1030
+ this.meetingCollection.delete(meeting.id);
1031
+ Trigger.trigger(
1032
+ this,
1033
+ {
1034
+ file: 'meetings',
1035
+ function: 'destroy',
1036
+ },
1037
+ EVENT_TRIGGERS.MEETING_REMOVED,
1038
+ {
1039
+ meetingId: meeting.id,
1040
+ reason,
1041
+ }
1042
+ );
1043
+ }
1044
+
1045
+ /**
1046
+ * Create a meeting or return an existing meeting.
1047
+ *
1048
+ * When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
1049
+ *
1050
+ * @param {string} destination - sipURL, phonenumber, or locus object}
1051
+ * @param {string} [type] - the optional specified type, such as locusId
1052
+ * @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
1053
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1054
+ * @param {string} correlationId - the optional specified correlationId (callStateForMetrics.correlationId can be provided instead)
1055
+ * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
1056
+ * @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
1057
+ * @param {Object} [meetingInfo] - Pre-fetched complete meeting info
1058
+ * @param {String} [meetingLookupUrl] - meeting info prefetch url
1059
+ * @returns {Promise<Meeting>} A new Meeting.
1060
+ * @public
1061
+ * @memberof Meetings
1062
+ */
1063
+ public create(
1064
+ destination: string,
1065
+ type: string = null,
1066
+ useRandomDelayForInfo = false,
1067
+ infoExtraParams = {},
1068
+ correlationId: string = undefined,
1069
+ failOnMissingMeetingInfo = false,
1070
+ callStateForMetrics: CallStateForMetrics = undefined,
1071
+ meetingInfo = undefined,
1072
+ meetingLookupUrl = undefined
1073
+ ) {
1074
+ // TODO: type should be from a dictionary
1075
+
1076
+ // Validate meeting information based on the provided destination and
1077
+ // type. This must be performed prior to determining if the meeting is
1078
+ // found in the collection, as we mutate the destination for hydra person
1079
+ // id values.
1080
+ if (correlationId) {
1081
+ callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
1082
+ }
1083
+
1084
+ return (
1085
+ this.meetingInfo
1086
+ .fetchInfoOptions(destination, type)
1087
+ // Catch a failure to fetch info options.
1088
+ .catch((error) => {
1089
+ LoggerProxy.logger.error(
1090
+ `Meetings:index#create --> ERROR, unable to determine info options: ${error.message}`
1091
+ );
1092
+ if (error instanceof SpaceIDDeprecatedError) {
1093
+ throw new SpaceIDDeprecatedError();
1094
+ }
1095
+ })
1096
+ .then((options: any = {}) => {
1097
+ // Normalize the destination.
1098
+ const targetDest = options.destination || destination;
1099
+
1100
+ // check for the conversation URL then sip Url
1101
+ let meeting = null;
1102
+
1103
+ if (type === _CONVERSATION_URL_ || options.type === _CONVERSATION_URL_) {
1104
+ const foundMeeting = this.meetingCollection.getByKey(CONVERSATION_URL, targetDest);
1105
+
1106
+ if (foundMeeting) {
1107
+ const foundMeetingIsNotCalendarMeeting = !foundMeeting.locusInfo.scheduledMeeting;
1108
+
1109
+ // If the found meeting is not a calendar meeting, return that meeting.
1110
+ // This allows for the creation of instant-meetings when calendar meetings are present.
1111
+ if (foundMeetingIsNotCalendarMeeting) {
1112
+ meeting = foundMeeting;
1113
+ }
1114
+ }
1115
+ }
1116
+
1117
+ // Attempt to collect the meeting if it exists.
1118
+ if (!meeting) {
1119
+ meeting = this.meetingCollection.getByKey(SIP_URI, targetDest);
1120
+ }
1121
+
1122
+ // Validate if a meeting was found.
1123
+ if (!meeting) {
1124
+ // Create a meeting based on the normalized destination and type.
1125
+ return this.createMeeting(
1126
+ targetDest,
1127
+ type,
1128
+ useRandomDelayForInfo,
1129
+ infoExtraParams,
1130
+ callStateForMetrics,
1131
+ failOnMissingMeetingInfo,
1132
+ meetingInfo,
1133
+ meetingLookupUrl
1134
+ ).then((createdMeeting: any) => {
1135
+ // If the meeting was successfully created.
1136
+ if (createdMeeting && createdMeeting.on) {
1137
+ // Create a destruction event for the meeting.
1138
+ createdMeeting.on(EVENTS.DESTROY_MEETING, (payload) => {
1139
+ // @ts-ignore
1140
+ if (this.config.autoUploadLogs) {
1141
+ this.uploadLogs({
1142
+ callStart: createdMeeting.locusInfo?.fullState?.lastActive,
1143
+ locussessionid: createdMeeting.locusInfo?.fullState?.sessionId,
1144
+ correlationId: createdMeeting.correlationId,
1145
+ feedbackId: createdMeeting.correlationId,
1146
+ locusId: createdMeeting.locusId,
1147
+ meetingId: createdMeeting.locusInfo?.info?.webExMeetingId,
1148
+ autoupload: true,
1149
+ }).then(() => this.destroy(createdMeeting, payload.reason));
1150
+ } else {
1151
+ this.destroy(createdMeeting, payload.reason);
1152
+ }
1153
+ });
1154
+
1155
+ createdMeeting.on(EVENTS.REQUEST_UPLOAD_LOGS, (meetingInstance) => {
1156
+ // @ts-ignore
1157
+ if (this.config.autoUploadLogs) {
1158
+ this.uploadLogs({
1159
+ callStart: meetingInstance?.locusInfo?.fullState?.lastActive,
1160
+ locussessionid: meetingInstance?.locusInfo?.fullState?.sessionId,
1161
+ correlationId: meetingInstance.correlationId,
1162
+ feedbackId: meetingInstance.correlationId,
1163
+ locusId: meetingInstance.locusId,
1164
+ meetingId: meetingInstance.locusInfo?.info?.webExMeetingId,
1165
+ autoupload: true,
1166
+ });
1167
+ }
1168
+ });
1169
+ } else {
1170
+ LoggerProxy.logger.error(
1171
+ `Meetings:index#create --> ERROR, meeting does not have on method, will not be destroyed, meeting cleanup impossible for meeting: ${meeting}`
1172
+ );
1173
+ }
1174
+
1175
+ // Return the newly created meeting.
1176
+ return Promise.resolve(createdMeeting);
1177
+ });
1178
+ }
1179
+ meeting.setCallStateForMetrics(callStateForMetrics);
1180
+
1181
+ // Return the existing meeting.
1182
+ return Promise.resolve(meeting);
1183
+ })
1184
+ );
1185
+ }
1186
+
1187
+ /**
1188
+ * Create meeting
1189
+ *
1190
+ * When meeting info passed it should be complete, e.g.: fetched after password or captcha provided
1191
+ *
1192
+ * @param {String} destination see create()
1193
+ * @param {String} type see create()
1194
+ * @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
1195
+ * @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
1196
+ * @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
1197
+ * @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
1198
+ * @param {Object} [meetingInfo] - Pre-fetched complete meeting info
1199
+ * @param {String} [meetingLookupUrl] - meeting info prefetch url
1200
+ * @returns {Promise} a new meeting instance complete with meeting info and destination
1201
+ * @private
1202
+ * @memberof Meetings
1203
+ */
1204
+ private async createMeeting(
1205
+ destination: any,
1206
+ type: string = null,
1207
+ useRandomDelayForInfo = false,
1208
+ infoExtraParams = {},
1209
+ callStateForMetrics: CallStateForMetrics = undefined,
1210
+ failOnMissingMeetingInfo = false,
1211
+ meetingInfo = undefined,
1212
+ meetingLookupUrl = undefined
1213
+ ) {
1214
+ const meeting = new Meeting(
1215
+ {
1216
+ // @ts-ignore
1217
+ userId: this.webex.internal.device.userId,
1218
+ // @ts-ignore
1219
+ deviceUrl: this.webex.internal.device.url,
1220
+ // @ts-ignore
1221
+ orgId: this.webex.internal.device.orgId,
1222
+ locus: type === _LOCUS_ID_ ? destination : null, // pass the locus object if present
1223
+ meetingInfoProvider: this.meetingInfo,
1224
+ destination,
1225
+ destinationType: type,
1226
+ callStateForMetrics,
1227
+ },
1228
+ {
1229
+ // @ts-ignore
1230
+ parent: this.webex,
1231
+ }
1232
+ );
1233
+
1234
+ this.meetingCollection.set(meeting);
1235
+
1236
+ try {
1237
+ // if no participant has joined the scheduled meeting (meaning meeting is not active) and we get a locusEvent,
1238
+ // it means the meeting will start in 5-6 min. In that case, we want to fetchMeetingInfo
1239
+ // between 5 and 2 min (random between 3 minutes) before the meeting starts
1240
+ // to avoid a spike in traffic to the wbxappi service
1241
+ let waitingTime = 0;
1242
+
1243
+ if (destination.meeting) {
1244
+ const {startTime} = destination.meeting;
1245
+ const startTimeDate = new Date(startTime);
1246
+ const startTimeDatestamp = startTimeDate.getTime();
1247
+ const timeToStart = startTimeDatestamp - Date.now();
1248
+ const maxWaitingTime = Math.max(
1249
+ Math.min(timeToStart, MAX_RANDOM_DELAY_FOR_MEETING_INFO),
1250
+ 0
1251
+ );
1252
+
1253
+ waitingTime = Math.round(Math.random() * maxWaitingTime);
1254
+ }
1255
+ const isMeetingActive = !!destination.fullState?.active;
1256
+ // @ts-ignore
1257
+ const {enableUnifiedMeetings} = this.config.experimental;
1258
+ const meetingInfoOptions = {
1259
+ extraParams: infoExtraParams,
1260
+ sendCAevents: !!callStateForMetrics?.correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
1261
+ };
1262
+
1263
+ if (meetingInfo) {
1264
+ meeting.injectMeetingInfo(meetingInfo, meetingInfoOptions, meetingLookupUrl);
1265
+ } else if (
1266
+ enableUnifiedMeetings &&
1267
+ !isMeetingActive &&
1268
+ useRandomDelayForInfo &&
1269
+ waitingTime > 0
1270
+ ) {
1271
+ meeting.fetchMeetingInfoTimeoutId = setTimeout(
1272
+ () => meeting.fetchMeetingInfo(meetingInfoOptions),
1273
+ waitingTime
1274
+ );
1275
+ meeting.parseMeetingInfo(undefined, destination);
1276
+ } else {
1277
+ await meeting.fetchMeetingInfo(meetingInfoOptions);
1278
+ }
1279
+ } catch (err) {
1280
+ if (
1281
+ !(err instanceof CaptchaError) &&
1282
+ !(err instanceof PasswordError) &&
1283
+ !(err instanceof PermissionError)
1284
+ ) {
1285
+ LoggerProxy.logger.info(
1286
+ `Meetings:index#createMeeting --> Info Unable to fetch meeting info for ${destination}.`
1287
+ );
1288
+ if (failOnMissingMeetingInfo) {
1289
+ LoggerProxy.logger.info(
1290
+ `Meetings:index#createMeeting --> Destroying meeting due to missing meeting info.`
1291
+ );
1292
+ // @ts-ignore
1293
+ this.destroy(meeting, MEETING_REMOVED_REASON.MISSING_MEETING_INFO);
1294
+ throw new NoMeetingInfoError();
1295
+ }
1296
+ // if there is no meeting info and no error should be thrown then we assume its a 1:1 call or wireless share
1297
+ LoggerProxy.logger.info(
1298
+ 'Meetings:index#createMeeting --> Info assuming this destination is a 1:1 or wireless share'
1299
+ );
1300
+ }
1301
+ LoggerProxy.logger.debug(
1302
+ `Meetings:index#createMeeting --> Debug ${err} fetching /meetingInfo for creation.`
1303
+ );
1304
+ } finally {
1305
+ // For type LOCUS_ID we need to parse the locus object to get the information
1306
+ // about the caller and callee
1307
+ // Meeting Added event will be created in `handleLocusEvent`
1308
+ if (type !== _LOCUS_ID_) {
1309
+ if (!meeting.sipUri) {
1310
+ meeting.setSipUri(destination);
1311
+ }
1312
+
1313
+ // TODO: check if we have to move this to parser
1314
+ const meetingAddedType = MeetingsUtil.getMeetingAddedType(type);
1315
+
1316
+ // We typically shouldn't need to trigger both and event and return a promise.
1317
+ // Is this a special case? We want to make the public API usage as simple as possible.
1318
+ Trigger.trigger(
1319
+ this,
1320
+ {
1321
+ file: 'meetings',
1322
+ function: 'createMeeting',
1323
+ },
1324
+ EVENT_TRIGGERS.MEETING_ADDED,
1325
+ {
1326
+ meeting,
1327
+ type: meetingAddedType,
1328
+ }
1329
+ );
1330
+ }
1331
+ }
1332
+
1333
+ return meeting;
1334
+
1335
+ // Create the meeting calling the necessary service endpoints.
1336
+
1337
+ // Internally, there are many more destinations:
1338
+ //
1339
+ // - locusID
1340
+ // - meetingURL
1341
+ // - globalMeetingID, e.g, *00*meetingID
1342
+ // - meetingID
1343
+ // - meetingURL
1344
+ // - PSTN
1345
+ // - phone number
1346
+ //
1347
+ // Our job is to determine the appropriate one
1348
+ // and its corresponding service so that developers
1349
+ // need only sipURL to get a meeting
1350
+ // and its ID, but have the option to use createWithType()
1351
+ // and specify those types to get meetingInfo
1352
+ }
1353
+
1354
+ /**
1355
+ * get a specifc meeting given it's type matched to the value, i.e., locus url
1356
+ * @param {String} type
1357
+ * @param {Object} value
1358
+ * @returns {Meeting}
1359
+ * @public
1360
+ * @memberof Meetings
1361
+ */
1362
+ public getMeetingByType(type: string, value: object) {
1363
+ return this.meetingCollection.getByKey(type, value);
1364
+ }
1365
+
1366
+ /**
1367
+ * Get all meetings.
1368
+ * @param {object} options
1369
+ * @param {object} options.startDate - get meetings after this start date
1370
+ * @param {object} options.endDate - get meetings before this end date
1371
+ * @returns {Object} All currently active meetings.
1372
+ * @public
1373
+ * @memberof Meetings
1374
+ */
1375
+ public getAllMeetings(
1376
+ options: {
1377
+ startDate: object;
1378
+ endDate: object;
1379
+ } = {} as any
1380
+ ) {
1381
+ // Options may include other parameters to filter this collection
1382
+ // of meetings.
1383
+ return this.meetingCollection.getAll(options);
1384
+ }
1385
+
1386
+ /**
1387
+ * Syncs all the meetings from server. Does nothing and returns immediately if unverified guest.
1388
+ * @param {boolean} keepOnlyLocusMeetings - whether the sync should keep only locus meetings or any other meeting in meetingCollection
1389
+ * @returns {Promise<void>}
1390
+ * @public
1391
+ * @memberof Meetings
1392
+ */
1393
+ public syncMeetings({keepOnlyLocusMeetings = true} = {}): Promise<void> {
1394
+ // @ts-ignore
1395
+ if (this.webex.credentials.isUnverifiedGuest) {
1396
+ LoggerProxy.logger.info(
1397
+ 'Meetings:index#syncMeetings --> skipping meeting sync as unverified guest'
1398
+ );
1399
+
1400
+ return Promise.resolve();
1401
+ }
1402
+
1403
+ return this.request
1404
+ .getActiveMeetings()
1405
+ .then((locusArray) => {
1406
+ const activeLocusUrl = [];
1407
+
1408
+ if (locusArray?.loci && locusArray.loci.length > 0) {
1409
+ const lociToUpdate = this.sortLocusArrayToUpdate(locusArray.loci);
1410
+ lociToUpdate.forEach((locus) => {
1411
+ activeLocusUrl.push(locus.url);
1412
+ this.handleLocusEvent({
1413
+ locus,
1414
+ locusUrl: locus.url,
1415
+ });
1416
+ });
1417
+ }
1418
+ const meetingsCollection = this.meetingCollection.getAll();
1419
+
1420
+ if (Object.keys(meetingsCollection).length > 0) {
1421
+ // Sometimes the mercury events are lost after mercury reconnect
1422
+ // Remove any Locus meetings that are not returned by Locus
1423
+ // (they had a locusUrl previously but are no longer active) in the sync
1424
+ for (const meeting of Object.values(meetingsCollection)) {
1425
+ // @ts-ignore
1426
+ const {locusUrl} = meeting;
1427
+ if ((keepOnlyLocusMeetings || locusUrl) && !activeLocusUrl.includes(locusUrl)) {
1428
+ // destroy function also uploads logs
1429
+ // @ts-ignore
1430
+ this.destroy(meeting, MEETING_REMOVED_REASON.NO_MEETINGS_TO_SYNC);
1431
+ }
1432
+ }
1433
+ }
1434
+ })
1435
+ .catch((error) => {
1436
+ LoggerProxy.logger.error(
1437
+ `Meetings:index#syncMeetings --> failed to sync meetings, ${error}`
1438
+ );
1439
+ throw new Error(error);
1440
+ });
1441
+ }
1442
+
1443
+ /**
1444
+ * sort out locus array for initial creating
1445
+ * @param {Array} loci original locus array
1446
+ * @returns {undefined}
1447
+ * @public
1448
+ * @memberof Meetings
1449
+ */
1450
+ sortLocusArrayToUpdate(loci: any[]) {
1451
+ const mainLoci = loci.filter((locus) => !MeetingsUtil.isBreakoutLocusDTO(locus));
1452
+ const breakoutLoci = loci.filter((locus) => MeetingsUtil.isValidBreakoutLocus(locus));
1453
+ this.breakoutLocusForHandleLater = [];
1454
+ const lociToUpdate = [...mainLoci];
1455
+ breakoutLoci.forEach((breakoutLocus) => {
1456
+ const associateMainLocus = mainLoci.find(
1457
+ (mainLocus) => mainLocus.controls?.breakout?.url === breakoutLocus.controls?.breakout?.url
1458
+ );
1459
+ const existCorrespondingMeeting = this.getCorrespondingMeetingByLocus({
1460
+ locus: breakoutLocus,
1461
+ locusUrl: breakoutLocus.url,
1462
+ });
1463
+
1464
+ if (associateMainLocus && !existCorrespondingMeeting) {
1465
+ // if exists both main session and breakout session locus of the same non-exist meeting, handle main locus first,
1466
+ // after meeting create with main locus, then handle the associate breakout locus.
1467
+ // if only handle breakout locus, will miss some date
1468
+ this.breakoutLocusForHandleLater.push(breakoutLocus);
1469
+ } else {
1470
+ lociToUpdate.push(breakoutLocus);
1471
+ }
1472
+ });
1473
+
1474
+ return lociToUpdate;
1475
+ }
1476
+
1477
+ /**
1478
+ * check breakout locus which waiting for main locus's meeting to be created, then handle the breakout locus
1479
+ * @param {Object} newCreatedLocus the locus which just create meeting object of it
1480
+ * @returns {undefined}
1481
+ * @public
1482
+ * @memberof Meetings
1483
+ */
1484
+ checkHandleBreakoutLocus(newCreatedLocus) {
1485
+ if (
1486
+ !newCreatedLocus ||
1487
+ !this.breakoutLocusForHandleLater ||
1488
+ !this.breakoutLocusForHandleLater.length
1489
+ ) {
1490
+ return;
1491
+ }
1492
+ if (MeetingsUtil.isBreakoutLocusDTO(newCreatedLocus)) {
1493
+ return;
1494
+ }
1495
+ const existIndex = this.breakoutLocusForHandleLater.findIndex(
1496
+ (breakoutLocus) =>
1497
+ breakoutLocus.controls?.breakout?.url === newCreatedLocus.controls?.breakout?.url
1498
+ );
1499
+
1500
+ if (existIndex < 0) {
1501
+ return;
1502
+ }
1503
+
1504
+ const associateBreakoutLocus = this.breakoutLocusForHandleLater[existIndex];
1505
+ this.handleLocusEvent({locus: associateBreakoutLocus, locusUrl: associateBreakoutLocus.url});
1506
+ this.breakoutLocusForHandleLater.splice(existIndex, 1);
1507
+ }
1508
+
1509
+ /**
1510
+ * Get all scheduled meetings.
1511
+ * @param {object} options
1512
+ * @param {object} options.startDate - get meetings after this start date
1513
+ * @param {object} options.endDate - get meetings before this end date
1514
+ * @returns {Object} All scheduled meetings.
1515
+ * @memberof Meetings
1516
+ */
1517
+ getScheduledMeetings() {
1518
+ return this.meetingCollection.getAll({scheduled: true});
1519
+ }
1520
+
1521
+ /**
1522
+ * Get the logger instance for plugin-meetings
1523
+ * @returns {Logger}
1524
+ */
1525
+ getLogger() {
1526
+ return LoggerProxy.get();
1527
+ }
1528
+
1529
+ /**
1530
+ * Returns the first meeting it finds that has the webrtc media connection created.
1531
+ * Useful for debugging in the console.
1532
+ *
1533
+ * @private
1534
+ * @returns {Meeting} Meeting object that has a webrtc media connection, else undefined
1535
+ */
1536
+ getActiveWebrtcMeeting() {
1537
+ return this.meetingCollection.getActiveWebrtcMeeting();
1538
+ }
1539
+ }