@webex/contact-center 3.12.0-next.15 → 3.12.0-next.151

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 (322) 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 +382 -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 +1010 -47
  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 +40 -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 +211 -0
  52. package/dist/metrics/behavioral-events.js.map +1 -1
  53. package/dist/metrics/constants.js +58 -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 +351 -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/WebexCrossClientService.js +225 -0
  68. package/dist/services/WebexCrossClientService.js.map +1 -0
  69. package/dist/services/WxAppTelephonyMercurySync.js +111 -0
  70. package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
  71. package/dist/services/config/Util.js +48 -48
  72. package/dist/services/config/Util.js.map +1 -1
  73. package/dist/services/config/constants.js +56 -78
  74. package/dist/services/config/constants.js.map +1 -1
  75. package/dist/services/config/index.js +100 -226
  76. package/dist/services/config/index.js.map +1 -1
  77. package/dist/services/config/types.js +97 -24
  78. package/dist/services/config/types.js.map +1 -1
  79. package/dist/services/core/Err.js.map +1 -1
  80. package/dist/services/core/Utils.js +111 -32
  81. package/dist/services/core/Utils.js.map +1 -1
  82. package/dist/services/core/WebexRequest.js +6 -2
  83. package/dist/services/core/WebexRequest.js.map +1 -1
  84. package/dist/services/core/aqm-reqs.js +28 -14
  85. package/dist/services/core/aqm-reqs.js.map +1 -1
  86. package/dist/services/core/types.js.map +1 -1
  87. package/dist/services/core/websocket/WebSocketManager.js +2 -1
  88. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  89. package/dist/services/core/websocket/types.js.map +1 -1
  90. package/dist/services/index.js +1 -1
  91. package/dist/services/index.js.map +1 -1
  92. package/dist/services/task/Task.js +955 -0
  93. package/dist/services/task/Task.js.map +1 -0
  94. package/dist/services/task/TaskFactory.js +50 -0
  95. package/dist/services/task/TaskFactory.js.map +1 -0
  96. package/dist/services/task/TaskManager.js +1272 -523
  97. package/dist/services/task/TaskManager.js.map +1 -1
  98. package/dist/services/task/TaskUtils.js +221 -27
  99. package/dist/services/task/TaskUtils.js.map +1 -1
  100. package/dist/services/task/WebexCallingUtils.js +70 -0
  101. package/dist/services/task/WebexCallingUtils.js.map +1 -0
  102. package/dist/services/task/constants.js +21 -2
  103. package/dist/services/task/constants.js.map +1 -1
  104. package/dist/services/task/contact.js +29 -0
  105. package/dist/services/task/contact.js.map +1 -1
  106. package/dist/services/task/dialer.js +78 -0
  107. package/dist/services/task/dialer.js.map +1 -1
  108. package/dist/services/task/digital/Digital.js +78 -0
  109. package/dist/services/task/digital/Digital.js.map +1 -0
  110. package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
  111. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  112. package/dist/services/task/state-machine/actions.js +572 -0
  113. package/dist/services/task/state-machine/actions.js.map +1 -0
  114. package/dist/services/task/state-machine/constants.js +161 -0
  115. package/dist/services/task/state-machine/constants.js.map +1 -0
  116. package/dist/services/task/state-machine/guards.js +379 -0
  117. package/dist/services/task/state-machine/guards.js.map +1 -0
  118. package/dist/services/task/state-machine/index.js +53 -0
  119. package/dist/services/task/state-machine/index.js.map +1 -0
  120. package/dist/services/task/state-machine/types.js +54 -0
  121. package/dist/services/task/state-machine/types.js.map +1 -0
  122. package/dist/services/task/state-machine/uiControlsComputer.js +703 -0
  123. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  124. package/dist/services/task/taskDataNormalizer.js +99 -0
  125. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  126. package/dist/services/task/types.js +259 -5
  127. package/dist/services/task/types.js.map +1 -1
  128. package/dist/services/task/voice/Voice.js +1504 -0
  129. package/dist/services/task/voice/Voice.js.map +1 -0
  130. package/dist/services/task/voice/WebRTC.js +152 -0
  131. package/dist/services/task/voice/WebRTC.js.map +1 -0
  132. package/dist/services/task/voice/wxAppOfferObservability.js +145 -0
  133. package/dist/services/task/voice/wxAppOfferObservability.js.map +1 -0
  134. package/dist/services/task/voice/wxAppVoiceMethods.js +395 -0
  135. package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
  136. package/dist/services/wxAppDiagnosticLogging.js +159 -0
  137. package/dist/services/wxAppDiagnosticLogging.js.map +1 -0
  138. package/dist/services/wxAppTelephonyUtils.js +19 -0
  139. package/dist/services/wxAppTelephonyUtils.js.map +1 -0
  140. package/dist/types/cc.d.ts +196 -9
  141. package/dist/types/config.d.ts +13 -0
  142. package/dist/types/constants.d.ts +38 -1
  143. package/dist/types/index.d.ts +54 -20
  144. package/dist/types/metrics/MetricsManager.d.ts +6 -0
  145. package/dist/types/metrics/constants.d.ts +52 -1
  146. package/dist/types/services/AddressBook.d.ts +2 -1
  147. package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
  148. package/dist/types/services/ApiAiAssistant.d.ts +58 -5
  149. package/dist/types/services/EntryPoint.d.ts +7 -5
  150. package/dist/types/services/Queue.d.ts +5 -3
  151. package/dist/types/services/UserPreference.d.ts +118 -0
  152. package/dist/types/services/WebexCrossClientService.d.ts +32 -0
  153. package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
  154. package/dist/types/services/config/Util.d.ts +4 -8
  155. package/dist/types/services/config/constants.d.ts +49 -76
  156. package/dist/types/services/config/index.d.ts +16 -64
  157. package/dist/types/services/config/types.d.ts +248 -114
  158. package/dist/types/services/core/Err.d.ts +6 -0
  159. package/dist/types/services/core/Utils.d.ts +35 -13
  160. package/dist/types/services/core/WebexRequest.d.ts +1 -0
  161. package/dist/types/services/core/types.d.ts +2 -0
  162. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  163. package/dist/types/services/core/websocket/types.d.ts +1 -1
  164. package/dist/types/services/index.d.ts +1 -1
  165. package/dist/types/services/task/Task.d.ts +186 -0
  166. package/dist/types/services/task/TaskFactory.d.ts +14 -0
  167. package/dist/types/services/task/TaskUtils.d.ts +54 -2
  168. package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
  169. package/dist/types/services/task/constants.d.ts +19 -0
  170. package/dist/types/services/task/contact.d.ts +4 -0
  171. package/dist/types/services/task/dialer.d.ts +30 -0
  172. package/dist/types/services/task/digital/Digital.d.ts +23 -0
  173. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1442 -0
  174. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  175. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  176. package/dist/types/services/task/state-machine/guards.d.ts +103 -0
  177. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  178. package/dist/types/services/task/state-machine/types.d.ts +277 -0
  179. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  180. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  181. package/dist/types/services/task/types.d.ts +790 -66
  182. package/dist/types/services/task/voice/Voice.d.ts +241 -0
  183. package/dist/types/services/task/voice/WebRTC.d.ts +54 -0
  184. package/dist/types/services/task/voice/wxAppOfferObservability.d.ts +39 -0
  185. package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +68 -0
  186. package/dist/types/services/wxAppDiagnosticLogging.d.ts +63 -0
  187. package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
  188. package/dist/types/types.d.ts +213 -11
  189. package/dist/types/utils/PageCache.d.ts +20 -3
  190. package/dist/types/webex.d.ts +1 -0
  191. package/dist/types.js +168 -6
  192. package/dist/types.js.map +1 -1
  193. package/dist/utils/PageCache.js +19 -5
  194. package/dist/utils/PageCache.js.map +1 -1
  195. package/dist/webex.js +22 -2
  196. package/dist/webex.js.map +1 -1
  197. package/package.json +16 -12
  198. package/src/cc.ts +1338 -121
  199. package/src/config.ts +13 -0
  200. package/src/constants.ts +41 -1
  201. package/src/index.ts +62 -15
  202. package/src/metrics/MetricsManager.ts +16 -0
  203. package/src/metrics/ai-docs/AGENTS.md +350 -0
  204. package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
  205. package/src/metrics/ai-docs/metrics-spec.md +971 -0
  206. package/src/metrics/behavioral-events.ts +218 -0
  207. package/src/metrics/constants.ts +63 -4
  208. package/src/services/AddressBook.ts +17 -6
  209. package/src/services/AnswerCallOnWebexService.ts +239 -0
  210. package/src/services/ApiAiAssistant.ts +470 -15
  211. package/src/services/EntryPoint.ts +59 -60
  212. package/src/services/Queue.ts +29 -12
  213. package/src/services/UserPreference.ts +509 -0
  214. package/src/services/WebexCrossClientService.ts +298 -0
  215. package/src/services/WxAppTelephonyMercurySync.ts +142 -0
  216. package/src/services/agent/ai-docs/AGENTS.md +240 -0
  217. package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
  218. package/src/services/agent/ai-docs/agent-spec.md +505 -0
  219. package/src/services/ai-docs/AGENTS.md +386 -0
  220. package/src/services/ai-docs/services-spec.md +505 -0
  221. package/src/services/config/Util.ts +54 -84
  222. package/src/services/config/ai-docs/AGENTS.md +250 -0
  223. package/src/services/config/ai-docs/ARCHITECTURE.md +413 -0
  224. package/src/services/config/ai-docs/config-spec.md +669 -0
  225. package/src/services/config/constants.ts +63 -85
  226. package/src/services/config/index.ts +116 -277
  227. package/src/services/config/types.ts +233 -125
  228. package/src/services/core/Err.ts +3 -0
  229. package/src/services/core/Utils.ts +127 -37
  230. package/src/services/core/WebexRequest.ts +3 -1
  231. package/src/services/core/ai-docs/AGENTS.md +381 -0
  232. package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
  233. package/src/services/core/ai-docs/core-spec.md +787 -0
  234. package/src/services/core/aqm-reqs.ts +30 -15
  235. package/src/services/core/types.ts +33 -1
  236. package/src/services/core/websocket/WebSocketManager.ts +2 -0
  237. package/src/services/core/websocket/types.ts +1 -1
  238. package/src/services/index.ts +1 -1
  239. package/src/services/task/Task.ts +1211 -0
  240. package/src/services/task/TaskFactory.ts +82 -0
  241. package/src/services/task/TaskManager.ts +1584 -643
  242. package/src/services/task/TaskUtils.ts +316 -25
  243. package/src/services/task/WebexCallingUtils.ts +136 -0
  244. package/src/services/task/ai-docs/AGENTS.md +457 -0
  245. package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
  246. package/src/services/task/ai-docs/task-spec.md +1501 -0
  247. package/src/services/task/constants.ts +20 -0
  248. package/src/services/task/contact.ts +30 -0
  249. package/src/services/task/dialer.ts +80 -0
  250. package/src/services/task/digital/Digital.ts +102 -0
  251. package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
  252. package/src/services/task/state-machine/actions.ts +741 -0
  253. package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
  254. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
  255. package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
  256. package/src/services/task/state-machine/constants.ts +172 -0
  257. package/src/services/task/state-machine/guards.ts +442 -0
  258. package/src/services/task/state-machine/index.ts +28 -0
  259. package/src/services/task/state-machine/types.ts +258 -0
  260. package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
  261. package/src/services/task/taskDataNormalizer.ts +137 -0
  262. package/src/services/task/types.ts +974 -70
  263. package/src/services/task/voice/Voice.ts +1878 -0
  264. package/src/services/task/voice/WebRTC.ts +194 -0
  265. package/src/services/task/voice/wxAppOfferObservability.ts +204 -0
  266. package/src/services/task/voice/wxAppVoiceMethods.ts +575 -0
  267. package/src/services/wxAppDiagnosticLogging.ts +286 -0
  268. package/src/services/wxAppTelephonyUtils.ts +14 -0
  269. package/src/types.ts +272 -13
  270. package/src/utils/AGENTS.md +289 -0
  271. package/src/utils/PageCache.ts +38 -5
  272. package/src/utils/ai-docs/utils-spec.md +391 -0
  273. package/src/webex.js +10 -0
  274. package/test/unit/fixtures/aiSummaryTestUtils.ts +40 -0
  275. package/test/unit/spec/cc.ts +3705 -150
  276. package/test/unit/spec/index.ts +885 -0
  277. package/test/unit/spec/logger-proxy.ts +70 -0
  278. package/test/unit/spec/metrics/MetricsManager.ts +25 -0
  279. package/test/unit/spec/metrics/behavioral-events.ts +60 -0
  280. package/test/unit/spec/services/AddressBook.ts +37 -6
  281. package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
  282. package/test/unit/spec/services/ApiAiAssistant.ts +429 -23
  283. package/test/unit/spec/services/EntryPoint.ts +87 -40
  284. package/test/unit/spec/services/Queue.ts +123 -12
  285. package/test/unit/spec/services/UserPreference.ts +401 -0
  286. package/test/unit/spec/services/WebCallingService.ts +7 -1
  287. package/test/unit/spec/services/WebexCrossClientService.ts +509 -0
  288. package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
  289. package/test/unit/spec/services/config/Util.ts +501 -0
  290. package/test/unit/spec/services/config/index.ts +317 -547
  291. package/test/unit/spec/services/core/Utils.ts +425 -8
  292. package/test/unit/spec/services/core/WebexRequest.ts +8 -7
  293. package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
  294. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
  295. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  296. package/test/unit/spec/services/task/Task.ts +2723 -0
  297. package/test/unit/spec/services/task/TaskFactory.ts +116 -0
  298. package/test/unit/spec/services/task/TaskManager.ts +4781 -1585
  299. package/test/unit/spec/services/task/TaskUtils.ts +307 -0
  300. package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
  301. package/test/unit/spec/services/task/contact.ts +33 -0
  302. package/test/unit/spec/services/task/dialer.ts +190 -0
  303. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  304. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +4060 -0
  305. package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
  306. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  307. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
  308. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  309. package/test/unit/spec/services/task/voice/Voice.ts +2355 -0
  310. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  311. package/test/unit/spec/services/task/voice/wxAppOfferObservability.ts +361 -0
  312. package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +719 -0
  313. package/test/unit/spec/services/wxAppDiagnosticLogging.ts +179 -0
  314. package/test/unit/spec/wellnessSampleUtils.ts +288 -0
  315. package/typedoc.md +1 -1
  316. package/umd/contact-center.min.js +2 -2
  317. package/umd/contact-center.min.js.map +1 -1
  318. package/dist/services/task/index.js +0 -1530
  319. package/dist/services/task/index.js.map +0 -1
  320. package/dist/types/services/task/index.d.ts +0 -650
  321. package/src/services/task/index.ts +0 -1806
  322. package/test/unit/spec/services/task/index.ts +0 -2205
