@webex/contact-center 3.9.0 → 3.10.0-next.2

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 (111) hide show
  1. package/dist/cc.js +196 -47
  2. package/dist/cc.js.map +1 -1
  3. package/dist/constants.js +1 -0
  4. package/dist/constants.js.map +1 -1
  5. package/dist/index.js +9 -0
  6. package/dist/index.js.map +1 -1
  7. package/dist/logger-proxy.js +24 -1
  8. package/dist/logger-proxy.js.map +1 -1
  9. package/dist/metrics/MetricsManager.js +1 -1
  10. package/dist/metrics/MetricsManager.js.map +1 -1
  11. package/dist/metrics/behavioral-events.js +89 -0
  12. package/dist/metrics/behavioral-events.js.map +1 -1
  13. package/dist/metrics/constants.js +32 -2
  14. package/dist/metrics/constants.js.map +1 -1
  15. package/dist/services/AddressBook.js +271 -0
  16. package/dist/services/AddressBook.js.map +1 -0
  17. package/dist/services/EntryPoint.js +227 -0
  18. package/dist/services/EntryPoint.js.map +1 -0
  19. package/dist/services/Queue.js +261 -0
  20. package/dist/services/Queue.js.map +1 -0
  21. package/dist/services/config/constants.js +36 -2
  22. package/dist/services/config/constants.js.map +1 -1
  23. package/dist/services/config/index.js +29 -21
  24. package/dist/services/config/index.js.map +1 -1
  25. package/dist/services/config/types.js +33 -1
  26. package/dist/services/config/types.js.map +1 -1
  27. package/dist/services/core/GlobalTypes.js.map +1 -1
  28. package/dist/services/core/Utils.js +162 -2
  29. package/dist/services/core/Utils.js.map +1 -1
  30. package/dist/services/core/aqm-reqs.js +0 -4
  31. package/dist/services/core/aqm-reqs.js.map +1 -1
  32. package/dist/services/core/websocket/WebSocketManager.js +0 -4
  33. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  34. package/dist/services/task/TaskManager.js +114 -3
  35. package/dist/services/task/TaskManager.js.map +1 -1
  36. package/dist/services/task/TaskUtils.js +76 -0
  37. package/dist/services/task/TaskUtils.js.map +1 -0
  38. package/dist/services/task/constants.js +26 -1
  39. package/dist/services/task/constants.js.map +1 -1
  40. package/dist/services/task/contact.js +86 -0
  41. package/dist/services/task/contact.js.map +1 -1
  42. package/dist/services/task/index.js +418 -87
  43. package/dist/services/task/index.js.map +1 -1
  44. package/dist/services/task/types.js +14 -0
  45. package/dist/services/task/types.js.map +1 -1
  46. package/dist/types/cc.d.ts +115 -35
  47. package/dist/types/constants.d.ts +1 -0
  48. package/dist/types/index.d.ts +3 -2
  49. package/dist/types/metrics/constants.d.ts +25 -1
  50. package/dist/types/services/AddressBook.d.ts +74 -0
  51. package/dist/types/services/EntryPoint.d.ts +67 -0
  52. package/dist/types/services/Queue.d.ts +76 -0
  53. package/dist/types/services/config/constants.d.ts +35 -1
  54. package/dist/types/services/config/index.d.ts +6 -9
  55. package/dist/types/services/config/types.d.ts +79 -58
  56. package/dist/types/services/core/GlobalTypes.d.ts +25 -0
  57. package/dist/types/services/core/Utils.d.ts +40 -1
  58. package/dist/types/services/task/TaskUtils.d.ts +28 -0
  59. package/dist/types/services/task/constants.d.ts +23 -0
  60. package/dist/types/services/task/contact.d.ts +10 -0
  61. package/dist/types/services/task/index.d.ts +85 -4
  62. package/dist/types/services/task/types.d.ts +233 -21
  63. package/dist/types/types.d.ts +162 -0
  64. package/dist/types/utils/PageCache.d.ts +173 -0
  65. package/dist/types.js +17 -0
  66. package/dist/types.js.map +1 -1
  67. package/dist/utils/PageCache.js +192 -0
  68. package/dist/utils/PageCache.js.map +1 -0
  69. package/dist/webex.js +1 -1
  70. package/package.json +10 -9
  71. package/src/cc.ts +221 -52
  72. package/src/constants.ts +1 -0
  73. package/src/index.ts +16 -2
  74. package/src/logger-proxy.ts +24 -1
  75. package/src/metrics/MetricsManager.ts +1 -1
  76. package/src/metrics/behavioral-events.ts +94 -0
  77. package/src/metrics/constants.ts +37 -1
  78. package/src/services/AddressBook.ts +291 -0
  79. package/src/services/EntryPoint.ts +241 -0
  80. package/src/services/Queue.ts +277 -0
  81. package/src/services/config/constants.ts +42 -2
  82. package/src/services/config/index.ts +30 -30
  83. package/src/services/config/types.ts +59 -58
  84. package/src/services/core/GlobalTypes.ts +27 -0
  85. package/src/services/core/Utils.ts +199 -1
  86. package/src/services/core/aqm-reqs.ts +0 -5
  87. package/src/services/core/websocket/WebSocketManager.ts +0 -4
  88. package/src/services/task/TaskManager.ts +123 -5
  89. package/src/services/task/TaskUtils.ts +81 -0
  90. package/src/services/task/constants.ts +25 -0
  91. package/src/services/task/contact.ts +80 -0
  92. package/src/services/task/index.ts +510 -71
  93. package/src/services/task/types.ts +251 -20
  94. package/src/types.ts +180 -0
  95. package/src/utils/PageCache.ts +252 -0
  96. package/test/unit/spec/cc.ts +282 -85
  97. package/test/unit/spec/metrics/MetricsManager.ts +0 -1
  98. package/test/unit/spec/metrics/behavioral-events.ts +42 -0
  99. package/test/unit/spec/services/AddressBook.ts +332 -0
  100. package/test/unit/spec/services/EntryPoint.ts +259 -0
  101. package/test/unit/spec/services/Queue.ts +323 -0
  102. package/test/unit/spec/services/config/index.ts +279 -65
  103. package/test/unit/spec/services/core/Utils.ts +50 -0
  104. package/test/unit/spec/services/core/aqm-reqs.ts +1 -3
  105. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +0 -4
  106. package/test/unit/spec/services/task/TaskManager.ts +390 -1
  107. package/test/unit/spec/services/task/TaskUtils.ts +131 -0
  108. package/test/unit/spec/services/task/contact.ts +31 -1
  109. package/test/unit/spec/services/task/index.ts +585 -130
  110. package/umd/contact-center.min.js +2 -2
  111. package/umd/contact-center.min.js.map +1 -1
