@webex/contact-center 3.12.0-next.16 → 3.12.0-next.161

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 (328) hide show
  1. package/.sdd/manifest.json +887 -0
  2. package/AGENTS.md +94 -0
  3. package/ai-docs/ARCHITECTURE.md +168 -0
  4. package/ai-docs/CONTRACTS.md +62 -0
  5. package/ai-docs/GETTING_STARTED.md +168 -0
  6. package/ai-docs/GLOSSARY.md +43 -0
  7. package/ai-docs/README.md +138 -0
  8. package/ai-docs/REVIEW_CHECKLIST.md +41 -0
  9. package/ai-docs/RULES.md +444 -0
  10. package/ai-docs/SECURITY.md +52 -0
  11. package/ai-docs/SERVICE_STATE.md +52 -0
  12. package/ai-docs/SPEC_INDEX.md +65 -0
  13. package/ai-docs/adr/0001-spec-source-policy.md +55 -0
  14. package/ai-docs/adr/README.md +8 -0
  15. package/ai-docs/adr/_adr-template.md +31 -0
  16. package/ai-docs/contact-center-spec.md +385 -0
  17. package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
  18. package/ai-docs/features/contact-owner-change-refactor.md +78 -0
  19. package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
  20. package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
  21. package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
  22. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  23. package/ai-docs/patterns/testing-patterns.md +480 -0
  24. package/ai-docs/patterns/typescript-patterns.md +365 -0
  25. package/ai-docs/templates/README.md +102 -0
  26. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  27. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  28. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  29. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  30. package/ai-docs/templates/new-method/00-master.md +80 -0
  31. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  32. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  33. package/ai-docs/templates/new-method/03-tests.md +201 -0
  34. package/ai-docs/templates/new-method/04-validation.md +141 -0
  35. package/ai-docs/templates/new-service/00-master.md +109 -0
  36. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  37. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  38. package/ai-docs/templates/new-service/03-integration.md +178 -0
  39. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  40. package/ai-docs/templates/new-service/05-validation.md +145 -0
  41. package/dist/cc.js +888 -49
  42. package/dist/cc.js.map +1 -1
  43. package/dist/config.js +13 -0
  44. package/dist/config.js.map +1 -1
  45. package/dist/constants.js +38 -3
  46. package/dist/constants.js.map +1 -1
  47. package/dist/index.js +54 -17
  48. package/dist/index.js.map +1 -1
  49. package/dist/metrics/MetricsManager.js +16 -0
  50. package/dist/metrics/MetricsManager.js.map +1 -1
  51. package/dist/metrics/behavioral-events.js +185 -0
  52. package/dist/metrics/behavioral-events.js.map +1 -1
  53. package/dist/metrics/constants.js +54 -4
  54. package/dist/metrics/constants.js.map +1 -1
  55. package/dist/services/AddressBook.js +18 -15
  56. package/dist/services/AddressBook.js.map +1 -1
  57. package/dist/services/AnswerCallOnWebexService.js +202 -0
  58. package/dist/services/AnswerCallOnWebexService.js.map +1 -0
  59. package/dist/services/ApiAiAssistant.js +369 -14
  60. package/dist/services/ApiAiAssistant.js.map +1 -1
  61. package/dist/services/EntryPoint.js +46 -68
  62. package/dist/services/EntryPoint.js.map +1 -1
  63. package/dist/services/Queue.js +27 -22
  64. package/dist/services/Queue.js.map +1 -1
  65. package/dist/services/UserPreference.js +427 -0
  66. package/dist/services/UserPreference.js.map +1 -0
  67. package/dist/services/WebCallingService.js +10 -2
  68. package/dist/services/WebCallingService.js.map +1 -1
  69. package/dist/services/WebexCrossClientService.js +225 -0
  70. package/dist/services/WebexCrossClientService.js.map +1 -0
  71. package/dist/services/WxAppTelephonyMercurySync.js +111 -0
  72. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  73. package/dist/services/config/Util.js +48 -48
  74. package/dist/services/config/Util.js.map +1 -1
  75. package/dist/services/config/constants.js +56 -78
  76. package/dist/services/config/constants.js.map +1 -1
  77. package/dist/services/config/index.js +100 -226
  78. package/dist/services/config/index.js.map +1 -1
  79. package/dist/services/config/types.js +93 -24
  80. package/dist/services/config/types.js.map +1 -1
  81. package/dist/services/constants.js +11 -1
  82. package/dist/services/constants.js.map +1 -1
  83. package/dist/services/core/Err.js.map +1 -1
  84. package/dist/services/core/Utils.js +131 -32
  85. package/dist/services/core/Utils.js.map +1 -1
  86. package/dist/services/core/WebexRequest.js +6 -2
  87. package/dist/services/core/WebexRequest.js.map +1 -1
  88. package/dist/services/core/aqm-reqs.js +17 -11
  89. package/dist/services/core/aqm-reqs.js.map +1 -1
  90. package/dist/services/core/constants.js +9 -1
  91. package/dist/services/core/constants.js.map +1 -1
  92. package/dist/services/core/types.js.map +1 -1
  93. package/dist/services/core/websocket/WebSocketManager.js +19 -2
  94. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  95. package/dist/services/core/websocket/types.js.map +1 -1
  96. package/dist/services/index.js +1 -1
  97. package/dist/services/index.js.map +1 -1
  98. package/dist/services/task/Task.js +955 -0
  99. package/dist/services/task/Task.js.map +1 -0
  100. package/dist/services/task/TaskFactory.js +50 -0
  101. package/dist/services/task/TaskFactory.js.map +1 -0
  102. package/dist/services/task/TaskManager.js +1272 -605
  103. package/dist/services/task/TaskManager.js.map +1 -1
  104. package/dist/services/task/TaskUtils.js +221 -27
  105. package/dist/services/task/TaskUtils.js.map +1 -1
  106. package/dist/services/task/WebexCallingUtils.js +70 -0
  107. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  108. package/dist/services/task/constants.js +19 -2
  109. package/dist/services/task/constants.js.map +1 -1
  110. package/dist/services/task/contact.js +29 -0
  111. package/dist/services/task/contact.js.map +1 -1
  112. package/dist/services/task/digital/Digital.js +78 -0
  113. package/dist/services/task/digital/Digital.js.map +1 -0
  114. package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
  115. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  116. package/dist/services/task/state-machine/actions.js +572 -0
  117. package/dist/services/task/state-machine/actions.js.map +1 -0
  118. package/dist/services/task/state-machine/constants.js +161 -0
  119. package/dist/services/task/state-machine/constants.js.map +1 -0
  120. package/dist/services/task/state-machine/guards.js +379 -0
  121. package/dist/services/task/state-machine/guards.js.map +1 -0
  122. package/dist/services/task/state-machine/index.js +53 -0
  123. package/dist/services/task/state-machine/index.js.map +1 -0
  124. package/dist/services/task/state-machine/types.js +54 -0
  125. package/dist/services/task/state-machine/types.js.map +1 -0
  126. package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
  127. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  128. package/dist/services/task/taskDataNormalizer.js +99 -0
  129. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  130. package/dist/services/task/types.js +215 -5
  131. package/dist/services/task/types.js.map +1 -1
  132. package/dist/services/task/voice/Voice.js +1504 -0
  133. package/dist/services/task/voice/Voice.js.map +1 -0
  134. package/dist/services/task/voice/WebRTC.js +152 -0
  135. package/dist/services/task/voice/WebRTC.js.map +1 -0
  136. package/dist/services/task/voice/wxAppOfferObservability.js +145 -0
  137. package/dist/services/task/voice/wxAppOfferObservability.js.map +1 -0
  138. package/dist/services/task/voice/wxAppVoiceMethods.js +395 -0
  139. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  140. package/dist/services/wxAppDiagnosticLogging.js +159 -0
  141. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  142. package/dist/services/wxAppTelephonyUtils.js +19 -0
  143. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  144. package/dist/types/cc.d.ts +152 -9
  145. package/dist/types/config.d.ts +13 -0
  146. package/dist/types/constants.d.ts +36 -1
  147. package/dist/types/index.d.ts +54 -20
  148. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  149. package/dist/types/metrics/constants.d.ts +48 -1
  150. package/dist/types/services/AddressBook.d.ts +2 -1
  151. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  152. package/dist/types/services/ApiAiAssistant.d.ts +67 -5
  153. package/dist/types/services/EntryPoint.d.ts +7 -5
  154. package/dist/types/services/Queue.d.ts +5 -3
  155. package/dist/types/services/UserPreference.d.ts +118 -0
  156. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  157. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  158. package/dist/types/services/config/Util.d.ts +4 -8
  159. package/dist/types/services/config/constants.d.ts +49 -76
  160. package/dist/types/services/config/index.d.ts +16 -64
  161. package/dist/types/services/config/types.d.ts +240 -114
  162. package/dist/types/services/constants.d.ts +9 -0
  163. package/dist/types/services/core/Err.d.ts +2 -0
  164. package/dist/types/services/core/Utils.d.ts +43 -13
  165. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  166. package/dist/types/services/core/constants.d.ts +7 -0
  167. package/dist/types/services/core/types.d.ts +2 -0
  168. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  169. package/dist/types/services/core/websocket/types.d.ts +1 -1
  170. package/dist/types/services/index.d.ts +1 -1
  171. package/dist/types/services/task/Task.d.ts +186 -0
  172. package/dist/types/services/task/TaskFactory.d.ts +14 -0
  173. package/dist/types/services/task/TaskUtils.d.ts +54 -2
  174. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  175. package/dist/types/services/task/constants.d.ts +17 -0
  176. package/dist/types/services/task/contact.d.ts +4 -0
  177. package/dist/types/services/task/digital/Digital.d.ts +23 -0
  178. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
  179. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  180. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  181. package/dist/types/services/task/state-machine/guards.d.ts +103 -0
  182. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  183. package/dist/types/services/task/state-machine/types.d.ts +277 -0
  184. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  185. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  186. package/dist/types/services/task/types.d.ts +738 -66
  187. package/dist/types/services/task/voice/Voice.d.ts +241 -0
  188. package/dist/types/services/task/voice/WebRTC.d.ts +54 -0
  189. package/dist/types/services/task/voice/wxAppOfferObservability.d.ts +39 -0
  190. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +68 -0
  191. package/dist/types/services/wxAppDiagnosticLogging.d.ts +63 -0
  192. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  193. package/dist/types/types.d.ts +213 -11
  194. package/dist/types/utils/PageCache.d.ts +20 -3
  195. package/dist/types/webex.d.ts +1 -0
  196. package/dist/types.js +168 -6
  197. package/dist/types.js.map +1 -1
  198. package/dist/utils/PageCache.js +19 -5
  199. package/dist/utils/PageCache.js.map +1 -1
  200. package/dist/webex.js +22 -2
  201. package/dist/webex.js.map +1 -1
  202. package/package.json +16 -12
  203. package/src/cc.ts +1137 -67
  204. package/src/config.ts +13 -0
  205. package/src/constants.ts +39 -1
  206. package/src/index.ts +62 -15
  207. package/src/metrics/MetricsManager.ts +16 -0
  208. package/src/metrics/ai-docs/AGENTS.md +350 -0
  209. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  210. package/src/metrics/ai-docs/metrics-spec.md +971 -0
  211. package/src/metrics/behavioral-events.ts +190 -0
  212. package/src/metrics/constants.ts +59 -4
  213. package/src/services/AddressBook.ts +17 -6
  214. package/src/services/AnswerCallOnWebexService.ts +239 -0
  215. package/src/services/ApiAiAssistant.ts +494 -15
  216. package/src/services/EntryPoint.ts +59 -60
  217. package/src/services/Queue.ts +29 -12
  218. package/src/services/UserPreference.ts +509 -0
  219. package/src/services/WebCallingService.ts +16 -2
  220. package/src/services/WebexCrossClientService.ts +298 -0
  221. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  222. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  223. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  224. package/src/services/agent/ai-docs/agent-spec.md +505 -0
  225. package/src/services/ai-docs/AGENTS.md +386 -0
  226. package/src/services/ai-docs/services-spec.md +512 -0
  227. package/src/services/config/Util.ts +54 -84
  228. package/src/services/config/ai-docs/AGENTS.md +250 -0
  229. package/src/services/config/ai-docs/ARCHITECTURE.md +413 -0
  230. package/src/services/config/ai-docs/config-spec.md +669 -0
  231. package/src/services/config/constants.ts +63 -85
  232. package/src/services/config/index.ts +116 -277
  233. package/src/services/config/types.ts +229 -125
  234. package/src/services/constants.ts +10 -0
  235. package/src/services/core/Err.ts +1 -0
  236. package/src/services/core/Utils.ts +151 -37
  237. package/src/services/core/WebexRequest.ts +3 -1
  238. package/src/services/core/ai-docs/AGENTS.md +381 -0
  239. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  240. package/src/services/core/ai-docs/core-spec.md +797 -0
  241. package/src/services/core/aqm-reqs.ts +18 -12
  242. package/src/services/core/constants.ts +8 -0
  243. package/src/services/core/types.ts +33 -1
  244. package/src/services/core/websocket/WebSocketManager.ts +28 -2
  245. package/src/services/core/websocket/types.ts +1 -1
  246. package/src/services/index.ts +1 -1
  247. package/src/services/task/Task.ts +1211 -0
  248. package/src/services/task/TaskFactory.ts +82 -0
  249. package/src/services/task/TaskManager.ts +1585 -724
  250. package/src/services/task/TaskUtils.ts +316 -25
  251. package/src/services/task/WebexCallingUtils.ts +136 -0
  252. package/src/services/task/ai-docs/AGENTS.md +457 -0
  253. package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
  254. package/src/services/task/ai-docs/task-spec.md +1501 -0
  255. package/src/services/task/constants.ts +18 -0
  256. package/src/services/task/contact.ts +30 -0
  257. package/src/services/task/digital/Digital.ts +102 -0
  258. package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
  259. package/src/services/task/state-machine/actions.ts +741 -0
  260. package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
  261. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
  262. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
  263. package/src/services/task/state-machine/constants.ts +172 -0
  264. package/src/services/task/state-machine/guards.ts +442 -0
  265. package/src/services/task/state-machine/index.ts +28 -0
  266. package/src/services/task/state-machine/types.ts +258 -0
  267. package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
  268. package/src/services/task/taskDataNormalizer.ts +137 -0
  269. package/src/services/task/types.ts +918 -70
  270. package/src/services/task/voice/Voice.ts +1878 -0
  271. package/src/services/task/voice/WebRTC.ts +194 -0
  272. package/src/services/task/voice/wxAppOfferObservability.ts +204 -0
  273. package/src/services/task/voice/wxAppVoiceMethods.ts +575 -0
  274. package/src/services/wxAppDiagnosticLogging.ts +286 -0
  275. package/src/services/wxAppTelephonyUtils.ts +14 -0
  276. package/src/types.ts +272 -13
  277. package/src/utils/AGENTS.md +289 -0
  278. package/src/utils/PageCache.ts +38 -5
  279. package/src/utils/ai-docs/utils-spec.md +391 -0
  280. package/src/webex.js +10 -0
  281. package/test/unit/fixtures/aiSummaryTestUtils.ts +40 -0
  282. package/test/unit/spec/cc.ts +3553 -107
  283. package/test/unit/spec/index.ts +885 -0
  284. package/test/unit/spec/logger-proxy.ts +70 -0
  285. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  286. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  287. package/test/unit/spec/services/AddressBook.ts +37 -6
  288. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  289. package/test/unit/spec/services/ApiAiAssistant.ts +442 -23
  290. package/test/unit/spec/services/EntryPoint.ts +87 -40
  291. package/test/unit/spec/services/Queue.ts +123 -12
  292. package/test/unit/spec/services/UserPreference.ts +401 -0
  293. package/test/unit/spec/services/WebCallingService.ts +45 -1
  294. package/test/unit/spec/services/WebexCrossClientService.ts +509 -0
  295. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  296. package/test/unit/spec/services/config/Util.ts +501 -0
  297. package/test/unit/spec/services/config/index.ts +317 -547
  298. package/test/unit/spec/services/core/Utils.ts +447 -8
  299. package/test/unit/spec/services/core/WebexRequest.ts +8 -7
  300. package/test/unit/spec/services/core/aqm-reqs.ts +142 -1
  301. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +129 -53
  302. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  303. package/test/unit/spec/services/task/Task.ts +2723 -0
  304. package/test/unit/spec/services/task/TaskFactory.ts +116 -0
  305. package/test/unit/spec/services/task/TaskManager.ts +4734 -1769
  306. package/test/unit/spec/services/task/TaskUtils.ts +307 -0
  307. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  308. package/test/unit/spec/services/task/contact.ts +33 -0
  309. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  310. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
  311. package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
  312. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  313. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
  314. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  315. package/test/unit/spec/services/task/voice/Voice.ts +2355 -0
  316. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  317. package/test/unit/spec/services/task/voice/wxAppOfferObservability.ts +361 -0
  318. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +719 -0
  319. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +179 -0
  320. package/test/unit/spec/wellnessSampleUtils.ts +288 -0
  321. package/typedoc.md +1 -1
  322. package/umd/contact-center.min.js +2 -2
  323. package/umd/contact-center.min.js.map +1 -1
  324. package/dist/services/task/index.js +0 -1530
  325. package/dist/services/task/index.js.map +0 -1
  326. package/dist/types/services/task/index.d.ts +0 -650
  327. package/src/services/task/index.ts +0 -1806
  328. package/test/unit/spec/services/task/index.ts +0 -2205
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _loggerProxy = _interopRequireDefault(require("../logger-proxy"));
8
+ var _constants = require("../constants");
9
+ var _MetricsManager = _interopRequireDefault(require("../metrics/MetricsManager"));
10
+ var _constants2 = require("../metrics/constants");
11
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
12
+ const WEBEX_CROSS_CLIENT_FILE = 'WebexCrossClientService';
13
+ const DEFAULT_CROSS_CLIENT_STATE_TTL = 900;
14
+ const EXPIRATION_OFFSET_MS = 60_000;
15
+ /** Must match Agent Desktop usersub publish — Webex App reads `wxcc` cross-client state. */
16
+ const DEFAULT_APP_NAME = 'wxcc';
17
+ const REFRESH_RETRY_DELAY_MS = 30_000;
18
+ const MAX_REFRESH_RETRIES = 3;
19
+ /**
20
+ * Publishes usersub cross-client state so Webex App suppresses native calling toasts (WXCC-6026).
21
+ */
22
+ class WebexCrossClientService {
23
+ answerCallsState = false;
24
+ appName = DEFAULT_APP_NAME;
25
+ /** Incremented on teardown/disable to ignore stale refresh timer callbacks. */
26
+ refreshGeneration = 0;
27
+ /** Monotonic id for usersub publish metrics timers; stale publishes cancel only their own timer. */
28
+ usersubPublishMetricsId = 0;
29
+ constructor(webex) {
30
+ this.webex = webex;
31
+ }
32
+ extractDeviceIdFromUrl(url) {
33
+ const match = url.match(/\/devices\/([^/?]+)/);
34
+ return match ? match[1] : '';
35
+ }
36
+ getDeviceUrl() {
37
+ return this.webex.internal.device?.url;
38
+ }
39
+ clearRefreshTimer() {
40
+ if (this.refreshTimer) {
41
+ clearTimeout(this.refreshTimer);
42
+ this.refreshTimer = undefined;
43
+ }
44
+ if (this.refreshRetryTimer) {
45
+ clearTimeout(this.refreshRetryTimer);
46
+ this.refreshRetryTimer = undefined;
47
+ }
48
+ }
49
+ scheduleRefreshRetry(userId, ttl, scheduledGeneration, retryAttempt) {
50
+ if (retryAttempt >= MAX_REFRESH_RETRIES || scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {
51
+ return;
52
+ }
53
+ this.refreshRetryTimer = setTimeout(async () => {
54
+ if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {
55
+ return;
56
+ }
57
+ try {
58
+ await this.setManageWebexCallingInWxcc(true, {
59
+ userId,
60
+ ttl,
61
+ appName: this.appName
62
+ });
63
+ } catch (error) {
64
+ _loggerProxy.default.error(`WebexCrossClientService refresh retry failed: ${error}`, {
65
+ module: WEBEX_CROSS_CLIENT_FILE,
66
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
67
+ });
68
+ this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, retryAttempt + 1);
69
+ }
70
+ }, REFRESH_RETRY_DELAY_MS);
71
+ }
72
+ startRefreshTimer(userId, ttl) {
73
+ this.clearRefreshTimer();
74
+ if (!this.answerCallsState) {
75
+ return;
76
+ }
77
+ const refreshTime = ttl * 1000 - EXPIRATION_OFFSET_MS;
78
+ const scheduledGeneration = this.refreshGeneration;
79
+ this.refreshTimer = setTimeout(async () => {
80
+ if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {
81
+ return;
82
+ }
83
+ try {
84
+ await this.setManageWebexCallingInWxcc(true, {
85
+ userId,
86
+ ttl,
87
+ appName: this.appName
88
+ });
89
+ } catch (error) {
90
+ _loggerProxy.default.error(`WebexCrossClientService refresh failed: ${error}`, {
91
+ module: WEBEX_CROSS_CLIENT_FILE,
92
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
93
+ });
94
+ this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, 0);
95
+ }
96
+ }, refreshTime);
97
+ }
98
+ publishCrossClientState(users, ttl, composition, logContext) {
99
+ const body = {
100
+ users,
101
+ compositions: [{
102
+ type: 'cross-client-state',
103
+ ttl,
104
+ composition
105
+ }]
106
+ };
107
+ return this.webex.request({
108
+ method: 'POST',
109
+ service: 'usersub',
110
+ resource: 'publish',
111
+ body
112
+ }).then(response => response?.body).catch(error => {
113
+ _loggerProxy.default.error(`WebexCrossClientService.${logContext} failed: ${error}`, {
114
+ module: WEBEX_CROSS_CLIENT_FILE,
115
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
116
+ });
117
+ return Promise.reject(error);
118
+ });
119
+ }
120
+ async setManageWebexCallingInWxcc(enable, options) {
121
+ const operationGeneration = this.refreshGeneration;
122
+ const userId = options?.userId ?? this.webex.internal.device?.userId;
123
+ const ttl = options?.ttl ?? DEFAULT_CROSS_CLIENT_STATE_TTL;
124
+ const appName = options?.appName ?? DEFAULT_APP_NAME;
125
+ const trackPublishMetrics = options?.trackPublishMetrics ?? false;
126
+ this.appName = appName;
127
+ if (!userId) {
128
+ const error = 'User ID is unavailable for cross-client publish';
129
+ this.trackUsersubPreflightFailure(enable, 'user_id_unavailable', error, trackPublishMetrics);
130
+ throw new Error(error);
131
+ }
132
+ const deviceUrl = this.getDeviceUrl();
133
+ if (!deviceUrl) {
134
+ const error = 'Device URL is unavailable for cross-client publish';
135
+ this.trackUsersubPreflightFailure(enable, 'device_url_unavailable', error, trackPublishMetrics);
136
+ throw new Error(error);
137
+ }
138
+ const composition = {
139
+ devices: [{
140
+ deviceId: this.extractDeviceIdFromUrl(deviceUrl),
141
+ appName,
142
+ state: {
143
+ 'answer-calls-on-wxcc': enable
144
+ }
145
+ }]
146
+ };
147
+ const metricsManager = _MetricsManager.default.getInstance();
148
+ const usersubPublishEventKeys = [_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS, _constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED];
149
+ let publishMetricsId = 0;
150
+ if (trackPublishMetrics) {
151
+ this.usersubPublishMetricsId += 1;
152
+ publishMetricsId = this.usersubPublishMetricsId;
153
+ metricsManager.timeEvent(usersubPublishEventKeys);
154
+ }
155
+ try {
156
+ await this.publishCrossClientState([userId], ttl, composition, 'setManageWebexCallingInWxcc');
157
+ } catch (error) {
158
+ if (trackPublishMetrics) {
159
+ if (operationGeneration !== this.refreshGeneration) {
160
+ if (publishMetricsId === this.usersubPublishMetricsId) {
161
+ metricsManager.cancelTimedEvent(usersubPublishEventKeys);
162
+ }
163
+ } else {
164
+ metricsManager.trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED, {
165
+ enableWxBetterTogether: enable,
166
+ usersubPublished: this.answerCallsState,
167
+ error: error instanceof Error ? error.toString() : String(error)
168
+ }, ['operational', 'behavioral']);
169
+ }
170
+ }
171
+ throw error;
172
+ }
173
+ if (operationGeneration !== this.refreshGeneration) {
174
+ if (trackPublishMetrics && publishMetricsId === this.usersubPublishMetricsId) {
175
+ metricsManager.cancelTimedEvent(usersubPublishEventKeys);
176
+ }
177
+ return;
178
+ }
179
+ this.answerCallsState = enable;
180
+ if (enable) {
181
+ this.startRefreshTimer(userId, ttl);
182
+ } else {
183
+ this.refreshGeneration += 1;
184
+ this.clearRefreshTimer();
185
+ }
186
+ if (trackPublishMetrics) {
187
+ metricsManager.trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS, {
188
+ enableWxBetterTogether: enable,
189
+ usersubPublished: enable
190
+ }, ['operational', 'behavioral']);
191
+ }
192
+ _loggerProxy.default.log(`Cross-client answer-calls-on-wxcc set to ${enable}`, {
193
+ module: WEBEX_CROSS_CLIENT_FILE,
194
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,
195
+ data: {
196
+ appName,
197
+ deviceId: this.extractDeviceIdFromUrl(deviceUrl),
198
+ ttl
199
+ }
200
+ });
201
+ }
202
+ trackUsersubPreflightFailure(enable, skipReason, error, trackPublishMetrics) {
203
+ if (!trackPublishMetrics) {
204
+ return;
205
+ }
206
+ _MetricsManager.default.getInstance().trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED, {
207
+ enableWxBetterTogether: enable,
208
+ usersubPublished: this.answerCallsState,
209
+ skipReason,
210
+ error
211
+ }, ['operational', 'behavioral']);
212
+ }
213
+ teardown() {
214
+ this.refreshGeneration += 1;
215
+ this.clearRefreshTimer();
216
+ this.answerCallsState = false;
217
+ }
218
+
219
+ /** Whether usersub `answer-calls-on-wxcc: true` was successfully published this session. */
220
+ isAnswerCallsStateActive() {
221
+ return this.answerCallsState;
222
+ }
223
+ }
224
+ exports.default = WebexCrossClientService;
225
+ //# sourceMappingURL=WebexCrossClientService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","_MetricsManager","_constants2","e","__esModule","default","WEBEX_CROSS_CLIENT_FILE","DEFAULT_CROSS_CLIENT_STATE_TTL","EXPIRATION_OFFSET_MS","DEFAULT_APP_NAME","REFRESH_RETRY_DELAY_MS","MAX_REFRESH_RETRIES","WebexCrossClientService","answerCallsState","appName","refreshGeneration","usersubPublishMetricsId","constructor","webex","extractDeviceIdFromUrl","url","match","getDeviceUrl","internal","device","clearRefreshTimer","refreshTimer","clearTimeout","undefined","refreshRetryTimer","scheduleRefreshRetry","userId","ttl","scheduledGeneration","retryAttempt","setTimeout","setManageWebexCallingInWxcc","error","LoggerProxy","module","method","METHODS","SET_MANAGE_WEBEX_CALLING_IN_WXCC","startRefreshTimer","refreshTime","publishCrossClientState","users","composition","logContext","body","compositions","type","request","service","resource","then","response","catch","Promise","reject","enable","options","operationGeneration","trackPublishMetrics","trackUsersubPreflightFailure","Error","deviceUrl","devices","deviceId","state","metricsManager","MetricsManager","getInstance","usersubPublishEventKeys","METRIC_EVENT_NAMES","WXAPP_USERSUB_PUBLISH_SUCCESS","WXAPP_USERSUB_PUBLISH_FAILED","publishMetricsId","timeEvent","cancelTimedEvent","trackEvent","enableWxBetterTogether","usersubPublished","toString","String","log","data","skipReason","teardown","isAnswerCallsStateActive","exports"],"sources":["WebexCrossClientService.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {METHODS} from '../constants';\nimport {WebexSDK} from '../types';\nimport MetricsManager from '../metrics/MetricsManager';\nimport {METRIC_EVENT_NAMES} from '../metrics/constants';\n\nconst WEBEX_CROSS_CLIENT_FILE = 'WebexCrossClientService';\nconst DEFAULT_CROSS_CLIENT_STATE_TTL = 900;\nconst EXPIRATION_OFFSET_MS = 60_000;\n/** Must match Agent Desktop usersub publish — Webex App reads `wxcc` cross-client state. */\nconst DEFAULT_APP_NAME = 'wxcc';\nconst REFRESH_RETRY_DELAY_MS = 30_000;\nconst MAX_REFRESH_RETRIES = 3;\n\ntype RefreshTimer = ReturnType<typeof setTimeout>;\n\n/**\n * Publishes usersub cross-client state so Webex App suppresses native calling toasts (WXCC-6026).\n */\nexport default class WebexCrossClientService {\n private webex: WebexSDK;\n private refreshTimer?: RefreshTimer;\n private refreshRetryTimer?: RefreshTimer;\n private answerCallsState = false;\n private appName = DEFAULT_APP_NAME;\n /** Incremented on teardown/disable to ignore stale refresh timer callbacks. */\n private refreshGeneration = 0;\n /** Monotonic id for usersub publish metrics timers; stale publishes cancel only their own timer. */\n private usersubPublishMetricsId = 0;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private extractDeviceIdFromUrl(url: string): string {\n const match = url.match(/\\/devices\\/([^/?]+)/);\n\n return match ? match[1] : '';\n }\n\n private getDeviceUrl(): string | undefined {\n return this.webex.internal.device?.url;\n }\n\n private clearRefreshTimer(): void {\n if (this.refreshTimer) {\n clearTimeout(this.refreshTimer);\n this.refreshTimer = undefined;\n }\n\n if (this.refreshRetryTimer) {\n clearTimeout(this.refreshRetryTimer);\n this.refreshRetryTimer = undefined;\n }\n }\n\n private scheduleRefreshRetry(\n userId: string,\n ttl: number,\n scheduledGeneration: number,\n retryAttempt: number\n ): void {\n if (\n retryAttempt >= MAX_REFRESH_RETRIES ||\n scheduledGeneration !== this.refreshGeneration ||\n !this.answerCallsState\n ) {\n return;\n }\n\n this.refreshRetryTimer = setTimeout(async () => {\n if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {\n return;\n }\n\n try {\n await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});\n } catch (error) {\n LoggerProxy.error(`WebexCrossClientService refresh retry failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, retryAttempt + 1);\n }\n }, REFRESH_RETRY_DELAY_MS);\n }\n\n private startRefreshTimer(userId: string, ttl: number): void {\n this.clearRefreshTimer();\n\n if (!this.answerCallsState) {\n return;\n }\n\n const refreshTime = ttl * 1000 - EXPIRATION_OFFSET_MS;\n const scheduledGeneration = this.refreshGeneration;\n this.refreshTimer = setTimeout(async () => {\n if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {\n return;\n }\n\n try {\n await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});\n } catch (error) {\n LoggerProxy.error(`WebexCrossClientService refresh failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, 0);\n }\n }, refreshTime);\n }\n\n private publishCrossClientState(\n users: string[],\n ttl: number,\n composition: Record<string, unknown>,\n logContext: string\n ): Promise<unknown> {\n const body = {\n users,\n compositions: [\n {\n type: 'cross-client-state',\n ttl,\n composition,\n },\n ],\n };\n\n return this.webex\n .request({\n method: 'POST',\n service: 'usersub',\n resource: 'publish',\n body,\n })\n .then((response: {body?: unknown}) => response?.body)\n .catch((error: unknown) => {\n LoggerProxy.error(`WebexCrossClientService.${logContext} failed: ${error}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n });\n\n return Promise.reject(error);\n });\n }\n\n public async setManageWebexCallingInWxcc(\n enable: boolean,\n options?: {userId?: string; ttl?: number; appName?: string; trackPublishMetrics?: boolean}\n ): Promise<void> {\n const operationGeneration = this.refreshGeneration;\n const userId = options?.userId ?? this.webex.internal.device?.userId;\n const ttl = options?.ttl ?? DEFAULT_CROSS_CLIENT_STATE_TTL;\n const appName = options?.appName ?? DEFAULT_APP_NAME;\n const trackPublishMetrics = options?.trackPublishMetrics ?? false;\n this.appName = appName;\n\n if (!userId) {\n const error = 'User ID is unavailable for cross-client publish';\n this.trackUsersubPreflightFailure(enable, 'user_id_unavailable', error, trackPublishMetrics);\n throw new Error(error);\n }\n\n const deviceUrl = this.getDeviceUrl();\n if (!deviceUrl) {\n const error = 'Device URL is unavailable for cross-client publish';\n this.trackUsersubPreflightFailure(\n enable,\n 'device_url_unavailable',\n error,\n trackPublishMetrics\n );\n throw new Error(error);\n }\n\n const composition = {\n devices: [\n {\n deviceId: this.extractDeviceIdFromUrl(deviceUrl),\n appName,\n state: {\n 'answer-calls-on-wxcc': enable,\n },\n },\n ],\n };\n\n const metricsManager = MetricsManager.getInstance();\n const usersubPublishEventKeys = [\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS,\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED,\n ];\n\n let publishMetricsId = 0;\n if (trackPublishMetrics) {\n this.usersubPublishMetricsId += 1;\n publishMetricsId = this.usersubPublishMetricsId;\n metricsManager.timeEvent(usersubPublishEventKeys);\n }\n\n try {\n await this.publishCrossClientState([userId], ttl, composition, 'setManageWebexCallingInWxcc');\n } catch (error) {\n if (trackPublishMetrics) {\n if (operationGeneration !== this.refreshGeneration) {\n if (publishMetricsId === this.usersubPublishMetricsId) {\n metricsManager.cancelTimedEvent(usersubPublishEventKeys);\n }\n } else {\n metricsManager.trackEvent(\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED,\n {\n enableWxBetterTogether: enable,\n usersubPublished: this.answerCallsState,\n error: error instanceof Error ? error.toString() : String(error),\n },\n ['operational', 'behavioral']\n );\n }\n }\n\n throw error;\n }\n\n if (operationGeneration !== this.refreshGeneration) {\n if (trackPublishMetrics && publishMetricsId === this.usersubPublishMetricsId) {\n metricsManager.cancelTimedEvent(usersubPublishEventKeys);\n }\n\n return;\n }\n\n this.answerCallsState = enable;\n\n if (enable) {\n this.startRefreshTimer(userId, ttl);\n } else {\n this.refreshGeneration += 1;\n this.clearRefreshTimer();\n }\n\n if (trackPublishMetrics) {\n metricsManager.trackEvent(\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_SUCCESS,\n {\n enableWxBetterTogether: enable,\n usersubPublished: enable,\n },\n ['operational', 'behavioral']\n );\n }\n\n LoggerProxy.log(`Cross-client answer-calls-on-wxcc set to ${enable}`, {\n module: WEBEX_CROSS_CLIENT_FILE,\n method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,\n data: {\n appName,\n deviceId: this.extractDeviceIdFromUrl(deviceUrl),\n ttl,\n },\n });\n }\n\n private trackUsersubPreflightFailure(\n enable: boolean,\n skipReason: 'user_id_unavailable' | 'device_url_unavailable',\n error: string,\n trackPublishMetrics: boolean\n ): void {\n if (!trackPublishMetrics) {\n return;\n }\n\n MetricsManager.getInstance().trackEvent(\n METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED,\n {\n enableWxBetterTogether: enable,\n usersubPublished: this.answerCallsState,\n skipReason,\n error,\n },\n ['operational', 'behavioral']\n );\n }\n\n public teardown(): void {\n this.refreshGeneration += 1;\n this.clearRefreshTimer();\n this.answerCallsState = false;\n }\n\n /** Whether usersub `answer-calls-on-wxcc: true` was successfully published this session. */\n public isAnswerCallsStateActive(): boolean {\n return this.answerCallsState;\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.TELEPHONY_CALL_UNMUTED = exports.TELEPHONY_CALL_MUTED = void 0;
7
+ var _loggerProxy = _interopRequireDefault(require("../logger-proxy"));
8
+ var _constants = require("../constants");
9
+ var _MetricsManager = _interopRequireDefault(require("../metrics/MetricsManager"));
10
+ var _constants2 = require("../metrics/constants");
11
+ var _wxAppDiagnosticLogging = require("./wxAppDiagnosticLogging");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ const WXAPP_TELEPHONY_MERCURY_SYNC_FILE = 'WxAppTelephonyMercurySync';
14
+ const TELEPHONY_CALL_MUTED = exports.TELEPHONY_CALL_MUTED = 'event:telephony_calls.muted';
15
+ const TELEPHONY_CALL_UNMUTED = exports.TELEPHONY_CALL_UNMUTED = 'event:telephony_calls.unmuted';
16
+ /**
17
+ * Subscribes to Mercury telephony mute/unmute events for wxApp thick-client sync (AD parity).
18
+ */
19
+ class WxAppTelephonyMercurySync {
20
+ constructor(webex) {
21
+ this.webex = webex;
22
+ }
23
+ decodeBase64(value) {
24
+ try {
25
+ return atob(value);
26
+ } catch {
27
+ return value;
28
+ }
29
+ }
30
+ handleMuteStateEvent = (agentId, event) => {
31
+ const {
32
+ actorId,
33
+ callId,
34
+ muted
35
+ } = event?.data ?? {};
36
+ if (!actorId || !callId || muted === undefined) {
37
+ (0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
38
+ phase: 'dropped',
39
+ dropReason: 'missing_mercury_event_fields'
40
+ });
41
+ return;
42
+ }
43
+ const decodedActorId = this.decodeBase64(actorId);
44
+ const decodedCallId = this.decodeBase64(callId);
45
+ if (!decodedActorId.endsWith(agentId)) {
46
+ (0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
47
+ phase: 'dropped',
48
+ muted,
49
+ callIdSuffix: (0, _wxAppDiagnosticLogging.callIdSuffix)(decodedCallId),
50
+ dropReason: 'actor_id_mismatch'
51
+ });
52
+ return;
53
+ }
54
+ (0, _wxAppDiagnosticLogging.logWxAppMercuryMuteSync)({
55
+ phase: 'received',
56
+ muted,
57
+ callIdSuffix: (0, _wxAppDiagnosticLogging.callIdSuffix)(decodedCallId)
58
+ });
59
+ this.muteChangeHandler?.(decodedCallId, muted);
60
+ };
61
+ subscribe(agentId, onMuteChange) {
62
+ this.unsubscribe();
63
+ const mercury = this.webex.internal.mercury;
64
+ if (!mercury) {
65
+ _loggerProxy.default.error('Mercury is unavailable for wxApp mute sync', {
66
+ module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
67
+ method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
68
+ });
69
+ _MetricsManager.default.getInstance().trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_FAILED, {
70
+ error: 'Mercury is unavailable for wxApp mute sync',
71
+ mercurySubscribed: false
72
+ }, ['operational', 'behavioral']);
73
+ return;
74
+ }
75
+ this.subscribedAgentId = agentId;
76
+ this.muteChangeHandler = onMuteChange;
77
+ this.boundMuteHandler = event => {
78
+ this.handleMuteStateEvent(agentId, event);
79
+ };
80
+ this.boundUnmuteHandler = event => {
81
+ this.handleMuteStateEvent(agentId, event);
82
+ };
83
+ mercury.on(TELEPHONY_CALL_MUTED, this.boundMuteHandler);
84
+ mercury.on(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);
85
+ _MetricsManager.default.getInstance().trackEvent(_constants2.METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_SUCCESS, {
86
+ mercurySubscribed: true
87
+ }, ['operational', 'behavioral']);
88
+ _loggerProxy.default.log('Subscribed to wxApp telephony Mercury mute sync', {
89
+ module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
90
+ method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
91
+ });
92
+ }
93
+ unsubscribe() {
94
+ const mercury = this.webex.internal.mercury;
95
+ if (mercury && this.boundMuteHandler) {
96
+ mercury.off(TELEPHONY_CALL_MUTED, this.boundMuteHandler);
97
+ }
98
+ if (mercury && this.boundUnmuteHandler) {
99
+ mercury.off(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);
100
+ }
101
+ this.subscribedAgentId = undefined;
102
+ this.muteChangeHandler = undefined;
103
+ this.boundMuteHandler = undefined;
104
+ this.boundUnmuteHandler = undefined;
105
+ }
106
+ isSubscribed() {
107
+ return Boolean(this.subscribedAgentId && this.muteChangeHandler);
108
+ }
109
+ }
110
+ exports.default = WxAppTelephonyMercurySync;
111
+ //# sourceMappingURL=WxAppTelephonyMercurySync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_loggerProxy","_interopRequireDefault","require","_constants","_MetricsManager","_constants2","_wxAppDiagnosticLogging","e","__esModule","default","WXAPP_TELEPHONY_MERCURY_SYNC_FILE","TELEPHONY_CALL_MUTED","exports","TELEPHONY_CALL_UNMUTED","WxAppTelephonyMercurySync","constructor","webex","decodeBase64","value","atob","handleMuteStateEvent","agentId","event","actorId","callId","muted","data","undefined","logWxAppMercuryMuteSync","phase","dropReason","decodedActorId","decodedCallId","endsWith","callIdSuffix","muteChangeHandler","subscribe","onMuteChange","unsubscribe","mercury","internal","LoggerProxy","error","module","method","METHODS","SYNC_WXAPP_MUTE_FROM_MERCURY","MetricsManager","getInstance","trackEvent","METRIC_EVENT_NAMES","WXAPP_MERCURY_SUBSCRIBE_FAILED","mercurySubscribed","subscribedAgentId","boundMuteHandler","boundUnmuteHandler","on","WXAPP_MERCURY_SUBSCRIBE_SUCCESS","log","off","isSubscribed","Boolean"],"sources":["WxAppTelephonyMercurySync.ts"],"sourcesContent":["import LoggerProxy from '../logger-proxy';\nimport {METHODS} from '../constants';\nimport {WebexSDK} from '../types';\nimport MetricsManager from '../metrics/MetricsManager';\nimport {METRIC_EVENT_NAMES} from '../metrics/constants';\nimport {callIdSuffix, logWxAppMercuryMuteSync} from './wxAppDiagnosticLogging';\n\nconst WXAPP_TELEPHONY_MERCURY_SYNC_FILE = 'WxAppTelephonyMercurySync';\n\nexport const TELEPHONY_CALL_MUTED = 'event:telephony_calls.muted';\nexport const TELEPHONY_CALL_UNMUTED = 'event:telephony_calls.unmuted';\n\nexport type UpdatedCallMuteStateEvent = {\n data: {\n actorId: string;\n callId: string;\n muted: boolean;\n };\n};\n\ntype MuteChangeHandler = (callId: string, muted: boolean) => void;\n\n/**\n * Subscribes to Mercury telephony mute/unmute events for wxApp thick-client sync (AD parity).\n */\nexport default class WxAppTelephonyMercurySync {\n private webex: WebexSDK;\n private subscribedAgentId?: string;\n private muteChangeHandler?: MuteChangeHandler;\n private boundMuteHandler?: (event: UpdatedCallMuteStateEvent) => void;\n private boundUnmuteHandler?: (event: UpdatedCallMuteStateEvent) => void;\n\n constructor(webex: WebexSDK) {\n this.webex = webex;\n }\n\n private decodeBase64(value: string): string {\n try {\n return atob(value);\n } catch {\n return value;\n }\n }\n\n private handleMuteStateEvent = (agentId: string, event: UpdatedCallMuteStateEvent): void => {\n const {actorId, callId, muted} = event?.data ?? {};\n if (!actorId || !callId || muted === undefined) {\n logWxAppMercuryMuteSync({\n phase: 'dropped',\n dropReason: 'missing_mercury_event_fields',\n });\n\n return;\n }\n\n const decodedActorId = this.decodeBase64(actorId);\n const decodedCallId = this.decodeBase64(callId);\n\n if (!decodedActorId.endsWith(agentId)) {\n logWxAppMercuryMuteSync({\n phase: 'dropped',\n muted,\n callIdSuffix: callIdSuffix(decodedCallId),\n dropReason: 'actor_id_mismatch',\n });\n\n return;\n }\n\n logWxAppMercuryMuteSync({\n phase: 'received',\n muted,\n callIdSuffix: callIdSuffix(decodedCallId),\n });\n\n this.muteChangeHandler?.(decodedCallId, muted);\n };\n\n public subscribe(agentId: string, onMuteChange: MuteChangeHandler): void {\n this.unsubscribe();\n\n const mercury = this.webex.internal.mercury;\n if (!mercury) {\n LoggerProxy.error('Mercury is unavailable for wxApp mute sync', {\n module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,\n method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,\n });\n\n MetricsManager.getInstance().trackEvent(\n METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_FAILED,\n {error: 'Mercury is unavailable for wxApp mute sync', mercurySubscribed: false},\n ['operational', 'behavioral']\n );\n\n return;\n }\n\n this.subscribedAgentId = agentId;\n this.muteChangeHandler = onMuteChange;\n\n this.boundMuteHandler = (event: UpdatedCallMuteStateEvent) => {\n this.handleMuteStateEvent(agentId, event);\n };\n this.boundUnmuteHandler = (event: UpdatedCallMuteStateEvent) => {\n this.handleMuteStateEvent(agentId, event);\n };\n\n mercury.on(TELEPHONY_CALL_MUTED, this.boundMuteHandler);\n mercury.on(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);\n\n MetricsManager.getInstance().trackEvent(\n METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_SUCCESS,\n {mercurySubscribed: true},\n ['operational', 'behavioral']\n );\n\n LoggerProxy.log('Subscribed to wxApp telephony Mercury mute sync', {\n module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,\n method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,\n });\n }\n\n public unsubscribe(): void {\n const mercury = this.webex.internal.mercury;\n\n if (mercury && this.boundMuteHandler) {\n mercury.off(TELEPHONY_CALL_MUTED, this.boundMuteHandler);\n }\n if (mercury && this.boundUnmuteHandler) {\n mercury.off(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);\n }\n\n this.subscribedAgentId = undefined;\n this.muteChangeHandler = undefined;\n this.boundMuteHandler = undefined;\n this.boundUnmuteHandler = undefined;\n }\n\n public isSubscribed(): boolean {\n return Boolean(this.subscribedAgentId && this.muteChangeHandler);\n }\n}\n"],"mappings":"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","ignoreList":[]}
@@ -5,39 +5,29 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.parseAgentConfigs = parseAgentConfigs;
7
7
  var _constants = require("../core/constants");