package/dist/cc.js CHANGED
@@ -19,6 +19,10 @@ var _Utils = require("./services/core/Utils");
19
19
  var _types3 = require("./services/config/types");
20
20
  var _TaskManager = _interopRequireDefault(require("./services/task/TaskManager"));
21
21
  var _WebCallingService = _interopRequireDefault(require("./services/WebCallingService"));
22
+ var _AnswerCallOnWebexService = _interopRequireDefault(require("./services/AnswerCallOnWebexService"));
23
+ var _WebexCrossClientService = _interopRequireDefault(require("./services/WebexCrossClientService"));
24
+ var _WxAppTelephonyMercurySync = _interopRequireDefault(require("./services/WxAppTelephonyMercurySync"));
25
+ var _wxAppDiagnosticLogging = require("./services/wxAppDiagnosticLogging");
22
26
  var _types4 = require("./services/task/types");
23
27
  var _MetricsManager = _interopRequireDefault(require("./metrics/MetricsManager"));
24
28
  var _constants4 = require("./metrics/constants");
@@ -26,6 +30,7 @@ var _EntryPoint = require("./services/EntryPoint");
26
30
  var _AddressBook = require("./services/AddressBook");
27
31
  var _Queue = require("./services/Queue");
28
32
  var _ApiAiAssistant = require("./services/ApiAiAssistant");
33
+ var _UserPreference = require("./services/UserPreference");
29
34
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
30
35
  /**
31
36
  * @module CCPlugin
@@ -118,7 +123,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
118
123
  *
119
124
  * // Login with browser-based calling
120
125
  * await cc.stationLogin({
121
- * teamId: profile.teams[0].teamId,
126
+ * teamId: profile.teams[0].id,
122
127
  * loginOption: 'BROWSER'
123
128
  * });
124
129
  *
@@ -184,6 +189,29 @@ class ContactCenter extends _webexCore.WebexPlugin {
184
189
  * @private
185
190
  */
186
191
 
192
+ /**
193
+ * REST telephony for wxApp thick-client answer (WXCC-6026)
194
+ * @private
195
+ */
196
+
197
+ /**
198
+ * usersub cross-client state for Webex App toast suppression
199
+ * @private
200
+ */
201
+
202
+ /**
203
+ * Mercury telephony mute sync for wxApp thick-client answer
204
+ * @private
205
+ */
206
+
207
+ /** True when wxApp mute sync opened Mercury (Extension/DN-only profiles). */
208
+ wxAppMercuryConnectedByCc = false;
209
+
210
+ /** True when wxApp mute sync registered the Webex device. */
211
+ wxAppDeviceRegisteredByCc = false;
212
+ static WXAPP_FALSE_PUBLISH_RETRY_DELAY_MS = 30_000;
213
+ static WXAPP_FALSE_PUBLISH_MAX_RETRIES = 3;
214
+
187
215
  /**
188
216
  * Core service managers for Contact Center operations
189
217
  * Includes agent, connection, and configuration services
@@ -212,6 +240,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
212
240
  * @private
213
241
  */
214
242
 
243
+ /** Current login/relogin session used for agent-scoped wellness validation. */
244
+
245
+ /** Registered-session cache for the system WellbeingBreak idle code. */
246
+
247
+ /** Registration generation that owns the wellness idle-code cache and in-flight lookups. */
248
+ wellnessRegistrationGeneration = 0;
249
+ updateWellnessSession(agentSessionId) {
250
+ this.currentAgentSessionId = agentSessionId;
251
+ }
252
+
215
253
  /**
216
254
  * API instance for managing Webex Contact Center entry points
217
255
  * Provides functionality to fetch entry points with caching support
@@ -274,6 +312,36 @@ class ContactCenter extends _webexCore.WebexPlugin {
274
312
  * ```
275
313
  */
276
314
 