@@ -120,7 +120,7 @@ class Task extends _events.default {
120
120
  * @param data - Initial task data
121
121
  * @param wrapupData - Wrap-up configuration data
122
122
  */
123
- constructor(contact, webCallingService, data, wrapupData) {
123
+ constructor(contact, webCallingService, data, wrapupData, agentId) {
124
124
  super();
125
125
  this.contact = contact;
126
126
  this.data = data;
@@ -130,6 +130,7 @@ class Task extends _events.default {
130
130
  this.metricsManager = _MetricsManager.default.getInstance();
131
131
  this.registerWebCallListeners();
132
132
  this.setupAutoWrapupTimer();
133
+ this.agentId = agentId;
133
134
  }
134
135
 
135
136
  /**
@@ -244,11 +245,17 @@ class Task extends _events.default {
244
245
  * @private
245
246
  */
246
247
  reconcileData(oldData, newData) {
248
+ // Remove keys from oldData that are not in newData
249
+ Object.keys(oldData).forEach(key => {
250
+ if (!(key in newData) && !_constants2.KEYS_TO_NOT_DELETE.includes(key)) {
251
+ delete oldData[key];
252
+ }
253
+ });
254
+
255
+ // Merge or update keys from newData
247
256
  Object.keys(newData).forEach(key => {
248
- if (newData[key] && typeof newData[key] === 'object' && !Array.isArray(newData[key])) {
249
- oldData[key] = this.reconcileData({
250
- ...oldData[key]
251
- }, newData[key]);
257
+ if (newData[key] && typeof newData[key] === 'object' && !Array.isArray(newData[key]) && oldData[key] && typeof oldData[key] === 'object' && !Array.isArray(oldData[key])) {
258
+ this.reconcileData(oldData[key], newData[key]);
252
259
  } else {
253
260
  oldData[key] = newData[key];
254
261
  }
@@ -331,15 +338,21 @@ class Task extends _events.default {
331
338
  }
332
339
  return Promise.resolve(); // TODO: reject for extension as part of refactor
333
340
  } catch (error) {
334
- const {
335
- error: detailedError
336
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.ACCEPT, _constants.TASK_FILE);
341
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.ACCEPT, _constants.TASK_FILE);
342
+ const taskErrorProps = {
343
+ trackingId: err.data?.trackingId,
344
+ errorMessage: err.data?.message,
345
+ errorType: err.data?.errorType,
346
+ errorData: err.data?.errorData,
347
+ reasonCode: err.data?.reasonCode
348
+ };
337
349
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_ACCEPT_FAILED, {
338
350
  taskId: this.data.interactionId,
339
351
  error: error.toString(),
352
+ ...taskErrorProps,
340
353
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details)
341
354
  }, ['operational', 'behavioral', 'business']);
342
- throw detailedError;
355
+ throw err;
343
356
  }
344
357
  }
345
358
 
@@ -372,10 +385,8 @@ class Task extends _events.default {
372
385
  });
373
386
  return Promise.resolve();
374
387
  } catch (error) {
375
- const {
376
- error: detailedError
377
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.TOGGLE_MUTE, _constants.TASK_FILE);
378
- throw detailedError;
388
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.TOGGLE_MUTE, _constants.TASK_FILE);
389
+ throw err;
379
390
  }
380
391
  }