8
+ var _constants2 = require("./constants");
8
9
  var _types = require("./types");
9
10
  /**
10
- * Get the URL mapping for the given name
11
- * @param {Array<URLMapping>} urlMappings
12
- * @param {string} name
13
- * @returns {string}
14
- */
15
- const getUrlMapping = (urlMappings, name) => {
16
- const mappedUrl = urlMappings.find(mapping => mapping.name === name)?.url;
17
- return mappedUrl || '';
18
- };
19
-
20
- /**
21
- * Get the MSFT and Webex configuration
22
- * @param {DesktopProfileResponse} agentProfileData
11
+ * Get the MSFT configuration
12
+ * @param {MicrosoftConfig} microsoftConfig
23
13
  * @returns {Object}
24
14
  */
25
- const getMsftConfig = agentProfileData => {
15
+ const getMsftConfig = microsoftConfig => {
26
16
  return {
27
- showUserDetailsMS: agentProfileData.showUserDetailsMS ?? false,
28
- stateSynchronizationMS: agentProfileData.stateSynchronizationMS ?? false
17
+ showUserDetailsMS: microsoftConfig?.showUserDetails ?? false,
18
+ stateSynchronizationMS: microsoftConfig?.stateSynchronization ?? false
29
19
  };
30
20
  };
31
21
 
32
22
  /**
33
23
  * Get the Webex configuration
34
- * @param {DesktopProfileResponse} agentProfileData
24
+ * @param {WebexConfig} webexConfig
35
25
  * @returns {Object}
36
26
  */
37
- const getWebexConfig = agentProfileData => {
27
+ const getWebexConfig = webexConfig => {
38
28
  return {
39
- showUserDetailsWebex: agentProfileData.showUserDetailsWebex ?? false,
40
- stateSynchronizationWebex: agentProfileData.stateSynchronizationWebex ?? false
29
+ showUserDetailsWebex: webexConfig?.showUserDetails ?? false,
30
+ stateSynchronizationWebex: webexConfig?.stateSynchronization ?? false
41
31
  };
42
32
  };
43
33
 
@@ -51,15 +41,16 @@ const getDefaultAgentDN = agentDNValidation => {
51
41
  };
52
42
 
53
43
  /**
54
- * Get the filtered dialplan entries
44
+ * Get the dialplan entries for every active plan in the organization.
45
+ * The desktop-login aggregate does not carry the per-profile `dialPlans` selection, so all active
46
+ * plans apply.
55
47
  * @param {Array<DialPlanEntity>} dialPlanData
56
- * @param {Array<string>} profileDialPlans
57
48
  * @returns {Array<Entity>}
58
49
  */
59
- const getFilteredDialplanEntries = (dialPlanData, profileDialPlans) => {
50
+ const getFilteredDialplanEntries = dialPlanData => {
60
51
  const dialPlanEntries = [];
61
52
  dialPlanData.forEach(dailPlan => {
62
- if (profileDialPlans.includes(dailPlan.id)) {
53
+ if (dailPlan.active) {
63
54
  const filteredPlan = {
64
55
  regex: dailPlan.regularExpression,
65
56
  prefix: dailPlan.prefix,
@@ -73,16 +64,17 @@ const getFilteredDialplanEntries = (dialPlanData, profileDialPlans) => {
73
64
  };
74
65
 
75
66
  /**
76
- * Get the filtered aux codes
67
+ * Get the active aux codes of the given type.
68
+ * The desktop-login aggregate does not carry the per-agent restriction lists, so the whole pool
69
+ * returned by the aux-code API applies.
77
70
  * @param {Array<AuxCode>} auxCodes
78
71
  * @param {AuxCodeType} type
79
- * @param {Array<string>} specificCodes
80
72
  * @returns {Array<Entity>}
81
73
  */
82
- const getFilterAuxCodes = (auxCodes, type, specificCodes) => {
74
+ const getFilterAuxCodes = (auxCodes, type) => {
83
75
  const filteredAuxCodes = [];
84
76
  auxCodes.forEach(auxCode => {
85
- if (auxCode.workTypeCode === type && auxCode.active && (specificCodes.length === 0 || specificCodes.includes(auxCode.id))) {
77
+ if (auxCode.workTypeCode === type && auxCode.active) {
86
78
  filteredAuxCodes.push({
87
79
  id: auxCode.id,
88
80
  name: auxCode.name,
@@ -110,21 +102,26 @@ function getDefaultWrapUpCode(wrapUpReasonList) {
110
102
  */
111
103
  function parseAgentConfigs(profileData) {
112
104
  const {
105
+ orgConfig,
113
106
  userData,
107
+ agentProfileData,
114
108
  teamData,
115
- tenantData,
116
- orgInfoData,
117
109
  auxCodes,
118
- orgSettingsData,
119
- agentProfileData,
120
- dialPlanData,
121
- urlMapping,
122
- aiFeatureFlags
110
+ dialPlanData
123
111
  } = profileData;
112
+ const {
113
+ organization: orgInfoData,
114
+ organizationSetting: orgSettingsData,
115
+ tenantConfiguration: tenantData,
116
+ urlMappings,
117
+ aiFeature,
118
+ microsoftConfig,
119
+ webexConfig
120
+ } = orgConfig;
124
121
  const tenantDataTimeout = tenantData.timeoutDesktopInactivityEnabled ? tenantData.timeoutDesktopInactivityMins : null;
125
122
  const inactivityTimeoutTimer = agentProfileData.timeoutDesktopInactivityCustomEnabled ? agentProfileData.timeoutDesktopInactivityMins : tenantDataTimeout;
126
- const wrapupCodes = getFilterAuxCodes(auxCodes, _types.WRAP_UP_CODE, agentProfileData.accessWrapUpCode === 'ALL' ? [] : agentProfileData.wrapUpCodes);
127
- const idleCodes = getFilterAuxCodes(auxCodes, _types.IDLE_CODE, agentProfileData.accessIdleCode === 'ALL' ? [] : agentProfileData.idleCodes);
123
+ const wrapupCodes = getFilterAuxCodes(auxCodes, _types.WRAP_UP_CODE);
124
+ const idleCodes = getFilterAuxCodes(auxCodes, _types.IDLE_CODE);
128
125
  idleCodes.push({
129
126
  id: '0',
130
127
  name: 'Available',
@@ -133,10 +130,11 @@ function parseAgentConfigs(profileData) {
133
130
  }); // pushing available state to idle codes
134
131
 
135
132
  const defaultWrapUpData = getDefaultWrapUpCode(wrapupCodes);
136
- const aiFeature = aiFeatureFlags?.data && aiFeatureFlags.data.length > 0 ? aiFeatureFlags.data[0] : undefined;
133
+ const isWellnessConfigured = aiFeature?.agentWellbeing?.enable === true && aiFeature.agentWellbeing.wellnessBreakReminders === _constants2.WELLNESS_BREAK_REMINDERS_ENABLED;
134
+ const hasAIAssistantLicense = (orgSettingsData.aiAssistantQuantity ?? 0) > 0;
137
135
  const finalData = {
138
136
  teams: teamData,
139
- defaultDn: userData.defaultDialledNumber,
137
+ defaultDn: userData.deafultDialledNumber,
140
138
  forceDefaultDn: tenantData.forceDefaultDn,
141
139
  forceDefaultDnForAgent: getDefaultAgentDN(agentProfileData.agentDNValidation),
142
140
  regexUS: tenantData.dnDefaultRegex,
@@ -145,17 +143,15 @@ function parseAgentConfigs(profileData) {
145
143
  agentName: `${userData.firstName} ${userData.lastName}`,
146
144
  agentMailId: userData.email,
147
145
  agentProfileID: userData.agentProfileId,
148
- autoAnswer: agentProfileData.autoAnswer,
149
146
  dialPlan: agentProfileData.dialPlanEnabled ? {
150
147
  type: 'adhocDial',
151
- dialPlanEntity: getFilteredDialplanEntries(dialPlanData, agentProfileData.dialPlans)
148
+ dialPlanEntity: getFilteredDialplanEntries(dialPlanData)
152
149
  } : undefined,
153
150
  multimediaProfileId: profileData.multimediaProfileId,
154
151
  skillProfileId: userData.skillProfileId ? userData.skillProfileId : null,
155
152
  siteId: userData.siteId,
156
153
  enterpriseId: orgInfoData.tenantId,
157
154
  tenantTimezone: orgInfoData.timezone,
158
- environment: orgInfoData.environment,
159
155
  privacyShieldVisible: tenantData.privacyShieldVisible,
160
156
  organizationIdleCodes: [],
161
157
  // TODO: for supervisor, getOrgFilteredIdleCodes(auxCodes, false),
@@ -179,28 +175,32 @@ function parseAgentConfigs(profileData) {
179
175
  isAgentAvailableAfterOutdial: agentProfileData.agentAvailableAfterOutdial,
180
176
  outDialEp: agentProfileData.outdialEntryPointId,
181
177
  isCampaignManagementEnabled: orgSettingsData.campaignManagerEnabled,
182
- isEndCallEnabled: tenantData.endCallEnabled,
178
+ isEndTaskEnabled: tenantData.endCallEnabled,
183
179
  isEndConsultEnabled: tenantData.endConsultEnabled,
184
180
  callVariablesSuppressed: tenantData.callVariablesSuppressed,
185
181
  agentDbId: userData.dbId,
186
182
  allowConsultToQueue: agentProfileData.consultToQueue,
183
+ accessQueue: agentProfileData.accessQueue,
184
+ accessEntryPoint: agentProfileData.accessEntryPoint,
185
+ accessBuddyTeam: agentProfileData.accessBuddyTeam,
187
186
  agentPersonalStatsEnabled: agentProfileData.viewableStatistics ? agentProfileData.viewableStatistics.agentStats : false,
188
187
  addressBookId: agentProfileData.addressBookId,
189
188
  outdialANIId: agentProfileData.outdialANIId,
190
189
  analyserUserId: userData.id,
191
190
  urlMappings: {
192
- acqueonApiUrl: getUrlMapping(urlMapping, 'ACQUEON_API_URL'),
193
- acqueonConsoleUrl: getUrlMapping(urlMapping, 'ACQUEON_CONSOLE_URL')
191
+ acqueonApiUrl: urlMappings?.ACQUEON_API_URL ?? '',
192
+ acqueonConsoleUrl: urlMappings?.ACQUEON_CONSOLE_URL ?? ''
194
193
  },
195
194
  isTimeoutDesktopInactivityEnabled: tenantData.timeoutDesktopInactivityEnabled,
196
195
  timeoutDesktopInactivityMins: inactivityTimeoutTimer,
197
196
  loginVoiceOptions: agentProfileData.loginVoiceOptions ?? [],
198
197
  webRtcEnabled: orgSettingsData.webRtcEnabled,
199
198
  maskSensitiveData: orgSettingsData.maskSensitiveData ? orgSettingsData.maskSensitiveData : false,
200
- microsoftConfig: getMsftConfig(agentProfileData),
201
- webexConfig: getWebexConfig(agentProfileData),
199
+ microsoftConfig: getMsftConfig(microsoftConfig),
200
+ webexConfig: getWebexConfig(webexConfig),
202
201
  lostConnectionRecoveryTimeout: tenantData.lostConnectionRecoveryTimeout || _constants.LOST_CONNECTION_RECOVERY_TIMEOUT,
203
- aiFeature
202
+ aiFeature,
203
+ isWellnessBreakEnabled: isWellnessConfigured && hasAIAssistantLicense
204
204
  };
205
205
  return finalData;
206
206
  }