@webex/contact-center 3.11.0 → 3.12.0-llmrefactor.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.sdd/manifest.json +882 -0
- package/AGENTS.md +94 -0
- package/ai-docs/ARCHITECTURE.md +168 -0
- package/ai-docs/CONTRACTS.md +46 -0
- package/ai-docs/GETTING_STARTED.md +168 -0
- package/ai-docs/GLOSSARY.md +43 -0
- package/ai-docs/README.md +138 -0
- package/ai-docs/REVIEW_CHECKLIST.md +41 -0
- package/ai-docs/RULES.md +444 -0
- package/ai-docs/SECURITY.md +52 -0
- package/ai-docs/SERVICE_STATE.md +48 -0
- package/ai-docs/SPEC_INDEX.md +65 -0
- package/ai-docs/adr/0001-spec-source-policy.md +55 -0
- package/ai-docs/adr/README.md +8 -0
- package/ai-docs/adr/_adr-template.md +31 -0
- package/ai-docs/contact-center-spec.md +341 -0
- package/ai-docs/features/generated-spec-conformance-fidelity-remediation/spec/feature-spec.md +117 -0
- package/ai-docs/features/residual-warning-coverage-completion/spec/feature-spec.md +203 -0
- package/ai-docs/features/validator-code-fidelity-drift-fix/spec/feature-spec.md +315 -0
- package/ai-docs/patterns/event-driven-patterns.md +485 -0
- package/ai-docs/patterns/testing-patterns.md +480 -0
- package/ai-docs/patterns/typescript-patterns.md +365 -0
- package/ai-docs/templates/README.md +102 -0
- package/ai-docs/templates/documentation/create-agents-md.md +240 -0
- package/ai-docs/templates/documentation/create-architecture-md.md +295 -0
- package/ai-docs/templates/existing-service/bug-fix.md +254 -0
- package/ai-docs/templates/existing-service/feature-enhancement.md +450 -0
- package/ai-docs/templates/new-method/00-master.md +80 -0
- package/ai-docs/templates/new-method/01-requirements.md +232 -0
- package/ai-docs/templates/new-method/02-implementation.md +295 -0
- package/ai-docs/templates/new-method/03-tests.md +201 -0
- package/ai-docs/templates/new-method/04-validation.md +141 -0
- package/ai-docs/templates/new-service/00-master.md +109 -0
- package/ai-docs/templates/new-service/01-pre-questions.md +159 -0
- package/ai-docs/templates/new-service/02-code-generation.md +346 -0
- package/ai-docs/templates/new-service/03-integration.md +178 -0
- package/ai-docs/templates/new-service/04-test-generation.md +205 -0
- package/ai-docs/templates/new-service/05-validation.md +145 -0
- package/dist/cc.js +379 -50
- package/dist/cc.js.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +22 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js +27 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +114 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +32 -3
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +318 -0
- package/dist/services/ApiAiAssistant.js.map +1 -0
- package/dist/services/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/agent/types.js.map +1 -1
- package/dist/services/config/Util.js +8 -4
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +35 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +41 -2
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +66 -8
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/constants.js +27 -1
- package/dist/services/constants.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +122 -25
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +92 -17
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +22 -6
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/connection-service.js +3 -1
- package/dist/services/core/websocket/connection-service.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +6 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +688 -0
- package/dist/services/task/Task.js.map +1 -0
- package/dist/services/task/TaskFactory.js +45 -0
- package/dist/services/task/TaskFactory.js.map +1 -0
- package/dist/services/task/TaskManager.js +751 -457
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +220 -23
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +23 -2
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +129 -0
- package/dist/services/task/dialer.js.map +1 -1
- package/dist/services/task/digital/Digital.js +77 -0
- package/dist/services/task/digital/Digital.js.map +1 -0
- package/dist/services/task/state-machine/TaskStateMachine.js +873 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +567 -0
- package/dist/services/task/state-machine/actions.js.map +1 -0
- package/dist/services/task/state-machine/constants.js +161 -0
- package/dist/services/task/state-machine/constants.js.map +1 -0
- package/dist/services/task/state-machine/guards.js +382 -0
- package/dist/services/task/state-machine/guards.js.map +1 -0
- package/dist/services/task/state-machine/index.js +53 -0
- package/dist/services/task/state-machine/index.js.map +1 -0
- package/dist/services/task/state-machine/types.js +54 -0
- package/dist/services/task/state-machine/types.js.map +1 -0
- package/dist/services/task/state-machine/uiControlsComputer.js +603 -0
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -0
- package/dist/services/task/taskDataNormalizer.js +99 -0
- package/dist/services/task/taskDataNormalizer.js.map +1 -0
- package/dist/services/task/types.js +227 -4
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1044 -0
- package/dist/services/task/voice/Voice.js.map +1 -0
- package/dist/services/task/voice/WebRTC.js +149 -0
- package/dist/services/task/voice/WebRTC.js.map +1 -0
- package/dist/types/cc.d.ts +894 -0
- package/dist/types/config.d.ts +72 -0
- package/dist/types/constants.d.ts +66 -0
- package/dist/types/index.d.ts +199 -0
- package/dist/types/logger-proxy.d.ts +71 -0
- package/dist/types/metrics/MetricsManager.d.ts +223 -0
- package/dist/types/metrics/behavioral-events.d.ts +29 -0
- package/dist/types/metrics/constants.d.ts +181 -0
- package/dist/types/services/AddressBook.d.ts +74 -0
- package/dist/types/services/ApiAiAssistant.d.ts +49 -0
- package/dist/types/services/EntryPoint.d.ts +67 -0
- package/dist/types/services/Queue.d.ts +76 -0
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/WebCallingService.d.ts +1 -0
- package/dist/types/services/agent/index.d.ts +46 -0
- package/dist/types/services/agent/types.d.ts +413 -0
- package/dist/types/services/config/Util.d.ts +20 -0
- package/dist/types/services/config/constants.d.ts +270 -0
- package/dist/types/services/config/index.d.ts +177 -0
- package/dist/types/services/config/types.d.ts +1368 -0
- package/dist/types/services/constants.d.ts +110 -0
- package/dist/types/services/core/Err.d.ts +125 -0
- package/dist/types/services/core/GlobalTypes.d.ts +58 -0
- package/dist/types/services/core/Utils.d.ts +121 -0
- package/dist/types/services/core/WebexRequest.d.ts +22 -0
- package/dist/types/services/core/aqm-reqs.d.ts +65 -0
- package/dist/types/services/core/constants.d.ts +99 -0
- package/dist/types/services/core/types.d.ts +47 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +36 -0
- package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
- package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
- package/dist/types/services/core/websocket/types.d.ts +37 -0
- package/dist/types/services/index.d.ts +54 -0
- package/dist/types/services/task/AutoWrapup.d.ts +40 -0
- package/dist/types/services/task/Task.d.ts +157 -0
- package/dist/types/services/task/TaskFactory.d.ts +12 -0
- package/dist/types/services/task/TaskManager.d.ts +1 -0
- package/dist/types/services/task/TaskUtils.d.ts +138 -0
- package/dist/types/services/task/constants.d.ts +91 -0
- package/dist/types/services/task/contact.d.ts +69 -0
- package/dist/types/services/task/dialer.d.ts +73 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1194 -0
- package/dist/types/services/task/state-machine/actions.d.ts +10 -0
- package/dist/types/services/task/state-machine/constants.d.ts +107 -0
- package/dist/types/services/task/state-machine/guards.d.ts +102 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +269 -0
- package/dist/types/services/task/state-machine/uiControlsComputer.d.ts +9 -0
- package/dist/types/services/task/taskDataNormalizer.d.ts +10 -0
- package/dist/types/services/task/types.d.ts +1856 -0
- package/dist/types/services/task/voice/Voice.d.ts +184 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- package/dist/types/types.d.ts +778 -0
- package/dist/types/utils/PageCache.d.ts +173 -0
- package/dist/types/webex-config.d.ts +53 -0
- package/dist/types/webex.d.ts +8 -0
- package/dist/types.js +130 -1
- package/dist/types.js.map +1 -1
- package/dist/webex.js +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +16 -12
- package/src/cc.ts +477 -51
- package/src/config.ts +6 -0
- package/src/constants.ts +21 -1
- package/src/index.ts +24 -5
- package/src/metrics/ai-docs/AGENTS.md +350 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
- package/src/metrics/ai-docs/metrics-spec.md +854 -0
- package/src/metrics/behavioral-events.ts +120 -0
- package/src/metrics/constants.ts +37 -3
- package/src/services/ApiAiAssistant.ts +412 -0
- package/src/services/UserPreference.ts +509 -0
- package/src/services/agent/ai-docs/AGENTS.md +240 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
- package/src/services/agent/ai-docs/agent-spec.md +504 -0
- package/src/services/agent/types.ts +1 -1
- package/src/services/ai-docs/AGENTS.md +386 -0
- package/src/services/ai-docs/services-spec.md +492 -0
- package/src/services/config/Util.ts +10 -2
- package/src/services/config/ai-docs/AGENTS.md +255 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
- package/src/services/config/ai-docs/config-spec.md +669 -0
- package/src/services/config/constants.ts +37 -1
- package/src/services/config/index.ts +45 -1
- package/src/services/config/types.ts +241 -11
- package/src/services/constants.ts +29 -0
- package/src/services/core/Err.ts +3 -0
- package/src/services/core/Utils.ts +143 -30
- package/src/services/core/ai-docs/AGENTS.md +381 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +698 -0
- package/src/services/core/ai-docs/core-spec.md +783 -0
- package/src/services/core/aqm-reqs.ts +100 -22
- package/src/services/core/websocket/WebSocketManager.ts +23 -6
- package/src/services/core/websocket/connection-service.ts +5 -1
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +4 -0
- package/src/services/task/Task.ts +837 -0
- package/src/services/task/TaskFactory.ts +55 -0
- package/src/services/task/TaskManager.ts +793 -521
- package/src/services/task/TaskUtils.ts +314 -24
- package/src/services/task/ai-docs/AGENTS.md +457 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +594 -0
- package/src/services/task/ai-docs/task-spec.md +1319 -0
- package/src/services/task/constants.ts +23 -0
- package/src/services/task/dialer.ts +136 -1
- package/src/services/task/digital/Digital.ts +95 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1166 -0
- package/src/services/task/state-machine/actions.ts +738 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +458 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1137 -0
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2177 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +445 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +243 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +961 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +734 -71
- package/src/services/task/voice/Voice.ts +1270 -0
- package/src/services/task/voice/WebRTC.ts +187 -0
- package/src/types.ts +205 -2
- package/src/utils/AGENTS.md +278 -0
- package/src/utils/ai-docs/utils-spec.md +381 -0
- package/src/webex.js +2 -0
- package/test/unit/spec/cc.ts +503 -43
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +273 -0
- package/test/unit/spec/services/UserPreference.ts +401 -0
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/config/index.ts +85 -29
- package/test/unit/spec/services/core/Utils.ts +481 -2
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +137 -41
- package/test/unit/spec/services/core/websocket/connection-service.ts +3 -1
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +477 -0
- package/test/unit/spec/services/task/TaskFactory.ts +62 -0
- package/test/unit/spec/services/task/TaskManager.ts +1001 -1003
- package/test/unit/spec/services/task/TaskUtils.ts +235 -0
- package/test/unit/spec/services/task/dialer.ts +372 -96
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +2651 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +637 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2663 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +649 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
- package/dist/services/task/index.js +0 -1525
- package/dist/services/task/index.js.map +0 -1
- package/src/services/task/index.ts +0 -1801
- package/test/unit/spec/services/task/index.ts +0 -2184
package/dist/cc.js
CHANGED
|
@@ -22,9 +22,11 @@ var _WebCallingService = _interopRequireDefault(require("./services/WebCallingSe
|
|
|
22
22
|
var _types4 = require("./services/task/types");
|
|
23
23
|
var _MetricsManager = _interopRequireDefault(require("./metrics/MetricsManager"));
|
|
24
24
|
var _constants4 = require("./metrics/constants");
|
|
25
|
-
var _EntryPoint =
|
|
26
|
-
var _AddressBook =
|
|
27
|
-
var _Queue =
|
|
25
|
+
var _EntryPoint = require("./services/EntryPoint");
|
|
26
|
+
var _AddressBook = require("./services/AddressBook");
|
|
27
|
+
var _Queue = require("./services/Queue");
|
|
28
|
+
var _ApiAiAssistant = require("./services/ApiAiAssistant");
|
|
29
|
+
var _UserPreference = require("./services/UserPreference");
|
|
28
30
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
29
31
|
/**
|
|
30
32
|
* @module CCPlugin
|
|
@@ -84,6 +86,7 @@ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e
|
|
|
84
86
|
* - `task:established` - Task/call has been connected
|
|
85
87
|
* - `task:ended` - Task/call has ended
|
|
86
88
|
* - `task:error` - An error occurred during task handling
|
|
89
|
+
* - `task:campaignPreviewReservation` - Campaign preview contact offered to agent
|
|
87
90
|
*
|
|
88
91
|
* @public
|
|
89
92
|
*
|
|
@@ -272,6 +275,42 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
272
275
|
* ```
|
|
273
276
|
*/
|
|
274
277
|
|
|
278
|
+
/**
|
|
279
|
+
* API instance for managing Webex Contact Center user preferences
|
|
280
|
+
* Provides functionality to get, create, update, and delete user preferences
|
|
281
|
+
* @type {UserPreference}
|
|
282
|
+
* @public
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* const cc = webex.cc;
|
|
286
|
+
* await cc.register();
|
|
287
|
+
* await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
|
|
288
|
+
*
|
|
289
|
+
* // Get user preferences for current user
|
|
290
|
+
* const preferences = await cc.userPreference.getUserPreference();
|
|
291
|
+
*
|
|
292
|
+
* // Create new user preferences
|
|
293
|
+
* const newPrefs = await cc.userPreference.createUserPreference({
|
|
294
|
+
* userId: 'user123',
|
|
295
|
+
* preferences: { e911Reminder: true }
|
|
296
|
+
* });
|
|
297
|
+
*
|
|
298
|
+
* // Update user preferences
|
|
299
|
+
* const updatedPrefs = await cc.userPreference.updateUserPreference('user123', {
|
|
300
|
+
* preferences: { e911Reminder: false }
|
|
301
|
+
* });
|
|
302
|
+
*
|
|
303
|
+
* // Delete user preferences
|
|
304
|
+
* await cc.userPreference.deleteUserPreference('user123');
|
|
305
|
+
* ```
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* API instance for AI Assistant operations such as transcript controls.
|
|
310
|
+
* @type {ApiAIAssistant}
|
|
311
|
+
* @public
|
|
312
|
+
*/
|
|
313
|
+
|
|
275
314
|
/**
|
|
276
315
|
* Logger utility for Contact Center plugin
|
|
277
316
|
* Provides consistent logging across the plugin
|
|
@@ -293,6 +332,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
293
332
|
this.$webex.once(_constants.READY, () => {
|
|
294
333
|
// @ts-ignore
|
|
295
334
|
this.$config = this.config;
|
|
335
|
+
this.validatePluginConfig();
|
|
296
336
|
|
|
297
337
|
/**
|
|
298
338
|
* This is used for handling the async requests by sending webex.request and wait for corresponding websocket event.
|
|
@@ -304,21 +344,20 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
304
344
|
webex: this.$webex,
|
|
305
345
|
connectionConfig: this.getConnectionConfig()
|
|
306
346
|
});
|
|
307
|
-
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
|
|
308
347
|
this.webCallingService = new _WebCallingService.default(this.$webex);
|
|
348
|
+
this.apiAIAssistant = new _ApiAiAssistant.ApiAIAssistant(this.$webex);
|
|
309
349
|
this.metricsManager = _MetricsManager.default.getInstance({
|
|
310
350
|
webex: this.$webex
|
|
311
351
|
});
|
|
312
|
-
this.taskManager = _TaskManager.default.getTaskManager(this.services.contact, this.webCallingService, this.services.webSocketManager);
|
|
352
|
+
this.taskManager = _TaskManager.default.getTaskManager(this.apiAIAssistant, this.services.contact, this.webCallingService, this.services.webSocketManager, this.services.rtdWebSocketManager);
|
|
313
353
|
this.incomingTaskListener();
|
|
314
354
|
|
|
315
355
|
// Initialize API instances
|
|
316
356
|
// will have future function for indivdual fetch etc so better be in an object
|
|
317
|
-
this.entryPoint = new _EntryPoint.
|
|
318
|
-
this.addressBook = new _AddressBook.
|
|
319
|
-
this.queue = new _Queue.
|
|
320
|
-
|
|
321
|
-
// Initialize logger
|
|
357
|
+
this.entryPoint = new _EntryPoint.EntryPoint(this.$webex);
|
|
358
|
+
this.addressBook = new _AddressBook.AddressBook(this.$webex, () => this.agentConfig?.addressBookId);
|
|
359
|
+
this.queue = new _Queue.Queue(this.$webex);
|
|
360
|
+
this.userPreference = new _UserPreference.UserPreference(this.$webex, () => this.agentConfig?.agentId);
|
|
322
361
|
_loggerProxy.default.initialize(this.$webex.logger);
|
|
323
362
|
});
|
|
324
363
|
}
|
|
@@ -343,6 +382,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
343
382
|
this.trigger(_types4.TASK_EVENTS.TASK_HYDRATE, task);
|
|
344
383
|
};
|
|
345
384
|
|
|
385
|
+
/**
|
|
386
|
+
* Handles multi-login hydrate events for SDK instances without Mobius registration
|
|
387
|
+
* @private
|
|
388
|
+
* @param {ITask} task The task object associated with the multi-login hydrate
|
|
389
|
+
*/
|
|
390
|
+
handleTaskMultiLoginHydrate = task => {
|
|
391
|
+
// @ts-ignore
|
|
392
|
+
this.trigger(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, task);
|
|
393
|
+
};
|
|
394
|
+
|
|
346
395
|
/**
|
|
347
396
|
* Handles task merged events when tasks are combined eg: EPDN merge/transfer
|
|
348
397
|
* @private
|
|
@@ -353,6 +402,19 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
353
402
|
this.trigger(_types4.TASK_EVENTS.TASK_MERGED, task);
|
|
354
403
|
};
|
|
355
404
|
|
|
405
|
+
/**
|
|
406
|
+
* Handles campaign preview reservation events when a contact is offered to the agent
|
|
407
|
+
* @private
|
|
408
|
+
* @param {ITask} task The campaign reservation task
|
|
409
|
+
*/
|
|
410
|
+
handleCampaignPreviewReservation = task => {
|
|
411
|
+
// @ts-ignore
|
|
412
|
+
this.trigger(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, task);
|
|
413
|
+
};
|
|
414
|
+
handleRTDWebsocketMessage = event => {
|
|
415
|
+
this.taskManager.handleRealtimeWebsocketEvent(event);
|
|
416
|
+
};
|
|
417
|
+
|
|
356
418
|
/**
|
|
357
419
|
* Sets up event listeners for incoming tasks and task hydration
|
|
358
420
|
* Subscribes to task events from the task manager
|
|
@@ -361,7 +423,9 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
361
423
|
incomingTaskListener() {
|
|
362
424
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
363
425
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
|
|
426
|
+
this.taskManager.on(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, this.handleTaskMultiLoginHydrate);
|
|
364
427
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_MERGED, this.handleTaskMerged);
|
|
428
|
+
this.taskManager.on(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, this.handleCampaignPreviewReservation);
|
|
365
429
|
}
|
|
366
430
|
|
|
367
431
|
/**
|
|
@@ -401,13 +465,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
401
465
|
* ```
|
|
402
466
|
*/
|
|
403
467
|
async register() {
|
|
404
|
-
_loggerProxy.default.
|
|
468
|
+
_loggerProxy.default.log('Starting CC SDK registration', {
|
|
405
469
|
module: _constants.CC_FILE,
|
|
406
470
|
method: _constants.METHODS.REGISTER
|
|
407
471
|
});
|
|
408
472
|
try {
|
|
409
473
|
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_SUCCESS, _constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_FAILED]);
|
|
410
474
|
this.setupEventListeners();
|
|
475
|
+
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
|
|
411
476
|
const resp = await this.connectWebsocket();
|
|
412
477
|
// Ensure 'dn' is always populated from 'defaultDn'
|
|
413
478
|
resp.dn = resp.defaultDn;
|
|
@@ -470,8 +535,11 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
470
535
|
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WEBSOCKET_DEREGISTER_SUCCESS, _constants4.METRIC_EVENT_NAMES.WEBSOCKET_DEREGISTER_FAIL]);
|
|
471
536
|
this.taskManager.off(_types4.TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
472
537
|
this.taskManager.off(_types4.TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
|
|
538
|
+
this.taskManager.off(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, this.handleTaskMultiLoginHydrate);
|
|
539
|
+
this.taskManager.off(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, this.handleCampaignPreviewReservation);
|
|
473
540
|
this.taskManager.unregisterIncomingCallEvent();
|
|
474
541
|
this.services.webSocketManager.off('message', this.handleWebsocketMessage);
|
|
542
|
+
this.services.rtdWebSocketManager.off('message', this.handleRTDWebsocketMessage);
|
|
475
543
|
this.services.connectionService.off('connectionLost', this.handleConnectionLost);
|
|
476
544
|
if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER)) {
|
|
477
545
|
if (this.$webex.internal.mercury.connected) {
|
|
@@ -489,6 +557,12 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
489
557
|
if (!this.services.webSocketManager.isSocketClosed) {
|
|
490
558
|
this.services.webSocketManager.close(false, 'Unregistering the SDK');
|
|
491
559
|
}
|
|
560
|
+
if (this.services.rtdWebSocketManager && !this.services.rtdWebSocketManager.isSocketClosed) {
|
|
561
|
+
this.services.rtdWebSocketManager.close(false, 'Unregistering the SDK');
|
|
562
|
+
}
|
|
563
|
+
if (this.services.rtdWebSocketManager && !this.services.rtdWebSocketManager.isSocketClosed) {
|
|
564
|
+
this.services.rtdWebSocketManager.close(false, 'Unregistering the RTD websocket');
|
|
565
|
+
}
|
|
492
566
|
|
|
493
567
|
// Clear any cached agent configuration
|
|
494
568
|
this.agentConfig = null;
|
|
@@ -590,13 +664,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
590
664
|
* @private
|
|
591
665
|
*/
|
|
592
666
|
async connectWebsocket() {
|
|
593
|
-
_loggerProxy.default.
|
|
667
|
+
_loggerProxy.default.log('Connecting to websocket', {
|
|
594
668
|
module: _constants.CC_FILE,
|
|
595
669
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
596
670
|
});
|
|
597
671
|
try {
|
|
598
672
|
const data = await this.services.webSocketManager.initWebSocket({
|
|
599
|
-
body: this.getConnectionConfig()
|
|
673
|
+
body: this.getConnectionConfig(),
|
|
674
|
+
resource: _constants3.SUBSCRIBE_API
|
|
600
675
|
});
|
|
601
676
|
const agentId = data.agentId;
|
|
602
677
|
const orgId = this.$webex.credentials.getOrgId();
|
|
@@ -605,12 +680,46 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
605
680
|
module: _constants.CC_FILE,
|
|
606
681
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
607
682
|
});
|
|
608
|
-
|
|
683
|
+
const configFlags = {
|
|
684
|
+
isEndTaskEnabled: this.agentConfig.isEndTaskEnabled,
|
|
685
|
+
isEndConsultEnabled: this.agentConfig.isEndConsultEnabled,
|
|
686
|
+
webRtcEnabled: this.agentConfig.webRtcEnabled,
|
|
687
|
+
autoWrapup: this.agentConfig.wrapUpData?.wrapUpProps?.autoWrapup ?? false,
|
|
688
|
+
aiFeature: this.agentConfig.aiFeature
|
|
689
|
+
};
|
|
690
|
+
this.taskManager.setConfigFlags(configFlags);
|
|
609
691
|
// TODO: Make profile a singleton to make it available throughout app/sdk so we dont need to inject info everywhere
|
|
610
692
|
this.taskManager.setWrapupData(this.agentConfig.wrapUpData);
|
|
611
693
|
this.taskManager.setAgentId(this.agentConfig.agentId);
|
|
612
694
|
this.taskManager.setWebRtcEnabled(this.agentConfig.webRtcEnabled);
|
|
613
|
-
|
|
695
|
+
this.apiAIAssistant.setAIFeatureFlags(this.agentConfig.aiFeature);
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* RTD websocket currently supports realtime transcripts and suggested responses.
|
|
699
|
+
* Extend this condition when additional AI RTD features are introduced.
|
|
700
|
+
*/
|
|
701
|
+
if (this.agentConfig.aiFeature?.realtimeTranscripts?.enable || this.agentConfig.aiFeature?.suggestedResponses?.enable) {
|
|
702
|
+
_loggerProxy.default.info('Connecting to RTD websocket', {
|
|
703
|
+
module: _constants.CC_FILE,
|
|
704
|
+
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
705
|
+
});
|
|
706
|
+
this.services.rtdWebSocketManager.initWebSocket({
|
|
707
|
+
body: this.getConnectionConfig(),
|
|
708
|
+
resource: _constants3.RTD_SUBSCRIBE_API
|
|
709
|
+
}).then(() => {
|
|
710
|
+
_loggerProxy.default.log('RTD websocket connected successfully', {
|
|
711
|
+
module: _constants.CC_FILE,
|
|
712
|
+
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
713
|
+
});
|
|
714
|
+
this.services.rtdWebSocketManager.on('message', this.handleRTDWebsocketMessage);
|
|
715
|
+
}).catch(error => {
|
|
716
|
+
_loggerProxy.default.error(`Error connecting to RTD websocket ${error}`, {
|
|
717
|
+
module: _constants.CC_FILE,
|
|
718
|
+
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
719
|
+
});
|
|
720
|
+
});
|
|
721
|
+
}
|
|
722
|
+
if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER) && !this.isWebRTCRegistrationDisabled()) {
|
|
614
723
|
try {
|
|
615
724
|
await this.$webex.internal.mercury.connect();
|
|
616
725
|
_loggerProxy.default.log('Authentication: webex.internal.mercury.connect successful', {
|
|
@@ -623,9 +732,19 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
623
732
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
624
733
|
});
|
|
625
734
|
}
|
|
735
|
+
} else if (this.isWebRTCRegistrationDisabled()) {
|
|
736
|
+
_loggerProxy.default.info('Skipping Mobius registration because disableWebRTCRegistration is enabled', {
|
|
737
|
+
module: _constants.CC_FILE,
|
|
738
|
+
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
739
|
+
});
|
|
626
740
|
}
|
|
627
741
|
if (this.$config && this.$config.allowAutomatedRelogin) {
|
|
628
742
|
await this.silentRelogin();
|
|
743
|
+
} else {
|
|
744
|
+
_loggerProxy.default.log('Skipping silent relogin: allowAutomatedRelogin is disabled', {
|
|
745
|
+
module: _constants.CC_FILE,
|
|
746
|
+
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
747
|
+
});
|
|
629
748
|
}
|
|
630
749
|
return this.agentConfig;
|
|
631
750
|
} catch (error) {
|
|
@@ -666,21 +785,27 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
666
785
|
* ```
|
|
667
786
|
*/
|
|
668
787
|
async stationLogin(data) {
|
|
669
|
-
|
|
788
|
+
const loggerContext = {
|
|
670
789
|
module: _constants.CC_FILE,
|
|
671
790
|
method: _constants.METHODS.STATION_LOGIN
|
|
672
|
-
}
|
|
791
|
+
};
|
|
673
792
|
try {
|
|
793
|
+
_loggerProxy.default.log(`Starting agent station login | loginOption: ${data?.loginOption} teamId: ${data?.teamId}`, loggerContext);
|
|
674
794
|
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, _constants4.METRIC_EVENT_NAMES.STATION_LOGIN_FAILED]);
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
data: {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
795
|
+
const dialPlanEntries = this.agentConfig?.dialPlan?.dialPlanEntity ?? [];
|
|
796
|
+
if (data.loginOption === _types.LoginOption.AGENT_DN) {
|
|
797
|
+
_loggerProxy.default.log(`Validating dial number | dialPlanEnabled: ${!!this.agentConfig?.dialPlan} | dialPlanEntryCount: ${dialPlanEntries.length}`, loggerContext);
|
|
798
|
+
if (!(0, _Utils.isValidDialNumber)(data.dialNumber, dialPlanEntries)) {
|
|
799
|
+
_loggerProxy.default.log(`Dial number validation failed | dialNumber: ${data.dialNumber} | dialPlanEntryCount: ${dialPlanEntries.length}`, loggerContext);
|
|
800
|
+
const error = new Error('INVALID_DIAL_NUMBER');
|
|
801
|
+
// @ts-ignore - adding custom key to the error object
|
|
802
|
+
error.details = {
|
|
803
|
+
data: {
|
|
804
|
+
reason: 'INVALID_DIAL_NUMBER'
|
|
805
|
+
}
|
|
806
|
+
};
|
|
807
|
+
throw error;
|
|
808
|
+
}
|
|
684
809
|
}
|
|
685
810
|
const loginResponse = await this.services.agent.stationLogin({
|
|
686
811
|
data: {
|
|
@@ -696,8 +821,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
696
821
|
auxCodeId: _constants.EMPTY_STRING
|
|
697
822
|
}
|
|
698
823
|
});
|
|
699
|
-
if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER) {
|
|
824
|
+
if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER && !this.isWebRTCRegistrationDisabled()) {
|
|
700
825
|
await this.webCallingService.registerWebCallingLine();
|
|
826
|
+
} else if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER && this.isWebRTCRegistrationDisabled()) {
|
|
827
|
+
_loggerProxy.default.info('Skipping web calling line registration because disableWebRTCRegistration is enabled', {
|
|
828
|
+
module: _constants.CC_FILE,
|
|
829
|
+
method: _constants.METHODS.STATION_LOGIN
|
|
830
|
+
});
|
|
701
831
|
}
|
|
702
832
|
const resp = await loginResponse;
|
|
703
833
|
const {
|
|
@@ -1021,6 +1151,25 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1021
1151
|
}
|
|
1022
1152
|
};
|
|
1023
1153
|
|
|
1154
|
+
/**
|
|
1155
|
+
* Checks whether Mobius/WebRTC registration should be skipped by config
|
|
1156
|
+
* @returns {boolean} True when browser WebRTC registration is disabled
|
|
1157
|
+
* @private
|
|
1158
|
+
*/
|
|
1159
|
+
isWebRTCRegistrationDisabled() {
|
|
1160
|
+
return this.$config?.disableWebRTCRegistration === true;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
/**
|
|
1164
|
+
* Validates contact-center plugin configuration before service initialization
|
|
1165
|
+
* @private
|
|
1166
|
+
*/
|
|
1167
|
+
validatePluginConfig() {
|
|
1168
|
+
if (this.$config?.disableWebRTCRegistration === true && this.$config?.allowMultiLogin === false) {
|
|
1169
|
+
throw new Error('Invalid Contact Center configuration: disableWebRTCRegistration cannot be true when allowMultiLogin is false. Enable allowMultiLogin or allow WebRTC registration so an SDK instance can receive Mobius/WebRTC task events.');
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1024
1173
|
/**
|
|
1025
1174
|
* Initializes event listeners for the Contact Center service
|
|
1026
1175
|
* Sets up handlers for connection state changes and other core events
|
|
@@ -1052,13 +1201,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1052
1201
|
async handleConnectionLost(msg) {
|
|
1053
1202
|
if (msg.isConnectionLost) {
|
|
1054
1203
|
// TODO: Emit an event saying connection is lost
|
|
1055
|
-
_loggerProxy.default.
|
|
1204
|
+
_loggerProxy.default.log('event=handleConnectionLost | Connection lost', {
|
|
1056
1205
|
module: _constants.CC_FILE,
|
|
1057
1206
|
method: _constants.METHODS.HANDLE_CONNECTION_LOST
|
|
1058
1207
|
});
|
|
1059
1208
|
} else if (msg.isSocketReconnected) {
|
|
1060
1209
|
// TODO: Emit an event saying connection is re-estabilished
|
|
1061
|
-
_loggerProxy.default.
|
|
1210
|
+
_loggerProxy.default.log('event=handleConnectionReconnect | Connection reconnected attempting to request silent relogin', {
|
|
1062
1211
|
module: _constants.CC_FILE,
|
|
1063
1212
|
method: _constants.METHODS.HANDLE_CONNECTION_LOST
|
|
1064
1213
|
});
|
|
@@ -1073,7 +1222,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1073
1222
|
* @private
|
|
1074
1223
|
*/
|
|
1075
1224
|
async silentRelogin() {
|
|
1076
|
-
_loggerProxy.default.
|
|
1225
|
+
_loggerProxy.default.log('Starting silent relogin process', {
|
|
1077
1226
|
module: _constants.CC_FILE,
|
|
1078
1227
|
method: _constants.METHODS.SILENT_RELOGIN
|
|
1079
1228
|
});
|
|
@@ -1095,7 +1244,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1095
1244
|
this.agentConfig.currentTeamId = reLoginResponse.data.teamId;
|
|
1096
1245
|
await this.handleDeviceType(deviceType, dn);
|
|
1097
1246
|
if (lastStateChangeReason === 'agent-wss-disconnect') {
|
|
1098
|
-
_loggerProxy.default.
|
|
1247
|
+
_loggerProxy.default.log('event=requestAutoStateChange | Requesting state change to available on socket reconnect', {
|
|
1099
1248
|
module: _constants.CC_FILE,
|
|
1100
1249
|
method: _constants.METHODS.SILENT_RELOGIN
|
|
1101
1250
|
});
|
|
@@ -1119,8 +1268,6 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1119
1268
|
}
|
|
1120
1269
|
this.agentConfig.lastStateAuxCodeId = auxCodeId;
|
|
1121
1270
|
this.agentConfig.isAgentLoggedIn = true;
|
|
1122
|
-
// TODO: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-626777 Implement the de-register method and close the listener there
|
|
1123
|
-
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
|
|
1124
1271
|
_loggerProxy.default.log(`Silent relogin process completed successfully with login Option: ${reLoginResponse.data.deviceType} teamId: ${reLoginResponse.data.teamId}`, {
|
|
1125
1272
|
module: _constants.CC_FILE,
|
|
1126
1273
|
method: _constants.METHODS.SILENT_RELOGIN,
|
|
@@ -1155,6 +1302,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1155
1302
|
this.agentConfig.deviceType = deviceType;
|
|
1156
1303
|
switch (deviceType) {
|
|
1157
1304
|
case _types.LoginOption.BROWSER:
|
|
1305
|
+
if (this.isWebRTCRegistrationDisabled()) {
|
|
1306
|
+
_loggerProxy.default.info('Skipping web calling line registration because disableWebRTCRegistration is enabled', {
|
|
1307
|
+
module: _constants.CC_FILE,
|
|
1308
|
+
method: _constants.METHODS.HANDLE_DEVICE_TYPE
|
|
1309
|
+
});
|
|
1310
|
+
break;
|
|
1311
|
+
}
|
|
1158
1312
|
try {
|
|
1159
1313
|
await this.webCallingService.registerWebCallingLine();
|
|
1160
1314
|
} catch (error) {
|
|
@@ -1336,6 +1490,196 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1336
1490
|
}
|
|
1337
1491
|
}
|
|
1338
1492
|
|
|
1493
|
+
/**
|
|
1494
|
+
* Accepts a campaign preview contact, initiating the outbound call.
|
|
1495
|
+
*
|
|
1496
|
+
* When a campaign manager reserves a contact for an agent, the agent receives an
|
|
1497
|
+
* `AgentOfferCampaignReservation` event. The agent can then accept the preview contact
|
|
1498
|
+
* to initiate the outbound call.
|
|
1499
|
+
*
|
|
1500
|
+
* @param {PreviewContactPayload} payload - The preview contact payload containing interactionId and campaignId (campaign name, not UUID).
|
|
1501
|
+
* @returns {Promise<TaskResponse>} Promise resolving with agent contact on success.
|
|
1502
|
+
* @throws {Error} If the operation fails (network error, customer unavailable, etc.)
|
|
1503
|
+
*
|
|
1504
|
+
* @example
|
|
1505
|
+
* ```typescript
|
|
1506
|
+
* webex.cc.on('task:campaignPreviewReservation', async (task) => {
|
|
1507
|
+
* const { interactionId } = task.data;
|
|
1508
|
+
* // campaignId is the campaign name (e.g. "MyCampaign"), not a UUID
|
|
1509
|
+
* const campaignId = task.data.interaction.callProcessingDetails.campaignId;
|
|
1510
|
+
*
|
|
1511
|
+
* const result = await webex.cc.acceptPreviewContact({ interactionId, campaignId });
|
|
1512
|
+
* });
|
|
1513
|
+
* ```
|
|
1514
|
+
*/
|
|
1515
|
+
async acceptPreviewContact(payload) {
|
|
1516
|
+
_loggerProxy.default.info('Accepting campaign preview contact', {
|
|
1517
|
+
module: _constants.CC_FILE,
|
|
1518
|
+
method: _constants.METHODS.ACCEPT_PREVIEW_CONTACT
|
|
1519
|
+
});
|
|
1520
|
+
try {
|
|
1521
|
+
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS, _constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED]);
|
|
1522
|
+
const result = await this.services.dialer.acceptPreviewContact({
|
|
1523
|
+
data: payload
|
|
1524
|
+
});
|
|
1525
|
+
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS, {
|
|
1526
|
+
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result),
|
|
1527
|
+
interactionId: payload.interactionId,
|
|
1528
|
+
campaignId: payload.campaignId
|
|
1529
|
+
}, ['behavioral', 'business', 'operational']);
|
|
1530
|
+
_loggerProxy.default.log('Campaign preview contact accepted successfully', {
|
|
1531
|
+
module: _constants.CC_FILE,
|
|
1532
|
+
method: _constants.METHODS.ACCEPT_PREVIEW_CONTACT,
|
|
1533
|
+
trackingId: result.trackingId,
|
|
1534
|
+
interactionId: payload.interactionId
|
|
1535
|
+
});
|
|
1536
|
+
return result;
|
|
1537
|
+
} catch (error) {
|
|
1538
|
+
const failure = error.details;
|
|
1539
|
+
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED, {
|
|
1540
|
+
..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failure),
|
|
1541
|
+
interactionId: payload.interactionId,
|
|
1542
|
+
campaignId: payload.campaignId
|
|
1543
|
+
}, ['behavioral', 'business', 'operational']);
|
|
1544
|
+
const {
|
|
1545
|
+
error: detailedError
|
|
1546
|
+
} = (0, _Utils.getErrorDetails)(error, _constants.METHODS.ACCEPT_PREVIEW_CONTACT, _constants.CC_FILE);
|
|
1547
|
+
throw detailedError;
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
/**
|
|
1552
|
+
* Skips a campaign preview contact, requesting the next contact from the campaign.
|
|
1553
|
+
*
|
|
1554
|
+
* When a campaign manager reserves a contact for an agent, the agent receives an
|
|
1555
|
+
* `AgentOfferCampaignReservation` event. Instead of accepting, the agent can skip the
|
|
1556
|
+
* preview contact to move to the next contact in the campaign.
|
|
1557
|
+
*
|
|
1558
|
+
* @param {PreviewContactPayload} payload - The preview contact payload containing interactionId and campaignId (campaign name, not UUID).
|
|
1559
|
+
* @returns {Promise<TaskResponse>} Promise resolving with agent contact on success.
|
|
1560
|
+
* @throws {Error} If the operation fails (network error, etc.)
|
|
1561
|
+
*
|
|
1562
|
+
* @example
|
|
1563
|
+
* ```typescript
|
|
1564
|
+
* webex.cc.on('task:campaignPreviewReservation', async (task) => {
|
|
1565
|
+
* const { interactionId } = task.data;
|
|
1566
|
+
* const campaignId = task.data.interaction.callProcessingDetails.campaignId;
|
|
1567
|
+
*
|
|
1568
|
+
* const result = await webex.cc.skipPreviewContact({ interactionId, campaignId });
|
|
1569
|
+
* });
|
|
1570
|
+
* ```
|
|
1571
|
+
*/
|
|
1572
|
+
async skipPreviewContact(payload) {
|
|
1573
|
+
const task = this.taskManager.getTask(payload.interactionId);
|
|
1574
|
+
if (task?.data?.interaction?.callProcessingDetails?.campaignPreviewSkipDisabled === 'true') {
|
|
1575
|
+
_loggerProxy.default.warn('Skip action is disabled for this campaign preview contact', {
|
|
1576
|
+
module: _constants.CC_FILE,
|
|
1577
|
+
method: _constants.METHODS.SKIP_PREVIEW_CONTACT,
|
|
1578
|
+
interactionId: payload.interactionId
|
|
1579
|
+
});
|
|
1580
|
+
throw new Error('Skip action is disabled for this campaign preview contact');
|
|
1581
|
+
}
|
|
1582
|
+
_loggerProxy.default.info('Skipping campaign preview contact', {
|
|
1583
|
+
module: _constants.CC_FILE,
|
|
1584
|
+
method: _constants.METHODS.SKIP_PREVIEW_CONTACT
|
|
1585
|
+
});
|
|
1586
|
+
try {
|
|
1587
|
+
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_SUCCESS, _constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_FAILED]);
|
|
1588
|
+
const result = await this.services.dialer.skipPreviewContact({
|
|
1589
|
+
data: payload
|
|
1590
|
+
});
|
|
1591
|
+
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_SUCCESS, {
|
|
1592
|
+
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result),
|
|
1593
|
+
interactionId: payload.interactionId,
|
|
1594
|
+
campaignId: payload.campaignId
|
|
1595
|
+
}, ['behavioral', 'business', 'operational']);
|
|
1596
|
+
_loggerProxy.default.log('Campaign preview contact skipped successfully', {
|
|
1597
|
+
module: _constants.CC_FILE,
|
|
1598
|
+
method: _constants.METHODS.SKIP_PREVIEW_CONTACT,
|
|
1599
|
+
trackingId: result.trackingId,
|
|
1600
|
+
interactionId: payload.interactionId
|
|
1601
|
+
});
|
|
1602
|
+
return result;
|
|
1603
|
+
} catch (error) {
|
|
1604
|
+
const failure = error.details;
|
|
1605
|
+
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_FAILED, {
|
|
1606
|
+
..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failure),
|
|
1607
|
+
interactionId: payload.interactionId,
|
|
1608
|
+
campaignId: payload.campaignId
|
|
1609
|
+
}, ['behavioral', 'business', 'operational']);
|
|
1610
|
+
const {
|
|
1611
|
+
error: detailedError
|
|
1612
|
+
} = (0, _Utils.getErrorDetails)(error, _constants.METHODS.SKIP_PREVIEW_CONTACT, _constants.CC_FILE);
|
|
1613
|
+
throw detailedError;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
|
|
1617
|
+
/**
|
|
1618
|
+
* Removes a campaign preview contact from the campaign list entirely.
|
|
1619
|
+
*
|
|
1620
|
+
* When a campaign manager reserves a contact for an agent, the agent receives an
|
|
1621
|
+
* `AgentOfferCampaignReservation` event. Instead of accepting or skipping, the agent can
|
|
1622
|
+
* remove the preview contact to permanently take it out of the campaign contact list.
|
|
1623
|
+
*
|
|
1624
|
+
* @param {PreviewContactPayload} payload - The preview contact payload containing interactionId and campaignId (campaign name, not UUID).
|
|
1625
|
+
* @returns {Promise<TaskResponse>} Promise resolving with agent contact on success.
|
|
1626
|
+
* @throws {Error} If the operation fails (network error, etc.)
|
|
1627
|
+
*
|
|
1628
|
+
* @example
|
|
1629
|
+
* ```typescript
|
|
1630
|
+
* webex.cc.on('task:campaignPreviewReservation', async (task) => {
|
|
1631
|
+
* const { interactionId } = task.data;
|
|
1632
|
+
* const campaignId = task.data.interaction.callProcessingDetails.campaignId;
|
|
1633
|
+
*
|
|
1634
|
+
* const result = await webex.cc.removePreviewContact({ interactionId, campaignId });
|
|
1635
|
+
* });
|
|
1636
|
+
* ```
|
|
1637
|
+
*/
|
|
1638
|
+
async removePreviewContact(payload) {
|
|
1639
|
+
const task = this.taskManager.getTask(payload.interactionId);
|
|
1640
|
+
if (task?.data?.interaction?.callProcessingDetails?.campaignPreviewRemoveDisabled === 'true') {
|
|
1641
|
+
_loggerProxy.default.warn('Remove action is disabled for this campaign preview contact', {
|
|
1642
|
+
module: _constants.CC_FILE,
|
|
1643
|
+
method: _constants.METHODS.REMOVE_PREVIEW_CONTACT,
|
|
1644
|
+
interactionId: payload.interactionId
|
|
1645
|
+
});
|
|
1646
|
+
throw new Error('Remove action is disabled for this campaign preview contact');
|
|
1647
|
+
}
|
|
1648
|
+
_loggerProxy.default.info('Removing campaign preview contact', {
|
|
1649
|
+
module: _constants.CC_FILE,
|
|
1650
|
+
method: _constants.METHODS.REMOVE_PREVIEW_CONTACT
|
|
1651
|
+
});
|
|
1652
|
+
try {
|
|
1653
|
+
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_SUCCESS, _constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_FAILED]);
|
|
1654
|
+
const result = await this.services.dialer.removePreviewContact({
|
|
1655
|
+
data: payload
|
|
1656
|
+
});
|
|
1657
|
+
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_SUCCESS, {
|
|
1658
|
+
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(result),
|
|
1659
|
+
interactionId: payload.interactionId,
|
|
1660
|
+
campaignId: payload.campaignId
|
|
1661
|
+
}, ['behavioral', 'business', 'operational']);
|
|
1662
|
+
_loggerProxy.default.log('Campaign preview contact removed successfully', {
|
|
1663
|
+
module: _constants.CC_FILE,
|
|
1664
|
+
method: _constants.METHODS.REMOVE_PREVIEW_CONTACT,
|
|
1665
|
+
trackingId: result.trackingId,
|
|
1666
|
+
interactionId: payload.interactionId
|
|
1667
|
+
});
|
|
1668
|
+
return result;
|
|
1669
|
+
} catch (error) {
|
|
1670
|
+
const failure = error.details;
|
|
1671
|
+
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_FAILED, {
|
|
1672
|
+
..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failure),
|
|
1673
|
+
interactionId: payload.interactionId,
|
|
1674
|
+
campaignId: payload.campaignId
|
|
1675
|
+
}, ['behavioral', 'business', 'operational']);
|
|
1676
|
+
const {
|
|
1677
|
+
error: detailedError
|
|
1678
|
+
} = (0, _Utils.getErrorDetails)(error, _constants.METHODS.REMOVE_PREVIEW_CONTACT, _constants.CC_FILE);
|
|
1679
|
+
throw detailedError;
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1339
1683
|
/**
|
|
1340
1684
|
* Fetches outdial ANI (Automatic Number Identification) entries for an outdial ANI ID.
|
|
1341
1685
|
*
|
|
@@ -1467,6 +1811,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1467
1811
|
/**
|
|
1468
1812
|
* Updates the agent device type and login configuration.
|
|
1469
1813
|
* Use this method to change how an agent connects to the contact center system (e.g., switching from browser-based calling to a desk phone extension).
|
|
1814
|
+
* Change to any field of the profile is allowed;
|
|
1470
1815
|
*
|
|
1471
1816
|
* @param {AgentDeviceUpdate} data Configuration containing:
|
|
1472
1817
|
* - loginOption: New device type ('BROWSER', 'EXTENSION', 'AGENT_DN')
|
|
@@ -1500,24 +1845,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1500
1845
|
trackingId
|
|
1501
1846
|
});
|
|
1502
1847
|
try {
|
|
1503
|
-
// Only block if both loginOption AND teamId remain unchanged
|
|
1504
|
-
if (this.webCallingService?.loginOption === data.loginOption && data.teamId === this.agentConfig.currentTeamId) {
|
|
1505
|
-
const message = 'Will not proceed with device update as new Device type is same as current device type and teamId is same as current teamId';
|
|
1506
|
-
const err = new Error(message);
|
|
1507
|
-
err.details = {
|
|
1508
|
-
type: 'Identical Device Change Failure',
|
|
1509
|
-
orgId: this.$webex.credentials.getOrgId(),
|
|
1510
|
-
trackingId,
|
|
1511
|
-
data: {
|
|
1512
|
-
agentId: this.agentConfig.agentId,
|
|
1513
|
-
reasonCode: 'R002',
|
|
1514
|
-
reason: message
|
|
1515
|
-
}
|
|
1516
|
-
};
|
|
1517
|
-
throw err;
|
|
1518
|
-
}
|
|
1519
1848
|
await this.stationLogout({
|
|
1520
|
-
logoutReason: 'User requested agent
|
|
1849
|
+
logoutReason: 'User requested agent profile update'
|
|
1521
1850
|
});
|
|
1522
1851
|
const loginPayload = {
|
|
1523
1852
|
teamId: data.teamId,
|