381
392
 
@@ -413,15 +424,21 @@ class Task extends _events.default {
413
424
  });
414
425
  return Promise.resolve();
415
426
  } catch (error) {
416
- const {
417
- error: detailedError
418
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.DECLINE, _constants.TASK_FILE);
427
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.DECLINE, _constants.TASK_FILE);
428
+ const taskErrorProps = {
429
+ trackingId: err.data?.trackingId,
430
+ errorMessage: err.data?.message,
431
+ errorType: err.data?.errorType,
432
+ errorData: err.data?.errorData,
433
+ reasonCode: err.data?.reasonCode
434
+ };
419
435
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_DECLINE_FAILED, {
420
436
  taskId: this.data.interactionId,
421
437
  error: error.toString(),
438
+ ...taskErrorProps,
422
439
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
423
440
  }, ['operational', 'behavioral']);
424
- throw detailedError;
441
+ throw err;
425
442
  }
426
443
  }
427
444
 
@@ -429,6 +446,7 @@ class Task extends _events.default {
429
446
  * Puts the current task/interaction on hold.
430
447
  * Emits task:hold event when successful. For voice tasks, this mutes the audio.
431
448
  *
449
+ * @param mediaResourceId - Optional media resource ID to use for the hold operation. If not provided, uses the task's current mediaResourceId
432
450
  * @returns Promise<TaskResponse>
433
451
  * @throws Error if hold operation fails
434
452
  * @example
@@ -449,9 +467,17 @@ class Task extends _events.default {
449
467
  * console.error('Failed to place task on hold:', error);
450
468
  * // Handle error (e.g., show error message, reset UI state)
451
469
  * }
470
+ *
471
+ * // Place task on hold with custom mediaResourceId
472
+ * try {
473
+ * await task.hold('custom-media-resource-id');
474
+ * console.log('Successfully placed task on hold with custom mediaResourceId');
475
+ * } catch (error) {
476
+ * console.error('Failed to place task on hold:', error);
477
+ * }
452
478
  * ```
453
479
  */
454
- async hold() {
480
+ async hold(mediaResourceId) {
455
481
  try {
456
482
  _loggerProxy.default.info(`Holding task`, {
457
483
  module: _constants.TASK_FILE,
@@ -459,16 +485,17 @@ class Task extends _events.default {
459
485
  interactionId: this.data.interactionId
460
486
  });
461
487
  this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_HOLD_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_HOLD_FAILED]);
488
+ const effectiveMediaResourceId = mediaResourceId ?? this.data.mediaResourceId;
462
489
  const response = await this.contact.hold({
463
490
  interactionId: this.data.interactionId,
464
491
  data: {
465
- mediaResourceId: this.data.mediaResourceId
492
+ mediaResourceId: effectiveMediaResourceId
466
493
  }
467
494
  });
468
495
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_HOLD_SUCCESS, {
469
496
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response),
470
497
  taskId: this.data.interactionId,
471
- mediaResourceId: this.data.mediaResourceId
498
+ mediaResourceId: effectiveMediaResourceId
472
499
  }, ['operational', 'behavioral']);
473
500
  _loggerProxy.default.log(`Task placed on hold successfully`, {
474
501
  module: _constants.TASK_FILE,
@@ -478,16 +505,23 @@ class Task extends _events.default {
478
505
  });
479
506
  return response;
480
507
  } catch (error) {
481
- const {
482
- error: detailedError
483
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.HOLD, _constants.TASK_FILE);
508
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.HOLD, _constants.TASK_FILE);
509
+ const taskErrorProps = {
510
+ trackingId: err.data?.trackingId,
511
+ errorMessage: err.data?.message,
512
+ errorType: err.data?.errorType,
513
+ errorData: err.data?.errorData,
514
+ reasonCode: err.data?.reasonCode
515
+ };
516
+ const effectiveMediaResourceId = mediaResourceId ?? this.data.mediaResourceId;
484
517
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_HOLD_FAILED, {
485
518
  taskId: this.data.interactionId,
486
- mediaResourceId: this.data.mediaResourceId,
519
+ mediaResourceId: effectiveMediaResourceId,
487
520
  error: error.toString(),
521
+ ...taskErrorProps,
488
522
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
489
523
  }, ['operational', 'behavioral']);
490
- throw detailedError;
524
+ throw err;
491
525
  }
492
526
  }
493
527
 
@@ -495,6 +529,7 @@ class Task extends _events.default {
495
529
  * Resumes the task/interaction that was previously put on hold.
496
530
  * Emits task:resume event when successful. For voice tasks, this restores the audio.
497
531
  *
532
+ * @param mediaResourceId - Optional media resource ID to use for the resume operation. If not provided, uses the task's current mediaResourceId from interaction media
498
533
  * @returns Promise<TaskResponse>
499
534
  * @throws Error if resume operation fails
500
535
  * @example
@@ -515,9 +550,17 @@ class Task extends _events.default {
515
550
  * console.error('Failed to resume task:', error);
516
551
  * // Handle error (e.g., show error message)
517
552
  * }
553
+ *
554
+ * // Resume task from hold with custom mediaResourceId
555
+ * try {
556
+ * await task.resume('custom-media-resource-id');
557
+ * console.log('Successfully resumed task from hold with custom mediaResourceId');
558
+ * } catch (error) {
559
+ * console.error('Failed to resume task:', error);
560
+ * }
518
561
  * ```
519
562
  */
520
- async resume() {
563
+ async resume(mediaResourceId) {
521
564
  try {
522
565
  _loggerProxy.default.info(`Resuming task`, {
523
566
  module: _constants.TASK_FILE,
@@ -527,20 +570,19 @@ class Task extends _events.default {
527
570
  const {
528
571
  mainInteractionId
529
572
  } = this.data.interaction;
530
- const {
531
- mediaResourceId
532
- } = this.data.interaction.media[mainInteractionId];
573
+ const defaultMediaResourceId = this.data.interaction.media[mainInteractionId]?.mediaResourceId;
574
+ const effectiveMediaResourceId = mediaResourceId ?? defaultMediaResourceId;
533
575
  this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_RESUME_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_RESUME_FAILED]);
534
576
  const response = await this.contact.unHold({
535
577
  interactionId: this.data.interactionId,
536
578
  data: {
537
- mediaResourceId
579
+ mediaResourceId: effectiveMediaResourceId
538
580
  }
539
581
  });
540
582
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_SUCCESS, {
541
583
  taskId: this.data.interactionId,
542
584
  mainInteractionId,
543
- mediaResourceId,
585
+ mediaResourceId: effectiveMediaResourceId,
544
586
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
545
587
  }, ['operational', 'behavioral']);
546
588
  _loggerProxy.default.log(`Task resumed successfully`, {
@@ -551,17 +593,25 @@ class Task extends _events.default {
551
593
  });
552
594
  return response;
553
595
  } catch (error) {
554
- const {
555
- error: detailedError
556
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.RESUME, _constants.TASK_FILE);
596
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.RESUME, _constants.TASK_FILE);
557
597
  const mainInteractionId = this.data.interaction?.mainInteractionId;
598
+ const defaultMediaResourceId = mainInteractionId ? this.data.interaction.media[mainInteractionId]?.mediaResourceId : '';
599
+ const effectiveMediaResourceId = mediaResourceId ?? defaultMediaResourceId;
600
+ const taskErrorProps = {
601
+ trackingId: err.data?.trackingId,
602
+ errorMessage: err.data?.message,
603
+ errorType: err.data?.errorType,
604
+ errorData: err.data?.errorData,
605
+ reasonCode: err.data?.reasonCode
606
+ };
558
607
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_FAILED, {
559
608
  taskId: this.data.interactionId,
560
609
  mainInteractionId,
561
- mediaResourceId: mainInteractionId ? this.data.interaction.media[mainInteractionId].mediaResourceId : '',
610
+ mediaResourceId: effectiveMediaResourceId,
611
+ ...taskErrorProps,
562
612
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
563
613
  }, ['operational', 'behavioral']);
564
- throw detailedError;
614
+ throw err;
565
615
  }
566
616
  }
567
617
 
@@ -631,14 +681,20 @@ class Task extends _events.default {
631
681
  });