315
+ /**
316
+ * API instance for managing Webex Contact Center user preferences
317
+ * Provides functionality to get, create, update, and delete user preferences
318
+ * @type {UserPreference}
319
+ * @public
320
+ * @example
321
+ * ```typescript
322
+ * const cc = webex.cc;
323
+ * await cc.register();
324
+ * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
325
+ *
326
+ * // Get user preferences for current user
327
+ * const preferences = await cc.userPreference.getUserPreference();
328
+ *
329
+ * // Create new user preferences
330
+ * const newPrefs = await cc.userPreference.createUserPreference({
331
+ * userId: 'user123',
332
+ * preferences: { e911Reminder: true }
333
+ * });
334
+ *
335
+ * // Update user preferences
336
+ * const updatedPrefs = await cc.userPreference.updateUserPreference('user123', {
337
+ * preferences: { e911Reminder: false }
338
+ * });
339
+ *
340
+ * // Delete user preferences
341
+ * await cc.userPreference.deleteUserPreference('user123');
342
+ * ```
343
+ */
344
+
277
345
  /**
278
346
  * API instance for AI Assistant operations such as transcript controls.
279
347
  * @type {ApiAIAssistant}
@@ -301,6 +369,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
301
369
  this.$webex.once(_constants.READY, () => {
302
370
  // @ts-ignore
303
371
  this.$config = this.config;
372
+ this.validatePluginConfig();
304
373
 
305
374
  /**
306
375
  * This is used for handling the async requests by sending webex.request and wait for corresponding websocket event.
@@ -312,13 +381,20 @@ class ContactCenter extends _webexCore.WebexPlugin {
312
381
  webex: this.$webex,
313
382
  connectionConfig: this.getConnectionConfig()
314
383
  });
315
- this.services.webSocketManager.on('message', this.handleWebsocketMessage);
316
384
  this.webCallingService = new _WebCallingService.default(this.$webex);
317
- this.apiAIAssistant = new _ApiAiAssistant.ApiAIAssistant(this.$webex);
385
+ this.answerCallOnWebexService = new _AnswerCallOnWebexService.default(this.$webex);
386
+ this.webexCrossClientService = new _WebexCrossClientService.default(this.$webex);
387
+ this.wxAppTelephonyMercurySync = new _WxAppTelephonyMercurySync.default(this.$webex);
388
+ this.apiAIAssistant = new _ApiAiAssistant.ApiAIAssistant(this.$webex, () => ({
389
+ isWellnessBreakEnabled: this.agentConfig?.isWellnessBreakEnabled === true,
390
+ agentId: this.agentConfig?.agentId,
391
+ agentSessionId: this.currentAgentSessionId
392
+ }));
318
393
  this.metricsManager = _MetricsManager.default.getInstance({
319
394
  webex: this.$webex
320
395
  });
321
- this.taskManager = _TaskManager.default.getTaskManager(this.apiAIAssistant, this.services.contact, this.webCallingService, this.services.webSocketManager);
396
+ this.taskManager = _TaskManager.default.getTaskManager(this.apiAIAssistant, this.services.contact, this.webCallingService, this.services.webSocketManager, this.services.rtdWebSocketManager);
397
+ this.taskManager.setAnswerCallOnWebexService(this.answerCallOnWebexService);
322
398
  this.incomingTaskListener();
323
399
 
324
400
  // Initialize API instances
@@ -326,6 +402,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
326
402
  this.entryPoint = new _EntryPoint.EntryPoint(this.$webex);
327
403
  this.addressBook = new _AddressBook.AddressBook(this.$webex, () => this.agentConfig?.addressBookId);
328
404
  this.queue = new _Queue.Queue(this.$webex);
405
+ this.userPreference = new _UserPreference.UserPreference(this.$webex, () => this.agentConfig?.agentId);
329
406
  _loggerProxy.default.initialize(this.$webex.logger);
330
407
  });
331
408
  }
@@ -350,6 +427,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
350
427
  this.trigger(_types4.TASK_EVENTS.TASK_HYDRATE, task);
351
428
  };
352
429
 
430
+ /**
431
+ * Handles multi-login hydrate events for SDK instances without Mobius registration
432
+ * @private
433
+ * @param {ITask} task The task object associated with the multi-login hydrate
434
+ */
435
+ handleTaskMultiLoginHydrate = task => {
436
+ // @ts-ignore
437
+ this.trigger(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, task);
438
+ };
439
+
353
440
  /**
354
441
  * Handles task merged events when tasks are combined eg: EPDN merge/transfer
355
442
  * @private
@@ -369,8 +456,83 @@ class ContactCenter extends _webexCore.WebexPlugin {
369
456
  // @ts-ignore
370
457
  this.trigger(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, task);
371
458
  };
372
- handleRTDWebsocketMessage = payload => {
373
- this.taskManager.handleRealtimeWebsocketEvent(payload);
459
+ trackInvalidWellnessEvent(reason) {
460
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_EVENT_INVALID, {
461
+ reason
462
+ }, ['operational']);
463
+ }
464
+ normalizeWellnessBreakEvent(payload) {
465
+ if (this.agentConfig?.isWellnessBreakEnabled !== true) {
466
+ this.trackInvalidWellnessEvent('wellness_disabled');
467
+ return null;
468
+ }
469
+ const notificationData = (0, _Utils.isRecord)(payload.data) ? payload.data : null;
470
+ const notificationDetails = notificationData && (0, _Utils.isRecord)(notificationData.notifDetails) ? notificationData.notifDetails : null;
471
+ const sessionData = notificationData && (0, _Utils.isRecord)(notificationData.data) ? notificationData.data : null;
472
+ const actionEvent = notificationDetails?.actionEvent;
473
+ if (payload.type !== _constants.WELLNESS_BREAK_HANDLER || notificationData?.notifType !== _constants.WELLNESS_BREAK_HANDLER || typeof actionEvent !== 'string') {
474
+ this.trackInvalidWellnessEvent('malformed_wellness_event');
475
+ return null;
476
+ }
477
+ if (!Object.values(_types.WELLNESS_BREAK_NOTIFICATION_ACTIONS).includes(actionEvent)) {
478
+ this.trackInvalidWellnessEvent('unknown_wellness_action');
479
+ return null;
480
+ }
481
+ const agentId = notificationData.agentId;
482
+ const eventOrgId = notificationData.orgId;
483
+ const sessionOrgId = sessionData?.orgId;
484
+ const envelopeOrgId = payload.orgId;
485
+ const agentSessionId = sessionData?.agentSessionId;
486
+ const currentOrgId = this.$webex.credentials.getOrgId();
487
+ if (typeof agentId !== 'string' || typeof eventOrgId !== 'string' || typeof sessionOrgId !== 'string' || typeof envelopeOrgId !== 'string' || typeof agentSessionId !== 'string' || !agentId || !eventOrgId || !sessionOrgId || !envelopeOrgId || !agentSessionId) {
488
+ this.trackInvalidWellnessEvent('missing_wellness_identity');
489
+ return null;
490
+ }
491
+ if (agentId !== this.agentConfig?.agentId || eventOrgId !== currentOrgId || sessionOrgId !== currentOrgId || envelopeOrgId !== currentOrgId) {
492
+ this.trackInvalidWellnessEvent('mismatched_wellness_identity');
493
+ return null;
494
+ }
495
+ const interactionValue = sessionData.interactionId ?? sessionData.InteractionId;
496
+ const actionText = notificationDetails.actionText;
497
+ const trackingId = payload.trackingId;
498
+ return {
499
+ agentId,
500
+ orgId: currentOrgId,
501
+ agentSessionId,
502
+ actionEvent: actionEvent,
503
+ ...(typeof actionText === 'string' ? {
504
+ actionText
505
+ } : {}),
506
+ ...(typeof interactionValue === 'string' ? {
507
+ interactionId: interactionValue
508
+ } : {}),
509
+ ...(typeof trackingId === 'string' ? {
510
+ trackingId
511
+ } : {})
512
+ };
513
+ }
514
+ handleWellnessBreakWebsocketPayload(payload) {
515
+ if (payload.type !== _constants.WELLNESS_BREAK_HANDLER) {
516
+ return false;
517
+ }
518
+ const wellnessEvent = this.normalizeWellnessBreakEvent(payload);
519
+ if (wellnessEvent) {
520
+ // @ts-ignore - WebexPlugin emit is available at runtime but absent from its declaration.
521
+ this.emit(_types3.CC_EVENTS.WELLNESS_BREAK, wellnessEvent);
522
+ }
523
+ return true;
524
+ }
525
+ handleRTDWebsocketMessage = event => {
526
+ let payload;
527
+ try {
528
+ payload = JSON.parse(event);
529
+ } catch {
530
+ // TaskManager retains its existing malformed RTD message handling.
531
+ }
532
+ if ((0, _Utils.isRecord)(payload) && this.handleWellnessBreakWebsocketPayload(payload)) {
533
+ return;
534
+ }
535
+ this.taskManager.handleRealtimeWebsocketEvent(event);
374
536
  };
375
537
 
376
538
  /**
@@ -381,6 +543,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
381
543
  incomingTaskListener() {
382
544
  this.taskManager.on(_types4.TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
383
545
  this.taskManager.on(_types4.TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
546
+ this.taskManager.on(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, this.handleTaskMultiLoginHydrate);
384
547
  this.taskManager.on(_types4.TASK_EVENTS.TASK_MERGED, this.handleTaskMerged);
385
548
  this.taskManager.on(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, this.handleCampaignPreviewReservation);
386
549
  }
@@ -413,22 +576,25 @@ class ContactCenter extends _webexCore.WebexPlugin {
413
576
  *
414
577
  * console.log('Agent ID:', profile.agentId);
415
578
  * console.log('Default DN:', profile.defaultDn);
416
- * console.log('Teams:', profile.teams.map(t => t.teamId));
579
+ * console.log('Teams:', profile.teams.map(t => t.id));
417
580
  * console.log('WebRTC Enabled:', profile.webRtcEnabled);
418
581
  * console.log('Supported Login Options:', profile.loginVoiceOptions);
419
582
  *
420
583
  * // Now you can proceed with station login, state changes, etc.
421
- * await cc.stationLogin({ teamId: profile.teams[0].teamId, loginOption: 'BROWSER' });
584
+ * await cc.stationLogin({ teamId: profile.teams[0].id, loginOption: 'BROWSER' });
422
585
  * ```
423
586
  */
424
587
  async register() {
425
- _loggerProxy.default.info('Starting CC SDK registration', {
588
+ this.wellnessRegistrationGeneration += 1;
589
+ this.wellbeingBreakIdleCode = undefined;
590
+ _loggerProxy.default.log('Starting CC SDK registration', {
426
591
  module: _constants.CC_FILE,
427
592
  method: _constants.METHODS.REGISTER
428
593
  });
429
594
  try {
430
595
  this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_SUCCESS, _constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_FAILED]);
431
596
  this.setupEventListeners();
597
+ this.services.webSocketManager.on('message', this.handleWebsocketMessage);
432
598
  const resp = await this.connectWebsocket();
433
599
  // Ensure 'dn' is always populated from 'defaultDn'
434
600
  resp.dn = resp.defaultDn;
@@ -440,7 +606,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
440
606
  module: _constants.CC_FILE,
441
607
  method: _constants.METHODS.REGISTER
442
608
  });
