@webex/contact-center 0.0.0-next.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.
Files changed (177) hide show
  1. package/README.md +81 -0
  2. package/__mocks__/workerMock.js +15 -0
  3. package/babel.config.js +15 -0
  4. package/dist/cc.js +1416 -0
  5. package/dist/cc.js.map +1 -0
  6. package/dist/config.js +72 -0
  7. package/dist/config.js.map +1 -0
  8. package/dist/constants.js +58 -0
  9. package/dist/constants.js.map +1 -0
  10. package/dist/index.js +142 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/logger-proxy.js +115 -0
  13. package/dist/logger-proxy.js.map +1 -0
  14. package/dist/metrics/MetricsManager.js +474 -0
  15. package/dist/metrics/MetricsManager.js.map +1 -0
  16. package/dist/metrics/behavioral-events.js +322 -0
  17. package/dist/metrics/behavioral-events.js.map +1 -0
  18. package/dist/metrics/constants.js +134 -0
  19. package/dist/metrics/constants.js.map +1 -0
  20. package/dist/services/WebCallingService.js +323 -0
  21. package/dist/services/WebCallingService.js.map +1 -0
  22. package/dist/services/agent/index.js +177 -0
  23. package/dist/services/agent/index.js.map +1 -0
  24. package/dist/services/agent/types.js +137 -0
  25. package/dist/services/agent/types.js.map +1 -0
  26. package/dist/services/config/Util.js +203 -0
  27. package/dist/services/config/Util.js.map +1 -0
  28. package/dist/services/config/constants.js +221 -0
  29. package/dist/services/config/constants.js.map +1 -0
  30. package/dist/services/config/index.js +607 -0
  31. package/dist/services/config/index.js.map +1 -0
  32. package/dist/services/config/types.js +334 -0
  33. package/dist/services/config/types.js.map +1 -0
  34. package/dist/services/constants.js +117 -0
  35. package/dist/services/constants.js.map +1 -0
  36. package/dist/services/core/Err.js +43 -0
  37. package/dist/services/core/Err.js.map +1 -0
  38. package/dist/services/core/GlobalTypes.js +6 -0
  39. package/dist/services/core/GlobalTypes.js.map +1 -0
  40. package/dist/services/core/Utils.js +126 -0
  41. package/dist/services/core/Utils.js.map +1 -0
  42. package/dist/services/core/WebexRequest.js +96 -0
  43. package/dist/services/core/WebexRequest.js.map +1 -0
  44. package/dist/services/core/aqm-reqs.js +246 -0
  45. package/dist/services/core/aqm-reqs.js.map +1 -0
  46. package/dist/services/core/constants.js +109 -0
  47. package/dist/services/core/constants.js.map +1 -0
  48. package/dist/services/core/types.js +6 -0
  49. package/dist/services/core/types.js.map +1 -0
  50. package/dist/services/core/websocket/WebSocketManager.js +187 -0
  51. package/dist/services/core/websocket/WebSocketManager.js.map +1 -0
  52. package/dist/services/core/websocket/connection-service.js +111 -0
  53. package/dist/services/core/websocket/connection-service.js.map +1 -0
  54. package/dist/services/core/websocket/keepalive.worker.js +94 -0
  55. package/dist/services/core/websocket/keepalive.worker.js.map +1 -0
  56. package/dist/services/core/websocket/types.js +6 -0
  57. package/dist/services/core/websocket/types.js.map +1 -0
  58. package/dist/services/index.js +78 -0
  59. package/dist/services/index.js.map +1 -0
  60. package/dist/services/task/AutoWrapup.js +88 -0
  61. package/dist/services/task/AutoWrapup.js.map +1 -0
  62. package/dist/services/task/TaskManager.js +369 -0
  63. package/dist/services/task/TaskManager.js.map +1 -0
  64. package/dist/services/task/constants.js +58 -0
  65. package/dist/services/task/constants.js.map +1 -0
  66. package/dist/services/task/contact.js +464 -0
  67. package/dist/services/task/contact.js.map +1 -0
  68. package/dist/services/task/dialer.js +60 -0
  69. package/dist/services/task/dialer.js.map +1 -0
  70. package/dist/services/task/index.js +1188 -0
  71. package/dist/services/task/index.js.map +1 -0
  72. package/dist/services/task/types.js +214 -0
  73. package/dist/services/task/types.js.map +1 -0
  74. package/dist/types/cc.d.ts +676 -0
  75. package/dist/types/config.d.ts +66 -0
  76. package/dist/types/constants.d.ts +45 -0
  77. package/dist/types/index.d.ts +178 -0
  78. package/dist/types/logger-proxy.d.ts +71 -0
  79. package/dist/types/metrics/MetricsManager.d.ts +223 -0
  80. package/dist/types/metrics/behavioral-events.d.ts +29 -0
  81. package/dist/types/metrics/constants.d.ts +127 -0
  82. package/dist/types/services/WebCallingService.d.ts +1 -0
  83. package/dist/types/services/agent/index.d.ts +46 -0
  84. package/dist/types/services/agent/types.d.ts +413 -0
  85. package/dist/types/services/config/Util.d.ts +19 -0
  86. package/dist/types/services/config/constants.d.ts +203 -0
  87. package/dist/types/services/config/index.d.ts +171 -0
  88. package/dist/types/services/config/types.d.ts +1113 -0
  89. package/dist/types/services/constants.d.ts +97 -0
  90. package/dist/types/services/core/Err.d.ts +119 -0
  91. package/dist/types/services/core/GlobalTypes.d.ts +33 -0
  92. package/dist/types/services/core/Utils.d.ts +36 -0
  93. package/dist/types/services/core/WebexRequest.d.ts +22 -0
  94. package/dist/types/services/core/aqm-reqs.d.ts +16 -0
  95. package/dist/types/services/core/constants.d.ts +85 -0
  96. package/dist/types/services/core/types.d.ts +47 -0
  97. package/dist/types/services/core/websocket/WebSocketManager.d.ts +34 -0
  98. package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
  99. package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
  100. package/dist/types/services/core/websocket/types.d.ts +37 -0
  101. package/dist/types/services/index.d.ts +52 -0
  102. package/dist/types/services/task/AutoWrapup.d.ts +40 -0
  103. package/dist/types/services/task/TaskManager.d.ts +1 -0
  104. package/dist/types/services/task/constants.d.ts +46 -0
  105. package/dist/types/services/task/contact.d.ts +59 -0
  106. package/dist/types/services/task/dialer.d.ts +28 -0
  107. package/dist/types/services/task/index.d.ts +569 -0
  108. package/dist/types/services/task/types.d.ts +1041 -0
  109. package/dist/types/types.d.ts +452 -0
  110. package/dist/types/webex-config.d.ts +53 -0
  111. package/dist/types/webex.d.ts +7 -0
  112. package/dist/types.js +292 -0
  113. package/dist/types.js.map +1 -0
  114. package/dist/webex-config.js +60 -0
  115. package/dist/webex-config.js.map +1 -0
  116. package/dist/webex.js +99 -0
  117. package/dist/webex.js.map +1 -0
  118. package/jest.config.js +45 -0
  119. package/package.json +83 -0
  120. package/src/cc.ts +1618 -0
  121. package/src/config.ts +65 -0
  122. package/src/constants.ts +51 -0
  123. package/src/index.ts +220 -0
  124. package/src/logger-proxy.ts +110 -0
  125. package/src/metrics/MetricsManager.ts +512 -0
  126. package/src/metrics/behavioral-events.ts +332 -0
  127. package/src/metrics/constants.ts +135 -0
  128. package/src/services/WebCallingService.ts +351 -0
  129. package/src/services/agent/index.ts +149 -0
  130. package/src/services/agent/types.ts +440 -0
  131. package/src/services/config/Util.ts +261 -0
  132. package/src/services/config/constants.ts +249 -0
  133. package/src/services/config/index.ts +743 -0
  134. package/src/services/config/types.ts +1117 -0
  135. package/src/services/constants.ts +111 -0
  136. package/src/services/core/Err.ts +126 -0
  137. package/src/services/core/GlobalTypes.ts +34 -0
  138. package/src/services/core/Utils.ts +132 -0
  139. package/src/services/core/WebexRequest.ts +103 -0
  140. package/src/services/core/aqm-reqs.ts +272 -0
  141. package/src/services/core/constants.ts +106 -0
  142. package/src/services/core/types.ts +48 -0
  143. package/src/services/core/websocket/WebSocketManager.ts +196 -0
  144. package/src/services/core/websocket/connection-service.ts +142 -0
  145. package/src/services/core/websocket/keepalive.worker.js +88 -0
  146. package/src/services/core/websocket/types.ts +40 -0
  147. package/src/services/index.ts +71 -0
  148. package/src/services/task/AutoWrapup.ts +86 -0
  149. package/src/services/task/TaskManager.ts +420 -0
  150. package/src/services/task/constants.ts +52 -0
  151. package/src/services/task/contact.ts +429 -0
  152. package/src/services/task/dialer.ts +52 -0
  153. package/src/services/task/index.ts +1375 -0
  154. package/src/services/task/types.ts +1113 -0
  155. package/src/types.ts +639 -0
  156. package/src/webex-config.ts +54 -0
  157. package/src/webex.js +96 -0
  158. package/test/unit/spec/cc.ts +1985 -0
  159. package/test/unit/spec/metrics/MetricsManager.ts +491 -0
  160. package/test/unit/spec/metrics/behavioral-events.ts +102 -0
  161. package/test/unit/spec/services/WebCallingService.ts +416 -0
  162. package/test/unit/spec/services/agent/index.ts +65 -0
  163. package/test/unit/spec/services/config/index.ts +1035 -0
  164. package/test/unit/spec/services/core/Utils.ts +279 -0
  165. package/test/unit/spec/services/core/WebexRequest.ts +144 -0
  166. package/test/unit/spec/services/core/aqm-reqs.ts +570 -0
  167. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +378 -0
  168. package/test/unit/spec/services/core/websocket/connection-service.ts +178 -0
  169. package/test/unit/spec/services/task/TaskManager.ts +1351 -0
  170. package/test/unit/spec/services/task/contact.ts +204 -0
  171. package/test/unit/spec/services/task/dialer.ts +157 -0
  172. package/test/unit/spec/services/task/index.ts +1474 -0
  173. package/tsconfig.json +6 -0
  174. package/typedoc.json +37 -0
  175. package/typedoc.md +240 -0
  176. package/umd/contact-center.min.js +3 -0
  177. package/umd/contact-center.min.js.map +1 -0