632
682
  return response;
633
683
  } catch (error) {
634
- const {
635
- error: detailedError
636
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.END, _constants.TASK_FILE);
684
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.END, _constants.TASK_FILE);
685
+ const taskErrorProps = {
686
+ trackingId: err.data?.trackingId,
687
+ errorMessage: err.data?.message,
688
+ errorType: err.data?.errorType,
689
+ errorData: err.data?.errorData,
690
+ reasonCode: err.data?.reasonCode
691
+ };
637
692
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_END_FAILED, {
638
693
  taskId: this.data.interactionId,
694
+ ...taskErrorProps,
639
695
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
640
696
  }, ['operational', 'behavioral', 'business']);
641
- throw detailedError;
697
+ throw err;
642
698
  }
643
699
  }
644
700
 
@@ -720,16 +776,22 @@ class Task extends _events.default {
720
776
  });
721
777
  return response;
722
778
  } catch (error) {
723
- const {
724
- error: detailedError
725
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.WRAPUP, _constants.TASK_FILE);
779
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.WRAPUP, _constants.TASK_FILE);
780
+ const taskErrorProps = {
781
+ trackingId: err.data?.trackingId,
782
+ errorMessage: err.data?.message,
783
+ errorType: err.data?.errorType,
784
+ errorData: err.data?.errorData,
785
+ reasonCode: err.data?.reasonCode
786
+ };
726
787
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_WRAPUP_FAILED, {
727
788
  taskId: this.data.interactionId,
728
789
  wrapUpCode: wrapupPayload.auxCodeId,
729
790
  wrapUpReason: wrapupPayload.wrapUpReason,
791
+ ...taskErrorProps,
730
792
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
731
793
  }, ['operational', 'behavioral', 'business']);
732
- throw detailedError;
794
+ throw err;
733
795
  }
