@webex/contact-center 3.8.1-next.41 → 3.9.0-multipleLLM.1
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.
- package/dist/cc.js +105 -62
- package/dist/cc.js.map +1 -1
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/logger-proxy.js +24 -1
- package/dist/logger-proxy.js.map +1 -1
- package/dist/metrics/MetricsManager.js +1 -1
- package/dist/metrics/MetricsManager.js.map +1 -1
- package/dist/metrics/behavioral-events.js +76 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +26 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +271 -0
- package/dist/services/AddressBook.js.map +1 -0
- package/dist/services/EntryPoint.js +227 -0
- package/dist/services/EntryPoint.js.map +1 -0
- package/dist/services/Queue.js +261 -0
- package/dist/services/Queue.js.map +1 -0
- package/dist/services/config/constants.js +24 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +1 -43
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +22 -5
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/GlobalTypes.js.map +1 -1
- package/dist/services/core/Utils.js +162 -2
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +0 -4
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +0 -4
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/task/TaskManager.js +74 -2
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/constants.js +7 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +86 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/index.js +384 -72
- package/dist/services/task/index.js.map +1 -1
- package/dist/services/task/types.js +14 -0
- package/dist/services/task/types.js.map +1 -1
- package/dist/types/cc.d.ts +77 -43
- package/dist/types/index.d.ts +3 -2
- package/dist/types/metrics/constants.d.ts +20 -0
- package/dist/types/services/AddressBook.d.ts +74 -0
- package/dist/types/services/EntryPoint.d.ts +67 -0
- package/dist/types/services/Queue.d.ts +76 -0
- package/dist/types/services/config/constants.d.ts +23 -1
- package/dist/types/services/config/index.d.ts +1 -14
- package/dist/types/services/config/types.d.ts +44 -64
- package/dist/types/services/core/GlobalTypes.d.ts +25 -0
- package/dist/types/services/core/Utils.d.ts +40 -1
- package/dist/types/services/task/constants.d.ts +6 -0
- package/dist/types/services/task/contact.d.ts +10 -0
- package/dist/types/services/task/index.d.ts +44 -2
- package/dist/types/services/task/types.d.ts +123 -1
- package/dist/types/types.d.ts +162 -0
- package/dist/types/utils/PageCache.d.ts +173 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +192 -0
- package/dist/utils/PageCache.js.map +1 -0
- package/dist/webex.js +1 -1
- package/package.json +9 -9
- package/src/cc.ts +121 -80
- package/src/index.ts +16 -2
- package/src/logger-proxy.ts +24 -1
- package/src/metrics/MetricsManager.ts +1 -1
- package/src/metrics/behavioral-events.ts +80 -0
- package/src/metrics/constants.ts +30 -0
- package/src/services/AddressBook.ts +291 -0
- package/src/services/EntryPoint.ts +241 -0
- package/src/services/Queue.ts +277 -0
- package/src/services/config/constants.ts +26 -2
- package/src/services/config/index.ts +1 -55
- package/src/services/config/types.ts +22 -65
- package/src/services/core/GlobalTypes.ts +27 -0
- package/src/services/core/Utils.ts +199 -1
- package/src/services/core/aqm-reqs.ts +0 -5
- package/src/services/core/websocket/WebSocketManager.ts +0 -4
- package/src/services/task/TaskManager.ts +79 -3
- package/src/services/task/constants.ts +6 -0
- package/src/services/task/contact.ts +80 -0
- package/src/services/task/index.ts +457 -57
- package/src/services/task/types.ts +133 -0
- package/src/types.ts +180 -0
- package/src/utils/PageCache.ts +252 -0
- package/test/unit/spec/cc.ts +31 -82
- package/test/unit/spec/metrics/MetricsManager.ts +0 -1
- package/test/unit/spec/metrics/behavioral-events.ts +42 -0
- package/test/unit/spec/services/AddressBook.ts +332 -0
- package/test/unit/spec/services/EntryPoint.ts +259 -0
- package/test/unit/spec/services/Queue.ts +323 -0
- package/test/unit/spec/services/config/index.ts +0 -71
- package/test/unit/spec/services/core/Utils.ts +50 -0
- package/test/unit/spec/services/core/aqm-reqs.ts +1 -3
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +0 -4
- package/test/unit/spec/services/task/TaskManager.ts +145 -1
- package/test/unit/spec/services/task/contact.ts +31 -1
- package/test/unit/spec/services/task/index.ts +410 -123
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import EventEmitter from 'events';
|
|
2
2
|
import {CALL_EVENT_KEYS, LocalMicrophoneStream} from '@webex/calling';
|
|
3
3
|
import {CallId} from '@webex/calling/dist/types/common/types';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
generateTaskErrorObject,
|
|
6
|
+
deriveConsultTransferDestinationType,
|
|
7
|
+
getDestinationAgentId,
|
|
8
|
+
buildConsultConferenceParamData,
|
|
9
|
+
} from '../core/Utils';
|
|
10
|
+
import {Failure} from '../core/GlobalTypes';
|
|
5
11
|
import {LoginOption} from '../../types';
|
|
6
12
|
import {TASK_FILE} from '../../constants';
|
|
7
13
|
import {METHODS} from './constants';
|
|
@@ -19,14 +25,12 @@ import {
|
|
|
19
25
|
ConsultEndPayload,
|
|
20
26
|
TransferPayLoad,
|
|
21
27
|
DESTINATION_TYPE,
|
|
22
|
-
CONSULT_TRANSFER_DESTINATION_TYPE,
|
|
23
28
|
ConsultTransferPayLoad,
|
|
24
29
|
MEDIA_CHANNEL,
|
|
25
30
|
} from './types';
|
|
26
31
|
import WebCallingService from '../WebCallingService';
|
|
27
32
|
import MetricsManager from '../../metrics/MetricsManager';
|
|
28
33
|
import {METRIC_EVENT_NAMES} from '../../metrics/constants';
|
|
29
|
-
import {Failure} from '../core/GlobalTypes';
|
|
30
34
|
import AutoWrapup from './AutoWrapup';
|
|
31
35
|
import {WrapupData} from '../config/types';
|
|
32
36
|
|
|
@@ -135,6 +139,7 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
135
139
|
public webCallMap: Record<TaskId, CallId>;
|
|
136
140
|
private wrapupData: WrapupData;
|
|
137
141
|
public autoWrapup?: AutoWrapup;
|
|
142
|
+
private agentId: string;
|
|
138
143
|
|
|
139
144
|
/**
|
|
140
145
|
* Creates a new Task instance which provides the following features:
|
|
@@ -147,7 +152,8 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
147
152
|
contact: ReturnType<typeof routingContact>,
|
|
148
153
|
webCallingService: WebCallingService,
|
|
149
154
|
data: TaskData,
|
|
150
|
-
wrapupData: WrapupData
|
|
155
|
+
wrapupData: WrapupData,
|
|
156
|
+
agentId: string
|
|
151
157
|
) {
|
|
152
158
|
super();
|
|
153
159
|
this.contact = contact;
|
|
@@ -158,6 +164,7 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
158
164
|
this.metricsManager = MetricsManager.getInstance();
|
|
159
165
|
this.registerWebCallListeners();
|
|
160
166
|
this.setupAutoWrapupTimer();
|
|
167
|
+
this.agentId = agentId;
|
|
161
168
|
}
|
|
162
169
|
|
|
163
170
|
/**
|
|
@@ -373,17 +380,25 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
373
380
|
|
|
374
381
|
return Promise.resolve(); // TODO: reject for extension as part of refactor
|
|
375
382
|
} catch (error) {
|
|
376
|
-
const
|
|
383
|
+
const err = generateTaskErrorObject(error, METHODS.ACCEPT, TASK_FILE);
|
|
384
|
+
const taskErrorProps = {
|
|
385
|
+
trackingId: err.data?.trackingId,
|
|
386
|
+
errorMessage: err.data?.message,
|
|
387
|
+
errorType: err.data?.errorType,
|
|
388
|
+
errorData: err.data?.errorData,
|
|
389
|
+
reasonCode: err.data?.reasonCode,
|
|
390
|
+
};
|
|
377
391
|
this.metricsManager.trackEvent(
|
|
378
392
|
METRIC_EVENT_NAMES.TASK_ACCEPT_FAILED,
|
|
379
393
|
{
|
|
380
394
|
taskId: this.data.interactionId,
|
|
381
395
|
error: error.toString(),
|
|
396
|
+
...taskErrorProps,
|
|
382
397
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details as Failure),
|
|
383
398
|
},
|
|
384
399
|
['operational', 'behavioral', 'business']
|
|
385
400
|
);
|
|
386
|
-
throw
|
|
401
|
+
throw err;
|
|
387
402
|
}
|
|
388
403
|
}
|
|
389
404
|
|
|
@@ -422,8 +437,8 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
422
437
|
|
|
423
438
|
return Promise.resolve();
|
|
424
439
|
} catch (error) {
|
|
425
|
-
const
|
|
426
|
-
throw
|
|
440
|
+
const err = generateTaskErrorObject(error, METHODS.TOGGLE_MUTE, TASK_FILE);
|
|
441
|
+
throw err;
|
|
427
442
|
}
|
|
428
443
|
}
|
|
429
444
|
|
|
@@ -470,17 +485,25 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
470
485
|
|
|
471
486
|
return Promise.resolve();
|
|
472
487
|
} catch (error) {
|
|
473
|
-
const
|
|
488
|
+
const err = generateTaskErrorObject(error, METHODS.DECLINE, TASK_FILE);
|
|
489
|
+
const taskErrorProps = {
|
|
490
|
+
trackingId: err.data?.trackingId,
|
|
491
|
+
errorMessage: err.data?.message,
|
|
492
|
+
errorType: err.data?.errorType,
|
|
493
|
+
errorData: err.data?.errorData,
|
|
494
|
+
reasonCode: err.data?.reasonCode,
|
|
495
|
+
};
|
|
474
496
|
this.metricsManager.trackEvent(
|
|
475
497
|
METRIC_EVENT_NAMES.TASK_DECLINE_FAILED,
|
|
476
498
|
{
|
|
477
499
|
taskId: this.data.interactionId,
|
|
478
500
|
error: error.toString(),
|
|
501
|
+
...taskErrorProps,
|
|
479
502
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
480
503
|
},
|
|
481
504
|
['operational', 'behavioral']
|
|
482
505
|
);
|
|
483
|
-
throw
|
|
506
|
+
throw err;
|
|
484
507
|
}
|
|
485
508
|
}
|
|
486
509
|
|
|
@@ -547,18 +570,26 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
547
570
|
|
|
548
571
|
return response;
|
|
549
572
|
} catch (error) {
|
|
550
|
-
const
|
|
573
|
+
const err = generateTaskErrorObject(error, METHODS.HOLD, TASK_FILE);
|
|
574
|
+
const taskErrorProps = {
|
|
575
|
+
trackingId: err.data?.trackingId,
|
|
576
|
+
errorMessage: err.data?.message,
|
|
577
|
+
errorType: err.data?.errorType,
|
|
578
|
+
errorData: err.data?.errorData,
|
|
579
|
+
reasonCode: err.data?.reasonCode,
|
|
580
|
+
};
|
|
551
581
|
this.metricsManager.trackEvent(
|
|
552
582
|
METRIC_EVENT_NAMES.TASK_HOLD_FAILED,
|
|
553
583
|
{
|
|
554
584
|
taskId: this.data.interactionId,
|
|
555
585
|
mediaResourceId: this.data.mediaResourceId,
|
|
556
586
|
error: error.toString(),
|
|
587
|
+
...taskErrorProps,
|
|
557
588
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
558
589
|
},
|
|
559
590
|
['operational', 'behavioral']
|
|
560
591
|
);
|
|
561
|
-
throw
|
|
592
|
+
throw err;
|
|
562
593
|
}
|
|
563
594
|
}
|
|
564
595
|
|
|
@@ -628,8 +659,15 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
628
659
|
|
|
629
660
|
return response;
|
|
630
661
|
} catch (error) {
|
|
631
|
-
const
|
|
662
|
+
const err = generateTaskErrorObject(error, METHODS.RESUME, TASK_FILE);
|
|
632
663
|
const mainInteractionId = this.data.interaction?.mainInteractionId;
|
|
664
|
+
const taskErrorProps = {
|
|
665
|
+
trackingId: err.data?.trackingId,
|
|
666
|
+
errorMessage: err.data?.message,
|
|
667
|
+
errorType: err.data?.errorType,
|
|
668
|
+
errorData: err.data?.errorData,
|
|
669
|
+
reasonCode: err.data?.reasonCode,
|
|
670
|
+
};
|
|
633
671
|
this.metricsManager.trackEvent(
|
|
634
672
|
METRIC_EVENT_NAMES.TASK_RESUME_FAILED,
|
|
635
673
|
{
|
|
@@ -638,11 +676,12 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
638
676
|
mediaResourceId: mainInteractionId
|
|
639
677
|
? this.data.interaction.media[mainInteractionId].mediaResourceId
|
|
640
678
|
: '',
|
|
679
|
+
...taskErrorProps,
|
|
641
680
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
642
681
|
},
|
|
643
682
|
['operational', 'behavioral']
|
|
644
683
|
);
|
|
645
|
-
throw
|
|
684
|
+
throw err;
|
|
646
685
|
}
|
|
647
686
|
}
|
|
648
687
|
|
|
@@ -722,16 +761,24 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
722
761
|
|
|
723
762
|
return response;
|
|
724
763
|
} catch (error) {
|
|
725
|
-
const
|
|
764
|
+
const err = generateTaskErrorObject(error, METHODS.END, TASK_FILE);
|
|
765
|
+
const taskErrorProps = {
|
|
766
|
+
trackingId: err.data?.trackingId,
|
|
767
|
+
errorMessage: err.data?.message,
|
|
768
|
+
errorType: err.data?.errorType,
|
|
769
|
+
errorData: err.data?.errorData,
|
|
770
|
+
reasonCode: err.data?.reasonCode,
|
|
771
|
+
};
|
|
726
772
|
this.metricsManager.trackEvent(
|
|
727
773
|
METRIC_EVENT_NAMES.TASK_END_FAILED,
|
|
728
774
|
{
|
|
729
775
|
taskId: this.data.interactionId,
|
|
776
|
+
...taskErrorProps,
|
|
730
777
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
731
778
|
},
|
|
732
779
|
['operational', 'behavioral', 'business']
|
|
733
780
|
);
|
|
734
|
-
throw
|
|
781
|
+
throw err;
|
|
735
782
|
}
|
|
736
783
|
}
|
|
737
784
|
|
|
@@ -826,18 +873,26 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
826
873
|
|
|
827
874
|
return response;
|
|
828
875
|
} catch (error) {
|
|
829
|
-
const
|
|
876
|
+
const err = generateTaskErrorObject(error, METHODS.WRAPUP, TASK_FILE);
|
|
877
|
+
const taskErrorProps = {
|
|
878
|
+
trackingId: err.data?.trackingId,
|
|
879
|
+
errorMessage: err.data?.message,
|
|
880
|
+
errorType: err.data?.errorType,
|
|
881
|
+
errorData: err.data?.errorData,
|
|
882
|
+
reasonCode: err.data?.reasonCode,
|
|
883
|
+
};
|
|
830
884
|
this.metricsManager.trackEvent(
|
|
831
885
|
METRIC_EVENT_NAMES.TASK_WRAPUP_FAILED,
|
|
832
886
|
{
|
|
833
887
|
taskId: this.data.interactionId,
|
|
834
888
|
wrapUpCode: wrapupPayload.auxCodeId,
|
|
835
889
|
wrapUpReason: wrapupPayload.wrapUpReason,
|
|
890
|
+
...taskErrorProps,
|
|
836
891
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
837
892
|
},
|
|
838
893
|
['operational', 'behavioral', 'business']
|
|
839
894
|
);
|
|
840
|
-
throw
|
|
895
|
+
throw err;
|
|
841
896
|
}
|
|
842
897
|
}
|
|
843
898
|
|
|
@@ -906,17 +961,25 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
906
961
|
|
|
907
962
|
return result;
|
|
908
963
|
} catch (error) {
|
|
909
|
-
const
|
|
964
|
+
const err = generateTaskErrorObject(error, METHODS.PAUSE_RECORDING, TASK_FILE);
|
|
965
|
+
const taskErrorProps = {
|
|
966
|
+
trackingId: err.data?.trackingId,
|
|
967
|
+
errorMessage: err.data?.message,
|
|
968
|
+
errorType: err.data?.errorType,
|
|
969
|
+
errorData: err.data?.errorData,
|
|
970
|
+
reasonCode: err.data?.reasonCode,
|
|
971
|
+
};
|
|
910
972
|
this.metricsManager.trackEvent(
|
|
911
973
|
METRIC_EVENT_NAMES.TASK_PAUSE_RECORDING_FAILED,
|
|
912
974
|
{
|
|
913
975
|
taskId: this.data.interactionId,
|
|
914
976
|
error: error.toString(),
|
|
977
|
+
...taskErrorProps,
|
|
915
978
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
916
979
|
},
|
|
917
980
|
['operational', 'behavioral', 'business']
|
|
918
981
|
);
|
|
919
|
-
throw
|
|
982
|
+
throw err;
|
|
920
983
|
}
|
|
921
984
|
}
|
|
922
985
|
|
|
@@ -997,17 +1060,25 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
997
1060
|
|
|
998
1061
|
return result;
|
|
999
1062
|
} catch (error) {
|
|
1000
|
-
const
|
|
1063
|
+
const err = generateTaskErrorObject(error, METHODS.RESUME_RECORDING, TASK_FILE);
|
|
1064
|
+
const taskErrorProps = {
|
|
1065
|
+
trackingId: err.data?.trackingId,
|
|
1066
|
+
errorMessage: err.data?.message,
|
|
1067
|
+
errorType: err.data?.errorType,
|
|
1068
|
+
errorData: err.data?.errorData,
|
|
1069
|
+
reasonCode: err.data?.reasonCode,
|
|
1070
|
+
};
|
|
1001
1071
|
this.metricsManager.trackEvent(
|
|
1002
1072
|
METRIC_EVENT_NAMES.TASK_RESUME_RECORDING_FAILED,
|
|
1003
1073
|
{
|
|
1004
1074
|
taskId: this.data.interactionId,
|
|
1005
1075
|
error: error.toString(),
|
|
1076
|
+
...taskErrorProps,
|
|
1006
1077
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1007
1078
|
},
|
|
1008
1079
|
['operational', 'behavioral', 'business']
|
|
1009
1080
|
);
|
|
1010
|
-
throw
|
|
1081
|
+
throw err;
|
|
1011
1082
|
}
|
|
1012
1083
|
}
|
|
1013
1084
|
|
|
@@ -1082,7 +1153,14 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
1082
1153
|
|
|
1083
1154
|
return result;
|
|
1084
1155
|
} catch (error) {
|
|
1085
|
-
const
|
|
1156
|
+
const err = generateTaskErrorObject(error, METHODS.CONSULT, TASK_FILE);
|
|
1157
|
+
const taskErrorProps = {
|
|
1158
|
+
trackingId: err.data?.trackingId,
|
|
1159
|
+
errorMessage: err.data?.message,
|
|
1160
|
+
errorType: err.data?.errorType,
|
|
1161
|
+
errorData: err.data?.errorData,
|
|
1162
|
+
reasonCode: err.data?.reasonCode,
|
|
1163
|
+
};
|
|
1086
1164
|
this.metricsManager.trackEvent(
|
|
1087
1165
|
METRIC_EVENT_NAMES.TASK_CONSULT_START_FAILED,
|
|
1088
1166
|
{
|
|
@@ -1090,11 +1168,12 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
1090
1168
|
destination: consultPayload.to,
|
|
1091
1169
|
destinationType: consultPayload.destinationType,
|
|
1092
1170
|
error: error.toString(),
|
|
1171
|
+
...taskErrorProps,
|
|
1093
1172
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1094
1173
|
},
|
|
1095
1174
|
['operational', 'behavioral', 'business']
|
|
1096
1175
|
);
|
|
1097
|
-
throw
|
|
1176
|
+
throw err;
|
|
1098
1177
|
}
|
|
1099
1178
|
}
|
|
1100
1179
|
|
|
@@ -1167,17 +1246,25 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
1167
1246
|
|
|
1168
1247
|
return result;
|
|
1169
1248
|
} catch (error) {
|
|
1170
|
-
const
|
|
1249
|
+
const err = generateTaskErrorObject(error, METHODS.END_CONSULT, TASK_FILE);
|
|
1250
|
+
const taskErrorProps = {
|
|
1251
|
+
trackingId: err.data?.trackingId,
|
|
1252
|
+
errorMessage: err.data?.message,
|
|
1253
|
+
errorType: err.data?.errorType,
|
|
1254
|
+
errorData: err.data?.errorData,
|
|
1255
|
+
reasonCode: err.data?.reasonCode,
|
|
1256
|
+
};
|
|
1171
1257
|
this.metricsManager.trackEvent(
|
|
1172
1258
|
METRIC_EVENT_NAMES.TASK_CONSULT_END_FAILED,
|
|
1173
1259
|
{
|
|
1174
1260
|
taskId: this.data.interactionId,
|
|
1175
1261
|
error: error.toString(),
|
|
1262
|
+
...taskErrorProps,
|
|
1176
1263
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1177
1264
|
},
|
|
1178
1265
|
['operational', 'behavioral', 'business']
|
|
1179
1266
|
);
|
|
1180
|
-
throw
|
|
1267
|
+
throw err;
|
|
1181
1268
|
}
|
|
1182
1269
|
}
|
|
1183
1270
|
|
|
@@ -1258,7 +1345,14 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
1258
1345
|
|
|
1259
1346
|
return result;
|
|
1260
1347
|
} catch (error) {
|
|
1261
|
-
const
|
|
1348
|
+
const err = generateTaskErrorObject(error, METHODS.TRANSFER, TASK_FILE);
|
|
1349
|
+
const taskErrorProps = {
|
|
1350
|
+
trackingId: err.data?.trackingId,
|
|
1351
|
+
errorMessage: err.data?.message,
|
|
1352
|
+
errorType: err.data?.errorType,
|
|
1353
|
+
errorData: err.data?.errorData,
|
|
1354
|
+
reasonCode: err.data?.reasonCode,
|
|
1355
|
+
};
|
|
1262
1356
|
this.metricsManager.trackEvent(
|
|
1263
1357
|
METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED,
|
|
1264
1358
|
{
|
|
@@ -1267,11 +1361,12 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
1267
1361
|
destinationType: transferPayload.destinationType,
|
|
1268
1362
|
isConsultTransfer: false,
|
|
1269
1363
|
error: error.toString(),
|
|
1364
|
+
...taskErrorProps,
|
|
1270
1365
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1271
1366
|
},
|
|
1272
1367
|
['operational', 'behavioral', 'business']
|
|
1273
1368
|
);
|
|
1274
|
-
throw
|
|
1369
|
+
throw err;
|
|
1275
1370
|
}
|
|
1276
1371
|
}
|
|
1277
1372
|
|
|
@@ -1308,68 +1403,373 @@ export default class Task extends EventEmitter implements ITask {
|
|
|
1308
1403
|
* ```
|
|
1309
1404
|
*/
|
|
1310
1405
|
public async consultTransfer(
|
|
1311
|
-
consultTransferPayload
|
|
1406
|
+
consultTransferPayload?: ConsultTransferPayLoad
|
|
1312
1407
|
): Promise<TaskResponse> {
|
|
1313
1408
|
try {
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1409
|
+
// Get the destination agent ID using custom logic from participants data
|
|
1410
|
+
const destAgentId = getDestinationAgentId(
|
|
1411
|
+
this.data.interaction?.participants,
|
|
1412
|
+
this.data.agentId
|
|
1413
|
+
);
|
|
1414
|
+
|
|
1415
|
+
// Resolve the target id (queue consult transfers go to the accepted agent)
|
|
1416
|
+
if (!destAgentId) {
|
|
1417
|
+
throw new Error('No agent has accepted this queue consult yet');
|
|
1418
|
+
}
|
|
1319
1419
|
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1420
|
+
LoggerProxy.info(
|
|
1421
|
+
`Initiating consult transfer to ${consultTransferPayload?.to || destAgentId}`,
|
|
1422
|
+
{
|
|
1423
|
+
module: TASK_FILE,
|
|
1424
|
+
method: METHODS.CONSULT_TRANSFER,
|
|
1425
|
+
interactionId: this.data.interactionId,
|
|
1324
1426
|
}
|
|
1427
|
+
);
|
|
1428
|
+
// Obtain payload based on desktop logic using TaskData
|
|
1429
|
+
const finalDestinationType = deriveConsultTransferDestinationType(this.data);
|
|
1325
1430
|
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
}
|
|
1431
|
+
// By default we always use the computed destAgentId as the target id
|
|
1432
|
+
const consultTransferRequest: ConsultTransferPayLoad = {
|
|
1433
|
+
to: destAgentId,
|
|
1434
|
+
destinationType: finalDestinationType,
|
|
1435
|
+
};
|
|
1332
1436
|
|
|
1333
1437
|
const result = await this.contact.consultTransfer({
|
|
1334
1438
|
interactionId: this.data.interactionId,
|
|
1335
|
-
data:
|
|
1439
|
+
data: consultTransferRequest,
|
|
1336
1440
|
});
|
|
1337
1441
|
|
|
1338
1442
|
this.metricsManager.trackEvent(
|
|
1339
1443
|
METRIC_EVENT_NAMES.TASK_TRANSFER_SUCCESS,
|
|
1340
1444
|
{
|
|
1341
1445
|
taskId: this.data.interactionId,
|
|
1342
|
-
destination:
|
|
1343
|
-
destinationType:
|
|
1446
|
+
destination: consultTransferRequest.to,
|
|
1447
|
+
destinationType: consultTransferRequest.destinationType,
|
|
1344
1448
|
isConsultTransfer: true,
|
|
1345
1449
|
...MetricsManager.getCommonTrackingFieldForAQMResponse(result),
|
|
1346
1450
|
},
|
|
1347
1451
|
['operational', 'behavioral', 'business']
|
|
1348
1452
|
);
|
|
1349
1453
|
|
|
1350
|
-
LoggerProxy.log(
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1454
|
+
LoggerProxy.log(
|
|
1455
|
+
`Consult transfer completed successfully to ${consultTransferPayload?.to || destAgentId}`,
|
|
1456
|
+
{
|
|
1457
|
+
module: TASK_FILE,
|
|
1458
|
+
method: METHODS.CONSULT_TRANSFER,
|
|
1459
|
+
trackingId: result.trackingId,
|
|
1460
|
+
interactionId: this.data.interactionId,
|
|
1461
|
+
}
|
|
1462
|
+
);
|
|
1356
1463
|
|
|
1357
1464
|
return result;
|
|
1358
1465
|
} catch (error) {
|
|
1359
|
-
const
|
|
1466
|
+
const err = generateTaskErrorObject(error, METHODS.CONSULT_TRANSFER, TASK_FILE);
|
|
1467
|
+
const taskErrorProps = {
|
|
1468
|
+
trackingId: err.data?.trackingId,
|
|
1469
|
+
errorMessage: err.data?.message,
|
|
1470
|
+
errorType: err.data?.errorType,
|
|
1471
|
+
errorData: err.data?.errorData,
|
|
1472
|
+
reasonCode: err.data?.reasonCode,
|
|
1473
|
+
};
|
|
1474
|
+
const failedDestinationType = deriveConsultTransferDestinationType(this.data);
|
|
1475
|
+
const failedDestAgentId = getDestinationAgentId(
|
|
1476
|
+
this.data.interaction?.participants,
|
|
1477
|
+
this.data.agentId
|
|
1478
|
+
);
|
|
1360
1479
|
this.metricsManager.trackEvent(
|
|
1361
1480
|
METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED,
|
|
1362
1481
|
{
|
|
1363
1482
|
taskId: this.data.interactionId,
|
|
1364
|
-
destination:
|
|
1365
|
-
destinationType:
|
|
1483
|
+
destination: failedDestAgentId || '',
|
|
1484
|
+
destinationType: failedDestinationType,
|
|
1366
1485
|
isConsultTransfer: true,
|
|
1367
1486
|
error: error.toString(),
|
|
1487
|
+
...taskErrorProps,
|
|
1488
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1489
|
+
},
|
|
1490
|
+
['operational', 'behavioral', 'business']
|
|
1491
|
+
);
|
|
1492
|
+
throw err;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
|
|
1496
|
+
/**
|
|
1497
|
+
* Starts a consultation conference by merging the consultation call with the main call
|
|
1498
|
+
*
|
|
1499
|
+
* Creates a three-way conference between the agent, customer, and consulted party
|
|
1500
|
+
* Extracts required consultation data from the current task data
|
|
1501
|
+
* On success, emits a `task:conferenceStarted` event
|
|
1502
|
+
*
|
|
1503
|
+
* @returns Promise<TaskResponse> - Response from the consultation conference API
|
|
1504
|
+
* @throws Error if the operation fails or if consultation data is invalid
|
|
1505
|
+
*
|
|
1506
|
+
* @example
|
|
1507
|
+
* ```typescript
|
|
1508
|
+
* try {
|
|
1509
|
+
* await task.consultConference();
|
|
1510
|
+
* console.log('Conference started successfully');
|
|
1511
|
+
* } catch (error) {
|
|
1512
|
+
* console.error('Failed to start conference:', error);
|
|
1513
|
+
* }
|
|
1514
|
+
* ```
|
|
1515
|
+
*/
|
|
1516
|
+
public async consultConference(): Promise<TaskResponse> {
|
|
1517
|
+
// Extract consultation conference data from task data (used in both try and catch)
|
|
1518
|
+
const consultationData = {
|
|
1519
|
+
agentId: this.agentId,
|
|
1520
|
+
destAgentId: this.data.destAgentId,
|
|
1521
|
+
destinationType: this.data.destinationType || 'agent',
|
|
1522
|
+
};
|
|
1523
|
+
|
|
1524
|
+
try {
|
|
1525
|
+
LoggerProxy.info(`Initiating consult conference to ${consultationData.destAgentId}`, {
|
|
1526
|
+
module: TASK_FILE,
|
|
1527
|
+
method: METHODS.CONSULT_CONFERENCE,
|
|
1528
|
+
interactionId: this.data.interactionId,
|
|
1529
|
+
});
|
|
1530
|
+
|
|
1531
|
+
const paramsDataForConferenceV2 = buildConsultConferenceParamData(
|
|
1532
|
+
consultationData,
|
|
1533
|
+
this.data.interactionId
|
|
1534
|
+
);
|
|
1535
|
+
|
|
1536
|
+
const response = await this.contact.consultConference({
|
|
1537
|
+
interactionId: paramsDataForConferenceV2.interactionId,
|
|
1538
|
+
data: paramsDataForConferenceV2.data,
|
|
1539
|
+
});
|
|
1540
|
+
|
|
1541
|
+
// Track success metrics (following consultTransfer pattern)
|
|
1542
|
+
this.metricsManager.trackEvent(
|
|
1543
|
+
METRIC_EVENT_NAMES.TASK_CONFERENCE_START_SUCCESS,
|
|
1544
|
+
{
|
|
1545
|
+
taskId: this.data.interactionId,
|
|
1546
|
+
destination: paramsDataForConferenceV2.data.to,
|
|
1547
|
+
destinationType: paramsDataForConferenceV2.data.destinationType,
|
|
1548
|
+
agentId: paramsDataForConferenceV2.data.agentId,
|
|
1549
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(response),
|
|
1550
|
+
},
|
|
1551
|
+
['operational', 'behavioral', 'business']
|
|
1552
|
+
);
|
|
1553
|
+
|
|
1554
|
+
LoggerProxy.log(`Consult conference started successfully`, {
|
|
1555
|
+
module: TASK_FILE,
|
|
1556
|
+
method: METHODS.CONSULT_CONFERENCE,
|
|
1557
|
+
interactionId: this.data.interactionId,
|
|
1558
|
+
});
|
|
1559
|
+
|
|
1560
|
+
return response;
|
|
1561
|
+
} catch (error) {
|
|
1562
|
+
const err = generateTaskErrorObject(error, METHODS.CONSULT_CONFERENCE, TASK_FILE);
|
|
1563
|
+
const taskErrorProps = {
|
|
1564
|
+
trackingId: err.data?.trackingId,
|
|
1565
|
+
errorMessage: err.data?.message,
|
|
1566
|
+
errorType: err.data?.errorType,
|
|
1567
|
+
errorData: err.data?.errorData,
|
|
1568
|
+
reasonCode: err.data?.reasonCode,
|
|
1569
|
+
};
|
|
1570
|
+
|
|
1571
|
+
// Track failure metrics (following consultTransfer pattern)
|
|
1572
|
+
// Build conference data for error tracking using extracted data
|
|
1573
|
+
const failedParamsData = buildConsultConferenceParamData(
|
|
1574
|
+
consultationData,
|
|
1575
|
+
this.data.interactionId
|
|
1576
|
+
);
|
|
1577
|
+
|
|
1578
|
+
this.metricsManager.trackEvent(
|
|
1579
|
+
METRIC_EVENT_NAMES.TASK_CONFERENCE_START_FAILED,
|
|
1580
|
+
{
|
|
1581
|
+
taskId: this.data.interactionId,
|
|
1582
|
+
destination: failedParamsData.data.to,
|
|
1583
|
+
destinationType: failedParamsData.data.destinationType,
|
|
1584
|
+
agentId: failedParamsData.data.agentId,
|
|
1585
|
+
error: error.toString(),
|
|
1586
|
+
...taskErrorProps,
|
|
1368
1587
|
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1369
1588
|
},
|
|
1370
1589
|
['operational', 'behavioral', 'business']
|
|
1371
1590
|
);
|
|
1372
|
-
|
|
1591
|
+
|
|
1592
|
+
LoggerProxy.error(`Failed to start consult conference`, {
|
|
1593
|
+
module: TASK_FILE,
|
|
1594
|
+
method: METHODS.CONSULT_CONFERENCE,
|
|
1595
|
+
interactionId: this.data.interactionId,
|
|
1596
|
+
});
|
|
1597
|
+
|
|
1598
|
+
throw err;
|
|
1373
1599
|
}
|
|
1374
1600
|
}
|
|
1601
|
+
|
|
1602
|
+
/**
|
|
1603
|
+
* Exits the current conference by removing the agent from the conference call
|
|
1604
|
+
*
|
|
1605
|
+
* Exits the agent from the conference, leaving the customer and consulted party connected
|
|
1606
|
+
* On success, emits a `task:conferenceEnded` event
|
|
1607
|
+
*
|
|
1608
|
+
* @returns Promise<TaskResponse> - Response from the conference exit API
|
|
1609
|
+
* @throws Error if the operation fails or if no active conference exists
|
|
1610
|
+
*
|
|
1611
|
+
* @example
|
|
1612
|
+
* ```typescript
|
|
1613
|
+
* try {
|
|
1614
|
+
* await task.exitConference();
|
|
1615
|
+
* console.log('Successfully exited conference');
|
|
1616
|
+
* } catch (error) {
|
|
1617
|
+
* console.error('Failed to exit conference:', error);
|
|
1618
|
+
* }
|
|
1619
|
+
* ```
|
|
1620
|
+
*/
|
|
1621
|
+
public async exitConference(): Promise<TaskResponse> {
|
|
1622
|
+
try {
|
|
1623
|
+
LoggerProxy.info(`Exiting consult conference`, {
|
|
1624
|
+
module: TASK_FILE,
|
|
1625
|
+
method: METHODS.EXIT_CONFERENCE,
|
|
1626
|
+
interactionId: this.data.interactionId,
|
|
1627
|
+
});
|
|
1628
|
+
|
|
1629
|
+
// Validate that interaction ID exists
|
|
1630
|
+
if (!this.data.interactionId) {
|
|
1631
|
+
throw new Error('Invalid interaction ID');
|
|
1632
|
+
}
|
|
1633
|
+
|
|
1634
|
+
const response = await this.contact.exitConference({
|
|
1635
|
+
interactionId: this.data.interactionId,
|
|
1636
|
+
});
|
|
1637
|
+
|
|
1638
|
+
// Track success metrics (following consultTransfer pattern)
|
|
1639
|
+
this.metricsManager.trackEvent(
|
|
1640
|
+
METRIC_EVENT_NAMES.TASK_CONFERENCE_END_SUCCESS,
|
|
1641
|
+
{
|
|
1642
|
+
taskId: this.data.interactionId,
|
|
1643
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(response),
|
|
1644
|
+
},
|
|
1645
|
+
['operational', 'behavioral', 'business']
|
|
1646
|
+
);
|
|
1647
|
+
|
|
1648
|
+
LoggerProxy.log(`Consult conference exited successfully`, {
|
|
1649
|
+
module: TASK_FILE,
|
|
1650
|
+
method: METHODS.EXIT_CONFERENCE,
|
|
1651
|
+
interactionId: this.data.interactionId,
|
|
1652
|
+
});
|
|
1653
|
+
|
|
1654
|
+
return response;
|
|
1655
|
+
} catch (error) {
|
|
1656
|
+
const err = generateTaskErrorObject(error, METHODS.EXIT_CONFERENCE, TASK_FILE);
|
|
1657
|
+
const taskErrorProps = {
|
|
1658
|
+
trackingId: err.data?.trackingId,
|
|
1659
|
+
errorMessage: err.data?.message,
|
|
1660
|
+
errorType: err.data?.errorType,
|
|
1661
|
+
errorData: err.data?.errorData,
|
|
1662
|
+
reasonCode: err.data?.reasonCode,
|
|
1663
|
+
};
|
|
1664
|
+
|
|
1665
|
+
// Track failure metrics (following consultTransfer pattern)
|
|
1666
|
+
this.metricsManager.trackEvent(
|
|
1667
|
+
METRIC_EVENT_NAMES.TASK_CONFERENCE_END_FAILED,
|
|
1668
|
+
{
|
|
1669
|
+
taskId: this.data.interactionId,
|
|
1670
|
+
error: error.toString(),
|
|
1671
|
+
...taskErrorProps,
|
|
1672
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1673
|
+
},
|
|
1674
|
+
['operational', 'behavioral', 'business']
|
|
1675
|
+
);
|
|
1676
|
+
|
|
1677
|
+
LoggerProxy.error(`Failed to exit consult conference`, {
|
|
1678
|
+
module: TASK_FILE,
|
|
1679
|
+
method: METHODS.EXIT_CONFERENCE,
|
|
1680
|
+
interactionId: this.data.interactionId,
|
|
1681
|
+
});
|
|
1682
|
+
|
|
1683
|
+
throw err;
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
|
|
1687
|
+
// TODO: Uncomment this method in future PR for Multi-Party Conference support (>3 participants)
|
|
1688
|
+
// Conference transfer will be supported when implementing enhanced multi-party conference functionality
|
|
1689
|
+
/*
|
|
1690
|
+
/**
|
|
1691
|
+
* Transfers the current conference to another agent
|
|
1692
|
+
*
|
|
1693
|
+
* Moves the entire conference (including all participants) to a new agent,
|
|
1694
|
+
* while the current agent exits and goes to wrapup
|
|
1695
|
+
* On success, the current agent receives `task:conferenceEnded` event
|
|
1696
|
+
*
|
|
1697
|
+
* @returns Promise<TaskResponse> - Response from the conference transfer API
|
|
1698
|
+
* @throws Error if the operation fails or if no active conference exists
|
|
1699
|
+
*
|
|
1700
|
+
* @example
|
|
1701
|
+
* ```typescript
|
|
1702
|
+
* try {
|
|
1703
|
+
* await task.transferConference();
|
|
1704
|
+
* console.log('Conference transferred successfully');
|
|
1705
|
+
* } catch (error) {
|
|
1706
|
+
* console.error('Failed to transfer conference:', error);
|
|
1707
|
+
* }
|
|
1708
|
+
* ```
|
|
1709
|
+
*/
|
|
1710
|
+
/* public async transferConference(): Promise<TaskResponse> {
|
|
1711
|
+
try {
|
|
1712
|
+
LoggerProxy.info(`Transferring conference`, {
|
|
1713
|
+
module: TASK_FILE,
|
|
1714
|
+
method: METHODS.TRANSFER_CONFERENCE,
|
|
1715
|
+
interactionId: this.data.interactionId,
|
|
1716
|
+
});
|
|
1717
|
+
|
|
1718
|
+
// Validate that interaction ID exists
|
|
1719
|
+
if (!this.data.interactionId) {
|
|
1720
|
+
throw new Error('Invalid interaction ID');
|
|
1721
|
+
}
|
|
1722
|
+
|
|
1723
|
+
const response = await this.contact.conferenceTransfer({
|
|
1724
|
+
interactionId: this.data.interactionId,
|
|
1725
|
+
});
|
|
1726
|
+
|
|
1727
|
+
// Track success metrics (following consultTransfer pattern)
|
|
1728
|
+
this.metricsManager.trackEvent(
|
|
1729
|
+
METRIC_EVENT_NAMES.TASK_CONFERENCE_TRANSFER_SUCCESS,
|
|
1730
|
+
{
|
|
1731
|
+
taskId: this.data.interactionId,
|
|
1732
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponse(response),
|
|
1733
|
+
},
|
|
1734
|
+
['operational', 'behavioral', 'business']
|
|
1735
|
+
);
|
|
1736
|
+
|
|
1737
|
+
LoggerProxy.log(`Conference transferred successfully`, {
|
|
1738
|
+
module: TASK_FILE,
|
|
1739
|
+
method: METHODS.TRANSFER_CONFERENCE,
|
|
1740
|
+
interactionId: this.data.interactionId,
|
|
1741
|
+
});
|
|
1742
|
+
|
|
1743
|
+
return response;
|
|
1744
|
+
} catch (error) {
|
|
1745
|
+
const err = generateTaskErrorObject(error, METHODS.TRANSFER_CONFERENCE, TASK_FILE);
|
|
1746
|
+
const taskErrorProps = {
|
|
1747
|
+
trackingId: err.data?.trackingId,
|
|
1748
|
+
errorMessage: err.data?.message,
|
|
1749
|
+
errorType: err.data?.errorType,
|
|
1750
|
+
errorData: err.data?.errorData,
|
|
1751
|
+
reasonCode: err.data?.reasonCode,
|
|
1752
|
+
};
|
|
1753
|
+
|
|
1754
|
+
// Track failure metrics (following consultTransfer pattern)
|
|
1755
|
+
this.metricsManager.trackEvent(
|
|
1756
|
+
METRIC_EVENT_NAMES.TASK_CONFERENCE_TRANSFER_FAILED,
|
|
1757
|
+
{
|
|
1758
|
+
taskId: this.data.interactionId,
|
|
1759
|
+
error: error.toString(),
|
|
1760
|
+
...taskErrorProps,
|
|
1761
|
+
...MetricsManager.getCommonTrackingFieldForAQMResponseFailed(error.details || {}),
|
|
1762
|
+
},
|
|
1763
|
+
['operational', 'behavioral', 'business']
|
|
1764
|
+
);
|
|
1765
|
+
|
|
1766
|
+
LoggerProxy.error(`Failed to transfer conference`, {
|
|
1767
|
+
module: TASK_FILE,
|
|
1768
|
+
method: METHODS.TRANSFER_CONFERENCE,
|
|
1769
|
+
interactionId: this.data.interactionId,
|
|
1770
|
+
});
|
|
1771
|
+
|
|
1772
|
+
throw err;
|
|
1773
|
+
}
|
|
1774
|
+
} */
|
|
1375
1775
|
}
|