@webex/contact-center 3.12.0-next.8 → 3.12.0-next.80
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/AGENTS.md +438 -0
- package/ai-docs/README.md +131 -0
- package/ai-docs/RULES.md +455 -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 +265 -29
- package/dist/cc.js.map +1 -1
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +16 -1
- package/dist/constants.js.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +101 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +23 -4
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/ApiAiAssistant.js +74 -3
- package/dist/services/ApiAiAssistant.js.map +1 -1
- package/dist/services/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/config/Util.js +3 -3
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +23 -2
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +49 -9
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +107 -32
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/websocket/WebSocketManager.js +2 -1
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +1 -1
- 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 +725 -526
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +162 -26
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/constants.js +9 -2
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/dialer.js +78 -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 +837 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +543 -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 +340 -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 +553 -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 +212 -4
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1042 -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 +94 -1
- package/dist/types/config.d.ts +6 -0
- package/dist/types/constants.d.ts +16 -1
- package/dist/types/index.d.ts +21 -6
- package/dist/types/metrics/constants.d.ts +19 -1
- package/dist/types/services/ApiAiAssistant.d.ts +11 -3
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/config/constants.d.ts +21 -0
- package/dist/types/services/config/types.d.ts +171 -10
- package/dist/types/services/core/Err.d.ts +4 -0
- package/dist/types/services/core/Utils.d.ts +33 -13
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +1 -0
- package/dist/types/services/core/websocket/types.d.ts +1 -1
- package/dist/types/services/index.d.ts +1 -1
- 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/TaskUtils.d.ts +46 -2
- package/dist/types/services/task/constants.d.ts +7 -0
- package/dist/types/services/task/dialer.d.ts +30 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1144 -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 +90 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +267 -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 +603 -66
- 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 +94 -0
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +85 -0
- package/dist/types.js.map +1 -1
- package/dist/webex.js +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +15 -12
- package/src/cc.ts +329 -30
- package/src/config.ts +6 -0
- package/src/constants.ts +16 -1
- package/src/index.ts +23 -5
- package/src/metrics/ai-docs/AGENTS.md +348 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +336 -0
- package/src/metrics/behavioral-events.ts +106 -0
- package/src/metrics/constants.ts +23 -4
- package/src/services/ApiAiAssistant.ts +104 -3
- package/src/services/UserPreference.ts +509 -0
- package/src/services/agent/ai-docs/AGENTS.md +238 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +302 -0
- package/src/services/ai-docs/AGENTS.md +384 -0
- package/src/services/config/Util.ts +3 -3
- package/src/services/config/ai-docs/AGENTS.md +253 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +424 -0
- package/src/services/config/constants.ts +25 -1
- package/src/services/config/types.ts +174 -11
- package/src/services/core/Err.ts +2 -0
- package/src/services/core/Utils.ts +123 -37
- package/src/services/core/ai-docs/AGENTS.md +379 -0
- package/src/services/core/ai-docs/ARCHITECTURE.md +696 -0
- package/src/services/core/websocket/WebSocketManager.ts +2 -0
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +1 -1
- package/src/services/task/Task.ts +837 -0
- package/src/services/task/TaskFactory.ts +55 -0
- package/src/services/task/TaskManager.ts +738 -613
- package/src/services/task/TaskUtils.ts +205 -25
- package/src/services/task/ai-docs/AGENTS.md +455 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +585 -0
- package/src/services/task/constants.ts +7 -0
- package/src/services/task/dialer.ts +80 -0
- package/src/services/task/digital/Digital.ts +95 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1077 -0
- package/src/services/task/state-machine/actions.ts +685 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +495 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1135 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +406 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +241 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +867 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +710 -71
- package/src/services/task/voice/Voice.ts +1267 -0
- package/src/services/task/voice/WebRTC.ts +187 -0
- package/src/types.ts +122 -2
- package/src/utils/AGENTS.md +276 -0
- package/src/webex.js +2 -0
- package/test/unit/spec/cc.ts +343 -23
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +122 -17
- 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 +30 -30
- package/test/unit/spec/services/core/Utils.ts +425 -8
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +66 -40
- 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 +832 -1702
- package/test/unit/spec/services/task/TaskUtils.ts +206 -0
- package/test/unit/spec/services/task/dialer.ts +190 -0
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +1825 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +479 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +2020 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +631 -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/dist/types/services/task/index.d.ts +0 -650
- package/src/services/task/index.ts +0 -1801
- package/test/unit/spec/services/task/index.ts +0 -2184
package/dist/cc.js
CHANGED
|
@@ -26,6 +26,7 @@ var _EntryPoint = require("./services/EntryPoint");
|
|
|
26
26
|
var _AddressBook = require("./services/AddressBook");
|
|
27
27
|
var _Queue = require("./services/Queue");
|
|
28
28
|
var _ApiAiAssistant = require("./services/ApiAiAssistant");
|
|
29
|
+
var _UserPreference = require("./services/UserPreference");
|
|
29
30
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
30
31
|
/**
|
|
31
32
|
* @module CCPlugin
|
|
@@ -274,6 +275,36 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
274
275
|
* ```
|
|
275
276
|
*/
|
|
276
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
|
+
|
|
277
308
|
/**
|
|
278
309
|
* API instance for AI Assistant operations such as transcript controls.
|
|
279
310
|
* @type {ApiAIAssistant}
|
|
@@ -301,6 +332,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
301
332
|
this.$webex.once(_constants.READY, () => {
|
|
302
333
|
// @ts-ignore
|
|
303
334
|
this.$config = this.config;
|
|
335
|
+
this.validatePluginConfig();
|
|
304
336
|
|
|
305
337
|
/**
|
|
306
338
|
* This is used for handling the async requests by sending webex.request and wait for corresponding websocket event.
|
|
@@ -312,13 +344,12 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
312
344
|
webex: this.$webex,
|
|
313
345
|
connectionConfig: this.getConnectionConfig()
|
|
314
346
|
});
|
|
315
|
-
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
|
|
316
347
|
this.webCallingService = new _WebCallingService.default(this.$webex);
|
|
317
348
|
this.apiAIAssistant = new _ApiAiAssistant.ApiAIAssistant(this.$webex);
|
|
318
349
|
this.metricsManager = _MetricsManager.default.getInstance({
|
|
319
350
|
webex: this.$webex
|
|
320
351
|
});
|
|
321
|
-
this.taskManager = _TaskManager.default.getTaskManager(this.apiAIAssistant, 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);
|
|
322
353
|
this.incomingTaskListener();
|
|
323
354
|
|
|
324
355
|
// Initialize API instances
|
|
@@ -326,6 +357,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
326
357
|
this.entryPoint = new _EntryPoint.EntryPoint(this.$webex);
|
|
327
358
|
this.addressBook = new _AddressBook.AddressBook(this.$webex, () => this.agentConfig?.addressBookId);
|
|
328
359
|
this.queue = new _Queue.Queue(this.$webex);
|
|
360
|
+
this.userPreference = new _UserPreference.UserPreference(this.$webex, () => this.agentConfig?.agentId);
|
|
329
361
|
_loggerProxy.default.initialize(this.$webex.logger);
|
|
330
362
|
});
|
|
331
363
|
}
|
|
@@ -350,6 +382,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
350
382
|
this.trigger(_types4.TASK_EVENTS.TASK_HYDRATE, task);
|
|
351
383
|
};
|
|
352
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
|
+
|
|
353
395
|
/**
|
|
354
396
|
* Handles task merged events when tasks are combined eg: EPDN merge/transfer
|
|
355
397
|
* @private
|
|
@@ -369,8 +411,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
369
411
|
// @ts-ignore
|
|
370
412
|
this.trigger(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, task);
|
|
371
413
|
};
|
|
372
|
-
handleRTDWebsocketMessage =
|
|
373
|
-
this.taskManager.handleRealtimeWebsocketEvent(
|
|
414
|
+
handleRTDWebsocketMessage = event => {
|
|
415
|
+
this.taskManager.handleRealtimeWebsocketEvent(event);
|
|
374
416
|
};
|
|
375
417
|
|
|
376
418
|
/**
|
|
@@ -381,6 +423,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
381
423
|
incomingTaskListener() {
|
|
382
424
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
383
425
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
|
|
426
|
+
this.taskManager.on(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, this.handleTaskMultiLoginHydrate);
|
|
384
427
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_MERGED, this.handleTaskMerged);
|
|
385
428
|
this.taskManager.on(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, this.handleCampaignPreviewReservation);
|
|
386
429
|
}
|
|
@@ -422,13 +465,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
422
465
|
* ```
|
|
423
466
|
*/
|
|
424
467
|
async register() {
|
|
425
|
-
_loggerProxy.default.
|
|
468
|
+
_loggerProxy.default.log('Starting CC SDK registration', {
|
|
426
469
|
module: _constants.CC_FILE,
|
|
427
470
|
method: _constants.METHODS.REGISTER
|
|
428
471
|
});
|
|
429
472
|
try {
|
|
430
473
|
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_SUCCESS, _constants4.METRIC_EVENT_NAMES.WEBSOCKET_REGISTER_FAILED]);
|
|
431
474
|
this.setupEventListeners();
|
|
475
|
+
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
|
|
432
476
|
const resp = await this.connectWebsocket();
|
|
433
477
|
// Ensure 'dn' is always populated from 'defaultDn'
|
|
434
478
|
resp.dn = resp.defaultDn;
|
|
@@ -491,6 +535,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
491
535
|
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.WEBSOCKET_DEREGISTER_SUCCESS, _constants4.METRIC_EVENT_NAMES.WEBSOCKET_DEREGISTER_FAIL]);
|
|
492
536
|
this.taskManager.off(_types4.TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
|
|
493
537
|
this.taskManager.off(_types4.TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
|
|
538
|
+
this.taskManager.off(_types4.TASK_EVENTS.TASK_MULTI_LOGIN_HYDRATE, this.handleTaskMultiLoginHydrate);
|
|
494
539
|
this.taskManager.off(_types4.TASK_EVENTS.TASK_CAMPAIGN_PREVIEW_RESERVATION, this.handleCampaignPreviewReservation);
|
|
495
540
|
this.taskManager.unregisterIncomingCallEvent();
|
|
496
541
|
this.services.webSocketManager.off('message', this.handleWebsocketMessage);
|
|
@@ -512,6 +557,9 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
512
557
|
if (!this.services.webSocketManager.isSocketClosed) {
|
|
513
558
|
this.services.webSocketManager.close(false, 'Unregistering the SDK');
|
|
514
559
|
}
|
|
560
|
+
if (this.services.rtdWebSocketManager && !this.services.rtdWebSocketManager.isSocketClosed) {
|
|
561
|
+
this.services.rtdWebSocketManager.close(false, 'Unregistering the SDK');
|
|
562
|
+
}
|
|
515
563
|
if (this.services.rtdWebSocketManager && !this.services.rtdWebSocketManager.isSocketClosed) {
|
|
516
564
|
this.services.rtdWebSocketManager.close(false, 'Unregistering the RTD websocket');
|
|
517
565
|
}
|
|
@@ -616,7 +664,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
616
664
|
* @private
|
|
617
665
|
*/
|
|
618
666
|
async connectWebsocket() {
|
|
619
|
-
_loggerProxy.default.
|
|
667
|
+
_loggerProxy.default.log('Connecting to websocket', {
|
|
620
668
|
module: _constants.CC_FILE,
|
|
621
669
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
622
670
|
});
|
|
@@ -632,18 +680,30 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
632
680
|
module: _constants.CC_FILE,
|
|
633
681
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
634
682
|
});
|
|
635
|
-
|
|
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);
|
|
636
691
|
// TODO: Make profile a singleton to make it available throughout app/sdk so we dont need to inject info everywhere
|
|
637
692
|
this.taskManager.setWrapupData(this.agentConfig.wrapUpData);
|
|
638
693
|
this.taskManager.setAgentId(this.agentConfig.agentId);
|
|
639
694
|
this.taskManager.setWebRtcEnabled(this.agentConfig.webRtcEnabled);
|
|
640
695
|
this.apiAIAssistant.setAIFeatureFlags(this.agentConfig.aiFeature);
|
|
641
|
-
|
|
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) {
|
|
642
702
|
_loggerProxy.default.info('Connecting to RTD websocket', {
|
|
643
703
|
module: _constants.CC_FILE,
|
|
644
704
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
645
705
|
});
|
|
646
|
-
|
|
706
|
+
this.services.rtdWebSocketManager.initWebSocket({
|
|
647
707
|
body: this.getConnectionConfig(),
|
|
648
708
|
resource: _constants3.RTD_SUBSCRIBE_API
|
|
649
709
|
}).then(() => {
|
|
@@ -653,13 +713,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
653
713
|
});
|
|
654
714
|
this.services.rtdWebSocketManager.on('message', this.handleRTDWebsocketMessage);
|
|
655
715
|
}).catch(error => {
|
|
656
|
-
_loggerProxy.default.error(`Error
|
|
716
|
+
_loggerProxy.default.error(`Error connecting to RTD websocket ${error}`, {
|
|
657
717
|
module: _constants.CC_FILE,
|
|
658
718
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
659
719
|
});
|
|
660
720
|
});
|
|
661
721
|
}
|
|
662
|
-
if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER)) {
|
|
722
|
+
if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER) && !this.isWebRTCRegistrationDisabled()) {
|
|
663
723
|
try {
|
|
664
724
|
await this.$webex.internal.mercury.connect();
|
|
665
725
|
_loggerProxy.default.log('Authentication: webex.internal.mercury.connect successful', {
|
|
@@ -672,9 +732,19 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
672
732
|
method: _constants.METHODS.CONNECT_WEBSOCKET
|
|
673
733
|
});
|
|
674
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
|
+
});
|
|
675
740
|
}
|
|
676
741
|
if (this.$config && this.$config.allowAutomatedRelogin) {
|
|
677
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
|
+
});
|
|
678
748
|
}
|
|
679
749
|
return this.agentConfig;
|
|
680
750
|
} catch (error) {
|
|
@@ -715,22 +785,27 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
715
785
|
* ```
|
|
716
786
|
*/
|
|
717
787
|
async stationLogin(data) {
|
|
718
|
-
|
|
788
|
+
const loggerContext = {
|
|
719
789
|
module: _constants.CC_FILE,
|
|
720
790
|
method: _constants.METHODS.STATION_LOGIN
|
|
721
|
-
}
|
|
791
|
+
};
|
|
722
792
|
try {
|
|
793
|
+
_loggerProxy.default.log(`Starting agent station login | loginOption: ${data?.loginOption} teamId: ${data?.teamId}`, loggerContext);
|
|
723
794
|
this.metricsManager.timeEvent([_constants4.METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, _constants4.METRIC_EVENT_NAMES.STATION_LOGIN_FAILED]);
|
|
724
795
|
const dialPlanEntries = this.agentConfig?.dialPlan?.dialPlanEntity ?? [];
|
|
725
|
-
if (data.loginOption === _types.LoginOption.AGENT_DN
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
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
|
+
}
|
|
734
809
|
}
|
|
735
810
|
const loginResponse = await this.services.agent.stationLogin({
|
|
736
811
|
data: {
|
|
@@ -746,8 +821,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
746
821
|
auxCodeId: _constants.EMPTY_STRING
|
|
747
822
|
}
|
|
748
823
|
});
|
|
749
|
-
if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER) {
|
|
824
|
+
if (this.agentConfig.webRtcEnabled && data.loginOption === _types.LoginOption.BROWSER && !this.isWebRTCRegistrationDisabled()) {
|
|
750
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
|
+
});
|
|
751
831
|
}
|
|
752
832
|
const resp = await loginResponse;
|
|
753
833
|
const {
|
|
@@ -1071,6 +1151,25 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1071
1151
|
}
|
|
1072
1152
|
};
|
|
1073
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
|
+
|
|
1074
1173
|
/**
|
|
1075
1174
|
* Initializes event listeners for the Contact Center service
|
|
1076
1175
|
* Sets up handlers for connection state changes and other core events
|
|
@@ -1102,13 +1201,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1102
1201
|
async handleConnectionLost(msg) {
|
|
1103
1202
|
if (msg.isConnectionLost) {
|
|
1104
1203
|
// TODO: Emit an event saying connection is lost
|
|
1105
|
-
_loggerProxy.default.
|
|
1204
|
+
_loggerProxy.default.log('event=handleConnectionLost | Connection lost', {
|
|
1106
1205
|
module: _constants.CC_FILE,
|
|
1107
1206
|
method: _constants.METHODS.HANDLE_CONNECTION_LOST
|
|
1108
1207
|
});
|
|
1109
1208
|
} else if (msg.isSocketReconnected) {
|
|
1110
1209
|
// TODO: Emit an event saying connection is re-estabilished
|
|
1111
|
-
_loggerProxy.default.
|
|
1210
|
+
_loggerProxy.default.log('event=handleConnectionReconnect | Connection reconnected attempting to request silent relogin', {
|
|
1112
1211
|
module: _constants.CC_FILE,
|
|
1113
1212
|
method: _constants.METHODS.HANDLE_CONNECTION_LOST
|
|
1114
1213
|
});
|
|
@@ -1123,7 +1222,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1123
1222
|
* @private
|
|
1124
1223
|
*/
|
|
1125
1224
|
async silentRelogin() {
|
|
1126
|
-
_loggerProxy.default.
|
|
1225
|
+
_loggerProxy.default.log('Starting silent relogin process', {
|
|
1127
1226
|
module: _constants.CC_FILE,
|
|
1128
1227
|
method: _constants.METHODS.SILENT_RELOGIN
|
|
1129
1228
|
});
|
|
@@ -1145,7 +1244,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1145
1244
|
this.agentConfig.currentTeamId = reLoginResponse.data.teamId;
|
|
1146
1245
|
await this.handleDeviceType(deviceType, dn);
|
|
1147
1246
|
if (lastStateChangeReason === 'agent-wss-disconnect') {
|
|
1148
|
-
_loggerProxy.default.
|
|
1247
|
+
_loggerProxy.default.log('event=requestAutoStateChange | Requesting state change to available on socket reconnect', {
|
|
1149
1248
|
module: _constants.CC_FILE,
|
|
1150
1249
|
method: _constants.METHODS.SILENT_RELOGIN
|
|
1151
1250
|
});
|
|
@@ -1169,8 +1268,6 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1169
1268
|
}
|
|
1170
1269
|
this.agentConfig.lastStateAuxCodeId = auxCodeId;
|
|
1171
1270
|
this.agentConfig.isAgentLoggedIn = true;
|
|
1172
|
-
// TODO: https://jira-eng-gpk2.cisco.com/jira/browse/SPARK-626777 Implement the de-register method and close the listener there
|
|
1173
|
-
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
|
|
1174
1271
|
_loggerProxy.default.log(`Silent relogin process completed successfully with login Option: ${reLoginResponse.data.deviceType} teamId: ${reLoginResponse.data.teamId}`, {
|
|
1175
1272
|
module: _constants.CC_FILE,
|
|
1176
1273
|
method: _constants.METHODS.SILENT_RELOGIN,
|
|
@@ -1205,6 +1302,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1205
1302
|
this.agentConfig.deviceType = deviceType;
|
|
1206
1303
|
switch (deviceType) {
|
|
1207
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
|
+
}
|
|
1208
1312
|
try {
|
|
1209
1313
|
await this.webCallingService.registerWebCallingLine();
|
|
1210
1314
|
} catch (error) {
|
|
@@ -1444,6 +1548,138 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1444
1548
|
}
|
|
1445
1549
|
}
|
|
1446
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
|
+
|
|
1447
1683
|
/**
|
|
1448
1684
|
* Fetches outdial ANI (Automatic Number Identification) entries for an outdial ANI ID.
|
|
1449
1685
|
*
|