734
796
  }
735
797
 
@@ -788,15 +850,21 @@ class Task extends _events.default {
788
850
  });
789
851
  return result;
790
852
  } catch (error) {
791
- const {
792
- error: detailedError
793
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.PAUSE_RECORDING, _constants.TASK_FILE);
853
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.PAUSE_RECORDING, _constants.TASK_FILE);
854
+ const taskErrorProps = {
855
+ trackingId: err.data?.trackingId,
856
+ errorMessage: err.data?.message,
857
+ errorType: err.data?.errorType,
858
+ errorData: err.data?.errorData,
859
+ reasonCode: err.data?.reasonCode
860
+ };
794
861
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_PAUSE_RECORDING_FAILED, {
795
862
  taskId: this.data.interactionId,
796
863
  error: error.toString(),
864
+ ...taskErrorProps,
797
865
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
798
866
  }, ['operational', 'behavioral', 'business']);
799
- throw detailedError;
867
+ throw err;
800
868
  }
801
869
  }
802
870
 
@@ -864,15 +932,21 @@ class Task extends _events.default {
864
932
  });
865
933
  return result;
866
934
  } catch (error) {
867
- const {
868
- error: detailedError
869
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.RESUME_RECORDING, _constants.TASK_FILE);
935
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.RESUME_RECORDING, _constants.TASK_FILE);
936
+ const taskErrorProps = {
937
+ trackingId: err.data?.trackingId,
938
+ errorMessage: err.data?.message,
939
+ errorType: err.data?.errorType,
940
+ errorData: err.data?.errorData,
941
+ reasonCode: err.data?.reasonCode
942
+ };
870
943
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_RECORDING_FAILED, {
871
944
  taskId: this.data.interactionId,
872
945
  error: error.toString(),
946
+ ...taskErrorProps,
873
947
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
874
948
  }, ['operational', 'behavioral', 'business']);
875
- throw detailedError;
949
+ throw err;
876
950
  }
877
951
  }
878
952
 
@@ -935,17 +1009,23 @@ class Task extends _events.default {
935
1009
  });
936
1010
  return result;
937
1011
  } catch (error) {
938
- const {
939
- error: detailedError
940
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.CONSULT, _constants.TASK_FILE);
1012
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.CONSULT, _constants.TASK_FILE);
1013
+ const taskErrorProps = {
1014
+ trackingId: err.data?.trackingId,
1015
+ errorMessage: err.data?.message,
1016
+ errorType: err.data?.errorType,
1017
+ errorData: err.data?.errorData,
1018
+ reasonCode: err.data?.reasonCode
1019
+ };
941
1020
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_START_FAILED, {
942
1021
  taskId: this.data.interactionId,
943
1022
  destination: consultPayload.to,
944
1023
  destinationType: consultPayload.destinationType,
945
1024
  error: error.toString(),
1025
+ ...taskErrorProps,
946
1026
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
947
1027
  }, ['operational', 'behavioral', 'business']);
948
- throw detailedError;
1028
+ throw err;
949
1029
  }
950
1030
  }
951
1031
 
@@ -1006,15 +1086,21 @@ class Task extends _events.default {
1006
1086
  });
1007
1087
  return result;
1008
1088
  } catch (error) {
1009
- const {
1010
- error: detailedError
1011
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.END_CONSULT, _constants.TASK_FILE);
1089
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.END_CONSULT, _constants.TASK_FILE);
1090
+ const taskErrorProps = {
1091
+ trackingId: err.data?.trackingId,
1092
+ errorMessage: err.data?.message,
1093
+ errorType: err.data?.errorType,
1094
+ errorData: err.data?.errorData,
1095
+ reasonCode: err.data?.reasonCode
1096
+ };
1012
1097
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_END_FAILED, {
1013
1098
  taskId: this.data.interactionId,
1014
1099
  error: error.toString(),
1100
+ ...taskErrorProps,
1015
1101
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1016
1102
  }, ['operational', 'behavioral', 'business']);
1017
- throw detailedError;
1103
+ throw err;
1018
1104
  }
1019
1105
  }
1020
1106
 
@@ -1083,18 +1169,24 @@ class Task extends _events.default {
1083
1169
  });
1084
1170
  return result;
1085
1171
  } catch (error) {
1086
- const {
1087
- error: detailedError
1088
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.TRANSFER, _constants.TASK_FILE);
1172
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.TRANSFER, _constants.TASK_FILE);
1173
+ const taskErrorProps = {
1174
+ trackingId: err.data?.trackingId,
1175
+ errorMessage: err.data?.message,
1176
+ errorType: err.data?.errorType,
1177
+ errorData: err.data?.errorData,
1178
+ reasonCode: err.data?.reasonCode
1179
+ };
1089
1180
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED, {
1090
1181
  taskId: this.data.interactionId,
1091
1182
  destination: transferPayload.to,
1092
1183
  destinationType: transferPayload.destinationType,
1093
1184
  isConsultTransfer: false,
1094
1185
  error: error.toString(),
1186
+ ...taskErrorProps,
1095
1187
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1096
1188
  }, ['operational', 'behavioral', 'business']);