443
- return resp;
609
+
610
+ // Registration can silently restore a station session without emitting a
611
+ // relogin event. Project the active session for consumers that must
612
+ // recover session-scoped state after a page refresh.
613
+ return resp.isAgentLoggedIn && this.currentAgentSessionId ? {
614
+ ...resp,
615
+ agentSessionId: this.currentAgentSessionId
616
+ } : resp;
444
617
  } catch (error) {
445
618
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_FAILED, {
446
619
  orgId: error.orgId
@@ -487,15 +660,25 @@ class ContactCenter extends _webexCore.WebexPlugin {
487
660
  *
488
661
  */
489
662
  async deregister() {
663
+ this.wellnessRegistrationGeneration += 1;
664
+ this.wellbeingBreakIdleCode = undefined;
665
+ this.updateWellnessSession();
490
666
  try {
491
667
  this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WEBSOCKET_DEREGISTER_SUCCESS, _constants4.METRIC_EVENT_NAMES.WEBSOCKET_DEREGISTER_FAIL]);
668
+ this.taskManager.clearAISummaryState();
492
669
  this.taskManager.off(_types4.TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
493
670
  this.taskManager.off(_types4.TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
671
+ this.taskManager.off(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, this.handleTaskMultiLoginHydrate);
494
672
  this.taskManager.off(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, this.handleCampaignPreviewReservation);
495
673
  this.taskManager.unregisterIncomingCallEvent();
496
674
  this.services.webSocketManager.off('message', this.handleWebsocketMessage);
497
675
  this.services.rtdWebSocketManager.off('message', this.handleRTDWebsocketMessage);
498
676
  this.services.connectionService.off('connectionLost', this.handleConnectionLost);
677
+ const {
678
+ publishError: wxAppPublishError
679
+ } = await this.teardownWxAppLocalState({
680
+ clearInitFlag: true
681
+ });
499
682
  if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER)) {
500
683
  if (this.$webex.internal.mercury.connected) {
501
684
  this.$webex.internal.mercury.off('online');
@@ -512,12 +695,20 @@ class ContactCenter extends _webexCore.WebexPlugin {
512
695
  if (!this.services.webSocketManager.isSocketClosed) {
513
696
  this.services.webSocketManager.close(false, 'Unregistering the SDK');
514
697
  }
698
+ if (this.services.rtdWebSocketManager && !this.services.rtdWebSocketManager.isSocketClosed) {
699
+ this.services.rtdWebSocketManager.close(false, 'Unregistering the SDK');
700
+ }
515
701
  if (this.services.rtdWebSocketManager && !this.services.rtdWebSocketManager.isSocketClosed) {
516
702
  this.services.rtdWebSocketManager.close(false, 'Unregistering the RTD websocket');
517
703
  }
518
704
 
519
705
  // Clear any cached agent configuration
706
+ this.wellbeingBreakIdleCode = undefined;
520
707
  this.agentConfig = null;
708
+ this.updateWellnessSession();
709
+ if (wxAppPublishError) {
710
+ throw wxAppPublishError;
711
+ }
521
712
  _loggerProxy.default.log('Deregistered successfully', {
522
713
  module: _constants.CC_FILE,
523
714
  method: _constants.METHODS.DEREGISTER
@@ -571,6 +762,12 @@ class ContactCenter extends _webexCore.WebexPlugin {
571
762
  * ```
572
763
  */
573
764
  async getBuddyAgents(data) {
765
+ const {
766
+ action,
767
+ state,
768
+ mediaType = 'telephony'
769
+ } = data;
770
+ const buddyAgentState = state ?? (action === 'Transfer' ? _constants2.AGENT_STATE_AVAILABLE : undefined);
574
771
  _loggerProxy.default.info('Fetching buddy agents', {
575
772
  module: _constants.CC_FILE,
576
773
  method: _constants.METHODS.GET_BUDDY_AGENTS
@@ -580,13 +777,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
580
777
  const resp = await this.services.agent.buddyAgents({
581
778
  data: {
582
779
  agentProfileId: this.agentConfig.agentProfileID,
583
- ...data
780
+ mediaType,
781
+ ...(buddyAgentState ? {
782
+ state: buddyAgentState
783
+ } : {})
584
784
  }
585
785
  });
586
786
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.FETCH_BUDDY_AGENTS_SUCCESS, {
587
787
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(resp),
588
- mediaType: data.mediaType,
589
- buddyAgentState: data.state,
788
+ mediaType,
789
+ buddyAgentState,
590
790
  buddyAgentCount: resp.data.agentList.length
591
791
  }, ['operational']);
592
792
  _loggerProxy.default.log(`Successfully retrieved ${resp.data.agentList.length} buddy agents`, {
@@ -599,8 +799,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
599
799
  const failureResp = error.details;
600
800
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.FETCH_BUDDY_AGENTS_FAILED, {
601
801
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failureResp),
602
- mediaType: data.mediaType,
603
- buddyAgentState: data.state
802
+ mediaType,
803
+ buddyAgentState
604
804
  }, ['operational']);
605
805
  const {
606
806
  error: detailedError
@@ -616,7 +816,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
616
816
  * @private
617
817
  */
618
818
  async connectWebsocket() {
619
- _loggerProxy.default.info('Connecting to websocket', {
819
+ _loggerProxy.default.log('Connecting to websocket', {
620
820
  module: _constants.CC_FILE,
621
821
  method: _constants.METHODS.CONNECT_WEBSOCKET
622
822
  });
@@ -632,18 +832,42 @@ class ContactCenter extends _webexCore.WebexPlugin {
632
832
  module: _constants.CC_FILE,
633
833
  method: _constants.METHODS.CONNECT_WEBSOCKET
634
834
  });
635
-
835
+ const configFlags = {
836
+ isEndTaskEnabled: this.agentConfig.isEndTaskEnabled,
837
+ isEndConsultEnabled: this.agentConfig.isEndConsultEnabled,
838
+ webRtcEnabled: this.agentConfig.webRtcEnabled,
839
+ autoWrapup: this.agentConfig.wrapUpData?.wrapUpProps?.autoWrapup ?? false,
840
+ aiFeature: this.agentConfig.aiFeature,
841
+ consultTransfer: {
842
+ allowConsultToQueue: this.agentConfig.allowConsultToQueue,
843
+ accessQueue: this.agentConfig.accessQueue,
844
+ accessEntryPoint: this.agentConfig.accessEntryPoint,
845
+ accessBuddyTeam: this.agentConfig.accessBuddyTeam
846
+ },
847
+ enableWxBetterTogether: this.isWxBetterTogetherEnabled(),
848
+ getWxAppUsersubPublished: () => this.webexCrossClientService.isAnswerCallsStateActive()
849
+ };
850
+ this.taskManager.setConfigFlags(configFlags);
636
851
  // TODO: Make profile a singleton to make it available throughout app/sdk so we dont need to inject info everywhere
637
852
  this.taskManager.setWrapupData(this.agentConfig.wrapUpData);
638
853
  this.taskManager.setAgentId(this.agentConfig.agentId);
854
+ this.taskManager.setAgentName(this.agentConfig.agentName);
639
855
  this.taskManager.setWebRtcEnabled(this.agentConfig.webRtcEnabled);
640
856
  this.apiAIAssistant.setAIFeatureFlags(this.agentConfig.aiFeature);
641
- if (this.agentConfig.aiFeature?.realtimeTranscripts?.enable) {
857
+ this.wellbeingBreakIdleCode = undefined;
858
+ this.updateWellnessSession();
859
+
860
+ /**
861
+ * RTD websocket currently supports realtime transcripts and suggested responses.
862
+ * Extend this condition when additional AI RTD features are introduced.
863
+ * Wellness break notifications also arrive on this websocket.
864
+ */
865
+ if (this.agentConfig.aiFeature?.realtimeTranscripts?.enable || this.agentConfig.aiFeature?.suggestedResponses?.enable || this.agentConfig.aiFeature?.generatedSummaries?.wrapUpSummariesEnabled === true || this.agentConfig.aiFeature?.generatedSummaries?.consultTransferSummariesEnabled === true || this.agentConfig.isWellnessBreakEnabled) {
642
866
  _loggerProxy.default.info('Connecting to RTD websocket', {
643
867
  module: _constants.CC_FILE,
644
868
  method: _constants.METHODS.CONNECT_WEBSOCKET
645
869
  });
646
- await this.services.rtdWebSocketManager.initWebSocket({
870
+ this.services.rtdWebSocketManager.initWebSocket({
647
871
  body: this.getConnectionConfig(),
648
872
  resource: _constants3.RTD_SUBSCRIBE_API
649
873
  }).then(() => {
@@ -653,13 +877,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
653
877
  });
654
878
  this.services.rtdWebSocketManager.on('message', this.handleRTDWebsocketMessage);
655
879
  }).catch(error => {
656
- _loggerProxy.default.error(`Error during RTD websocket setup: ${error}`, {
880
+ _loggerProxy.default.error(`Error connecting to RTD websocket ${error}`, {
657
881
  module: _constants.CC_FILE,
658
882
  method: _constants.METHODS.CONNECT_WEBSOCKET
659
883
  });
660
884
  });
661
885
  }
662
- if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER)) {
886
+ if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER) && !this.isWebRTCRegistrationDisabled()) {
663
887
  try {
664
888
  await this.$webex.internal.mercury.connect();
665
889
  _loggerProxy.default.log('Authentication: webex.internal.mercury.connect successful', {
@@ -672,12 +896,23 @@ class ContactCenter extends _webexCore.WebexPlugin {
672
896
  method: _constants.METHODS.CONNECT_WEBSOCKET
673
897
  });
674
898
  }
899
+ } else if (this.isWebRTCRegistrationDisabled()) {
900
+ _loggerProxy.default.info('Skipping Mobius registration because disableWebRTCRegistration is enabled', {
901
+ module: _constants.CC_FILE,
902
+ method: _constants.METHODS.CONNECT_WEBSOCKET
903
+ });
675
904
  }
676
905
  if (this.$config && this.$config.allowAutomatedRelogin) {
677
906
  await this.silentRelogin();
907
+ } else {
908
+ _loggerProxy.default.log('Skipping silent relogin: allowAutomatedRelogin is disabled', {
909
+ module: _constants.CC_FILE,
910
+ method: _constants.METHODS.CONNECT_WEBSOCKET
911
+ });
678
912
  }
679
913
  return this.agentConfig;
680
914
  } catch (error) {
915
+ this.updateWellnessSession();
681
916
  _loggerProxy.default.error(`Error during register: ${error}`, {
682
917
  module: _constants.CC_FILE,
683
918
  method: _constants.METHODS.CONNECT_WEBSOCKET
@@ -715,30 +950,37 @@ class ContactCenter extends _webexCore.WebexPlugin {
715
950
  * ```
716
951
  */
717
952
  async stationLogin(data) {
718
- _loggerProxy.default.info('Starting agent station login', {
953
+ const loggerContext = {
719
954
  module: _constants.CC_FILE,
720
955
  method: _constants.METHODS.STATION_LOGIN
721
- });
956
+ };
722
957
  try {
958
+ _loggerProxy.default.log(`Starting agent station login | loginOption: ${data?.loginOption} teamId: ${data?.teamId}`, loggerContext);
723
959
  this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, _constants4.METRIC_EVENT_NAMES.STATION_LOGIN_FAILED]);
724
960
  const dialPlanEntries = this.agentConfig?.dialPlan?.dialPlanEntity ?? [];
725
- if (data.loginOption === _types.LoginOption.AGENT_DN && !(0, _Utils.isValidDialNumber)(data.dialNumber, dialPlanEntries)) {
726
- const error = new Error('INVALID_DIAL_NUMBER');
727
- // @ts-ignore - adding custom key to the error object
728
- error.details = {
729
- data: {
730
- reason: 'INVALID_DIAL_NUMBER'
731
- }
732
- };
733
- throw error;
961
+ if (data.loginOption === _types.LoginOption.AGENT_DN) {
962
+ _loggerProxy.default.log(`Validating dial number | dialPlanEnabled: ${!!this.agentConfig?.dialPlan} | dialPlanEntryCount: ${dialPlanEntries.length}`, loggerContext);
963
+ if (!(0, _Utils.isValidDialNumber)(data.dialNumber, dialPlanEntries)) {
964
+ _loggerProxy.default.log(`Dial number validation failed | dialNumber: ${data.dialNumber} | dialPlanEntryCount: ${dialPlanEntries.length}`, loggerContext);
965
+ const error = new Error('INVALID_DIAL_NUMBER');
966
+ // @ts-ignore - adding custom key to the error object
967
+ error.details = {
968
+ data: {
969
+ reason: 'INVALID_DIAL_NUMBER'
970
+ }
971
+ };
972
+ throw error;
973
+ }
734
974
  }
975
+ const deviceId = this.getDeviceId(data.loginOption, data.dialNumber);
735
976
  const loginResponse = await this.services.agent.stationLogin({
736
977
  data: {
737
- dialNumber: data.loginOption === _types.LoginOption.BROWSER ? this.agentConfig.agentId : data.dialNumber,
978
+ // BROWSER DN must be webrtc-{agentId} so VPOP/RTMS do not treat a bare UUID as PSTN.
979
+ dialNumber: data.loginOption === _types.LoginOption.BROWSER ? deviceId : data.dialNumber,
738
980
  teamId: data.teamId,
739
981
  deviceType: data.loginOption,
740
982
  isExtension: data.loginOption === _types.LoginOption.EXTENSION,
741
- deviceId: this.getDeviceId(data.loginOption, data.dialNumber),
983
+ deviceId,
742
984
  roles: [_constants3.AGENT],
743
985
  teamName: _constants.EMPTY_STRING,
744
986
  siteId: _constants.EMPTY_STRING,
@@ -746,14 +988,20 @@ class ContactCenter extends _webexCore.WebexPlugin {
746
988
  auxCodeId: _constants.EMPTY_STRING
747
989
  }
748
990
  });
749
- if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER) {
991
+ if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER && !this.isWebRTCRegistrationDisabled()) {
750
992
  await this.webCallingService.registerWebCallingLine();
993
+ } else if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER && this.isWebRTCRegistrationDisabled()) {
994
+ _loggerProxy.default.info('Skipping web calling line registration because disableWebRTCRegistration is enabled', {
995
+ module: _constants.CC_FILE,
996
+ method: _constants.METHODS.STATION_LOGIN
997
+ });
751
998
  }
752
999
  const resp = await loginResponse;
753
1000
  const {
754
1001
  channelsMap,
755
1002
  ...loginData
756
1003
  } = resp.data;
1004
+ this.updateWellnessSession(resp.data.agentSessionId);
757
1005
  this.agentConfig.currentTeamId = resp.data.teamId;
758
1006
  const response = {
759
1007
  ...loginData,
@@ -766,6 +1014,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
766
1014
  notifsTrackingId: resp.trackingId
767
1015
  };
768
1016
  this.webCallingService.setLoginOption(data.loginOption);
1017
+ if (this.agentConfig) {
1018
+ this.agentConfig.deviceType = data.loginOption;
1019
+ if (data.loginOption === _types.LoginOption.AGENT_DN || data.loginOption === _types.LoginOption.EXTENSION) {
1020
+ this.agentConfig.defaultDn = data.dialNumber;
1021
+ this.agentConfig.dn = data.dialNumber;
1022
+ }
1023
+ }
769
1024
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, {
770
1025
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(resp),
771
1026
  loginType: data.loginOption,
@@ -778,6 +1033,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
778
1033
  method: _constants.METHODS.STATION_LOGIN,
779
1034
  trackingId: resp.trackingId
780
1035
  });
1036
+ await this.ensureWxAppPostStationLogin();
781
1037
  return response;
782
1038
  } catch (error) {
783
1039
  const failure = error.details;
@@ -832,6 +1088,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
832
1088
  if (this.webCallingService) {
833
1089
  this.webCallingService.deregisterWebCallingLine();
834
1090
  }
1091
+ await this.teardownWxAppLocalState();
1092
+ this.updateWellnessSession();
835
1093
  _loggerProxy.default.log(`Agent station logout completed successfully`, {
836
1094
  module: _constants.CC_FILE,
837
1095
  method: _constants.METHODS.STATION_LOGOUT,
@@ -925,7 +1183,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
925
1183
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.AGENT_STATE_CHANGE_SUCCESS, {
926
1184
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(agentStatusResponse),
927
1185
  requestedState: data.state,
928
- teamId: this.agentConfig?.teams[0]?.teamId ?? _constants.EMPTY_STRING,
1186
+ teamId: this.agentConfig?.teams[0]?.id ?? _constants.EMPTY_STRING,
929
1187
  status: agentStatusResponse.data?.status,
930
1188
  subStatus: agentStatusResponse.data?.subStatus,
931
1189
  auxCodeId: data.auxCodeId,
@@ -952,6 +1210,63 @@ class ContactCenter extends _webexCore.WebexPlugin {
952
1210
  }
953
1211
  }
954
1212
 
1213
+ /**
1214
+ * Returns the system-managed `WellbeingBreak` idle code for the current registration.
1215
+ * The value is fetched outside Desktop Profile filtering and cached until deregistration.
1216
+ * @returns The normalized system idle-code entity
1217
+ * @throws Structured Contact Center error when wellness is disabled or the code is unavailable
1218
+ * @example
1219
+ * const idleCode = await webex.cc.getWellbeingBreakIdleCode();
1220
+ * @public
1221
+ */
1222
+ async getWellbeingBreakIdleCode() {
1223
+ const method = _constants.METHODS.GET_WELLBEING_BREAK_IDLE_CODE;
1224
+ try {
1225
+ if (!this.agentConfig?.isWellnessBreakEnabled) {
1226
+ const validationError = new Error('WELLNESS_BREAK_NOT_ENABLED');
1227
+ validationError.details = {
1228
+ type: 'SDK_VALIDATION_ERROR',
1229
+ orgId: this.$webex.credentials.getOrgId(),
1230
+ trackingId: _constants.EMPTY_STRING,
1231
+ data: {
1232
+ reason: 'WELLNESS_BREAK_NOT_ENABLED'
1233
+ }
1234
+ };
1235
+ throw validationError;
1236
+ }
1237
+ if (this.wellbeingBreakIdleCode) {
1238
+ return this.wellbeingBreakIdleCode;
1239
+ }
1240
+ this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WELLBEING_BREAK_IDLE_CODE_FETCH_SUCCESS, _constants4.METRIC_EVENT_NAMES.WELLBEING_BREAK_IDLE_CODE_FETCH_FAILED]);
1241
+ const registrationGeneration = this.wellnessRegistrationGeneration;
1242
+ const orgId = this.$webex.credentials.getOrgId();
1243
+ const idleCode = await this.services.config.getWellbeingBreakIdleCode(orgId);
1244
+ if (registrationGeneration !== this.wellnessRegistrationGeneration || orgId !== this.$webex.credentials.getOrgId() || !this.agentConfig?.isWellnessBreakEnabled) {
1245
+ const staleRegistrationError = new Error('WELLNESS_BREAK_REGISTRATION_CHANGED');
1246
+ staleRegistrationError.details = {
1247
+ type: 'SDK_VALIDATION_ERROR',
1248
+ orgId,
1249
+ trackingId: _constants.EMPTY_STRING,
1250
+ data: {
1251
+ reason: 'WELLNESS_BREAK_REGISTRATION_CHANGED'
1252
+ }
1253
+ };
1254
+ throw staleRegistrationError;
1255
+ }
1256
+ this.wellbeingBreakIdleCode = idleCode;
1257
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WELLBEING_BREAK_IDLE_CODE_FETCH_SUCCESS, {}, ['operational']);
1258
+ return idleCode;
1259
+ } catch (error) {
1260
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WELLBEING_BREAK_IDLE_CODE_FETCH_FAILED, {
1261
+ reason: error instanceof Error ? error.message : _constants.UNKNOWN_ERROR
1262
+ }, ['operational']);
1263
+ const {
1264
+ error: detailedError
1265
+ } = (0, _Utils.getErrorDetails)(error, method, _constants.CC_FILE);
1266
+ throw detailedError;
1267
+ }
1268
+ }
1269
+
955
1270
  /**
956
1271
  * Processes incoming websocket messages and emits corresponding events
957
1272
  * Handles various event types including agent state changes, login events,
@@ -985,8 +1300,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
985
1300
  };
986
1301
  this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WEBSOCKET_EVENT_RECEIVED, metricsPayload, ['operational']);
987
1302
  }
1303
+ if (this.handleWellnessBreakWebsocketPayload(eventData)) {
1304
+ return;
1305
+ }
988
1306
  switch (eventData.type) {
989
1307
  case _types3.CC_EVENTS.AGENT_MULTI_LOGIN:
1308
+ if (eventData.data?.type === 'AgentMultiLoginCloseSession' && (!eventData.data.agentSessionId || eventData.data.agentSessionId === this.currentAgentSessionId)) {
1309
+ this.updateWellnessSession();
1310
+ }
990
1311
  // @ts-ignore
991
1312
  this.emit(_types2.AGENT_EVENTS.AGENT_MULTI_LOGIN, eventData.data);
992
1313
  break;
@@ -1007,6 +1328,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
1007
1328
  channelsMap,
1008
1329
  ...loginData
1009
1330
  } = eventData.data;
1331
+ this.updateWellnessSession(loginData.agentSessionId);
1010
1332
  const stationLoginData = {
1011
1333
  ...loginData,
1012
1334
  mmProfile: {
@@ -1028,6 +1350,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
1028
1350
  channelsMap,
1029
1351
  ...loginData
1030
1352
  } = eventData.data;
1353
+ this.updateWellnessSession(loginData.agentSessionId);
1031
1354
  const stationReLoginData = {
1032
1355
  ...loginData,
1033
1356
  mmProfile: {
@@ -1040,8 +1363,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
1040
1363
  };
1041
1364
  // @ts-ignore
1042
1365
  this.emit(_types2.AGENT_EVENTS.AGENT_RELOGIN_SUCCESS, stationReLoginData);
1366
+ break;
1043
1367
  }
1044
- break;
1045
1368
  case _types3.CC_EVENTS.AGENT_STATE_CHANGE_SUCCESS:
1046
1369
  // @ts-ignore
1047
1370
  this.emit(_types2.AGENT_EVENTS.AGENT_STATE_CHANGE_SUCCESS, eventData.data);
@@ -1055,6 +1378,9 @@ class ContactCenter extends _webexCore.WebexPlugin {
1055
1378
  this.emit(_types2.AGENT_EVENTS.AGENT_STATION_LOGIN_FAILED, eventData.data);
1056
1379
  break;
1057
1380
  case _types3.CC_EVENTS.AGENT_LOGOUT_SUCCESS:
1381
+ if (!eventData.data.agentSessionId || eventData.data.agentSessionId === this.currentAgentSessionId) {
1382
+ this.updateWellnessSession();
1383
+ }
1058
1384
  // @ts-ignore
1059
1385
  this.emit(_types2.AGENT_EVENTS.AGENT_LOGOUT_SUCCESS, eventData.data);
1060
1386
  break;
@@ -1071,6 +1397,504 @@ class ContactCenter extends _webexCore.WebexPlugin {
1071
1397
  }
1072
1398
  };
1073
1399
 
1400
+ /**
1401
+ * Checks whether Mobius/WebRTC registration should be skipped by config
1402
+ * @returns {boolean} True when browser WebRTC registration is disabled
1403
+ * @private
1404
+ */
1405
+ isWebRTCRegistrationDisabled() {
1406
+ return this.$config?.disableWebRTCRegistration === true;
1407
+ }
1408
+
1409
+ /**
1410
+ * Validates contact-center plugin configuration before service initialization
1411
+ * @private
1412
+ */
1413
+ validatePluginConfig() {
1414
+ if (this.$config?.disableWebRTCRegistration === true && this.$config?.allowMultiLogin === false) {
1415
+ throw new Error('Invalid Contact Center configuration: disableWebRTCRegistration cannot be true when allowMultiLogin is false. Enable allowMultiLogin or allow WebRTC registration so an SDK instance can receive Mobius/WebRTC task events.');
1416
+ }
1417
+ }
1418
+
1419
+ /**
1420
+ * Whether wxApp thick-client answer is enabled for this SDK instance.
1421
+ * @public
1422
+ */
1423
+ isWxBetterTogetherEnabled() {
1424
+ return this.$config?.enableWxBetterTogether === true;
1425
+ }
1426
+
1427
+ /**
1428
+ * Current station login option (Extension, Dial Number, or Browser/Desktop).
1429
+ * Prefer webCallingService — updated on every stationLogin before wxApp hooks run.
1430
+ * @private
1431
+ */
1432
+ getCurrentStationLoginOption() {
1433
+ return this.webCallingService?.loginOption ?? this.agentConfig?.deviceType;
1434
+ }
1435
+
1436
+ /**
1437
+ * wxApp thick-client answer is supported for Extension and Dial Number station login only —
1438
+ * not Browser/Desktop (WebRTC) login.
1439
+ * @private
1440
+ */
1441
+ assertWxAppStationLoginSupportedForEnable() {
1442
+ const loginOption = this.getCurrentStationLoginOption();
1443
+ if (loginOption !== _types.LoginOption.EXTENSION && loginOption !== _types.LoginOption.AGENT_DN) {
1444
+ throw new Error('setManageWebexCallingInWxcc requires EXTENSION or AGENT_DN station login. Complete station login before enabling.');
1445
+ }
1446
+ }
1447
+
1448
+ /**
1449
+ * Clears runtime wxApp config after logout/deregister so stale flags do not apply on relogin.
1450
+ * @private
1451
+ */
1452
+ resetEnableWxBetterTogetherConfig() {
1453
+ if (this.$config) {
1454
+ this.$config.enableWxBetterTogether = false;
1455
+ }
1456
+ this.taskManager.applyEnableWxBetterTogether(false);
1457
+ }
1458
+
1459
+ /**
1460
+ * Runtime enable/disable for wxApp Better Together (toast suppression + Mercury mute sync).
1461
+ *
1462
+ * **Phase 1 (WXCC-6026 / MMT): NOT part of the public host contract.**
1463
+ * Hosts must set `webexConfig.cc.enableWxBetterTogether` before `webex.init()` / `cc.register()`.
1464
+ * To change the flag after the SDK is initialized, re-init the SDK with the updated config.
1465
+ *
1466
+ * **Supported public read API:** {@link isWxBetterTogetherEnabled}.
1467
+ * **Supported telephony API:** unified `task.accept()`, `task.decline()`, `task.toggleMute()`,
1468
+ * `task.transmitDtmf()` — SDK routes wxApp calls internally when the init flag is active.
1469
+ *
1470
+ * **Production lifecycle does not call this method.** Station login, silent relogin, logout,
1471
+ * and deregister use {@link ensureWxAppPostStationLogin} and {@link teardownWxAppLocalState}
1472
+ * (usersub publish + Mercury subscribe/unsubscribe based on the init flag).
1473
+ *
1474
+ * This setter remains as a **private implementation** for Phase 2 runtime toggle and unit tests.
1475
+ * It updates `$config.enableWxBetterTogether`, TaskManager flags, cross-client usersub
1476
+ * (`answer-calls-on-wxcc`), and Mercury mute sync; rolls back config on publish/connect failure.
1477
+ *
1478
+ * @param enabled - `true` to enable wxApp answer + usersub suppression; `false` to disable and tear down.
1479
+ * @throws When enabling without login, on unsupported BROWSER station login, or when usersub/Mercury init fails.
1480
+ * @internal
1481
+ * @see enableWxBetterTogether (CCPluginConfig init flag)
1482
+ * @see ensureWxAppPostStationLogin
1483
+ * @see teardownWxAppLocalState
1484
+ */
1485
+ async setManageWebexCallingInWxcc(enabled) {
1486
+ if (enabled && !this.$webex.internal.device?.userId) {
1487
+ throw new Error('Cannot publish answer-calls-on-wxcc: user is not logged in');
1488
+ }
1489
+ if (enabled) {
1490
+ this.assertWxAppStationLoginSupportedForEnable();
1491
+ }
1492
+ const previousEnabled = this.isWxBetterTogetherEnabled();
1493
+ if (this.$config) {
1494
+ this.$config.enableWxBetterTogether = enabled;
1495
+ }
1496
+ this.taskManager.applyEnableWxBetterTogether(enabled);
1497
+ let publishedEnable = false;
1498
+ try {
1499
+ if (enabled) {
1500
+ await this.ensureWxAppMercuryAndSubscribe();
1501
+ await this.publishAnswerOnWebexCrossClientState(true);
1502
+ publishedEnable = true;
1503
+ this.taskManager.syncWxAppMuteFromCallDetailsForAllTasks();
1504
+ this.taskManager.refreshWxAppOfferObservabilityForAllTasks();
1505
+ } else {
1506
+ await this.publishAnswerOnWebexCrossClientState(false);
1507
+ this.wxAppTelephonyMercurySync.unsubscribe();
1508
+ await this.releaseWxAppMercuryResources();
1509
+ }
1510
+ } catch (error) {
1511
+ if (publishedEnable) {
1512
+ await this.revertWxAppCrossClientPublish();
1513
+ } else if (enabled) {
1514
+ this.wxAppTelephonyMercurySync.unsubscribe();
1515
+ await this.releaseWxAppMercuryResources();
1516
+ }
1517
+ if (this.$config) {
1518
+ this.$config.enableWxBetterTogether = previousEnabled;
1519
+ }
1520
+ this.taskManager.applyEnableWxBetterTogether(previousEnabled);
1521
+ throw error;
1522
+ }
1523
+ }
1524
+ getWxAppTelephonyTaskType() {
1525
+ const loginOption = this.getCurrentStationLoginOption();
1526
+ if (loginOption === _types.LoginOption.BROWSER) {
1527
+ return 'WebRTC';
1528
+ }
1529
+ if (loginOption === _types.LoginOption.EXTENSION || loginOption === _types.LoginOption.AGENT_DN) {
1530
+ return 'Voice';
1531
+ }
1532
+ return 'unknown';
1533
+ }
1534
+ async ensureWxAppPostStationLogin() {
1535
+ const loginOption = this.getCurrentStationLoginOption();
1536
+ const flagEnabled = this.isWxBetterTogetherEnabled();
1537
+ const telephonyTaskType = this.getWxAppTelephonyTaskType();
1538
+ if (loginOption === _types.LoginOption.BROWSER) {
1539
+ if (flagEnabled) {
1540
+ (0, _wxAppDiagnosticLogging.logWxAppSessionReadiness)({
1541
+ enableWxBetterTogether: true,
1542
+ loginOption,
1543
+ wxAppHooksApplied: false,
1544
+ usersubPublished: false,
1545
+ mercurySubscribed: false,
1546
+ telephonyTaskType,
1547
+ skipReason: 'unsupported_browser_login'
1548
+ });
1549
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_SKIPPED, {
1550
+ loginOption,
1551
+ enableWxBetterTogether: true,
1552
+ skipReason: 'unsupported_browser_login'
1553
+ }, ['operational', 'behavioral']);
1554
+ }
1555
+ return;
1556
+ }
1557
+ let publishedEnable = false;
1558
+ let wxAppInitStage = 'mercury';
1559
+ try {
1560
+ if (flagEnabled) {
1561
+ this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_INIT_SUCCESS, _constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_INIT_FAILED]);
1562
+ await this.ensureWxAppMercuryAndSubscribe();
1563
+ wxAppInitStage = 'publish';
1564
+ await this.publishAnswerOnWebexCrossClientState(true);
1565
+ publishedEnable = true;
1566
+ this.taskManager.syncWxAppMuteFromCallDetailsForAllTasks();
1567
+ this.taskManager.refreshWxAppOfferObservabilityForAllTasks();
1568
+ const mercurySubscribed = this.wxAppTelephonyMercurySync.isSubscribed();
1569
+ const usersubPublished = this.webexCrossClientService.isAnswerCallsStateActive();
1570
+ (0, _wxAppDiagnosticLogging.logWxAppSessionReadiness)({
1571
+ enableWxBetterTogether: true,
1572
+ loginOption,
1573
+ wxAppHooksApplied: true,
1574
+ usersubPublished,
1575
+ mercurySubscribed,
1576
+ telephonyTaskType
1577
+ });
1578
+ const sessionInitReady = mercurySubscribed && usersubPublished;
1579
+ if (sessionInitReady) {
1580
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_INIT_SUCCESS, {
1581
+ loginOption,
1582
+ enableWxBetterTogether: true,
1583
+ usersubPublished,
1584
+ mercurySubscribed,
1585
+ telephonyTaskType
1586
+ }, ['operational', 'behavioral']);
1587
+ } else {
1588
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_INIT_FAILED, {
1589
+ loginOption,
1590
+ enableWxBetterTogether: true,
1591
+ usersubPublished,
1592
+ mercurySubscribed,
1593
+ telephonyTaskType,
1594
+ skipReason: !usersubPublished ? 'usersub_not_published' : 'mercury_not_subscribed'
1595
+ }, ['operational', 'behavioral']);
1596
+ }
1597
+ } else {
1598
+ await this.ensureWxAppDeviceRegistered();
1599
+ await this.publishAnswerOnWebexCrossClientState(false, {
1600
+ force: true
1601
+ });
1602
+ this.webexCrossClientService.teardown();
1603
+ this.wxAppTelephonyMercurySync.unsubscribe();
1604
+ await this.releaseWxAppMercuryResources();
1605
+ (0, _wxAppDiagnosticLogging.logWxAppSessionReadiness)({
1606
+ enableWxBetterTogether: false,
1607
+ loginOption,
1608
+ wxAppHooksApplied: true,
1609
+ usersubPublished: false,
1610
+ mercurySubscribed: false,
1611
+ telephonyTaskType,
1612
+ skipReason: 'flag_disabled'
1613
+ });
1614
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_SKIPPED, {
1615
+ loginOption,
1616
+ enableWxBetterTogether: false,
1617
+ skipReason: 'flag_disabled'
1618
+ }, ['operational', 'behavioral']);
1619
+ }
1620
+ } catch (error) {
1621
+ _loggerProxy.default.error(`Failed to initialize wxApp post-station-login: ${error}`, {
1622
+ module: _constants.CC_FILE,
1623
+ method: _constants.METHODS.STATION_LOGIN
1624
+ });
1625
+ if (flagEnabled) {
1626
+ const sessionInitFailureReason = wxAppInitStage === 'mercury' ? 'mercury_subscribe_failed' : 'publish_failed';
1627
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_SESSION_INIT_FAILED, {
1628
+ loginOption,
1629
+ enableWxBetterTogether: true,
1630
+ usersubPublished: this.webexCrossClientService.isAnswerCallsStateActive(),
1631
+ mercurySubscribed: this.wxAppTelephonyMercurySync.isSubscribed(),
1632
+ telephonyTaskType,
1633
+ skipReason: sessionInitFailureReason,
1634
+ error: error instanceof Error ? error.toString() : String(error)
1635
+ }, ['operational', 'behavioral']);
1636
+ (0, _wxAppDiagnosticLogging.logWxAppSessionReadiness)({
1637
+ enableWxBetterTogether: true,
1638
+ loginOption,
1639
+ wxAppHooksApplied: false,
1640
+ usersubPublished: this.webexCrossClientService.isAnswerCallsStateActive(),
1641
+ mercurySubscribed: this.wxAppTelephonyMercurySync.isSubscribed(),
1642
+ telephonyTaskType,
1643
+ skipReason: sessionInitFailureReason
1644
+ });
1645
+ if (publishedEnable) {
1646
+ await this.revertWxAppCrossClientPublish();
1647
+ } else {
1648
+ this.wxAppTelephonyMercurySync.unsubscribe();
1649
+ await this.releaseWxAppMercuryResources();
1650
+ }
1651
+ this.resetEnableWxBetterTogetherConfig();
1652
+ } else {
1653
+ this.scheduleForcedFalsePublishRetry();
1654
+ }
1655
+ }
1656
+ }
1657
+ clearWxAppFalsePublishRetryTimer() {
1658
+ if (this.wxAppFalsePublishRetryTimer) {
1659
+ clearTimeout(this.wxAppFalsePublishRetryTimer);
1660
+ this.wxAppFalsePublishRetryTimer = undefined;
1661
+ }
1662
+ }
1663
+ scheduleForcedFalsePublishRetry(retryAttempt = 0) {
1664
+ this.scheduleFalsePublishRetry(retryAttempt, {
1665
+ requireDisabled: true
1666
+ });
1667
+ }
1668
+
1669
+ /**
1670
+ * Retries compensating false publish after rollback failure, regardless of enabled flag.
1671
+ * @private
1672
+ */
1673
+ scheduleCompensatingFalsePublishRetry(retryAttempt = 0) {
1674
+ this.scheduleFalsePublishRetry(retryAttempt);
1675
+ }
1676
+ scheduleFalsePublishRetry(retryAttempt = 0, options = {}) {
1677
+ if (retryAttempt >= ContactCenter.WXAPP_FALSE_PUBLISH_MAX_RETRIES) {
1678
+ return;
1679
+ }
1680
+ if (options?.requireDisabled && this.isWxBetterTogetherEnabled()) {
1681
+ return;
1682
+ }
1683
+ this.clearWxAppFalsePublishRetryTimer();
1684
+ this.wxAppFalsePublishRetryTimer = setTimeout(async () => {
1685
+ this.wxAppFalsePublishRetryTimer = undefined;
1686
+ if (options?.requireDisabled && this.isWxBetterTogetherEnabled()) {
1687
+ return;
1688
+ }
1689
+ if (!options?.requireDisabled && this.isWxBetterTogetherEnabled() && this.webexCrossClientService.isAnswerCallsStateActive()) {
1690
+ return;
1691
+ }
1692
+ try {
1693
+ await this.ensureWxAppDeviceRegistered();
1694
+ await this.publishAnswerOnWebexCrossClientState(false, {
1695
+ force: true
1696
+ });
1697
+ this.webexCrossClientService.teardown();
1698
+ this.wxAppTelephonyMercurySync.unsubscribe();
1699
+ await this.releaseWxAppMercuryResources();
1700
+ } catch (retryError) {
1701
+ _loggerProxy.default.error(`Failed to retry forced answer-calls-on-wxcc false publish: ${retryError}`, {
1702
+ module: _constants.CC_FILE,
1703
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
1704
+ });
1705
+ this.scheduleFalsePublishRetry(retryAttempt + 1, options);
1706
+ }
1707
+ }, ContactCenter.WXAPP_FALSE_PUBLISH_RETRY_DELAY_MS);
1708
+ }
1709
+
1710
+ /**
1711
+ * Best-effort rollback when usersub true was published but wxApp setup did not complete.
1712
+ * @private
1713
+ */
1714
+ async revertWxAppCrossClientPublish() {
1715
+ try {
1716
+ await this.publishAnswerOnWebexCrossClientState(false, {
1717
+ force: true
1718
+ });
1719
+ } catch (error) {
1720
+ _loggerProxy.default.error(`Failed to publish compensating answer-calls-on-wxcc false during wxApp rollback: ${error}`, {
1721
+ module: _constants.CC_FILE,
1722
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
1723
+ });
1724
+ this.scheduleCompensatingFalsePublishRetry();
1725
+ }
1726
+ this.webexCrossClientService.teardown();
1727
+ this.wxAppTelephonyMercurySync.unsubscribe();
1728
+ await this.releaseWxAppMercuryResources();
1729
+ }
1730
+ async ensureWxAppDeviceRegistered() {
1731
+ const device = this.$webex.internal.device;
1732
+ if (device && !device.registered && device.register) {
1733
+ await device.register();
1734
+ this.wxAppDeviceRegisteredByCc = true;
1735
+ _loggerProxy.default.log('WxApp: device registered for cross-client publish', {
1736
+ module: _constants.CC_FILE,
1737
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1738
+ });
1739
+ }
1740
+ }
1741
+ async ensureWxAppMercuryConnected() {
1742
+ const mercury = this.$webex.internal.mercury;
1743
+ await this.ensureWxAppDeviceRegistered();
1744
+ if (mercury && !mercury.connected) {
1745
+ await mercury.connect();
1746
+ this.wxAppMercuryConnectedByCc = true;
1747
+ _loggerProxy.default.log('WxApp mute sync: mercury connected', {
1748
+ module: _constants.CC_FILE,
1749
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1750
+ });
1751
+ }
1752
+ }
1753
+
1754
+ /**
1755
+ * Disconnects Mercury and unregisters the device when wxApp mute sync opened them.
1756
+ * @private
1757
+ */
1758
+ async releaseWxAppMercuryResources() {
1759
+ const mercury = this.$webex.internal.mercury;
1760
+ const device = this.$webex.internal.device;
1761
+ if (this.wxAppMercuryConnectedByCc && mercury?.connected) {
1762
+ try {
1763
+ await mercury.disconnect();
1764
+ this.wxAppMercuryConnectedByCc = false;
1765
+ _loggerProxy.default.log('WxApp mute sync: mercury disconnected', {
1766
+ module: _constants.CC_FILE,
1767
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1768
+ });
1769
+ } catch (error) {
1770
+ _loggerProxy.default.error(`Failed to disconnect wxApp Mercury: ${error}`, {
1771
+ module: _constants.CC_FILE,
1772
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1773
+ });
1774
+ }
1775
+ }
1776
+ if (this.wxAppDeviceRegisteredByCc && device?.registered && device.unregister) {
1777
+ try {
1778
+ // @ts-ignore
1779
+ await device.unregister();
1780
+ this.wxAppDeviceRegisteredByCc = false;
1781
+ _loggerProxy.default.log('WxApp mute sync: device unregistered', {
1782
+ module: _constants.CC_FILE,
1783
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1784
+ });
1785
+ } catch (error) {
1786
+ _loggerProxy.default.error(`Failed to unregister wxApp device: ${error}`, {
1787
+ module: _constants.CC_FILE,
1788
+ method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
1789
+ });
1790
+ }
1791
+ } else if (this.wxAppDeviceRegisteredByCc) {
1792
+ this.wxAppDeviceRegisteredByCc = false;
1793
+ }
1794
+ }
1795
+
1796
+ /**
1797
+ * Clears wxApp runtime state and feature-owned resources. Publish failures are logged;
1798
+ * optional rethrow for deregister when callers need to surface usersub errors.
1799
+ * @private
1800
+ */
1801
+ async teardownWxAppLocalState(options) {
1802
+ this.clearWxAppFalsePublishRetryTimer();
1803
+ let publishError;
1804
+ try {
1805
+ const shouldForceFalsePublish = this.isWxBetterTogetherEnabled() || this.webexCrossClientService.isAnswerCallsStateActive();
1806
+ await this.publishAnswerOnWebexCrossClientState(false, {
1807
+ force: shouldForceFalsePublish
1808
+ });
1809
+ } catch (error) {
1810
+ publishError = error;
1811
+ _loggerProxy.default.error(`Failed to publish answer-calls-on-wxcc false during wxApp teardown: ${error}`, {
1812
+ module: _constants.CC_FILE,
1813
+ method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
1814
+ });
1815
+ }
1816
+ this.webexCrossClientService.teardown();
1817
+ this.wxAppTelephonyMercurySync.unsubscribe();
1818
+ await this.releaseWxAppMercuryResources();
1819
+ if (options?.clearInitFlag) {
1820
+ this.resetEnableWxBetterTogetherConfig();
1821
+ }
1822
+ if (publishError) {
1823
+ this.scheduleCompensatingFalsePublishRetry();
1824
+ }
1825
+ if (options?.rethrowPublishError && publishError) {
1826
+ throw publishError;
1827
+ }
1828
+ return {
1829
+ publishError: publishError ?? undefined
1830
+ };
1831
+ }
1832
+ async ensureWxAppMercuryAndSubscribe() {
1833
+ if (!this.isWxBetterTogetherEnabled()) {
1834
+ return;
1835
+ }
1836
+ if (this.getCurrentStationLoginOption() === _types.LoginOption.BROWSER) {
1837
+ return;
1838
+ }
1839
+ const agentId = this.agentConfig?.agentId;
1840
+ if (!agentId) {
1841
+ _loggerProxy.default.error('Cannot subscribe wxApp mute sync: agentId unavailable', {
1842
+ module: _constants.CC_FILE,
1843
+ method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
1844
+ });
1845
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_FAILED, {
1846
+ error: 'agentId unavailable',
1847
+ mercurySubscribed: false
1848
+ }, ['operational', 'behavioral']);
1849
+ return;
1850
+ }
1851
+ try {
1852
+ await this.ensureWxAppMercuryConnected();
1853
+ this.wxAppTelephonyMercurySync.subscribe(agentId, (callId, muted) => {
1854
+ this.taskManager.applyWxAppMuteStateFromSync(callId, muted);
1855
+ });
1856
+ } catch (error) {
1857
+ _loggerProxy.default.error(`Failed to ensure wxApp Mercury mute sync: ${error}`, {
1858
+ module: _constants.CC_FILE,
1859
+ method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
1860
+ });
1861
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_MERCURY_SUBSCRIBE_FAILED, {
1862
+ error: error instanceof Error ? error.toString() : String(error),
1863
+ mercurySubscribed: false
1864
+ }, ['operational', 'behavioral']);
1865
+ this.wxAppTelephonyMercurySync.unsubscribe();
1866
+ await this.releaseWxAppMercuryResources();
1867
+ throw error;
1868
+ }
1869
+ }
1870
+ async publishAnswerOnWebexCrossClientState(enable, options) {
1871
+ if (enable && !this.isWxBetterTogetherEnabled()) {
1872
+ return;
1873
+ }
1874
+ if (!enable && !options?.force && !this.webexCrossClientService.isAnswerCallsStateActive()) {
1875
+ return;
1876
+ }
1877
+ const userId = this.$webex.internal.device?.userId;
1878
+ if (!userId) {
1879
+ if (enable && this.isWxBetterTogetherEnabled()) {
1880
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.WXAPP_USERSUB_PUBLISH_FAILED, {
1881
+ enableWxBetterTogether: true,
1882
+ usersubPublished: this.webexCrossClientService.isAnswerCallsStateActive(),
1883
+ skipReason: 'user_id_unavailable',
1884
+ error: 'User ID is unavailable for cross-client publish'
1885
+ }, ['operational', 'behavioral']);
1886
+ }
1887
+ return;
1888
+ }
1889
+ await this.webexCrossClientService.setManageWebexCallingInWxcc(enable, {
1890
+ userId,
1891
+ trackPublishMetrics: true
1892
+ });
1893
+ if (enable) {
1894
+ this.clearWxAppFalsePublishRetryTimer();
1895
+ }
1896
+ }
1897
+
1074
1898
  /**
1075
1899
  * Initializes event listeners for the Contact Center service
1076
1900
  * Sets up handlers for connection state changes and other core events
@@ -1102,13 +1926,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
1102
1926
  async handleConnectionLost(msg) {
1103
1927
  if (msg.isConnectionLost) {
1104
1928
  // TODO: Emit an event saying connection is lost
1105
- _loggerProxy.default.info('event=handleConnectionLost | Connection lost', {
1929
+ _loggerProxy.default.log('event=handleConnectionLost | Connection lost', {
1106
1930
  module: _constants.CC_FILE,
1107
1931
  method: _constants.METHODS.HANDLE_CONNECTION_LOST
1108
1932
  });
1109
1933
  } else if (msg.isSocketReconnected) {
1110
1934
  // TODO: Emit an event saying connection is re-estabilished
1111
- _loggerProxy.default.info('event=handleConnectionReconnect | Connection reconnected attempting to request silent relogin', {
1935
+ _loggerProxy.default.log('event=handleConnectionReconnect | Connection reconnected attempting to request silent relogin', {
1112
1936
  module: _constants.CC_FILE,
1113
1937
  method: _constants.METHODS.HANDLE_CONNECTION_LOST
1114
1938
  });
@@ -1123,12 +1947,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
1123
1947
  * @private
1124
1948
  */