@@ -0,0 +1,1188 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _events = _interopRequireDefault(require("events"));
8
+ var _calling = require("@webex/calling");
9
+ var _Utils = require("../core/Utils");
10
+ var _types = require("../../types");
11
+ var _constants = require("../../constants");
12
+ var _constants2 = require("./constants");
13
+ var _loggerProxy = _interopRequireDefault(require("../../logger-proxy"));
14
+ var _types2 = require("./types");
15
+ var _MetricsManager = _interopRequireDefault(require("../../metrics/MetricsManager"));
16
+ var _constants3 = require("../../metrics/constants");
17
+ var _AutoWrapup = _interopRequireDefault(require("./AutoWrapup"));
18
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
+ /**
20
+ * Task class represents a contact center task/interaction that can be managed by an agent.
21
+ * This class provides all the necessary methods to manage tasks in a contact center environment,
22
+ * handling various call control operations and task lifecycle management.
23
+ *
24
+ * - Task Lifecycle Management:
25
+ * - {@link accept} - Accept incoming task
26
+ * - {@link decline} - Decline incoming task
27
+ * - {@link end} - End active task
28
+ * - Media Controls:
29
+ * - {@link toggleMute} - Mute/unmute microphone for voice tasks
30
+ * - {@link hold} - Place task on hold
31
+ * - {@link resume} - Resume held task
32
+ * - Recording Controls:
33
+ * - {@link pauseRecording} - Pause task recording
34
+ * - {@link resumeRecording} - Resume paused recording
35
+ * - Task Transfer & Consultation:
36
+ * - {@link consult} - Initiate consultation with another agent/queue
37
+ * - {@link endConsult} - End ongoing consultation
38
+ * - {@link transfer} - Transfer task to another agent/queue
39
+ * - {@link consultTransfer} - Transfer after consultation
40
+ * - Task Completion:
41
+ * - {@link wrapup} - Complete task wrap-up
42
+ *
43
+ * Key events emitted by Task instances (see {@link TASK_EVENTS} for details):
44
+ *
45
+ * - Task Lifecycle:
46
+ * - task:incoming — New task is being offered
47
+ * - task:assigned — Task assigned to agent
48
+ * - task:unassigned — Task unassigned from agent
49
+ * - task:end — Task has ended
50
+ * - task:wrapup — Task entered wrap-up state
51
+ * - task:wrappedup — Task wrap-up completed
52
+ * - task:rejected — Task was rejected/unanswered
53
+ * - task:hydrate — Task data populated
54
+ *
55
+ * - Media & Controls:
56
+ * - task:media — Voice call media track received
57
+ * - task:hold — Task placed on hold
58
+ * - task:unhold — Task resumed from hold
59
+ *
60
+ * - Consultation & Transfer:
61
+ * - task:consultCreated — Consultation initiated
62
+ * - task:consulting — Consultation in progress
63
+ * - task:consultAccepted — Consultation accepted
64
+ * - task:consultEnd — Consultation ended
65
+ * - task:consultQueueCancelled — Queue consultation cancelled
66
+ * - task:consultQueueFailed — Queue consultation failed
67
+ * - task:offerConsult — Consultation offered
68
+ * - task:offerContact — New contact offered
69
+ *
70
+ * - Recording:
71
+ * - task:recordingPaused — Recording paused
72
+ * - task:recordingPauseFailed — Recording pause failed
73
+ * - task:recordingResumed — Recording resumed
74
+ * - task:recordingResumeFailed — Recording resume failed
75
+ *
76
+ * @implements {ITask}
77
+ * @example
78
+ * ```typescript
79
+ * // 1. Initialize task
80
+ * const task = new Task(contact, webCallingService, taskData);
81
+ *
82
+ * // 2. Set up event listeners
83
+ * task.on('task:media', (track) => {
84
+ * // Handle voice call media
85
+ * const audioElement = document.getElementById('remote-audio');
86
+ * audioElement.srcObject = new MediaStream([track]);
87
+ * });
88
+ *
89
+ * task.on('task:hold', () => {
90
+ * console.log('Task is on hold');
91
+ * // Update UI to show hold state
92
+ * });
93
+ *
94
+ * task.on('task:end', () => {
95
+ * console.log('Task ended');
96
+ * if (task.data.wrapUpRequired) {
97
+ * // Show wrap-up form
98
+ * }
99
+ * });
100
+ *
101
+ * // 3. Example task operations
102
+ * await task.accept(); // Accept incoming task
103
+ * await task.hold(); // Place on hold
104
+ * await task.resume(); // Resume from hold
105
+ * await task.end(); // End task
106
+ *
107
+ * // 4. Handle wrap-up if required
108
+ * await task.wrapup({
109
+ * auxCodeId: 'RESOLVED',
110
+ * wrapUpReason: 'Customer issue resolved'
111
+ * });
112
+ * ```
113
+ */
114
+
115
+ class Task extends _events.default {
116
+ /**
117
+ * Creates a new Task instance which provides the following features:
118
+ * @param contact - The routing contact service instance
119
+ * @param webCallingService - The web calling service instance
120
+ * @param data - Initial task data
121
+ * @param wrapupData - Wrap-up configuration data
122
+ */
123
+ constructor(contact, webCallingService, data, wrapupData) {
124
+ super();
125
+ this.contact = contact;
126
+ this.data = data;
127
+ this.webCallingService = webCallingService;
128
+ this.webCallMap = {};
129
+ this.wrapupData = wrapupData;
130
+ this.metricsManager = _MetricsManager.default.getInstance();
131
+ this.registerWebCallListeners();
132
+ this.setupAutoWrapupTimer();
133
+ }
134
+
135
+ /**
136
+ * Sets up the automatic wrap-up timer if wrap-up is required
137
+ * @private
138
+ */
139
+ setupAutoWrapupTimer() {
140
+ if (this.data.wrapUpRequired &&
141
+ // only when wrapup required
142
+ !this.autoWrapup &&
143
+ // if autoWrapup is not already set
144
+ this.wrapupData &&
145
+ // wrapupData is not defined
146
+ this.wrapupData.wrapUpProps // wrapUpProps is defined
147
+ ) {
148
+ const wrapUpProps = this.wrapupData.wrapUpProps;
149
+ if (!wrapUpProps || wrapUpProps.autoWrapup === false) {
150
+ _loggerProxy.default.info(`Auto wrap-up is not required for this task`, {
151
+ module: _constants.TASK_FILE,
152
+ method: _constants2.METHODS.SETUP_AUTO_WRAPUP_TIMER,
153
+ interactionId: this.data.interactionId
154
+ });
155
+ return;
156
+ }
157
+ const defaultWrapupReason = wrapUpProps.wrapUpReasonList?.find(r => r.isDefault) ?? wrapUpProps.wrapUpReasonList?.[0];
158
+ if (!defaultWrapupReason) {
159
+ _loggerProxy.default.error('No wrap-up reason configured', {
160
+ module: _constants.TASK_FILE,
161
+ method: _constants2.METHODS.SETUP_AUTO_WRAPUP_TIMER
162
+ });
163
+ return;
164
+ }
165
+ const intervalMs = wrapUpProps.autoWrapupInterval;
166
+ if (!intervalMs || intervalMs <= 0) {
167
+ _loggerProxy.default.error(`Invalid auto wrap-up interval: ${intervalMs}`, {
168
+ module: _constants.TASK_FILE,
169
+ method: _constants2.METHODS.SETUP_AUTO_WRAPUP_TIMER
170
+ });
171
+ }
172
+ this.autoWrapup = new _AutoWrapup.default(intervalMs, wrapUpProps.allowCancelAutoWrapup);
173
+ this.autoWrapup.start(async () => {
174
+ _loggerProxy.default.info(`Auto wrap-up timer triggered`, {
175
+ module: _constants.TASK_FILE,
176
+ method: _constants2.METHODS.SETUP_AUTO_WRAPUP_TIMER,
177
+ interactionId: this.data.interactionId
178
+ });
179
+ await this.wrapup({
180
+ wrapUpReason: defaultWrapupReason.name,
181
+ auxCodeId: defaultWrapupReason.id
182
+ });
183
+ });
184
+ }
185
+ }
186
+
187
+ /**
188
+ * Cancels the automatic wrap-up timer if it's running
189
+ * @public - Public so it can be called externally when needed
190
+ * Note: This is supported only in single session mode. Not supported in multi-session mode.
191
+ */
192
+ cancelAutoWrapupTimer() {
193
+ this.autoWrapup?.clear();
194
+ this.autoWrapup = undefined;
195
+ _loggerProxy.default.info(`Auto wrap-up timer cancelled`, {
196
+ module: _constants.TASK_FILE,
197
+ method: _constants2.METHODS.CANCEL_AUTO_WRAPUP_TIMER,
198
+ interactionId: this.data?.interactionId
199
+ });
200
+ }
201
+
202
+ /**
203
+ * @ignore
204
+ * @private
205
+ */
206
+ handleRemoteMedia = track => {
207
+ this.emit(_types2.TASK_EVENTS.TASK_MEDIA, track);
208
+ };
209
+
210
+ /**
211
+ * @ignore
212
+ * @private
213
+ */
214
+ registerWebCallListeners() {
215
+ this.webCallingService.on(_calling.CALL_EVENT_KEYS.REMOTE_MEDIA, this.handleRemoteMedia);
216
+ }
217
+
218
+ /**
219
+ * @ignore
220
+ */
221
+ unregisterWebCallListeners() {
222
+ this.webCallingService.off(_calling.CALL_EVENT_KEYS.REMOTE_MEDIA, this.handleRemoteMedia);
223
+ }
224
+
225
+ /**
226
+ * Updates the task data with new information
227
+ * @param updatedData - New task data to merge with existing data
228
+ * @param shouldOverwrite - If true, completely replace data instead of merging
229
+ * @returns The updated task instance
230
+ * @example
231
+ * ```typescript
232
+ * task.updateTaskData(newData);
233
+ * task.updateTaskData(newData, true); // completely replace data
234
+ * ```
235
+ */
236
+ updateTaskData = (updatedData, shouldOverwrite = false) => {
237
+ this.data = shouldOverwrite ? updatedData : this.reconcileData(this.data, updatedData);
238
+ this.setupAutoWrapupTimer();
239
+ return this;
240
+ };
241
+
242
+ /**
243
+ * Recursively merges old data with new data
244
+ * @private
245
+ */
246
+ reconcileData(oldData, newData) {
247
+ 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]);
252
+ } else {
253
+ oldData[key] = newData[key];
254
+ }
255
+ });
256
+ return oldData;
257
+ }
258
+
259
+ /**
260
+ * Agent accepts the incoming task.
261
+ * After accepting, the task will emit task:assigned event and for voice calls,
262
+ * a task:media event with the audio stream.
263
+ *
264
+ * @returns Promise<TaskResponse>
265
+ * @throws Error if accepting task fails or media requirements not met
266
+ * @example
267
+ * ```typescript
268
+ * // Set up event handlers before accepting
269
+ * task.on(TASK_EVENTS.TASK_ASSIGNED, () => {
270
+ * console.log('Task assigned, ID:', task.data.interactionId);
271
+ * // Update UI to show active task
272
+ * });
273
+ *
274
+ * // For voice calls, handle media
275
+ * task.on(TASK_EVENTS.TASK_MEDIA, (track) => {
276
+ * const audioElement = document.getElementById('remote-audio');
277
+ * audioElement.srcObject = new MediaStream([track]);
278
+ * });
279
+ *
280
+ * // Accept the task
281
+ * try {
282
+ * await task.accept();
283
+ * console.log('Successfully accepted task');
284
+ * } catch (error) {
285
+ * console.error('Failed to accept task:', error);
286
+ * // Handle error (e.g., show error message to agent)
287
+ * }
288
+ * ```
289
+ */
290
+ async accept() {
291
+ try {
292
+ _loggerProxy.default.info(`Accepting task`, {
293
+ module: _constants.TASK_FILE,
294
+ method: _constants2.METHODS.ACCEPT,
295
+ interactionId: this.data.interactionId
296
+ });
297
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_ACCEPT_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_ACCEPT_FAILED]);
298
+ if (this.data.interaction.mediaType !== _types2.MEDIA_CHANNEL.TELEPHONY) {
299
+ const response = await this.contact.accept({
300
+ interactionId: this.data.interactionId
301
+ });
302
+ _loggerProxy.default.log(`Task accepted successfully`, {
303
+ module: _constants.TASK_FILE,
304
+ method: _constants2.METHODS.ACCEPT,
305
+ trackingId: response.trackingId,
306
+ interactionId: this.data.interactionId
307
+ });
308
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_ACCEPT_SUCCESS, {
309
+ taskId: this.data.interactionId,
310
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(this.data)
311
+ }, ['operational', 'behavioral', 'business']);
312
+ return response;
313
+ }
314
+ if (this.webCallingService.loginOption === _types.LoginOption.BROWSER) {
315
+ const constraints = {
316
+ audio: true
317
+ };
318
+ const localStream = await navigator.mediaDevices.getUserMedia(constraints);
319
+ const audioTrack = localStream.getAudioTracks()[0];
320
+ this.localAudioStream = new _calling.LocalMicrophoneStream(new MediaStream([audioTrack]));
321
+ this.webCallingService.answerCall(this.localAudioStream, this.data.interactionId);
322
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_ACCEPT_SUCCESS, {
323
+ taskId: this.data.interactionId,
324
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(this.data)
325
+ }, ['operational', 'behavioral', 'business']);
326
+ _loggerProxy.default.log(`Task accepted successfully with webrtc calling`, {
327
+ module: _constants.TASK_FILE,
328
+ method: _constants2.METHODS.ACCEPT,
329
+ interactionId: this.data.interactionId
330
+ });
331
+ }
332
+ return Promise.resolve(); // TODO: reject for extension as part of refactor
333
+ } catch (error) {
334
+ const {
335
+ error: detailedError
336
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.ACCEPT, _constants.TASK_FILE);
337
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_ACCEPT_FAILED, {
338
+ taskId: this.data.interactionId,
339
+ error: error.toString(),
340
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details)
341
+ }, ['operational', 'behavioral', 'business']);
342
+ throw detailedError;
343
+ }
344
+ }
345
+
346
+ /**
347
+ * Agent can mute/unmute their microphone during a WebRTC task.
348
+ * This method toggles between muted and unmuted states for the local audio stream.
349
+ *
350
+ * @returns Promise<void> - Resolves when mute/unmute operation completes
351
+ * @throws Error if toggling mute state fails or audio stream is not available
352
+ * @example
353
+ * ```typescript
354
+ * // Toggle mute state
355
+ * task.toggleMute()
356
+ * .then(() => console.log('Mute state toggled successfully'))
357
+ * .catch(error => console.error('Failed to toggle mute:', error));
358
+ * ```
359
+ */
360
+ async toggleMute() {
361
+ try {
362
+ _loggerProxy.default.info(`Toggling mute state`, {
363
+ module: _constants.TASK_FILE,
364
+ method: _constants2.METHODS.TOGGLE_MUTE,
365
+ interactionId: this.data.interactionId
366
+ });
367
+ this.webCallingService.muteUnmuteCall(this.localAudioStream);
368
+ _loggerProxy.default.log(`Mute state toggled successfully isCallMuted: ${this.webCallingService.isCallMuted()}`, {
369
+ module: _constants.TASK_FILE,
370
+ method: _constants2.METHODS.TOGGLE_MUTE,
371
+ interactionId: this.data.interactionId
372
+ });
373
+ return Promise.resolve();
374
+ } catch (error) {
375
+ const {
376
+ error: detailedError
377
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.TOGGLE_MUTE, _constants.TASK_FILE);
378
+ throw detailedError;
379
+ }
380
+ }
381
+
382
+ /**
383
+ * Declines the incoming task. This will reject the task and notify the routing system.
384
+ * For voice calls, this is equivalent to declining the incoming call.
385
+ *
386
+ * @returns Promise<TaskResponse>
387
+ * @throws Error if the decline operation fails
388
+ * @example
389
+ * ```typescript
390
+ * // Decline an incoming task
391
+ * task.decline()
392
+ * .then(() => console.log('Task declined successfully'))
393
+ * .catch(error => console.error('Failed to decline task:', error));
394
+ * ```
395
+ */
396
+ async decline() {
397
+ try {
398
+ _loggerProxy.default.info(`Declining task`, {
399
+ module: _constants.TASK_FILE,
400
+ method: _constants2.METHODS.DECLINE,
401
+ interactionId: this.data.interactionId
402
+ });
403
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_DECLINE_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_DECLINE_FAILED]);
404
+ this.webCallingService.declineCall(this.data.interactionId);
405
+ this.unregisterWebCallListeners();
406
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_DECLINE_SUCCESS, {
407
+ taskId: this.data.interactionId
408
+ }, ['operational', 'behavioral']);
409
+ _loggerProxy.default.log(`Task declined successfully`, {
410
+ module: _constants.TASK_FILE,
411
+ method: _constants2.METHODS.DECLINE,
412
+ interactionId: this.data.interactionId
413
+ });
414
+ return Promise.resolve();
415
+ } catch (error) {
416
+ const {
417
+ error: detailedError
418
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.DECLINE, _constants.TASK_FILE);
419
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_DECLINE_FAILED, {
420
+ taskId: this.data.interactionId,
421
+ error: error.toString(),
422
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
423
+ }, ['operational', 'behavioral']);
424
+ throw detailedError;
425
+ }
426
+ }
427
+
428
+ /**
429
+ * Puts the current task/interaction on hold.
430
+ * Emits task:hold event when successful. For voice tasks, this mutes the audio.
431
+ *
432
+ * @returns Promise<TaskResponse>
433
+ * @throws Error if hold operation fails
434
+ * @example
435
+ * ```typescript
436
+ * // Set up hold event handler
437
+ * task.on(TASK_EVENTS.TASK_HOLD, () => {
438
+ * console.log('Task is now on hold');
439
+ * // Update UI to show hold state (e.g., enable resume button, show hold indicator)
440
+ * document.getElementById('resume-btn').disabled = false;
441
+ * document.getElementById('hold-indicator').style.display = 'block';
442
+ * });
443
+ *
444
+ * // Place task on hold
445
+ * try {
446
+ * await task.hold();
447
+ * console.log('Successfully placed task on hold');
448
+ * } catch (error) {
449
+ * console.error('Failed to place task on hold:', error);
450
+ * // Handle error (e.g., show error message, reset UI state)
451
+ * }
452
+ * ```
453
+ */
454
+ async hold() {
455
+ try {
456
+ _loggerProxy.default.info(`Holding task`, {
457
+ module: _constants.TASK_FILE,
458
+ method: _constants2.METHODS.HOLD,
459
+ interactionId: this.data.interactionId
460
+ });
461
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_HOLD_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_HOLD_FAILED]);
462
+ const response = await this.contact.hold({
463
+ interactionId: this.data.interactionId,
464
+ data: {
465
+ mediaResourceId: this.data.mediaResourceId
466
+ }
467
+ });
468
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_HOLD_SUCCESS, {
469
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response),
470
+ taskId: this.data.interactionId,
471
+ mediaResourceId: this.data.mediaResourceId
472
+ }, ['operational', 'behavioral']);
473
+ _loggerProxy.default.log(`Task placed on hold successfully`, {
474
+ module: _constants.TASK_FILE,
475
+ method: _constants2.METHODS.HOLD,
476
+ trackingId: response.trackingId,
477
+ interactionId: this.data.interactionId
478
+ });
479
+ return response;
480
+ } catch (error) {
481
+ const {
482
+ error: detailedError
483
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.HOLD, _constants.TASK_FILE);
484
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_HOLD_FAILED, {
485
+ taskId: this.data.interactionId,
486
+ mediaResourceId: this.data.mediaResourceId,
487
+ error: error.toString(),
488
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
489
+ }, ['operational', 'behavioral']);
490
+ throw detailedError;
491
+ }
492
+ }
493
+
494
+ /**
495
+ * Resumes the task/interaction that was previously put on hold.
496
+ * Emits task:resume event when successful. For voice tasks, this restores the audio.
497
+ *
498
+ * @returns Promise<TaskResponse>
499
+ * @throws Error if resume operation fails
500
+ * @example
501
+ * ```typescript
502
+ * // Set up resume event handler
503
+ * task.on(TASK_EVENTS.TASK_RESUME, () => {
504
+ * console.log('Task resumed from hold');
505
+ * // Update UI to show active state
506
+ * document.getElementById('hold-btn').disabled = false;
507
+ * document.getElementById('hold-indicator').style.display = 'none';
508
+ * });
509
+ *
510
+ * // Resume task from hold
511
+ * try {
512
+ * await task.resume();
513
+ * console.log('Successfully resumed task from hold');
514
+ * } catch (error) {
515
+ * console.error('Failed to resume task:', error);
516
+ * // Handle error (e.g., show error message)
517
+ * }
518
+ * ```
519
+ */
520
+ async resume() {
521
+ try {
522
+ _loggerProxy.default.info(`Resuming task`, {
523
+ module: _constants.TASK_FILE,
524
+ method: _constants2.METHODS.RESUME,
525
+ interactionId: this.data.interactionId
526
+ });
527
+ const {
528
+ mainInteractionId
529
+ } = this.data.interaction;
530
+ const {
531
+ mediaResourceId
532
+ } = this.data.interaction.media[mainInteractionId];
533
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_RESUME_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_RESUME_FAILED]);
534
+ const response = await this.contact.unHold({
535
+ interactionId: this.data.interactionId,
536
+ data: {
537
+ mediaResourceId
538
+ }
539
+ });
540
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_SUCCESS, {
541
+ taskId: this.data.interactionId,
542
+ mainInteractionId,
543
+ mediaResourceId,
544
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
545
+ }, ['operational', 'behavioral']);
546
+ _loggerProxy.default.log(`Task resumed successfully`, {
547
+ module: _constants.TASK_FILE,
548
+ method: _constants2.METHODS.RESUME,
549
+ trackingId: response.trackingId,
550
+ interactionId: this.data.interactionId
551
+ });
552
+ return response;
553
+ } catch (error) {
554
+ const {
555
+ error: detailedError
556
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.RESUME, _constants.TASK_FILE);
557
+ const mainInteractionId = this.data.interaction?.mainInteractionId;
558
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_FAILED, {
559
+ taskId: this.data.interactionId,
560
+ mainInteractionId,
561
+ mediaResourceId: mainInteractionId ? this.data.interaction.media[mainInteractionId].mediaResourceId : '',
562
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
563
+ }, ['operational', 'behavioral']);
564
+ throw detailedError;
565
+ }
566
+ }
567
+
568
+ /**
569
+ * Ends the task/interaction with the customer.
570
+ * Emits task:end event when successful. If task requires wrap-up,
571
+ * this will be indicated in the task:end event data.
572
+ *
573
+ * @returns Promise<TaskResponse>
574
+ * @throws Error if ending task fails
575
+ * @example
576
+ * ```typescript
577
+ * // Set up task end event handler
578
+ * task.on(TASK_EVENTS.TASK_END, (data) => {
579
+ * console.log('Task ended:', task.data.interactionId);
580
+ *
581
+ * if (data.wrapUpRequired) {
582
+ * // Show wrap-up form
583
+ * showWrapupForm();
584
+ * } else {
585
+ * // Clean up and prepare for next task
586
+ * cleanupTask();
587
+ * }
588
+ * });
589
+ *
590
+ * // End the task
591
+ * try {
592
+ * await task.end();
593
+ * console.log('Task end request successful');
594
+ * } catch (error) {
595
+ * console.error('Failed to end task:', error);
596
+ * // Handle error (e.g., show error message, retry option)
597
+ * }
598
+ *
599
+ * function showWrapupForm() {
600
+ * // Show wrap-up UI with required codes
601
+ * document.getElementById('wrapup-form').style.display = 'block';
602
+ * }
603
+ *
604
+ * function cleanupTask() {
605
+ * // Reset UI state
606
+ * document.getElementById('active-task').style.display = 'none';
607
+ * document.getElementById('controls').style.display = 'none';
608
+ * }
609
+ * ```
610
+ */
611
+ async end() {
612
+ try {
613
+ _loggerProxy.default.info(`Ending task`, {
614
+ module: _constants.TASK_FILE,
615
+ method: _constants2.METHODS.END,
616
+ interactionId: this.data.interactionId
617
+ });
618
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_END_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_END_FAILED]);
619
+ const response = await this.contact.end({
620
+ interactionId: this.data.interactionId
621
+ });
622
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_END_SUCCESS, {
623
+ taskId: this.data.interactionId,
624
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
625
+ }, ['operational', 'behavioral', 'business']);
626
+ _loggerProxy.default.log(`Task ended successfully`, {
627
+ module: _constants.TASK_FILE,
628
+ method: _constants2.METHODS.END,
629
+ trackingId: response.trackingId,
630
+ interactionId: this.data.interactionId
631
+ });
632
+ return response;
633
+ } catch (error) {
634
+ const {
635
+ error: detailedError
636
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.END, _constants.TASK_FILE);
637
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_END_FAILED, {
638
+ taskId: this.data.interactionId,
639
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
640
+ }, ['operational', 'behavioral', 'business']);
641
+ throw detailedError;
642
+ }
643
+ }
644
+
645
+ /**
646
+ * Wraps up the task/interaction with the customer.
647
+ * This is called after task:end event if wrapUpRequired is true.
648
+ * Emits task:wrappedup event when successful.
649
+ *
650
+ * @param wrapupPayload - WrapupPayLoad containing:
651
+ * - auxCodeId: Required ID for the wrap-up code
652
+ * - wrapUpReason: Required description of wrap-up reason
653
+ * @returns Promise<TaskResponse>
654
+ * @throws Error if task data is unavailable, auxCodeId is missing, or wrapUpReason is missing
655
+ * @example
656
+ * ```typescript
657
+ * // Set up wrap-up events
658
+ * task.on(TASK_EVENTS.TASK_WRAPUP, () => {
659
+ * console.log('Task ready for wrap-up');
660
+ * // Show wrap-up form
661
+ * document.getElementById('wrapup-form').style.display = 'block';
662
+ * });
663
+ *
664
+ * task.on(TASK_EVENTS.TASK_WRAPPEDUP, () => {
665
+ * console.log('Task wrap-up completed');
666
+ * // Clean up UI
667
+ * document.getElementById('wrapup-form').style.display = 'none';
668
+ * });
669
+ *
670
+ * // Submit wrap-up
671
+ * try {
672
+ * const wrapupPayload = {
673
+ * auxCodeId: selectedCode, // e.g., 'ISSUE_RESOLVED'
674
+ * wrapUpReason: 'Customer issue resolved successfully'
675
+ * };
676
+ * await task.wrapup(wrapupPayload);
677
+ * console.log('Successfully submitted wrap-up');
678
+ * } catch (error) {
679
+ * console.error('Failed to submit wrap-up:', error);
680
+ * // Handle validation errors
681
+ * if (error.message.includes('required')) {
682
+ * // Show validation error to agent
683
+ * }
684
+ * }
685
+ * ```
686
+ */
687
+ async wrapup(wrapupPayload) {
688
+ try {
689
+ this.cancelAutoWrapupTimer();
690
+ _loggerProxy.default.info(`Wrapping up task`, {
691
+ module: _constants.TASK_FILE,
692
+ method: _constants2.METHODS.WRAPUP,
693
+ interactionId: this.data.interactionId
694
+ });
695
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_WRAPUP_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_WRAPUP_FAILED]);
696
+ if (!this.data) {
697
+ throw new Error('No task data available');
698
+ }
699
+ if (!wrapupPayload.auxCodeId || wrapupPayload.auxCodeId.length === 0) {
700
+ throw new Error('AuxCodeId is required');
701
+ }
702
+ if (!wrapupPayload.wrapUpReason || wrapupPayload.wrapUpReason.length === 0) {
703
+ throw new Error('WrapUpReason is required');
704
+ }
705
+ const response = await this.contact.wrapup({
706
+ interactionId: this.data.interactionId,
707
+ data: wrapupPayload
708
+ });
709
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_WRAPUP_SUCCESS, {
710
+ taskId: this.data.interactionId,
711
+ wrapUpCode: wrapupPayload.auxCodeId,
712
+ wrapUpReason: wrapupPayload.wrapUpReason,
713
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(response)
714
+ }, ['operational', 'behavioral', 'business']);
715
+ _loggerProxy.default.log(`Task wrapped up successfully`, {
716
+ module: _constants.TASK_FILE,
717
+ method: _constants2.METHODS.WRAPUP,
718
+ trackingId: response.trackingId,
719
+ interactionId: this.data.interactionId
720
+ });
721
+ return response;
722
+ } catch (error) {
723
+ const {
724
+ error: detailedError
725
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.WRAPUP, _constants.TASK_FILE);
726
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_WRAPUP_FAILED, {
727
+ taskId: this.data.interactionId,
728
+ wrapUpCode: wrapupPayload.auxCodeId,
729
+ wrapUpReason: wrapupPayload.wrapUpReason,
730
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
731
+ }, ['operational', 'behavioral', 'business']);
732
+ throw detailedError;
733
+ }
734
+ }
735
+
736
+ /**
737
+ * Pauses the recording for the current voice task.
738
+ * Emits task:recordingPaused event when successful.
739
+ *
740
+ * @returns Promise<TaskResponse>
741
+ * @throws Error if pause recording fails
742
+ * @example
743
+ * ```typescript
744
+ * // Set up recording events
745
+ * task.on(TASK_EVENTS.TASK_RECORDING_PAUSED, () => {
746
+ * console.log('Recording paused');
747
+ * // Update UI to show recording paused state
748
+ * document.getElementById('recording-status').textContent = 'Recording Paused';
749
+ * document.getElementById('pause-recording-btn').style.display = 'none';
750
+ * document.getElementById('resume-recording-btn').style.display = 'block';
751
+ * });
752
+ *
753
+ * task.on(TASK_EVENTS.TASK_RECORDING_PAUSE_FAILED, (error) => {
754
+ * console.error('Failed to pause recording:', error);
755
+ * // Show error to agent
756
+ * });
757
+ *
758
+ * // Pause recording
759
+ * try {
760
+ * await task.pauseRecording();
761
+ * console.log('Pause recording request sent');
762
+ * } catch (error) {
763
+ * console.error('Error sending pause recording request:', error);
764
+ * // Handle error
765
+ * }
766
+ * ```
767
+ */
768
+ async pauseRecording() {
769
+ try {
770
+ _loggerProxy.default.info(`Pausing recording`, {
771
+ module: _constants.TASK_FILE,
772
+ method: _constants2.METHODS.PAUSE_RECORDING,
773
+ interactionId: this.data.interactionId
774
+ });
775
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_PAUSE_RECORDING_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_PAUSE_RECORDING_FAILED]);
776
+ const result = await this.contact.pauseRecording({
777
+ interactionId: this.data.interactionId
778
+ });
779
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_PAUSE_RECORDING_SUCCESS, {
780
+ taskId: this.data.interactionId,
781
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
782
+ }, ['operational', 'behavioral', 'business']);
783
+ _loggerProxy.default.log(`Recording paused successfully`, {
784
+ module: _constants.TASK_FILE,
785
+ method: _constants2.METHODS.PAUSE_RECORDING,
786
+ trackingId: result.trackingId,
787
+ interactionId: this.data.interactionId
788
+ });
789
+ return result;
790
+ } catch (error) {
791
+ const {
792
+ error: detailedError
793
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.PAUSE_RECORDING, _constants.TASK_FILE);
794
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_PAUSE_RECORDING_FAILED, {
795
+ taskId: this.data.interactionId,
796
+ error: error.toString(),
797
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
798
+ }, ['operational', 'behavioral', 'business']);
799
+ throw detailedError;
800
+ }
801
+ }
802
+
803
+ /**
804
+ * Resumes the recording for the voice task that was previously paused.
805
+ * Emits task:recordingResumed event when successful.
806
+ *
807
+ * @param resumeRecordingPayload - Configuration for resuming recording:
808
+ * - autoResumed: Indicates if resume was automatic (defaults to false)
809
+ * @returns Promise<TaskResponse>
810
+ * @throws Error if resume recording fails
811
+ * @example
812
+ * ```typescript
813
+ * // Set up recording resume events
814
+ * task.on(TASK_EVENTS.TASK_RECORDING_RESUMED, () => {
815
+ * console.log('Recording resumed');
816
+ * // Update UI to show active recording state
817
+ * document.getElementById('recording-status').textContent = 'Recording Active';
818
+ * document.getElementById('pause-recording-btn').style.display = 'block';
819
+ * document.getElementById('resume-recording-btn').style.display = 'none';
820
+ * });
821
+ *
822
+ * task.on(TASK_EVENTS.TASK_RECORDING_RESUME_FAILED, (error) => {
823
+ * console.error('Failed to resume recording:', error);
824
+ * // Show error to agent
825
+ * });
826
+ *
827
+ * // Resume recording
828
+ * try {
829
+ * const resumePayload = {
830
+ * autoResumed: false // Set to true if triggered by system
831
+ * };
832
+ * await task.resumeRecording(resumePayload);
833
+ * console.log('Resume recording request sent');
834
+ * } catch (error) {
835
+ * console.error('Error sending resume recording request:', error);
836
+ * // Handle error
837
+ * }
838
+ * ```
839
+ */
840
+ async resumeRecording(resumeRecordingPayload) {
841
+ try {
842
+ _loggerProxy.default.info(`Resuming recording`, {
843
+ module: _constants.TASK_FILE,
844
+ method: _constants2.METHODS.RESUME_RECORDING,
845
+ interactionId: this.data.interactionId
846
+ });
847
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_RESUME_RECORDING_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_RESUME_RECORDING_FAILED]);
848
+ resumeRecordingPayload ??= {
849
+ autoResumed: false
850
+ };
851
+ const result = await this.contact.resumeRecording({
852
+ interactionId: this.data.interactionId,
853
+ data: resumeRecordingPayload
854
+ });
855
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_RECORDING_SUCCESS, {
856
+ taskId: this.data.interactionId,
857
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
858
+ }, ['operational', 'behavioral', 'business']);
859
+ _loggerProxy.default.log(`Recording resumed successfully`, {
860
+ module: _constants.TASK_FILE,
861
+ method: _constants2.METHODS.RESUME_RECORDING,
862
+ trackingId: result.trackingId,
863
+ interactionId: this.data.interactionId
864
+ });
865
+ return result;
866
+ } catch (error) {
867
+ const {
868
+ error: detailedError
869
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.RESUME_RECORDING, _constants.TASK_FILE);
870
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_RESUME_RECORDING_FAILED, {
871
+ taskId: this.data.interactionId,
872
+ error: error.toString(),
873
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
874
+ }, ['operational', 'behavioral', 'business']);
875
+ throw detailedError;
876
+ }
877
+ }
878
+
879
+ /**
880
+ * Consults another agent or queue on an ongoing task for further assistance.
881
+ * During consultation, the original customer is typically placed on hold while
882
+ * the agent seeks guidance from another agent or queue.
883
+ *
884
+ * @param consultPayload - Configuration for the consultation containing:
885
+ * - to: ID of the agent or queue to consult with
886
+ * - destinationType: Type of destination (AGENT, QUEUE, etc.)
887
+ * - holdParticipants: Whether to hold other participants (defaults to true)
888
+ * @returns Promise<TaskResponse> - Resolves with consultation result
889
+ * @throws Error if consultation fails or invalid parameters provided
890
+ * @example
891
+ * ```typescript
892
+ * // Consult with another agent
893
+ * const consultPayload = {
894
+ * to: 'agentId123',
895
+ * destinationType: DESTINATION_TYPE.AGENT,
896
+ * holdParticipants: true
897
+ * };
898
+ * task.consult(consultPayload)
899
+ * .then(response => console.log('Consultation started successfully'))
900
+ * .catch(error => console.error('Failed to start consultation:', error));
901
+ *
902
+ * // Consult with a queue
903
+ * const queueConsultPayload = {
904
+ * to: 'salesQueue123',
905
+ * destinationType: DESTINATION_TYPE.QUEUE
906
+ * };
907
+ * task.consult(queueConsultPayload)
908
+ * .then(response => console.log('Queue consultation started'))
909
+ * .catch(error => console.error('Failed to start queue consultation:', error));
910
+ * ```
911
+ */
912
+ async consult(consultPayload) {
913
+ try {
914
+ _loggerProxy.default.info(`Starting consult`, {
915
+ module: _constants.TASK_FILE,
916
+ method: _constants2.METHODS.CONSULT,
917
+ interactionId: this.data.interactionId
918
+ });
919
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_START_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_CONSULT_START_FAILED]);
920
+ const result = await this.contact.consult({
921
+ interactionId: this.data.interactionId,
922
+ data: consultPayload
923
+ });
924
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_START_SUCCESS, {
925
+ taskId: this.data.interactionId,
926
+ destination: consultPayload.to,
927
+ destinationType: consultPayload.destinationType,
928
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
929
+ }, ['operational', 'behavioral', 'business']);
930
+ _loggerProxy.default.log(`Consult started successfully to ${consultPayload.to}`, {
931
+ module: _constants.TASK_FILE,
932
+ method: _constants2.METHODS.CONSULT,
933
+ trackingId: result.trackingId,
934
+ interactionId: this.data.interactionId
935
+ });
936
+ return result;
937
+ } catch (error) {
938
+ const {
939
+ error: detailedError
940
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.CONSULT, _constants.TASK_FILE);
941
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_START_FAILED, {
942
+ taskId: this.data.interactionId,
943
+ destination: consultPayload.to,
944
+ destinationType: consultPayload.destinationType,
945
+ error: error.toString(),
946
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
947
+ }, ['operational', 'behavioral', 'business']);
948
+ throw detailedError;
949
+ }
950
+ }
951
+
952
+ /**
953
+ * Ends an ongoing consultation session for the task.
954
+ * This terminates the consultation while maintaining the original customer connection.
955
+ *
956
+ * @param consultEndPayload - Configuration for ending the consultation containing:
957
+ * - isConsult: Must be true to indicate this is a consultation end
958
+ * - taskId: ID of the task being consulted on
959
+ * - queueId: (Optional) Queue ID if this was a queue consultation
960
+ * - isSecondaryEpDnAgent: (Optional) Indicates if this involves a secondary entry point
961
+ * @returns Promise<TaskResponse> - Resolves when consultation is ended
962
+ * @throws Error if ending consultation fails or invalid parameters provided
963
+ * @example
964
+ * ```typescript
965
+ * // End a direct agent consultation
966
+ * const consultEndPayload = {
967
+ * isConsult: true,
968
+ * taskId: 'task123'
969
+ * };
970
+ * task.endConsult(consultEndPayload)
971
+ * .then(response => console.log('Consultation ended successfully'))
972
+ * .catch(error => console.error('Failed to end consultation:', error));
973
+ *
974
+ * // End a queue consultation
975
+ * const queueConsultEndPayload = {
976
+ * isConsult: true,
977
+ * taskId: 'task123',
978
+ * queueId: 'queue123'
979
+ * };
980
+ * task.endConsult(queueConsultEndPayload)
981
+ * .then(response => console.log('Queue consultation ended'))
982
+ * .catch(error => console.error('Failed to end queue consultation:', error));
983
+ * ```
984
+ */
985
+ async endConsult(consultEndPayload) {
986
+ try {
987
+ _loggerProxy.default.info(`Ending consult`, {
988
+ module: _constants.TASK_FILE,
989
+ method: _constants2.METHODS.END_CONSULT,
990
+ interactionId: this.data.interactionId
991
+ });
992
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_END_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_CONSULT_END_FAILED]);
993
+ const result = await this.contact.consultEnd({
994
+ interactionId: this.data.interactionId,
995
+ data: consultEndPayload
996
+ });
997
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_END_SUCCESS, {
998
+ taskId: this.data.interactionId,
999
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
1000
+ }, ['operational', 'behavioral', 'business']);
1001
+ _loggerProxy.default.log(`Consult ended successfully`, {
1002
+ module: _constants.TASK_FILE,
1003
+ method: _constants2.METHODS.END_CONSULT,
1004
+ trackingId: result.trackingId,
1005
+ interactionId: this.data.interactionId
1006
+ });
1007
+ return result;
1008
+ } catch (error) {
1009
+ const {
1010
+ error: detailedError
1011
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.END_CONSULT, _constants.TASK_FILE);
1012
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_CONSULT_END_FAILED, {
1013
+ taskId: this.data.interactionId,
1014
+ error: error.toString(),
1015
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1016
+ }, ['operational', 'behavioral', 'business']);
1017
+ throw detailedError;
1018
+ }
1019
+ }
1020
+
1021
+ /**
1022
+ * Transfer the task to an agent directly or to a queue.
1023
+ * This is a blind transfer that immediately redirects the task to the specified destination.
1024
+ *
1025
+ * @param transferPayload - Transfer configuration containing:
1026
+ * - to: ID of the agent or queue to transfer to
1027
+ * - destinationType: Type of destination (AGENT, QUEUE, etc.)
1028
+ * @returns Promise<TaskResponse> - Resolves when transfer is completed
1029
+ * @throws Error if transfer fails or invalid parameters provided
1030
+ * @example
1031
+ * ```typescript
1032
+ * // Transfer to a queue
1033
+ * const queueTransferPayload = {
1034
+ * to: 'salesQueue123',
1035
+ * destinationType: DESTINATION_TYPE.QUEUE
1036
+ * };
1037
+ * task.transfer(queueTransferPayload)
1038
+ * .then(response => console.log('Task transferred to queue successfully'))
1039
+ * .catch(error => console.error('Failed to transfer to queue:', error));
1040
+ *
1041
+ * // Transfer to an agent
1042
+ * const agentTransferPayload = {
1043
+ * to: 'agentId123',
1044
+ * destinationType: DESTINATION_TYPE.AGENT
1045
+ * };
1046
+ * task.transfer(agentTransferPayload)
1047
+ * .then(response => console.log('Task transferred to agent successfully'))
1048
+ * .catch(error => console.error('Failed to transfer to agent:', error));
1049
+ * ```
1050
+ */
1051
+ async transfer(transferPayload) {
1052
+ try {
1053
+ _loggerProxy.default.info(`Transferring task to ${transferPayload.to}`, {
1054
+ module: _constants.TASK_FILE,
1055
+ method: _constants2.METHODS.TRANSFER,
1056
+ interactionId: this.data.interactionId
1057
+ });
1058
+ this.metricsManager.timeEvent([_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_SUCCESS, _constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED]);
1059
+ let result;
1060
+ if (transferPayload.destinationType === _types2.DESTINATION_TYPE.QUEUE) {
1061
+ result = await this.contact.vteamTransfer({
1062
+ interactionId: this.data.interactionId,
1063
+ data: transferPayload
1064
+ });
1065
+ } else {
1066
+ result = await this.contact.blindTransfer({
1067
+ interactionId: this.data.interactionId,
1068
+ data: transferPayload
1069
+ });
1070
+ }
1071
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_SUCCESS, {
1072
+ taskId: this.data.interactionId,
1073
+ destination: transferPayload.to,
1074
+ destinationType: transferPayload.destinationType,
1075
+ isConsultTransfer: false,
1076
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
1077
+ }, ['operational', 'behavioral', 'business']);
1078
+ _loggerProxy.default.log(`Task transferred successfully to ${transferPayload.to}`, {
1079
+ module: _constants.TASK_FILE,
1080
+ method: _constants2.METHODS.TRANSFER,
1081
+ trackingId: result.trackingId,
1082
+ interactionId: this.data.interactionId
1083
+ });
1084
+ return result;
1085
+ } catch (error) {
1086
+ const {
1087
+ error: detailedError
1088
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.TRANSFER, _constants.TASK_FILE);
1089
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED, {
1090
+ taskId: this.data.interactionId,
1091
+ destination: transferPayload.to,
1092
+ destinationType: transferPayload.destinationType,
1093
+ isConsultTransfer: false,
1094
+ error: error.toString(),
1095
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1096
+ }, ['operational', 'behavioral', 'business']);
1097
+ throw detailedError;
1098
+ }
1099
+ }
1100
+
1101
+ /**
1102
+ * Transfer the task to the party that was consulted.
1103
+ * This completes a consultative transfer where the agent first consulted with the target
1104
+ * before transferring the task. For queue consultations, the transfer is automatically
1105
+ * directed to the agent who accepted the consultation.
1106
+ *
1107
+ * @param consultTransferPayload - Configuration for the consultation transfer containing:
1108
+ * - to: ID of the agent or queue to transfer to
1109
+ * - destinationType: Type of destination (AGENT, QUEUE, etc. from CONSULT_TRANSFER_DESTINATION_TYPE)
1110
+ * @returns Promise<TaskResponse> - Resolves when consultation transfer is completed
1111
+ * @throws Error if transfer fails, no agent has accepted a queue consultation, or other validation errors
1112
+ * @example
1113
+ * ```typescript
1114
+ * // Complete consultation transfer to an agent
1115
+ * const agentConsultTransfer = {
1116
+ * to: 'agentId123',
1117
+ * destinationType: CONSULT_TRANSFER_DESTINATION_TYPE.AGENT
1118
+ * };
1119
+ * task.consultTransfer(agentConsultTransfer)
1120
+ * .then(response => console.log('Consultation transfer to agent completed'))
1121
+ * .catch(error => console.error('Failed to complete agent consultation transfer:', error));
1122
+ *
1123
+ * // Complete consultation transfer to a queue agent
1124
+ * const queueConsultTransfer = {
1125
+ * to: 'queue123',
1126
+ * destinationType: CONSULT_TRANSFER_DESTINATION_TYPE.QUEUE
1127
+ * };
1128
+ * task.consultTransfer(queueConsultTransfer)
1129
+ * .then(response => console.log('Consultation transfer to queue agent completed'))
1130
+ * .catch(error => console.error('Failed to complete queue consultation transfer:', error));
1131
+ * ```
1132
+ */
1133
+ async consultTransfer(consultTransferPayload) {
1134
+ try {
1135
+ _loggerProxy.default.info(`Initiating consult transfer to ${consultTransferPayload.to}`, {
1136
+ module: _constants.TASK_FILE,
1137
+ method: _constants2.METHODS.CONSULT_TRANSFER,
1138
+ interactionId: this.data.interactionId
1139
+ });
1140
+
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
+ }
1153
+ const result = await this.contact.consultTransfer({
1154
+ interactionId: this.data.interactionId,
1155
+ data: consultTransferPayload
1156
+ });
1157
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_SUCCESS, {
1158
+ taskId: this.data.interactionId,
1159
+ destination: consultTransferPayload.to,
1160
+ destinationType: consultTransferPayload.destinationType,
1161
+ isConsultTransfer: true,
1162
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result)
1163
+ }, ['operational', 'behavioral', 'business']);
1164
+ _loggerProxy.default.log(`Consult transfer completed successfully to ${consultTransferPayload.to}`, {
1165
+ module: _constants.TASK_FILE,
1166
+ method: _constants2.METHODS.CONSULT_TRANSFER,
1167
+ trackingId: result.trackingId,
1168
+ interactionId: this.data.interactionId
1169
+ });
1170
+ return result;
1171
+ } catch (error) {
1172
+ const {
1173
+ error: detailedError
1174
+ } = (0, _Utils.getErrorDetails)(error, _constants2.METHODS.CONSULT_TRANSFER, _constants.TASK_FILE);
1175
+ this.metricsManager.trackEvent(_constants3.METRIC_EVENT_NAMES.TASK_TRANSFER_FAILED, {
1176
+ taskId: this.data.interactionId,
1177
+ destination: consultTransferPayload.to,
1178
+ destinationType: consultTransferPayload.destinationType,
1179
+ isConsultTransfer: true,
1180
+ error: error.toString(),
1181
+ ..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(error.details || {})
1182
+ }, ['operational', 'behavioral', 'business']);
1183
+ throw detailedError;
1184
+ }
1185
+ }
1186
+ }
1187
+ exports.default = Task;
1188
+ //# sourceMappingURL=index.js.map