1097
- throw detailedError;
1189
+ throw err;
1098
1190
  }
1099
1191
  }
1100
1192
 
@@ -1132,36 +1224,38 @@ class Task extends _events.default {
1132
1224
  */
1133
1225
  async consultTransfer(consultTransferPayload) {
1134
1226
  try {
1135
- _loggerProxy.default.info(`Initiating consult transfer to ${consultTransferPayload.to}`, {
1227
+ // Get the destination agent ID using custom logic from participants data
1228
+ const destAgentId = (0, _Utils.getDestinationAgentId)(this.data.interaction?.participants, this.data.agentId);
1229
+
1230
+ // Resolve the target id (queue consult transfers go to the accepted agent)
1231
+ if (!destAgentId) {
1232
+ throw new Error('No agent has accepted this queue consult yet');
1233
+ }
1234
+ _loggerProxy.default.info(`Initiating consult transfer to ${consultTransferPayload?.to || destAgentId}`, {
1136
1235
  module: _constants.TASK_FILE,
1137
1236
  method: _constants2.METHODS.CONSULT_TRANSFER,
1138
1237
  interactionId: this.data.interactionId
1139
1238
  });
1239
+ // Obtain payload based on desktop logic using TaskData
1240
+ const finalDestinationType = (0, _Utils.deriveConsultTransferDestinationType)(this.data);
1140
1241
 
1141
- // For queue destinations, use the destAgentId from task data
1142
- if (consultTransferPayload.destinationType === _types2.CONSULT_TRANSFER_DESTINATION_TYPE.QUEUE) {
1143
- if (!this.data.destAgentId) {
1144
- throw new Error('No agent has accepted this queue consult yet');
1145
- }
1146
-
1147
- // Override the destination with the agent who accepted the queue consult
1148
- consultTransferPayload = {
1149
- to: this.data.destAgentId,
1150
- destinationType: _types2.CONSULT_TRANSFER_DESTINATION_TYPE.AGENT
1151
- };
1152
- }
1242
+ // By default we always use the computed destAgentId as the target id
1243
+ const consultTransferRequest = {
1244
+ to: destAgentId,
1245
+ destinationType: finalDestinationType
1246
+ };
1153
1247
  const result = await this.contact.consultTransfer({
1154
1248
  interactionId: this.data.interactionId,
1155
- data: consultTransferPayload
1249
+ data: consultTransferRequest
1156
1250
  });
1157
1251
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_SUCCESS, {
1158
1252
  taskId: this.data.interactionId,
1159
- destination: consultTransferPayload.to,
1160
- destinationType: consultTransferPayload.destinationType,
1253
+ destination: consultTransferRequest.to,
1254
+ destinationType: consultTransferRequest.destinationType,
1161
1255
  isConsultTransfer: true,
1162
1256
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
1163
1257
  }, ['operational', 'behavioral', 'business']);
1164
- _loggerProxy.default.log(`Consult transfer completed successfully to ${consultTransferPayload.to}`, {
1258
+ _loggerProxy.default.log(`Consult transfer completed successfully to ${consultTransferPayload?.to || destAgentId}`, {
1165
1259
  module: _constants.TASK_FILE,
1166
1260
  method: _constants2.METHODS.CONSULT_TRANSFER,
1167
1261
  trackingId: result.trackingId,
@@ -1169,18 +1263,255 @@ class Task extends _events.default {
1169
1263
  });
1170
1264
  return result;
1171
1265
  } catch (error) {
1172
- const {
1173
- error: detailedError
1174
- } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.CONSULT_TRANSFER, _constants.TASK_FILE);
1266
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.CONSULT_TRANSFER, _constants.TASK_FILE);
1267
+ const taskErrorProps = {
1268
+ trackingId: err.data?.trackingId,
1269
+ errorMessage: err.data?.message,
1270
+ errorType: err.data?.errorType,
1271
+ errorData: err.data?.errorData,
1272
+ reasonCode: err.data?.reasonCode
1273
+ };
1274
+ const failedDestinationType = (0, _Utils.deriveConsultTransferDestinationType)(this.data);
1275
+ const failedDestAgentId = (0, _Utils.getDestinationAgentId)(this.data.interaction?.participants, this.data.agentId);
1175
1276
  this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED, {
1176
1277
  taskId: this.data.interactionId,
1177
- destination: consultTransferPayload.to,
1178
- destinationType: consultTransferPayload.destinationType,
1278
+ destination: failedDestAgentId || '',
1279
+ destinationType: failedDestinationType,
1179
1280
  isConsultTransfer: true,
1180
1281
  error: error.toString(),
1282
+ ...taskErrorProps,
1181
1283
  ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1182
1284
  }, ['operational', 'behavioral', 'business']);
1183
- throw detailedError;
1285
+ throw err;
1286
+ }
1287
+ }
1288
+
1289
+ /**
1290
+ * Starts a consultation conference by merging the consultation call with the main call
1291
+ *
1292
+ * Creates a three-way conference between the agent, customer, and consulted party
1293
+ * Extracts required consultation data from the current task data
1294
+ * On success, emits a `task:conferenceStarted` event
1295
+ *
1296
+ * @returns Promise<TaskResponse> - Response from the consultation conference API
1297
+ * @throws Error if the operation fails or if consultation data is invalid
1298
+ *
1299
+ * @example
1300
+ * ```typescript
1301
+ * try {
1302
+ * await task.consultConference();
1303
+ * console.log('Conference started successfully');
1304
+ * } catch (error) {
1305
+ * console.error('Failed to start conference:', error);
1306
+ * }
1307
+ * ```
1308
+ */
1309
+ async consultConference() {
1310
+ // Extract consultation conference data from task data (used in both try and catch)
1311
+ const consultationData = {
1312
+ agentId: this.agentId,
1313
+ destAgentId: this.data.destAgentId,
1314
+ destinationType: this.data.destinationType || 'agent'
1315
+ };
1316
+ try {
1317
+ _loggerProxy.default.info(`Initiating consult conference to ${consultationData.destAgentId}`, {
1318
+ module: _constants.TASK_FILE,
1319
+ method: _constants2.METHODS.CONSULT_CONFERENCE,
1320
+ interactionId: this.data.interactionId
1321
+ });
1322
+ const paramsDataForConferenceV2 = (0, _Utils.buildConsultConferenceParamData)(consultationData, this.data.interactionId);
1323
+ const response = await this.contact.consultConference({
1324
+ interactionId: paramsDataForConferenceV2.interactionId,
1325
+ data: paramsDataForConferenceV2.data
1326
+ });
1327
+
1328
+ // Track success metrics (following consultTransfer pattern)
1329
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONFERENCE_START_SUCCESS, {
1330
+ taskId: this.data.interactionId,
1331
+ destination: paramsDataForConferenceV2.data.to,
1332
+ destinationType: paramsDataForConferenceV2.data.destinationType,
1333
+ agentId: paramsDataForConferenceV2.data.agentId,
1334
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
1335
+ }, ['operational', 'behavioral', 'business']);
1336
+ _loggerProxy.default.log(`Consult conference started successfully`, {
1337
+ module: _constants.TASK_FILE,
1338
+ method: _constants2.METHODS.CONSULT_CONFERENCE,
1339
+ interactionId: this.data.interactionId
1340
+ });
1341
+ return response;
1342
+ } catch (error) {
1343
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.CONSULT_CONFERENCE, _constants.TASK_FILE);
1344
+ const taskErrorProps = {
1345
+ trackingId: err.data?.trackingId,
1346
+ errorMessage: err.data?.message,
1347
+ errorType: err.data?.errorType,
1348
+ errorData: err.data?.errorData,
1349
+ reasonCode: err.data?.reasonCode
1350
+ };
1351
+
1352
+ // Track failure metrics (following consultTransfer pattern)
1353
+ // Build conference data for error tracking using extracted data
1354
+ const failedParamsData = (0, _Utils.buildConsultConferenceParamData)(consultationData, this.data.interactionId);
1355
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONFERENCE_START_FAILED, {
1356
+ taskId: this.data.interactionId,
1357
+ destination: failedParamsData.data.to,
1358
+ destinationType: failedParamsData.data.destinationType,
1359
+ agentId: failedParamsData.data.agentId,
1360
+ error: error.toString(),
1361
+ ...taskErrorProps,
1362
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1363
+ }, ['operational', 'behavioral', 'business']);
1364
+ _loggerProxy.default.error(`Failed to start consult conference`, {
1365
+ module: _constants.TASK_FILE,
1366
+ method: _constants2.METHODS.CONSULT_CONFERENCE,
1367
+ interactionId: this.data.interactionId
1368
+ });
1369
+ throw err;
1370
+ }
1371
+ }
1372
+
1373
+ /**
1374
+ * Exits the current conference by removing the agent from the conference call
1375
+ *
1376
+ * Exits the agent from the conference, leaving the customer and consulted party connected
1377
+ * On success, emits a `task:conferenceEnded` event
1378
+ *
1379
+ * @returns Promise<TaskResponse> - Response from the conference exit API
1380
+ * @throws Error if the operation fails or if no active conference exists
1381
+ *
1382
+ * @example
1383
+ * ```typescript
1384
+ * try {
1385
+ * await task.exitConference();
1386
+ * console.log('Successfully exited conference');
1387
+ * } catch (error) {
1388
+ * console.error('Failed to exit conference:', error);
1389
+ * }
1390
+ * ```
1391
+ */
1392
+ async exitConference() {
1393
+ try {
1394
+ _loggerProxy.default.info(`Exiting consult conference`, {
1395
+ module: _constants.TASK_FILE,
1396
+ method: _constants2.METHODS.EXIT_CONFERENCE,
1397
+ interactionId: this.data.interactionId
1398
+ });
1399
+
1400
+ // Validate that interaction ID exists
1401
+ if (!this.data.interactionId) {
1402
+ throw new Error('Invalid interaction ID');
1403
+ }
1404
+ const response = await this.contact.exitConference({
1405
+ interactionId: this.data.interactionId
1406
+ });
1407
+
1408
+ // Track success metrics (following consultTransfer pattern)
1409
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONFERENCE_END_SUCCESS, {
1410
+ taskId: this.data.interactionId,
1411
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
1412
+ }, ['operational', 'behavioral', 'business']);
1413
+ _loggerProxy.default.log(`Consult conference exited successfully`, {
1414
+ module: _constants.TASK_FILE,
1415
+ method: _constants2.METHODS.EXIT_CONFERENCE,
1416
+ interactionId: this.data.interactionId
1417
+ });
1418
+ return response;
1419
+ } catch (error) {
1420
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.EXIT_CONFERENCE, _constants.TASK_FILE);
1421
+ const taskErrorProps = {
1422
+ trackingId: err.data?.trackingId,
1423
+ errorMessage: err.data?.message,
1424
+ errorType: err.data?.errorType,
1425
+ errorData: err.data?.errorData,
1426
+ reasonCode: err.data?.reasonCode
1427
+ };
1428
+
1429
+ // Track failure metrics (following consultTransfer pattern)
1430
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONFERENCE_END_FAILED, {
1431
+ taskId: this.data.interactionId,
1432
+ error: error.toString(),
1433
+ ...taskErrorProps,
1434
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1435
+ }, ['operational', 'behavioral', 'business']);
1436
+ _loggerProxy.default.error(`Failed to exit consult conference`, {
1437
+ module: _constants.TASK_FILE,
1438
+ method: _constants2.METHODS.EXIT_CONFERENCE,
1439
+ interactionId: this.data.interactionId
1440
+ });
1441
+ throw err;
1442
+ }
1443
+ }
1444
+
1445
+ /**
1446
+ * Transfers the current conference to another agent
1447
+ *
1448
+ * Moves the entire conference (including all participants) to a new agent,
1449
+ * while the current agent exits and goes to wrapup
1450
+ * On success, the current agent receives `task:conferenceEnded` event
1451
+ *
1452
+ * @returns Promise<TaskResponse> - Response from the conference transfer API
1453
+ * @throws Error if the operation fails or if no active conference exists
1454
+ *
1455
+ * @example
1456
+ * ```typescript
1457
+ * try {
1458
+ * await task.transferConference();
1459
+ * console.log('Conference transferred successfully');
1460
+ * } catch (error) {
1461
+ * console.error('Failed to transfer conference:', error);
1462
+ * }
1463
+ * ```
1464
+ */
1465
+ async transferConference() {
1466
+ try {
1467
+ _loggerProxy.default.info(`Transferring conference`, {
1468
+ module: _constants.TASK_FILE,
1469
+ method: _constants2.METHODS.TRANSFER_CONFERENCE,
1470
+ interactionId: this.data.interactionId
1471
+ });
1472
+
1473
+ // Validate that interaction ID exists
1474
+ if (!this.data.interactionId) {
1475
+ throw new Error('Invalid interaction ID');
1476
+ }
1477
+ const response = await this.contact.conferenceTransfer({
1478
+ interactionId: this.data.interactionId
1479
+ });
1480
+
1481
+ // Track success metrics (following consultTransfer pattern)
1482
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONFERENCE_TRANSFER_SUCCESS, {
1483
+ taskId: this.data.interactionId,
1484
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
1485
+ }, ['operational', 'behavioral', 'business']);
1486
+ _loggerProxy.default.log(`Conference transferred successfully`, {
1487
+ module: _constants.TASK_FILE,
1488
+ method: _constants2.METHODS.TRANSFER_CONFERENCE,
1489
+ interactionId: this.data.interactionId
1490
+ });
1491
+ return response;
1492
+ } catch (error) {
1493
+ const err = (0, _Utils.generateTaskErrorObject)(error, _constants2.METHODS.TRANSFER_CONFERENCE, _constants.TASK_FILE);
1494
+ const taskErrorProps = {
1495
+ trackingId: err.data?.trackingId,
1496
+ errorMessage: err.data?.message,
1497
+ errorType: err.data?.errorType,
1498
+ errorData: err.data?.errorData,
1499
+ reasonCode: err.data?.reasonCode
1500
+ };
1501
+
1502
+ // Track failure metrics (following consultTransfer pattern)
1503
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONFERENCE_TRANSFER_FAILED, {
1504
+ taskId: this.data.interactionId,
1505
+ error: error.toString(),
1506
+ ...taskErrorProps,
1507
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1508
+ }, ['operational', 'behavioral', 'business']);
1509
+ _loggerProxy.default.error(`Failed to transfer conference`, {
1510
+ module: _constants.TASK_FILE,
1511
+ method: _constants2.METHODS.TRANSFER_CONFERENCE,
1512
+ interactionId: this.data.interactionId
1513
+ });
1514
+ throw err;
1184
1515
  }
1185
1516
  }
1186
1517
  }