1125
1949
  async silentRelogin() {
1126
- _loggerProxy.default.info('Starting silent relogin process', {
1950
+ _loggerProxy.default.log('Starting silent relogin process', {
1127
1951
  module: _constants.CC_FILE,
1128
1952
  method: _constants.METHODS.SILENT_RELOGIN
1129
1953
  });
1130
1954
  try {
1131
1955
  const reLoginResponse = await this.services.agent.reload();
1956
+ this.updateWellnessSession(reLoginResponse.data.agentSessionId);
1132
1957
  const {
1133
1958
  agentId,
1134
1959
  lastStateChangeReason,
@@ -1145,7 +1970,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
1145
1970
  this.agentConfig.currentTeamId = reLoginResponse.data.teamId;
1146
1971
  await this.handleDeviceType(deviceType, dn);
1147
1972
  if (lastStateChangeReason === 'agent-wss-disconnect') {
1148
- _loggerProxy.default.info('event=requestAutoStateChange | Requesting state change to available on socket reconnect', {
1973
+ _loggerProxy.default.log('event=requestAutoStateChange | Requesting state change to available on socket reconnect', {
1149
1974
  module: _constants.CC_FILE,
1150
1975
  method: _constants.METHODS.SILENT_RELOGIN
1151
1976
  });
@@ -1169,8 +1994,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
1169
1994
  }
1170
1995
  this.agentConfig.lastStateAuxCodeId = auxCodeId;
1171
1996
  this.agentConfig.isAgentLoggedIn = true;
1172
- // TODO: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-626777 Implement the de-register method and close the listener there
1173
- this.services.webSocketManager.on('message', this.handleWebsocketMessage);
1997
+ await this.ensureWxAppPostStationLogin();
1174
1998
  _loggerProxy.default.log(`Silent relogin process completed successfully with login Option: ${reLoginResponse.data.deviceType} teamId: ${reLoginResponse.data.teamId}`, {
1175
1999
  module: _constants.CC_FILE,
1176
2000
  method: _constants.METHODS.SILENT_RELOGIN,
@@ -1205,6 +2029,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
1205
2029
  this.agentConfig.deviceType = deviceType;
1206
2030
  switch (deviceType) {
1207
2031
  case _types.LoginOption.BROWSER:
2032
+ if (this.isWebRTCRegistrationDisabled()) {
2033
+ _loggerProxy.default.info('Skipping web calling line registration because disableWebRTCRegistration is enabled', {
2034
+ module: _constants.CC_FILE,
2035
+ method: _constants.METHODS.HANDLE_DEVICE_TYPE
2036
+ });
2037
+ break;
2038
+ }
1208
2039
  try {
1209
2040
  await this.webCallingService.registerWebCallingLine();
1210
2041
  } catch (error) {
@@ -1444,6 +2275,138 @@ class ContactCenter extends _webexCore.WebexPlugin {
1444
2275
  }
1445
2276
  }
1446
2277
 
2278
+ /**
2279
+ * Skips a campaign preview contact, requesting the next contact from the campaign.
2280
+ *
2281
+ * When a campaign manager reserves a contact for an agent, the agent receives an
2282
+ * `AgentOfferCampaignReservation` event. Instead of accepting, the agent can skip the
2283
+ * preview contact to move to the next contact in the campaign.
2284
+ *
2285
+ * @param {PreviewContactPayload} payload - The preview contact payload containing interactionId and campaignId (campaign name, not UUID).
2286
+ * @returns {Promise<TaskResponse>} Promise resolving with agent contact on success.
2287
+ * @throws {Error} If the operation fails (network error, etc.)
2288
+ *
2289
+ * @example
2290
+ * ```typescript
2291
+ * webex.cc.on('task:campaignPreviewReservation', async (task) => {
2292
+ * const { interactionId } = task.data;
2293
+ * const campaignId = task.data.interaction.callProcessingDetails.campaignId;
2294
+ *
2295
+ * const result = await webex.cc.skipPreviewContact({ interactionId, campaignId });
2296
+ * });
2297
+ * ```
2298
+ */
2299
+ async skipPreviewContact(payload) {
2300
+ const task = this.taskManager.getTask(payload.interactionId);
2301
+ if (task?.data?.interaction?.callProcessingDetails?.campaignPreviewSkipDisabled === 'true') {
2302
+ _loggerProxy.default.warn('Skip action is disabled for this campaign preview contact', {
2303
+ module: _constants.CC_FILE,
2304
+ method: _constants.METHODS.SKIP_PREVIEW_CONTACT,
2305
+ interactionId: payload.interactionId
2306
+ });
2307
+ throw new Error('Skip action is disabled for this campaign preview contact');
2308
+ }
2309
+ _loggerProxy.default.info('Skipping campaign preview contact', {
2310
+ module: _constants.CC_FILE,
2311
+ method: _constants.METHODS.SKIP_PREVIEW_CONTACT
2312
+ });
2313
+ try {
2314
+ this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_SUCCESS, _constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_FAILED]);
2315
+ const result = await this.services.dialer.skipPreviewContact({
2316
+ data: payload
2317
+ });
2318
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_SUCCESS, {
2319
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result),
2320
+ interactionId: payload.interactionId,
2321
+ campaignId: payload.campaignId
2322
+ }, ['behavioral', 'business', 'operational']);
2323
+ _loggerProxy.default.log('Campaign preview contact skipped successfully', {
2324
+ module: _constants.CC_FILE,
2325
+ method: _constants.METHODS.SKIP_PREVIEW_CONTACT,
2326
+ trackingId: result.trackingId,
2327
+ interactionId: payload.interactionId
2328
+ });
2329
+ return result;
2330
+ } catch (error) {
2331
+ const failure = error.details;
2332
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_FAILED, {
2333
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failure),
2334
+ interactionId: payload.interactionId,
2335
+ campaignId: payload.campaignId
2336
+ }, ['behavioral', 'business', 'operational']);
2337
+ const {
2338
+ error: detailedError
2339
+ } = (0, _Utils.getErrorDetails)(error, _constants.METHODS.SKIP_PREVIEW_CONTACT, _constants.CC_FILE);
2340
+ throw detailedError;
2341
+ }
2342
+ }
2343
+
2344
+ /**
2345
+ * Removes a campaign preview contact from the campaign list entirely.
2346
+ *
2347
+ * When a campaign manager reserves a contact for an agent, the agent receives an
2348
+ * `AgentOfferCampaignReservation` event. Instead of accepting or skipping, the agent can
2349
+ * remove the preview contact to permanently take it out of the campaign contact list.
2350
+ *
2351
+ * @param {PreviewContactPayload} payload - The preview contact payload containing interactionId and campaignId (campaign name, not UUID).
2352
+ * @returns {Promise<TaskResponse>} Promise resolving with agent contact on success.
2353
+ * @throws {Error} If the operation fails (network error, etc.)
2354
+ *
2355
+ * @example
2356
+ * ```typescript
2357
+ * webex.cc.on('task:campaignPreviewReservation', async (task) => {
2358
+ * const { interactionId } = task.data;
2359
+ * const campaignId = task.data.interaction.callProcessingDetails.campaignId;
2360
+ *
2361
+ * const result = await webex.cc.removePreviewContact({ interactionId, campaignId });
2362
+ * });
2363
+ * ```
2364
+ */
2365
+ async removePreviewContact(payload) {
2366
+ const task = this.taskManager.getTask(payload.interactionId);
2367
+ if (task?.data?.interaction?.callProcessingDetails?.campaignPreviewRemoveDisabled === 'true') {
2368
+ _loggerProxy.default.warn('Remove action is disabled for this campaign preview contact', {
2369
+ module: _constants.CC_FILE,
2370
+ method: _constants.METHODS.REMOVE_PREVIEW_CONTACT,
2371
+ interactionId: payload.interactionId
2372
+ });
2373
+ throw new Error('Remove action is disabled for this campaign preview contact');
2374
+ }
2375
+ _loggerProxy.default.info('Removing campaign preview contact', {
2376
+ module: _constants.CC_FILE,
2377
+ method: _constants.METHODS.REMOVE_PREVIEW_CONTACT
2378
+ });
2379
+ try {
2380
+ this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_SUCCESS, _constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_FAILED]);
2381
+ const result = await this.services.dialer.removePreviewContact({
2382
+ data: payload
2383
+ });
2384
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_SUCCESS, {
2385
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result),
2386
+ interactionId: payload.interactionId,
2387
+ campaignId: payload.campaignId
2388
+ }, ['behavioral', 'business', 'operational']);
2389
+ _loggerProxy.default.log('Campaign preview contact removed successfully', {
2390
+ module: _constants.CC_FILE,
2391
+ method: _constants.METHODS.REMOVE_PREVIEW_CONTACT,
2392
+ trackingId: result.trackingId,
2393
+ interactionId: payload.interactionId
2394
+ });
2395
+ return result;
2396
+ } catch (error) {
2397
+ const failure = error.details;
2398
+ this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_FAILED, {
2399
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failure),
2400
+ interactionId: payload.interactionId,
2401
+ campaignId: payload.campaignId
2402
+ }, ['behavioral', 'business', 'operational']);
2403
+ const {
2404
+ error: detailedError
2405
+ } = (0, _Utils.getErrorDetails)(error, _constants.METHODS.REMOVE_PREVIEW_CONTACT, _constants.CC_FILE);
2406
+ throw detailedError;
2407
+ }
2408
+ }
2409
+
1447
2410
  /**
1448
2411
  * Fetches outdial ANI (Automatic Number Identification) entries for an outdial ANI ID.
1449
2412
  *
@@ -1648,8 +2611,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
1648
2611
  }
1649
2612
 
1650
2613
  /**
1651
- * Returns paginated entry points for the organization.
1652
- * Thin wrapper around internal EntryPoint instance.
2614
+ * Returns paginated entry points using the EntryPoint service defaults.
2615
+ * Existing request parameters can override those defaults.
1653
2616
  * @public
1654
2617
  */
1655
2618
  async getEntryPoints(params = {}) {
@@ -1657,8 +2620,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
1657
2620
  }
1658
2621
 
1659
2622
  /**
1660
- * Returns paginated contact service queues for the organization.
1661
- * Thin wrapper around internal Queue instance.
2623
+ * Returns paginated contact service queues using the Queue service defaults.
2624
+ * Existing request parameters can override those defaults.
1662
2625
  * @public
1663
2626
  */
1664
2627
  async getQueues(params = {}) {