@webex/contact-center 3.12.0-next.8 → 3.12.0-next.81

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 (205) hide show
  1. package/AGENTS.md +438 -0
  2. package/ai-docs/README.md +131 -0
  3. package/ai-docs/RULES.md +455 -0
  4. package/ai-docs/patterns/event-driven-patterns.md +485 -0
  5. package/ai-docs/patterns/testing-patterns.md +480 -0
  6. package/ai-docs/patterns/typescript-patterns.md +365 -0
  7. package/ai-docs/templates/README.md +102 -0
  8. package/ai-docs/templates/documentation/create-agents-md.md +240 -0
  9. package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
  10. package/ai-docs/templates/existing-service/bug-fix.md +254 -0
  11. package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
  12. package/ai-docs/templates/new-method/00-master.md +80 -0
  13. package/ai-docs/templates/new-method/01-requirements.md +232 -0
  14. package/ai-docs/templates/new-method/02-implementation.md +295 -0
  15. package/ai-docs/templates/new-method/03-tests.md +201 -0
  16. package/ai-docs/templates/new-method/04-validation.md +141 -0
  17. package/ai-docs/templates/new-service/00-master.md +109 -0
  18. package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
  19. package/ai-docs/templates/new-service/02-code-generation.md +346 -0
  20. package/ai-docs/templates/new-service/03-integration.md +178 -0
  21. package/ai-docs/templates/new-service/04-test-generation.md +205 -0
  22. package/ai-docs/templates/new-service/05-validation.md +145 -0
  23. package/dist/cc.js +265 -29
  24. package/dist/cc.js.map +1 -1
  25. package/dist/config.js +6 -0
  26. package/dist/config.js.map +1 -1
  27. package/dist/constants.js +16 -1
  28. package/dist/constants.js.map +1 -1
  29. package/dist/index.js +20 -5
  30. package/dist/index.js.map +1 -1
  31. package/dist/metrics/behavioral-events.js +101 -0
  32. package/dist/metrics/behavioral-events.js.map +1 -1
  33. package/dist/metrics/constants.js +23 -4
  34. package/dist/metrics/constants.js.map +1 -1
  35. package/dist/services/ApiAiAssistant.js +74 -3
  36. package/dist/services/ApiAiAssistant.js.map +1 -1
  37. package/dist/services/UserPreference.js +427 -0
  38. package/dist/services/UserPreference.js.map +1 -0
  39. package/dist/services/config/Util.js +3 -3
  40. package/dist/services/config/Util.js.map +1 -1
  41. package/dist/services/config/constants.js +23 -2
  42. package/dist/services/config/constants.js.map +1 -1
  43. package/dist/services/config/types.js +49 -9
  44. package/dist/services/config/types.js.map +1 -1
  45. package/dist/services/core/Err.js.map +1 -1
  46. package/dist/services/core/Utils.js +107 -32
  47. package/dist/services/core/Utils.js.map +1 -1
  48. package/dist/services/core/websocket/WebSocketManager.js +2 -1
  49. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  50. package/dist/services/core/websocket/types.js.map +1 -1
  51. package/dist/services/index.js +1 -1
  52. package/dist/services/index.js.map +1 -1
  53. package/dist/services/task/Task.js +688 -0
  54. package/dist/services/task/Task.js.map +1 -0
  55. package/dist/services/task/TaskFactory.js +45 -0
  56. package/dist/services/task/TaskFactory.js.map +1 -0
  57. package/dist/services/task/TaskManager.js +725 -526
  58. package/dist/services/task/TaskManager.js.map +1 -1
  59. package/dist/services/task/TaskUtils.js +162 -26
  60. package/dist/services/task/TaskUtils.js.map +1 -1
  61. package/dist/services/task/constants.js +9 -2
  62. package/dist/services/task/constants.js.map +1 -1
  63. package/dist/services/task/dialer.js +78 -0
  64. package/dist/services/task/dialer.js.map +1 -1
  65. package/dist/services/task/digital/Digital.js +77 -0
  66. package/dist/services/task/digital/Digital.js.map +1 -0
  67. package/dist/services/task/state-machine/TaskStateMachine.js +837 -0
  68. package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
  69. package/dist/services/task/state-machine/actions.js +543 -0
  70. package/dist/services/task/state-machine/actions.js.map +1 -0
  71. package/dist/services/task/state-machine/constants.js +161 -0
  72. package/dist/services/task/state-machine/constants.js.map +1 -0
  73. package/dist/services/task/state-machine/guards.js +340 -0
  74. package/dist/services/task/state-machine/guards.js.map +1 -0
  75. package/dist/services/task/state-machine/index.js +53 -0
  76. package/dist/services/task/state-machine/index.js.map +1 -0
  77. package/dist/services/task/state-machine/types.js +54 -0
  78. package/dist/services/task/state-machine/types.js.map +1 -0
  79. package/dist/services/task/state-machine/uiControlsComputer.js +553 -0
  80. package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
  81. package/dist/services/task/taskDataNormalizer.js +99 -0
  82. package/dist/services/task/taskDataNormalizer.js.map +1 -0
  83. package/dist/services/task/types.js +212 -4
  84. package/dist/services/task/types.js.map +1 -1
  85. package/dist/services/task/voice/Voice.js +1042 -0
  86. package/dist/services/task/voice/Voice.js.map +1 -0
  87. package/dist/services/task/voice/WebRTC.js +149 -0
  88. package/dist/services/task/voice/WebRTC.js.map +1 -0
  89. package/dist/types/cc.d.ts +94 -1
  90. package/dist/types/config.d.ts +6 -0
  91. package/dist/types/constants.d.ts +16 -1
  92. package/dist/types/index.d.ts +21 -6
  93. package/dist/types/metrics/constants.d.ts +19 -1
  94. package/dist/types/services/ApiAiAssistant.d.ts +11 -3
  95. package/dist/types/services/UserPreference.d.ts +118 -0
  96. package/dist/types/services/config/constants.d.ts +21 -0
  97. package/dist/types/services/config/types.d.ts +171 -10
  98. package/dist/types/services/core/Err.d.ts +4 -0
  99. package/dist/types/services/core/Utils.d.ts +33 -13
  100. package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
  101. package/dist/types/services/core/websocket/types.d.ts +1 -1
  102. package/dist/types/services/index.d.ts +1 -1
  103. package/dist/types/services/task/Task.d.ts +157 -0
  104. package/dist/types/services/task/TaskFactory.d.ts +12 -0
  105. package/dist/types/services/task/TaskUtils.d.ts +46 -2
  106. package/dist/types/services/task/constants.d.ts +7 -0
  107. package/dist/types/services/task/dialer.d.ts +30 -0
  108. package/dist/types/services/task/digital/Digital.d.ts +22 -0
  109. package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1144 -0
  110. package/dist/types/services/task/state-machine/actions.d.ts +10 -0
  111. package/dist/types/services/task/state-machine/constants.d.ts +107 -0
  112. package/dist/types/services/task/state-machine/guards.d.ts +90 -0
  113. package/dist/types/services/task/state-machine/index.d.ts +13 -0
  114. package/dist/types/services/task/state-machine/types.d.ts +267 -0
  115. package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
  116. package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
  117. package/dist/types/services/task/types.d.ts +603 -66
  118. package/dist/types/services/task/voice/Voice.d.ts +184 -0
  119. package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
  120. package/dist/types/types.d.ts +94 -0
  121. package/dist/types/webex.d.ts +1 -0
  122. package/dist/types.js +85 -0
  123. package/dist/types.js.map +1 -1
  124. package/dist/webex.js +14 -2
  125. package/dist/webex.js.map +1 -1
  126. package/package.json +15 -12
  127. package/src/cc.ts +329 -30
  128. package/src/config.ts +6 -0
  129. package/src/constants.ts +16 -1
  130. package/src/index.ts +23 -5
  131. package/src/metrics/ai-docs/AGENTS.md +348 -0
  132. package/src/metrics/ai-docs/ARCHITECTURE.md +336 -0
  133. package/src/metrics/behavioral-events.ts +106 -0
  134. package/src/metrics/constants.ts +23 -4
  135. package/src/services/ApiAiAssistant.ts +104 -3
  136. package/src/services/UserPreference.ts +509 -0
  137. package/src/services/agent/ai-docs/AGENTS.md +238 -0
  138. package/src/services/agent/ai-docs/ARCHITECTURE.md +302 -0
  139. package/src/services/ai-docs/AGENTS.md +384 -0
  140. package/src/services/config/Util.ts +3 -3
  141. package/src/services/config/ai-docs/AGENTS.md +253 -0
  142. package/src/services/config/ai-docs/ARCHITECTURE.md +424 -0
  143. package/src/services/config/constants.ts +25 -1
  144. package/src/services/config/types.ts +174 -11
  145. package/src/services/core/Err.ts +2 -0
  146. package/src/services/core/Utils.ts +123 -37
  147. package/src/services/core/ai-docs/AGENTS.md +379 -0
  148. package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
  149. package/src/services/core/websocket/WebSocketManager.ts +2 -0
  150. package/src/services/core/websocket/types.ts +1 -1
  151. package/src/services/index.ts +1 -1
  152. package/src/services/task/Task.ts +837 -0
  153. package/src/services/task/TaskFactory.ts +55 -0
  154. package/src/services/task/TaskManager.ts +738 -613
  155. package/src/services/task/TaskUtils.ts +205 -25
  156. package/src/services/task/ai-docs/AGENTS.md +455 -0
  157. package/src/services/task/ai-docs/ARCHITECTURE.md +585 -0
  158. package/src/services/task/constants.ts +7 -0
  159. package/src/services/task/dialer.ts +80 -0
  160. package/src/services/task/digital/Digital.ts +95 -0
  161. package/src/services/task/state-machine/TaskStateMachine.ts +1077 -0
  162. package/src/services/task/state-machine/actions.ts +685 -0
  163. package/src/services/task/state-machine/ai-docs/AGENTS.md +495 -0
  164. package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1135 -0
  165. package/src/services/task/state-machine/constants.ts +172 -0
  166. package/src/services/task/state-machine/guards.ts +406 -0
  167. package/src/services/task/state-machine/index.ts +28 -0
  168. package/src/services/task/state-machine/types.ts +241 -0
  169. package/src/services/task/state-machine/uiControlsComputer.ts +867 -0
  170. package/src/services/task/taskDataNormalizer.ts +137 -0
  171. package/src/services/task/types.ts +710 -71
  172. package/src/services/task/voice/Voice.ts +1267 -0
  173. package/src/services/task/voice/WebRTC.ts +187 -0
  174. package/src/types.ts +122 -2
  175. package/src/utils/AGENTS.md +276 -0
  176. package/src/webex.js +2 -0
  177. package/test/unit/spec/cc.ts +343 -23
  178. package/test/unit/spec/logger-proxy.ts +70 -0
  179. package/test/unit/spec/services/ApiAiAssistant.ts +122 -17
  180. package/test/unit/spec/services/UserPreference.ts +401 -0
  181. package/test/unit/spec/services/WebCallingService.ts +7 -1
  182. package/test/unit/spec/services/config/index.ts +30 -30
  183. package/test/unit/spec/services/core/Utils.ts +425 -8
  184. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
  185. package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
  186. package/test/unit/spec/services/task/Task.ts +477 -0
  187. package/test/unit/spec/services/task/TaskFactory.ts +62 -0
  188. package/test/unit/spec/services/task/TaskManager.ts +832 -1702
  189. package/test/unit/spec/services/task/TaskUtils.ts +206 -0
  190. package/test/unit/spec/services/task/dialer.ts +190 -0
  191. package/test/unit/spec/services/task/digital/Digital.ts +105 -0
  192. package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +1825 -0
  193. package/test/unit/spec/services/task/state-machine/guards.ts +479 -0
  194. package/test/unit/spec/services/task/state-machine/types.ts +18 -0
  195. package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2020 -0
  196. package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
  197. package/test/unit/spec/services/task/voice/Voice.ts +631 -0
  198. package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
  199. package/umd/contact-center.min.js +2 -2
  200. package/umd/contact-center.min.js.map +1 -1
  201. package/dist/services/task/index.js +0 -1525
  202. package/dist/services/task/index.js.map +0 -1
  203. package/dist/types/services/task/index.d.ts +0 -650
  204. package/src/services/task/index.ts +0 -1801
  205. package/test/unit/spec/services/task/index.ts +0 -2184
@@ -65,6 +65,8 @@ export const CC_TASK_EVENTS = {
65
65
  AGENT_CONFERENCE_TRANSFER_FAILED: 'AgentConferenceTransferFailed',
66
66
  /** Event emitted for post-call activity by participant */
67
67
  PARTICIPANT_POST_CALL_ACTIVITY: 'ParticipantPostCallActivity',
68
+ /** Event emitted when consulted participant is being moved/transferred */
69
+ CONSULTED_PARTICIPANT_MOVING: 'ConsultedParticipantMoving',
68
70
  /** Event emitted when contact is blind transferred */
69
71
  AGENT_BLIND_TRANSFERRED: 'AgentBlindTransferred',
70
72
  /** Event emitted when blind transfer fails */
@@ -81,6 +83,8 @@ export const CC_TASK_EVENTS = {
81
83
  AGENT_CONSULT_TRANSFER_FAILED: 'AgentConsultTransferFailed',
82
84
  /** Event emitted when contact recording is paused */
83
85
  CONTACT_RECORDING_PAUSED: 'ContactRecordingPaused',
86
+ /** Event emitted when contact recording is started */
87
+ CONTACT_RECORDING_STARTED: 'ContactRecordingStarted',
84
88
  /** Event emitted when pausing contact recording fails */
85
89
  CONTACT_RECORDING_PAUSE_FAILED: 'ContactRecordingPauseFailed',
86
90
  /** Event emitted when contact recording is resumed */
@@ -91,6 +95,10 @@ export const CC_TASK_EVENTS = {
91
95
  CONTACT_ENDED: 'ContactEnded',
92
96
  /** Event emitted when contact is merged */
93
97
  CONTACT_MERGED: 'ContactMerged',
98
+ /** Event emitted when contact payload is updated (routing updates) */
99
+ CONTACT_UPDATED: 'ContactUpdated',
100
+ /** Event emitted when contact owner changes */
101
+ CONTACT_OWNER_CHANGED: 'ContactOwnerChanged',
94
102
  /** Event emitted when ending contact fails */
95
103
  AGENT_CONTACT_END_FAILED: 'AgentContactEndFailed',
96
104
  /** Event emitted when agent enters wrap-up state */
@@ -117,8 +125,20 @@ export const CC_TASK_EVENTS = {
117
125
  CAMPAIGN_CONTACT_UPDATED: 'CampaignContactUpdated',
118
126
  /** Event emitted when accepting a campaign preview contact fails */
119
127
  CAMPAIGN_PREVIEW_ACCEPT_FAILED: 'CampaignPreviewAcceptFailed',
128
+ /** Event emitted when skipping a campaign preview contact fails */
129
+ CAMPAIGN_PREVIEW_SKIP_FAILED: 'CampaignPreviewSkipFailed',
130
+ /** Event emitted when removing a campaign preview contact fails */
131
+ CAMPAIGN_PREVIEW_REMOVE_FAILED: 'CampaignPreviewRemoveFailed',
120
132
  /** Event emitted when a real-time transcript chunk is received */
121
133
  REAL_TIME_TRANSCRIPTION: 'REAL_TIME_TRANSCRIPTION',
134
+ /** Event emitted when an AI assistant suggested response is available */
135
+ SUGGESTED_RESPONSE: 'SUGGESTED_RESPONSE',
136
+ /** Event emitted when backend acknowledges it is listening for more context */
137
+ SUGGESTED_RESPONSE_ACKNOWLEDGE: 'SUGGESTED_RESPONSE_ACKNOWLEDGE',
138
+ /** Event emitted when a mid-call summary is available */
139
+ MID_CALL_SUMMARY: 'MID_CALL_SUMMARY',
140
+ /** Event emitted when a post-call summary is available */
141
+ POST_CALL_SUMMARY: 'POST_CALL_SUMMARY',
122
142
  } as const;
123
143
 
124
144
  /**
@@ -185,6 +205,15 @@ export type WelcomeEvent = {
185
205
  agentId: string;
186
206
  };
187
207
 
208
+ /**
209
+ * Available login options for voice channel access
210
+ * 'AGENT_DN' - Login using agent's DN
211
+ * 'EXTENSION' - Login using extension number
212
+ * 'BROWSER' - Login using browser-based WebRTC
213
+ * @public
214
+ */
215
+ export type LoginOption = 'AGENT_DN' | 'EXTENSION' | 'BROWSER';
216
+
188
217
  /**
189
218
  * Response type for welcome events which can be either success or error
190
219
  * @public
@@ -275,14 +304,40 @@ export type AgentResponse = {
275
304
 
276
305
  /**
277
306
  * The default dialed number of the agent.
307
+ * Note: The API returns this field as "deafultDialledNumber" (with typo).
278
308
  */
279
- defaultDialledNumber?: string;
309
+ deafultDialledNumber?: string;
280
310
  };
281
311
 
282
312
  /**
283
313
  * Represents the response from getDesktopProfileById method.
284
314
  */
285
315
  export type DesktopProfileResponse = {
316
+ /**
317
+ * Unique identifier of the agent profile configuration.
318
+ */
319
+ id: string;
320
+
321
+ /**
322
+ * Display name for the agent profile.
323
+ */
324
+ name: string;
325
+
326
+ /**
327
+ * Description of the agent profile.
328
+ */
329
+ description: string;
330
+
331
+ /**
332
+ * Parent entity type for the profile (for example ORGANIZATION).
333
+ */
334
+ parentType: string;
335
+
336
+ /**
337
+ * Indicates whether screen pop is enabled.
338
+ */
339
+ screenPopup: boolean;
340
+
286
341
  /**
287
342
  * Represents the voice options of an agent.
288
343
  */
@@ -323,6 +378,11 @@ export type DesktopProfileResponse = {
323
378
  */
324
379
  autoWrapUp: boolean;
325
380
 
381
+ /**
382
+ * Whether the agent personal greeting is enabled.
383
+ */
384
+ agentPersonalGreeting: boolean;
385
+
326
386
  /**
327
387
  * Auto answer allowed.
328
388
  */
@@ -343,6 +403,36 @@ export type DesktopProfileResponse = {
343
403
  */
344
404
  allowAutoWrapUpExtension: boolean;
345
405
 
406
+ /**
407
+ * Access control for queues assigned to the agent (ALL or SPECIFIC).
408
+ */
409
+ accessQueue: string;
410
+
411
+ /**
412
+ * Queue identifiers available to the agent when access is SPECIFIC.
413
+ */
414
+ queues: string[];
415
+
416
+ /**
417
+ * Access control for entry points assigned to the agent.
418
+ */
419
+ accessEntryPoint: string;
420
+
421
+ /**
422
+ * Entry point identifiers available to the agent when access is SPECIFIC.
423
+ */
424
+ entryPoints: string[];
425
+
426
+ /**
427
+ * Access control for buddy teams assigned to the agent.
428
+ */
429
+ accessBuddyTeam: string;
430
+
431
+ /**
432
+ * Buddy team identifiers available to the agent when access is SPECIFIC.
433
+ */
434
+ buddyTeams: string[];
435
+
346
436
  /**
347
437
  * Outdial enabled for the agent.
348
438
  */
@@ -386,6 +476,11 @@ export type DesktopProfileResponse = {
386
476
  */
387
477
  agentDNValidation: string;
388
478
 
479
+ /**
480
+ * Additional DN validation criteria configured for the agent.
481
+ */
482
+ agentDNValidationCriterions: string[];
483
+
389
484
  /**
390
485
  * Dial plans of the agent.
391
486
  */
@@ -420,6 +515,31 @@ export type DesktopProfileResponse = {
420
515
  * State synchronization in Webex enabled or not.
421
516
  */
422
517
  stateSynchronizationWebex: boolean;
518
+
519
+ /**
520
+ * Threshold rules configured for the agent profile.
521
+ */
522
+ thresholdRules: Array<Record<string, string | number>>;
523
+
524
+ /**
525
+ * Whether the agent profile is currently active.
526
+ */
527
+ active: boolean;
528
+
529
+ /**
530
+ * Whether this profile is the system default.
531
+ */
532
+ systemDefault: boolean;
533
+
534
+ /**
535
+ * Timestamp when the profile was created.
536
+ */
537
+ createdTime: number;
538
+
539
+ /**
540
+ * Timestamp when the profile was last updated.
541
+ */
542
+ lastUpdatedTime: number;
423
543
  };
424
544
 
425
545
  /**
@@ -866,15 +986,6 @@ export type WrapupData = {
866
986
  };
867
987
  };
868
988
 
869
- /**
870
- * Available login options for voice channel access
871
- * 'AGENT_DN' - Login using agent's DN
872
- * 'EXTENSION' - Login using extension number
873
- * 'BROWSER' - Login using browser-based WebRTC
874
- * @public
875
- */
876
- export type LoginOption = 'AGENT_DN' | 'EXTENSION' | 'BROWSER';
877
-
878
989
  /**
879
990
  * Team configuration information
880
991
  * @public
@@ -1047,7 +1158,7 @@ export type Profile = {
1047
1158
  /** Outbound entry point */
1048
1159
  outDialEp: string;
1049
1160
  /** Whether ending calls is enabled */
1050
- isEndCallEnabled: boolean;
1161
+ isEndTaskEnabled: boolean;
1051
1162
  /** Whether ending consultations is enabled */
1052
1163
  isEndConsultEnabled: boolean;
1053
1164
  /** Optional lifecycle manager URL */
@@ -1183,3 +1294,55 @@ export type OutdialAniParams = {
1183
1294
  /** Comma-separated list of attributes to include in response (optional) */
1184
1295
  attributes?: string;
1185
1296
  };
1297
+
1298
+ /**
1299
+ * User preference data structure
1300
+ * @public
1301
+ */
1302
+ export type UserPreference = {
1303
+ /** Unique identifier for the user preference */
1304
+ id: string;
1305
+ /** Organization ID */
1306
+ organizationId: string;
1307
+ /** User ID (CI user ID) */
1308
+ userId: string;
1309
+ /** User preference data as key-value pairs */
1310
+ preferences: Record<string, unknown>;
1311
+ /** Timestamp when this preference was created (Unix timestamp in milliseconds) */
1312
+ createdTime?: number;
1313
+ /** Timestamp when this preference was last updated (Unix timestamp in milliseconds) */
1314
+ lastUpdatedTime?: number;
1315
+ };
1316
+
1317
+ /**
1318
+ * Request payload for creating user preferences
1319
+ * @public
1320
+ */
1321
+ export type CreateUserPreferenceRequest = {
1322
+ /** User ID (CI user ID) */
1323
+ userId: string;
1324
+ /** Desktop preference data as a JSON string (required) */
1325
+ desktopPreference: string;
1326
+ };
1327
+
1328
+ /**
1329
+ * Request payload for updating user preferences
1330
+ * @public
1331
+ */
1332
+ export type UpdateUserPreferenceRequest = {
1333
+ /** Desktop preference data as a JSON string (required) */
1334
+ desktopPreference: string;
1335
+ };
1336
+
1337
+ /**
1338
+ * Query parameters for fetching user preferences
1339
+ * @public
1340
+ */
1341
+ export type GetUserPreferenceParams = {
1342
+ /** User ID to fetch preferences for. Defaults to current user's CI user ID. */
1343
+ userId?: string;
1344
+ /** Page number (0-indexed). Default: 0 */
1345
+ page?: number;
1346
+ /** Number of items per page. Default: 100 */
1347
+ pageSize?: number;
1348
+ };
@@ -39,6 +39,8 @@ export type TaskErrorIds =
39
39
  | {'Service.aqm.task.resumeRecording': Failure}
40
40
  | {'Service.aqm.dialer.startOutdial': Failure}
41
41
  | {'Service.aqm.dialer.acceptPreviewContact': Failure}
42
+ | {'Service.aqm.dialer.skipPreviewContact': Failure}
43
+ | {'Service.aqm.dialer.removePreviewContact': Failure}
42
44
  | {'Service.reqs.generic.failure': {trackingId: string}};
43
45
 
44
46
  export type ReqError =
@@ -4,10 +4,14 @@ import {Failure, AugmentedError} from './GlobalTypes';
4
4
  import LoggerProxy from '../../logger-proxy';
5
5
  import WebexRequest from './WebexRequest';
6
6
  import {
7
+ ConsultConferenceData,
8
+ consultConferencePayloadData,
9
+ ConsultTransferDestinationType,
7
10
  TaskData,
8
- ConsultTransferPayLoad,
9
11
  CONSULT_TRANSFER_DESTINATION_TYPE,
12
+ DESTINATION_TYPE,
10
13
  Interaction,
14
+ InteractionParticipant,
11
15
  } from '../task/types';
12
16
  import {PARTICIPANT_TYPES, STATE_CONSULT} from './constants';
13
17
  import {DialPlan} from '../config/types';
@@ -28,55 +32,68 @@ const getCommonErrorDetails = (errObj: WebexRequestPayload) => {
28
32
  };
29
33
 
30
34
  /**
31
- * Checks if the destination type represents an entry point variant (EPDN or ENTRYPOINT).
32
- */
33
- const isEntryPointOrEpdn = (destAgentType?: string): boolean => {
34
- return destAgentType === 'EPDN' || destAgentType === 'ENTRYPOINT';
35
- };
36
-
37
- /**
38
- * Determines if the task involves dialing a number based on the destination type.
39
- * Returns 'DIAL_NUMBER' for dial-related destinations, empty string otherwise.
35
+ * Strips characters defined in the dial plan entry from the input string.
36
+ *
37
+ * @param input - The dial number to sanitize
38
+ * @param strippedChars - String of characters to remove from the input
39
+ * @returns The sanitized input with specified characters removed
40
40
  */
41
- const getAgentActionTypeFromTask = (taskData?: TaskData): 'DIAL_NUMBER' | '' => {
42
- const destAgentType = taskData?.destinationType;
41
+ export const stripDialPlanChars = (input: string, strippedChars: string): string => {
42
+ if (!strippedChars) {
43
+ return input;
44
+ }
43
45
 
44
- // Check if destination requires dialing: direct dial number or entry point variants
45
- const isDialNumber = destAgentType === 'DN';
46
- const isEntryPointVariant = isEntryPointOrEpdn(destAgentType);
46
+ const charsToStrip = new Set(strippedChars.split(''));
47
47
 
48
- // If the destination type is a dial number or an entry point variant, return 'DIAL_NUMBER'
49
- return isDialNumber || isEntryPointVariant ? 'DIAL_NUMBER' : '';
48
+ return input
49
+ .split('')
50
+ .filter((c) => !charsToStrip.has(c))
51
+ .join('');
50
52
  };
51
53
 
52
- // Fallback regex for US/Canada dial numbers when no dial plan entries are configured
53
- export const FALLBACK_DIAL_NUMBER_REGEX = /1[0-9]{3}[2-9][0-9]{6}([,]{1,10}[0-9]+){0,1}/;
54
-
55
54
  /**
56
55
  * Validates a dial number against the provided dial plan regex patterns.
57
56
  * A number is valid if it matches at least one regex pattern in the dial plans.
58
- * Falls back to US/Canada regex validation if no dial plan entries are configured.
57
+ * Skips validation when no dial plan entries are configured, deferring to the server.
59
58
  *
60
59
  * @param input - The dial number to validate
61
60
  * @param dialPlanEntries - Array of dial plan entries containing regex patterns
62
- * @returns true if the input matches at least one dial plan regex pattern, false otherwise
61
+ * @returns true if the input matches at least one dial plan regex pattern or no entries are configured, false otherwise
63
62
  */
64
63
  export const isValidDialNumber = (
65
64
  input: string,
66
65
  dialPlanEntries: DialPlan['dialPlanEntity']
67
66
  ): boolean => {
67
+ if (!input) {
68
+ LoggerProxy.warn('Dial number is empty or undefined.', {
69
+ module: 'Utils',
70
+ method: 'isValidDialNumber',
71
+ });
72
+
73
+ return false;
74
+ }
75
+
68
76
  if (!dialPlanEntries || dialPlanEntries.length === 0) {
69
- LoggerProxy.info('No dial plan entries found. Falling back to US number validation.');
77
+ LoggerProxy.log(
78
+ 'No dial plan entries found. Skipping client-side validation, deferring to server.',
79
+ {module: 'Utils', method: 'isValidDialNumber'}
80
+ );
70
81
 
71
- return FALLBACK_DIAL_NUMBER_REGEX.test(input);
82
+ return true;
72
83
  }
73
84
 
74
85
  return dialPlanEntries.some((entry) => {
75
86
  try {
87
+ const sanitizedInput = stripDialPlanChars(input, entry.strippedChars);
76
88
  const regex = new RegExp(entry.regex);
77
89
 
78
- return regex.test(input);
79
- } catch {
90
+ return regex.test(sanitizedInput);
91
+ } catch (e) {
92
+ LoggerProxy.warn(`Failed to validate dial number against entry "${entry.name}": ${e}`, {
93
+ module: 'Utils',
94
+ method: 'isValidDialNumber',
95
+ });
96
+
80
97
  return false;
81
98
  }
82
99
  });
@@ -243,6 +260,7 @@ export const createErrDetailsObject = (errObj: WebexRequestPayload) => {
243
260
  return new Err.Details('Service.reqs.generic.failure', details);
244
261
  };
245
262
 
263
+ /*
246
264
  /**
247
265
  * Gets the consulted agent ID from the media object by finding the agent
248
266
  * in the consult media participants (excluding the current agent).
@@ -321,9 +339,16 @@ export const calculateDestAgentId = (interaction: Interaction, agentId: string):
321
339
  return destAgentIdCBT;
322
340
  }
323
341
 
324
- return interaction.participants[consultingAgent]?.type === PARTICIPANT_TYPES.EP_DN
325
- ? interaction.participants[consultingAgent]?.epId
326
- : interaction.participants[consultingAgent]?.id;
342
+ const participant = interaction.participants[consultingAgent];
343
+ if (!participant) {
344
+ return '';
345
+ }
346
+
347
+ if (participant.type === PARTICIPANT_TYPES.EP_DN) {
348
+ return (participant as InteractionParticipant & {epId?: string}).epId ?? '';
349
+ }
350
+
351
+ return participant.id ?? '';
327
352
  };
328
353
 
329
354
  /**
@@ -358,16 +383,77 @@ export const calculateDestType = (interaction: Interaction, agentId: string): st
358
383
  return CONSULT_TRANSFER_DESTINATION_TYPE.AGENT;
359
384
  };
360
385
 
386
+ /**
387
+ * Gets the destination agent ID from participants.
388
+ * Finds a participant who is not the current agent and is an agent type.
389
+ *
390
+ * @param participants - The participants object from interaction
391
+ * @param agentId - The current agent's ID
392
+ * @returns The destination agent ID, or undefined if none found
393
+ */
394
+ export const buildConsultConferenceParamData = (
395
+ dataPassed: consultConferencePayloadData,
396
+ interactionIdPassed: string
397
+ ): {interactionId: string; data: ConsultConferenceData} => {
398
+ const data: ConsultConferenceData = {
399
+ ...('agentId' in dataPassed && {agentId: dataPassed.agentId}),
400
+ to: dataPassed.destAgentId,
401
+ destinationType: '',
402
+ };
403
+
404
+ if ('destinationType' in dataPassed) {
405
+ const destinationType = String(dataPassed.destinationType || '').trim();
406
+ const normalizedDestinationType = destinationType.toUpperCase().replace(/[-_\s]/g, '');
407
+
408
+ if (normalizedDestinationType === 'DN' || normalizedDestinationType === 'DIALNUMBER') {
409
+ data.destinationType = DESTINATION_TYPE.DIALNUMBER;
410
+ } else if (normalizedDestinationType === 'EPDN' || normalizedDestinationType === 'ENTRYPOINT') {
411
+ data.destinationType = DESTINATION_TYPE.ENTRYPOINT;
412
+ } else if (normalizedDestinationType === 'QUEUE') {
413
+ data.destinationType = DESTINATION_TYPE.QUEUE;
414
+ } else if (normalizedDestinationType === 'AGENT') {
415
+ data.destinationType = DESTINATION_TYPE.AGENT;
416
+ } else {
417
+ data.destinationType = destinationType as ConsultConferenceData['destinationType'];
418
+ }
419
+ } else {
420
+ data.destinationType = DESTINATION_TYPE.AGENT;
421
+ }
422
+
423
+ return {
424
+ interactionId: interactionIdPassed,
425
+ data,
426
+ };
427
+ };
428
+
429
+ /**
430
+ * Derives the consult transfer destination type based on task data.
431
+ * This function determines the appropriate destination type for a consult transfer
432
+ * by examining the destination type stored in the task data.
433
+ *
434
+ * @param taskData - The task data containing destination information
435
+ * @returns The derived consult transfer destination type
436
+ * @public
437
+ */
361
438
  export const deriveConsultTransferDestinationType = (
362
- taskData?: TaskData
363
- ): ConsultTransferPayLoad['destinationType'] => {
364
- const agentActionType = getAgentActionTypeFromTask(taskData);
365
-
366
- if (agentActionType === 'DIAL_NUMBER') {
367
- return isEntryPointOrEpdn(taskData?.destinationType)
368
- ? CONSULT_TRANSFER_DESTINATION_TYPE.ENTRYPOINT
369
- : CONSULT_TRANSFER_DESTINATION_TYPE.DIALNUMBER;
439
+ taskData: TaskData
440
+ ): ConsultTransferDestinationType => {
441
+ const destType = taskData?.destinationType;
442
+ const normalizedDestType = String(destType || '')
443
+ .toUpperCase()
444
+ .replace(/[-_\s]/g, '');
445
+
446
+ // Map destination types to consult transfer destination types
447
+ if (normalizedDestType === 'DN' || normalizedDestType === 'DIALNUMBER') {
448
+ return CONSULT_TRANSFER_DESTINATION_TYPE.DIALNUMBER;
449
+ }
450
+ if (normalizedDestType === 'EPDN' || normalizedDestType === 'ENTRYPOINT') {
451
+ return CONSULT_TRANSFER_DESTINATION_TYPE.ENTRYPOINT;
452
+ }
453
+ if (normalizedDestType === 'QUEUE') {
454
+ return CONSULT_TRANSFER_DESTINATION_TYPE.QUEUE;
370
455
  }
371
456
 
457
+ // Default to agent if no specific type matches
372
458
  return CONSULT_TRANSFER_DESTINATION_TYPE.AGENT;
373
459
  };