@webex/contact-center 3.12.0-llmrefactor.2 → 3.12.0-llmrefactor.3
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 +5 -4
- package/ai-docs/ARCHITECTURE.md +1 -1
- package/ai-docs/CONTRACTS.md +5 -1
- package/ai-docs/SECURITY.md +1 -1
- package/ai-docs/contact-center-spec.md +22 -4
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/dist/cc.js +440 -10
- package/dist/cc.js.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +10 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +13 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/services/AddressBook.js +18 -15
- package/dist/services/AddressBook.js.map +1 -1
- package/dist/services/AnswerCallOnWebexService.js +174 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/EntryPoint.js +46 -68
- package/dist/services/EntryPoint.js.map +1 -1
- package/dist/services/Queue.js +27 -22
- package/dist/services/Queue.js.map +1 -1
- package/dist/services/WebexCrossClientService.js +171 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +93 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +3 -0
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +10 -6
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/types.js +4 -0
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/WebexRequest.js +6 -2
- package/dist/services/core/WebexRequest.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +28 -14
- package/dist/services/core/aqm-reqs.js.map +1 -1
- package/dist/services/core/types.js.map +1 -1
- package/dist/services/task/Task.js +73 -7
- package/dist/services/task/Task.js.map +1 -1
- package/dist/services/task/TaskFactory.js +8 -4
- package/dist/services/task/TaskFactory.js.map +1 -1
- package/dist/services/task/TaskManager.js +176 -20
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/WebexCallingUtils.js +70 -0
- package/dist/services/task/WebexCallingUtils.js.map +1 -0
- package/dist/services/task/constants.js +4 -1
- package/dist/services/task/constants.js.map +1 -1
- package/dist/services/task/contact.js +29 -0
- package/dist/services/task/contact.js.map +1 -1
- package/dist/services/task/digital/Digital.js +3 -2
- package/dist/services/task/digital/Digital.js.map +1 -1
- package/dist/services/task/state-machine/TaskStateMachine.js +135 -37
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -1
- package/dist/services/task/state-machine/actions.js +6 -1
- package/dist/services/task/state-machine/actions.js.map +1 -1
- package/dist/services/task/state-machine/guards.js +38 -11
- package/dist/services/task/state-machine/guards.js.map +1 -1
- package/dist/services/task/state-machine/types.js.map +1 -1
- package/dist/services/task/state-machine/uiControlsComputer.js +118 -18
- package/dist/services/task/state-machine/uiControlsComputer.js.map +1 -1
- package/dist/services/task/types.js +16 -1
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +350 -14
- package/dist/services/task/voice/Voice.js.map +1 -1
- package/dist/services/task/voice/WebRTC.js +4 -1
- package/dist/services/task/voice/WebRTC.js.map +1 -1
- package/dist/services/task/voice/wxAppVoiceMethods.js +201 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppTelephonyUtils.js +19 -0
- package/dist/services/wxAppTelephonyUtils.js.map +1 -0
- package/dist/types/cc.d.ts +77 -4
- package/dist/types/config.d.ts +7 -0
- package/dist/types/constants.d.ts +8 -0
- package/dist/types/index.d.ts +3 -1
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +37 -0
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/WebexCrossClientService.d.ts +28 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/constants.d.ts +8 -5
- package/dist/types/services/config/types.d.ts +17 -4
- package/dist/types/services/core/Err.d.ts +2 -0
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/types.d.ts +2 -0
- package/dist/types/services/task/Task.d.ts +20 -2
- package/dist/types/services/task/TaskFactory.d.ts +2 -1
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +3 -0
- package/dist/types/services/task/contact.d.ts +4 -0
- package/dist/types/services/task/digital/Digital.d.ts +2 -2
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +260 -56
- package/dist/types/services/task/state-machine/guards.d.ts +6 -5
- package/dist/types/services/task/state-machine/types.d.ts +9 -1
- package/dist/types/services/task/types.d.ts +81 -4
- package/dist/types/services/task/voice/Voice.d.ts +48 -9
- package/dist/types/services/task/voice/WebRTC.d.ts +2 -2
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +52 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +14 -8
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types.js +7 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/PageCache.js +19 -5
- package/dist/utils/PageCache.js.map +1 -1
- package/dist/webex.js +1 -1
- package/package.json +1 -1
- package/src/cc.ts +506 -9
- package/src/config.ts +7 -0
- package/src/constants.ts +8 -0
- package/src/index.ts +2 -0
- package/src/metrics/ai-docs/metrics-spec.md +9 -3
- package/src/metrics/behavioral-events.ts +14 -0
- package/src/metrics/constants.ts +2 -0
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +206 -0
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/WebexCrossClientService.ts +212 -0
- package/src/services/WxAppTelephonyMercurySync.ts +115 -0
- package/src/services/ai-docs/AGENTS.md +10 -10
- package/src/services/ai-docs/services-spec.md +6 -1
- package/src/services/config/Util.ts +3 -0
- package/src/services/config/ai-docs/AGENTS.md +1 -1
- package/src/services/config/ai-docs/ARCHITECTURE.md +2 -2
- package/src/services/config/ai-docs/config-spec.md +6 -0
- package/src/services/config/constants.ts +10 -6
- package/src/services/config/types.ts +16 -4
- package/src/services/core/Err.ts +1 -0
- package/src/services/core/WebexRequest.ts +3 -1
- package/src/services/core/ai-docs/core-spec.md +5 -1
- package/src/services/core/aqm-reqs.ts +30 -15
- package/src/services/core/types.ts +2 -0
- package/src/services/task/Task.ts +79 -8
- package/src/services/task/TaskFactory.ts +8 -3
- package/src/services/task/TaskManager.ts +254 -15
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +1 -0
- package/src/services/task/ai-docs/task-spec.md +117 -2
- package/src/services/task/constants.ts +3 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/digital/Digital.ts +4 -2
- package/src/services/task/state-machine/TaskStateMachine.ts +210 -63
- package/src/services/task/state-machine/actions.ts +5 -2
- package/src/services/task/state-machine/ai-docs/AGENTS.md +8 -4
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +17 -8
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +46 -22
- package/src/services/task/state-machine/guards.ts +64 -11
- package/src/services/task/state-machine/types.ts +16 -1
- package/src/services/task/state-machine/uiControlsComputer.ts +206 -32
- package/src/services/task/types.ts +114 -4
- package/src/services/task/voice/Voice.ts +462 -12
- package/src/services/task/voice/WebRTC.ts +5 -1
- package/src/services/task/voice/wxAppVoiceMethods.ts +307 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +33 -9
- package/src/utils/AGENTS.md +21 -10
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +21 -11
- package/test/unit/spec/cc.ts +1274 -0
- package/test/unit/spec/metrics/behavioral-events.ts +18 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +223 -0
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/WebexCrossClientService.ts +261 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +113 -0
- package/test/unit/spec/services/config/Util.ts +85 -0
- package/test/unit/spec/services/core/WebexRequest.ts +3 -1
- package/test/unit/spec/services/core/aqm-reqs.ts +113 -1
- package/test/unit/spec/services/task/Task.ts +200 -0
- package/test/unit/spec/services/task/TaskFactory.ts +39 -2
- package/test/unit/spec/services/task/TaskManager.ts +653 -1
- package/test/unit/spec/services/task/WebexCallingUtils.ts +153 -0
- package/test/unit/spec/services/task/contact.ts +33 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +854 -72
- package/test/unit/spec/services/task/state-machine/guards.ts +210 -8
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +445 -7
- package/test/unit/spec/services/task/voice/Voice.ts +874 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +459 -0
- package/umd/contact-center.min.js +2 -2
- package/umd/contact-center.min.js.map +1 -1
package/dist/cc.js
CHANGED
|
@@ -19,6 +19,9 @@ var _Utils = require("./services/core/Utils");
|
|
|
19
19
|
var _types3 = require("./services/config/types");
|
|
20
20
|
var _TaskManager = _interopRequireDefault(require("./services/task/TaskManager"));
|
|
21
21
|
var _WebCallingService = _interopRequireDefault(require("./services/WebCallingService"));
|
|
22
|
+
var _AnswerCallOnWebexService = _interopRequireDefault(require("./services/AnswerCallOnWebexService"));
|
|
23
|
+
var _WebexCrossClientService = _interopRequireDefault(require("./services/WebexCrossClientService"));
|
|
24
|
+
var _WxAppTelephonyMercurySync = _interopRequireDefault(require("./services/WxAppTelephonyMercurySync"));
|
|
22
25
|
var _types4 = require("./services/task/types");
|
|
23
26
|
var _MetricsManager = _interopRequireDefault(require("./metrics/MetricsManager"));
|
|
24
27
|
var _constants4 = require("./metrics/constants");
|
|
@@ -185,6 +188,29 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
185
188
|
* @private
|
|
186
189
|
*/
|
|
187
190
|
|
|
191
|
+
/**
|
|
192
|
+
* REST telephony for wxApp thick-client answer (WXCC-6026)
|
|
193
|
+
* @private
|
|
194
|
+
*/
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* usersub cross-client state for Webex App toast suppression
|
|
198
|
+
* @private
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Mercury telephony mute sync for wxApp thick-client answer
|
|
203
|
+
* @private
|
|
204
|
+
*/
|
|
205
|
+
|
|
206
|
+
/** True when wxApp mute sync opened Mercury (Extension/DN-only profiles). */
|
|
207
|
+
wxAppMercuryConnectedByCc = false;
|
|
208
|
+
|
|
209
|
+
/** True when wxApp mute sync registered the Webex device. */
|
|
210
|
+
wxAppDeviceRegisteredByCc = false;
|
|
211
|
+
static WXAPP_FALSE_PUBLISH_RETRY_DELAY_MS = 30_000;
|
|
212
|
+
static WXAPP_FALSE_PUBLISH_MAX_RETRIES = 3;
|
|
213
|
+
|
|
188
214
|
/**
|
|
189
215
|
* Core service managers for Contact Center operations
|
|
190
216
|
* Includes agent, connection, and configuration services
|
|
@@ -345,11 +371,15 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
345
371
|
connectionConfig: this.getConnectionConfig()
|
|
346
372
|
});
|
|
347
373
|
this.webCallingService = new _WebCallingService.default(this.$webex);
|
|
374
|
+
this.answerCallOnWebexService = new _AnswerCallOnWebexService.default(this.$webex);
|
|
375
|
+
this.webexCrossClientService = new _WebexCrossClientService.default(this.$webex);
|
|
376
|
+
this.wxAppTelephonyMercurySync = new _WxAppTelephonyMercurySync.default(this.$webex);
|
|
348
377
|
this.apiAIAssistant = new _ApiAiAssistant.ApiAIAssistant(this.$webex);
|
|
349
378
|
this.metricsManager = _MetricsManager.default.getInstance({
|
|
350
379
|
webex: this.$webex
|
|
351
380
|
});
|
|
352
381
|
this.taskManager = _TaskManager.default.getTaskManager(this.apiAIAssistant, this.services.contact, this.webCallingService, this.services.webSocketManager, this.services.rtdWebSocketManager);
|
|
382
|
+
this.taskManager.setAnswerCallOnWebexService(this.answerCallOnWebexService);
|
|
353
383
|
this.incomingTaskListener();
|
|
354
384
|
|
|
355
385
|
// Initialize API instances
|
|
@@ -541,6 +571,11 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
541
571
|
this.services.webSocketManager.off('message', this.handleWebsocketMessage);
|
|
542
572
|
this.services.rtdWebSocketManager.off('message', this.handleRTDWebsocketMessage);
|
|
543
573
|
this.services.connectionService.off('connectionLost', this.handleConnectionLost);
|
|
574
|
+
const {
|
|
575
|
+
publishError: wxAppPublishError
|
|
576
|
+
} = await this.teardownWxAppLocalState({
|
|
577
|
+
clearInitFlag: true
|
|
578
|
+
});
|
|
544
579
|
if (this.agentConfig.webRtcEnabled && this.agentConfig.loginVoiceOptions.includes(_types.LoginOption.BROWSER)) {
|
|
545
580
|
if (this.$webex.internal.mercury.connected) {
|
|
546
581
|
this.$webex.internal.mercury.off('online');
|
|
@@ -566,6 +601,9 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
566
601
|
|
|
567
602
|
// Clear any cached agent configuration
|
|
568
603
|
this.agentConfig = null;
|
|
604
|
+
if (wxAppPublishError) {
|
|
605
|
+
throw wxAppPublishError;
|
|
606
|
+
}
|
|
569
607
|
_loggerProxy.default.log('Deregistered successfully', {
|
|
570
608
|
module: _constants.CC_FILE,
|
|
571
609
|
method: _constants.METHODS.DEREGISTER
|
|
@@ -619,6 +657,12 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
619
657
|
* ```
|
|
620
658
|
*/
|
|
621
659
|
async getBuddyAgents(data) {
|
|
660
|
+
const {
|
|
661
|
+
action,
|
|
662
|
+
state,
|
|
663
|
+
mediaType = 'telephony'
|
|
664
|
+
} = data;
|
|
665
|
+
const buddyAgentState = state ?? (action === 'Transfer' ? _constants2.AGENT_STATE_AVAILABLE : undefined);
|
|
622
666
|
_loggerProxy.default.info('Fetching buddy agents', {
|
|
623
667
|
module: _constants.CC_FILE,
|
|
624
668
|
method: _constants.METHODS.GET_BUDDY_AGENTS
|
|
@@ -628,13 +672,16 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
628
672
|
const resp = await this.services.agent.buddyAgents({
|
|
629
673
|
data: {
|
|
630
674
|
agentProfileId: this.agentConfig.agentProfileID,
|
|
631
|
-
|
|
675
|
+
mediaType,
|
|
676
|
+
...(buddyAgentState ? {
|
|
677
|
+
state: buddyAgentState
|
|
678
|
+
} : {})
|
|
632
679
|
}
|
|
633
680
|
});
|
|
634
681
|
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.FETCH_BUDDY_AGENTS_SUCCESS, {
|
|
635
682
|
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(resp),
|
|
636
|
-
mediaType
|
|
637
|
-
buddyAgentState
|
|
683
|
+
mediaType,
|
|
684
|
+
buddyAgentState,
|
|
638
685
|
buddyAgentCount: resp.data.agentList.length
|
|
639
686
|
}, ['operational']);
|
|
640
687
|
_loggerProxy.default.log(`Successfully retrieved ${resp.data.agentList.length} buddy agents`, {
|
|
@@ -647,8 +694,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
647
694
|
const failureResp = error.details;
|
|
648
695
|
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.FETCH_BUDDY_AGENTS_FAILED, {
|
|
649
696
|
..._MetricsManager.default.getCommonTrackingFieldForAQMResponseFailed(failureResp),
|
|
650
|
-
mediaType
|
|
651
|
-
buddyAgentState
|
|
697
|
+
mediaType,
|
|
698
|
+
buddyAgentState
|
|
652
699
|
}, ['operational']);
|
|
653
700
|
const {
|
|
654
701
|
error: detailedError
|
|
@@ -685,7 +732,14 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
685
732
|
isEndConsultEnabled: this.agentConfig.isEndConsultEnabled,
|
|
686
733
|
webRtcEnabled: this.agentConfig.webRtcEnabled,
|
|
687
734
|
autoWrapup: this.agentConfig.wrapUpData?.wrapUpProps?.autoWrapup ?? false,
|
|
688
|
-
aiFeature: this.agentConfig.aiFeature
|
|
735
|
+
aiFeature: this.agentConfig.aiFeature,
|
|
736
|
+
consultTransfer: {
|
|
737
|
+
allowConsultToQueue: this.agentConfig.allowConsultToQueue,
|
|
738
|
+
accessQueue: this.agentConfig.accessQueue,
|
|
739
|
+
accessEntryPoint: this.agentConfig.accessEntryPoint,
|
|
740
|
+
accessBuddyTeam: this.agentConfig.accessBuddyTeam
|
|
741
|
+
},
|
|
742
|
+
enableWxBetterTogether: this.isWxBetterTogetherEnabled()
|
|
689
743
|
};
|
|
690
744
|
this.taskManager.setConfigFlags(configFlags);
|
|
691
745
|
// TODO: Make profile a singleton to make it available throughout app/sdk so we dont need to inject info everywhere
|
|
@@ -846,6 +900,13 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
846
900
|
notifsTrackingId: resp.trackingId
|
|
847
901
|
};
|
|
848
902
|
this.webCallingService.setLoginOption(data.loginOption);
|
|
903
|
+
if (this.agentConfig) {
|
|
904
|
+
this.agentConfig.deviceType = data.loginOption;
|
|
905
|
+
if (data.loginOption === _types.LoginOption.AGENT_DN || data.loginOption === _types.LoginOption.EXTENSION) {
|
|
906
|
+
this.agentConfig.defaultDn = data.dialNumber;
|
|
907
|
+
this.agentConfig.dn = data.dialNumber;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
849
910
|
this.metricsManager.trackEvent(_constants4.METRIC_EVENT_NAMES.STATION_LOGIN_SUCCESS, {
|
|
850
911
|
..._MetricsManager.default.getCommonTrackingFieldForAQMResponse(resp),
|
|
851
912
|
loginType: data.loginOption,
|
|
@@ -858,6 +919,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
858
919
|
method: _constants.METHODS.STATION_LOGIN,
|
|
859
920
|
trackingId: resp.trackingId
|
|
860
921
|
});
|
|
922
|
+
await this.ensureWxAppPostStationLogin();
|
|
861
923
|
return response;
|
|
862
924
|
} catch (error) {
|
|
863
925
|
const failure = error.details;
|
|
@@ -912,6 +974,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
912
974
|
if (this.webCallingService) {
|
|
913
975
|
this.webCallingService.deregisterWebCallingLine();
|
|
914
976
|
}
|
|
977
|
+
await this.teardownWxAppLocalState();
|
|
915
978
|
_loggerProxy.default.log(`Agent station logout completed successfully`, {
|
|
916
979
|
module: _constants.CC_FILE,
|
|
917
980
|
method: _constants.METHODS.STATION_LOGOUT,
|
|
@@ -1170,6 +1233,372 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1170
1233
|
}
|
|
1171
1234
|
}
|
|
1172
1235
|
|
|
1236
|
+
/**
|
|
1237
|
+
* Whether wxApp thick-client answer is enabled for this SDK instance.
|
|
1238
|
+
* @public
|
|
1239
|
+
*/
|
|
1240
|
+
isWxBetterTogetherEnabled() {
|
|
1241
|
+
return this.$config?.enableWxBetterTogether === true;
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
/**
|
|
1245
|
+
* Current station login option (Extension, Dial Number, or Browser/Desktop).
|
|
1246
|
+
* Prefer webCallingService — updated on every stationLogin before wxApp hooks run.
|
|
1247
|
+
* @private
|
|
1248
|
+
*/
|
|
1249
|
+
getCurrentStationLoginOption() {
|
|
1250
|
+
return this.webCallingService?.loginOption ?? this.agentConfig?.deviceType;
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* wxApp thick-client answer is supported for Extension and Dial Number station login only —
|
|
1255
|
+
* not Browser/Desktop (WebRTC) login.
|
|
1256
|
+
* @private
|
|
1257
|
+
*/
|
|
1258
|
+
assertWxAppStationLoginSupportedForEnable() {
|
|
1259
|
+
const loginOption = this.getCurrentStationLoginOption();
|
|
1260
|
+
if (loginOption !== _types.LoginOption.EXTENSION && loginOption !== _types.LoginOption.AGENT_DN) {
|
|
1261
|
+
throw new Error('setManageWebexCallingInWxcc requires EXTENSION or AGENT_DN station login. Complete station login before enabling.');
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
/**
|
|
1266
|
+
* Clears runtime wxApp config after logout/deregister so stale flags do not apply on relogin.
|
|
1267
|
+
* @private
|
|
1268
|
+
*/
|
|
1269
|
+
resetEnableWxBetterTogetherConfig() {
|
|
1270
|
+
if (this.$config) {
|
|
1271
|
+
this.$config.enableWxBetterTogether = false;
|
|
1272
|
+
}
|
|
1273
|
+
this.taskManager.applyEnableWxBetterTogether(false);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* Runtime enable/disable for wxApp Better Together (toast suppression + Mercury mute sync).
|
|
1278
|
+
*
|
|
1279
|
+
* **Phase 1 (WXCC-6026 / MMT): NOT part of the public host contract.**
|
|
1280
|
+
* Hosts must set `webexConfig.cc.enableWxBetterTogether` before `webex.init()` / `cc.register()`.
|
|
1281
|
+
* To change the flag after the SDK is initialized, re-init the SDK with the updated config.
|
|
1282
|
+
*
|
|
1283
|
+
* **Supported public read API:** {@link isWxBetterTogetherEnabled}.
|
|
1284
|
+
* **Supported telephony API:** unified `task.accept()`, `task.decline()`, `task.toggleMute()`,
|
|
1285
|
+
* `task.transmitDtmf()` — SDK routes wxApp calls internally when the init flag is active.
|
|
1286
|
+
*
|
|
1287
|
+
* **Production lifecycle does not call this method.** Station login, silent relogin, logout,
|
|
1288
|
+
* and deregister use {@link ensureWxAppPostStationLogin} and {@link teardownWxAppLocalState}
|
|
1289
|
+
* (usersub publish + Mercury subscribe/unsubscribe based on the init flag).
|
|
1290
|
+
*
|
|
1291
|
+
* This setter remains as a **private implementation** for Phase 2 runtime toggle and unit tests.
|
|
1292
|
+
* It updates `$config.enableWxBetterTogether`, TaskManager flags, cross-client usersub
|
|
1293
|
+
* (`answer-calls-on-wxcc`), and Mercury mute sync; rolls back config on publish/connect failure.
|
|
1294
|
+
*
|
|
1295
|
+
* @param enabled - `true` to enable wxApp answer + usersub suppression; `false` to disable and tear down.
|
|
1296
|
+
* @throws When enabling without login, on unsupported BROWSER station login, or when usersub/Mercury init fails.
|
|
1297
|
+
* @internal
|
|
1298
|
+
* @see enableWxBetterTogether (CCPluginConfig init flag)
|
|
1299
|
+
* @see ensureWxAppPostStationLogin
|
|
1300
|
+
* @see teardownWxAppLocalState
|
|
1301
|
+
*/
|
|
1302
|
+
async setManageWebexCallingInWxcc(enabled) {
|
|
1303
|
+
if (enabled && !this.$webex.internal.device?.userId) {
|
|
1304
|
+
throw new Error('Cannot publish answer-calls-on-wxcc: user is not logged in');
|
|
1305
|
+
}
|
|
1306
|
+
if (enabled) {
|
|
1307
|
+
this.assertWxAppStationLoginSupportedForEnable();
|
|
1308
|
+
}
|
|
1309
|
+
const previousEnabled = this.isWxBetterTogetherEnabled();
|
|
1310
|
+
if (this.$config) {
|
|
1311
|
+
this.$config.enableWxBetterTogether = enabled;
|
|
1312
|
+
}
|
|
1313
|
+
this.taskManager.applyEnableWxBetterTogether(enabled);
|
|
1314
|
+
let publishedEnable = false;
|
|
1315
|
+
try {
|
|
1316
|
+
if (enabled) {
|
|
1317
|
+
await this.ensureWxAppMercuryAndSubscribe();
|
|
1318
|
+
await this.publishAnswerOnWebexCrossClientState(true);
|
|
1319
|
+
publishedEnable = true;
|
|
1320
|
+
this.taskManager.syncWxAppMuteFromCallDetailsForAllTasks();
|
|
1321
|
+
} else {
|
|
1322
|
+
await this.publishAnswerOnWebexCrossClientState(false);
|
|
1323
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1324
|
+
await this.releaseWxAppMercuryResources();
|
|
1325
|
+
}
|
|
1326
|
+
} catch (error) {
|
|
1327
|
+
if (publishedEnable) {
|
|
1328
|
+
await this.revertWxAppCrossClientPublish();
|
|
1329
|
+
} else if (enabled) {
|
|
1330
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1331
|
+
await this.releaseWxAppMercuryResources();
|
|
1332
|
+
}
|
|
1333
|
+
if (this.$config) {
|
|
1334
|
+
this.$config.enableWxBetterTogether = previousEnabled;
|
|
1335
|
+
}
|
|
1336
|
+
this.taskManager.applyEnableWxBetterTogether(previousEnabled);
|
|
1337
|
+
throw error;
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
async ensureWxAppPostStationLogin() {
|
|
1341
|
+
if (this.getCurrentStationLoginOption() === _types.LoginOption.BROWSER) {
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
let publishedEnable = false;
|
|
1345
|
+
try {
|
|
1346
|
+
if (this.isWxBetterTogetherEnabled()) {
|
|
1347
|
+
await this.ensureWxAppMercuryAndSubscribe();
|
|
1348
|
+
await this.publishAnswerOnWebexCrossClientState(true);
|
|
1349
|
+
publishedEnable = true;
|
|
1350
|
+
this.taskManager.syncWxAppMuteFromCallDetailsForAllTasks();
|
|
1351
|
+
} else {
|
|
1352
|
+
await this.ensureWxAppDeviceRegistered();
|
|
1353
|
+
await this.publishAnswerOnWebexCrossClientState(false, {
|
|
1354
|
+
force: true
|
|
1355
|
+
});
|
|
1356
|
+
this.webexCrossClientService.teardown();
|
|
1357
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1358
|
+
await this.releaseWxAppMercuryResources();
|
|
1359
|
+
}
|
|
1360
|
+
} catch (error) {
|
|
1361
|
+
_loggerProxy.default.error(`Failed to initialize wxApp post-station-login: ${error}`, {
|
|
1362
|
+
module: _constants.CC_FILE,
|
|
1363
|
+
method: _constants.METHODS.STATION_LOGIN
|
|
1364
|
+
});
|
|
1365
|
+
if (this.isWxBetterTogetherEnabled()) {
|
|
1366
|
+
if (publishedEnable) {
|
|
1367
|
+
await this.revertWxAppCrossClientPublish();
|
|
1368
|
+
} else {
|
|
1369
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1370
|
+
await this.releaseWxAppMercuryResources();
|
|
1371
|
+
}
|
|
1372
|
+
this.resetEnableWxBetterTogetherConfig();
|
|
1373
|
+
} else {
|
|
1374
|
+
this.scheduleForcedFalsePublishRetry();
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
clearWxAppFalsePublishRetryTimer() {
|
|
1379
|
+
if (this.wxAppFalsePublishRetryTimer) {
|
|
1380
|
+
clearTimeout(this.wxAppFalsePublishRetryTimer);
|
|
1381
|
+
this.wxAppFalsePublishRetryTimer = undefined;
|
|
1382
|
+
}
|
|
1383
|
+
}
|
|
1384
|
+
scheduleForcedFalsePublishRetry(retryAttempt = 0) {
|
|
1385
|
+
this.scheduleFalsePublishRetry(retryAttempt, {
|
|
1386
|
+
requireDisabled: true
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1390
|
+
/**
|
|
1391
|
+
* Retries compensating false publish after rollback failure, regardless of enabled flag.
|
|
1392
|
+
* @private
|
|
1393
|
+
*/
|
|
1394
|
+
scheduleCompensatingFalsePublishRetry(retryAttempt = 0) {
|
|
1395
|
+
this.scheduleFalsePublishRetry(retryAttempt);
|
|
1396
|
+
}
|
|
1397
|
+
scheduleFalsePublishRetry(retryAttempt = 0, options = {}) {
|
|
1398
|
+
if (retryAttempt >= ContactCenter.WXAPP_FALSE_PUBLISH_MAX_RETRIES) {
|
|
1399
|
+
return;
|
|
1400
|
+
}
|
|
1401
|
+
if (options?.requireDisabled && this.isWxBetterTogetherEnabled()) {
|
|
1402
|
+
return;
|
|
1403
|
+
}
|
|
1404
|
+
this.clearWxAppFalsePublishRetryTimer();
|
|
1405
|
+
this.wxAppFalsePublishRetryTimer = setTimeout(async () => {
|
|
1406
|
+
this.wxAppFalsePublishRetryTimer = undefined;
|
|
1407
|
+
if (options?.requireDisabled && this.isWxBetterTogetherEnabled()) {
|
|
1408
|
+
return;
|
|
1409
|
+
}
|
|
1410
|
+
if (!options?.requireDisabled && this.isWxBetterTogetherEnabled() && this.webexCrossClientService.isAnswerCallsStateActive()) {
|
|
1411
|
+
return;
|
|
1412
|
+
}
|
|
1413
|
+
try {
|
|
1414
|
+
await this.ensureWxAppDeviceRegistered();
|
|
1415
|
+
await this.publishAnswerOnWebexCrossClientState(false, {
|
|
1416
|
+
force: true
|
|
1417
|
+
});
|
|
1418
|
+
this.webexCrossClientService.teardown();
|
|
1419
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1420
|
+
await this.releaseWxAppMercuryResources();
|
|
1421
|
+
} catch (retryError) {
|
|
1422
|
+
_loggerProxy.default.error(`Failed to retry forced answer-calls-on-wxcc false publish: ${retryError}`, {
|
|
1423
|
+
module: _constants.CC_FILE,
|
|
1424
|
+
method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
|
|
1425
|
+
});
|
|
1426
|
+
this.scheduleFalsePublishRetry(retryAttempt + 1, options);
|
|
1427
|
+
}
|
|
1428
|
+
}, ContactCenter.WXAPP_FALSE_PUBLISH_RETRY_DELAY_MS);
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
/**
|
|
1432
|
+
* Best-effort rollback when usersub true was published but wxApp setup did not complete.
|
|
1433
|
+
* @private
|
|
1434
|
+
*/
|
|
1435
|
+
async revertWxAppCrossClientPublish() {
|
|
1436
|
+
try {
|
|
1437
|
+
await this.publishAnswerOnWebexCrossClientState(false, {
|
|
1438
|
+
force: true
|
|
1439
|
+
});
|
|
1440
|
+
} catch (error) {
|
|
1441
|
+
_loggerProxy.default.error(`Failed to publish compensating answer-calls-on-wxcc false during wxApp rollback: ${error}`, {
|
|
1442
|
+
module: _constants.CC_FILE,
|
|
1443
|
+
method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
|
|
1444
|
+
});
|
|
1445
|
+
this.scheduleCompensatingFalsePublishRetry();
|
|
1446
|
+
}
|
|
1447
|
+
this.webexCrossClientService.teardown();
|
|
1448
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1449
|
+
await this.releaseWxAppMercuryResources();
|
|
1450
|
+
}
|
|
1451
|
+
async ensureWxAppDeviceRegistered() {
|
|
1452
|
+
const device = this.$webex.internal.device;
|
|
1453
|
+
if (device && !device.registered && device.register) {
|
|
1454
|
+
await device.register();
|
|
1455
|
+
this.wxAppDeviceRegisteredByCc = true;
|
|
1456
|
+
_loggerProxy.default.log('WxApp: device registered for cross-client publish', {
|
|
1457
|
+
module: _constants.CC_FILE,
|
|
1458
|
+
method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
async ensureWxAppMercuryConnected() {
|
|
1463
|
+
const mercury = this.$webex.internal.mercury;
|
|
1464
|
+
await this.ensureWxAppDeviceRegistered();
|
|
1465
|
+
if (mercury && !mercury.connected) {
|
|
1466
|
+
await mercury.connect();
|
|
1467
|
+
this.wxAppMercuryConnectedByCc = true;
|
|
1468
|
+
_loggerProxy.default.log('WxApp mute sync: mercury connected', {
|
|
1469
|
+
module: _constants.CC_FILE,
|
|
1470
|
+
method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1475
|
+
/**
|
|
1476
|
+
* Disconnects Mercury and unregisters the device when wxApp mute sync opened them.
|
|
1477
|
+
* @private
|
|
1478
|
+
*/
|
|
1479
|
+
async releaseWxAppMercuryResources() {
|
|
1480
|
+
const mercury = this.$webex.internal.mercury;
|
|
1481
|
+
const device = this.$webex.internal.device;
|
|
1482
|
+
if (this.wxAppMercuryConnectedByCc && mercury?.connected) {
|
|
1483
|
+
try {
|
|
1484
|
+
await mercury.disconnect();
|
|
1485
|
+
this.wxAppMercuryConnectedByCc = false;
|
|
1486
|
+
_loggerProxy.default.log('WxApp mute sync: mercury disconnected', {
|
|
1487
|
+
module: _constants.CC_FILE,
|
|
1488
|
+
method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
|
|
1489
|
+
});
|
|
1490
|
+
} catch (error) {
|
|
1491
|
+
_loggerProxy.default.error(`Failed to disconnect wxApp Mercury: ${error}`, {
|
|
1492
|
+
module: _constants.CC_FILE,
|
|
1493
|
+
method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
|
|
1494
|
+
});
|
|
1495
|
+
}
|
|
1496
|
+
}
|
|
1497
|
+
if (this.wxAppDeviceRegisteredByCc && device?.registered && device.unregister) {
|
|
1498
|
+
try {
|
|
1499
|
+
// @ts-ignore
|
|
1500
|
+
await device.unregister();
|
|
1501
|
+
this.wxAppDeviceRegisteredByCc = false;
|
|
1502
|
+
_loggerProxy.default.log('WxApp mute sync: device unregistered', {
|
|
1503
|
+
module: _constants.CC_FILE,
|
|
1504
|
+
method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
|
|
1505
|
+
});
|
|
1506
|
+
} catch (error) {
|
|
1507
|
+
_loggerProxy.default.error(`Failed to unregister wxApp device: ${error}`, {
|
|
1508
|
+
module: _constants.CC_FILE,
|
|
1509
|
+
method: _constants.METHODS.ENSURE_WXAPP_MERCURY_CONNECTED
|
|
1510
|
+
});
|
|
1511
|
+
}
|
|
1512
|
+
} else if (this.wxAppDeviceRegisteredByCc) {
|
|
1513
|
+
this.wxAppDeviceRegisteredByCc = false;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
|
|
1517
|
+
/**
|
|
1518
|
+
* Clears wxApp runtime state and feature-owned resources. Publish failures are logged;
|
|
1519
|
+
* optional rethrow for deregister when callers need to surface usersub errors.
|
|
1520
|
+
* @private
|
|
1521
|
+
*/
|
|
1522
|
+
async teardownWxAppLocalState(options) {
|
|
1523
|
+
this.clearWxAppFalsePublishRetryTimer();
|
|
1524
|
+
let publishError;
|
|
1525
|
+
try {
|
|
1526
|
+
const shouldForceFalsePublish = this.isWxBetterTogetherEnabled() || this.webexCrossClientService.isAnswerCallsStateActive();
|
|
1527
|
+
await this.publishAnswerOnWebexCrossClientState(false, {
|
|
1528
|
+
force: shouldForceFalsePublish
|
|
1529
|
+
});
|
|
1530
|
+
} catch (error) {
|
|
1531
|
+
publishError = error;
|
|
1532
|
+
_loggerProxy.default.error(`Failed to publish answer-calls-on-wxcc false during wxApp teardown: ${error}`, {
|
|
1533
|
+
module: _constants.CC_FILE,
|
|
1534
|
+
method: _constants.METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC
|
|
1535
|
+
});
|
|
1536
|
+
}
|
|
1537
|
+
this.webexCrossClientService.teardown();
|
|
1538
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1539
|
+
await this.releaseWxAppMercuryResources();
|
|
1540
|
+
if (options?.clearInitFlag) {
|
|
1541
|
+
this.resetEnableWxBetterTogetherConfig();
|
|
1542
|
+
}
|
|
1543
|
+
if (publishError) {
|
|
1544
|
+
this.scheduleCompensatingFalsePublishRetry();
|
|
1545
|
+
}
|
|
1546
|
+
if (options?.rethrowPublishError && publishError) {
|
|
1547
|
+
throw publishError;
|
|
1548
|
+
}
|
|
1549
|
+
return {
|
|
1550
|
+
publishError: publishError ?? undefined
|
|
1551
|
+
};
|
|
1552
|
+
}
|
|
1553
|
+
async ensureWxAppMercuryAndSubscribe() {
|
|
1554
|
+
if (!this.isWxBetterTogetherEnabled()) {
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
if (this.getCurrentStationLoginOption() === _types.LoginOption.BROWSER) {
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
const agentId = this.agentConfig?.agentId;
|
|
1561
|
+
if (!agentId) {
|
|
1562
|
+
_loggerProxy.default.error('Cannot subscribe wxApp mute sync: agentId unavailable', {
|
|
1563
|
+
module: _constants.CC_FILE,
|
|
1564
|
+
method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
|
|
1565
|
+
});
|
|
1566
|
+
return;
|
|
1567
|
+
}
|
|
1568
|
+
try {
|
|
1569
|
+
await this.ensureWxAppMercuryConnected();
|
|
1570
|
+
this.wxAppTelephonyMercurySync.subscribe(agentId, (callId, muted) => {
|
|
1571
|
+
this.taskManager.applyWxAppMuteStateFromSync(callId, muted);
|
|
1572
|
+
});
|
|
1573
|
+
} catch (error) {
|
|
1574
|
+
_loggerProxy.default.error(`Failed to ensure wxApp Mercury mute sync: ${error}`, {
|
|
1575
|
+
module: _constants.CC_FILE,
|
|
1576
|
+
method: _constants.METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY
|
|
1577
|
+
});
|
|
1578
|
+
this.wxAppTelephonyMercurySync.unsubscribe();
|
|
1579
|
+
await this.releaseWxAppMercuryResources();
|
|
1580
|
+
throw error;
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
async publishAnswerOnWebexCrossClientState(enable, options) {
|
|
1584
|
+
if (enable && !this.isWxBetterTogetherEnabled()) {
|
|
1585
|
+
return;
|
|
1586
|
+
}
|
|
1587
|
+
if (!enable && !options?.force && !this.webexCrossClientService.isAnswerCallsStateActive()) {
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
const userId = this.$webex.internal.device?.userId;
|
|
1591
|
+
if (!userId) {
|
|
1592
|
+
return;
|
|
1593
|
+
}
|
|
1594
|
+
await this.webexCrossClientService.setManageWebexCallingInWxcc(enable, {
|
|
1595
|
+
userId
|
|
1596
|
+
});
|
|
1597
|
+
if (enable) {
|
|
1598
|
+
this.clearWxAppFalsePublishRetryTimer();
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1173
1602
|
/**
|
|
1174
1603
|
* Initializes event listeners for the Contact Center service
|
|
1175
1604
|
* Sets up handlers for connection state changes and other core events
|
|
@@ -1268,6 +1697,7 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1268
1697
|
}
|
|
1269
1698
|
this.agentConfig.lastStateAuxCodeId = auxCodeId;
|
|
1270
1699
|
this.agentConfig.isAgentLoggedIn = true;
|
|
1700
|
+
await this.ensureWxAppPostStationLogin();
|
|
1271
1701
|
_loggerProxy.default.log(`Silent relogin process completed successfully with login Option: ${reLoginResponse.data.deviceType} teamId: ${reLoginResponse.data.teamId}`, {
|
|
1272
1702
|
module: _constants.CC_FILE,
|
|
1273
1703
|
method: _constants.METHODS.SILENT_RELOGIN,
|
|
@@ -1884,8 +2314,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1884
2314
|
}
|
|
1885
2315
|
|
|
1886
2316
|
/**
|
|
1887
|
-
* Returns paginated entry points
|
|
1888
|
-
*
|
|
2317
|
+
* Returns paginated entry points using the EntryPoint service defaults.
|
|
2318
|
+
* Existing request parameters can override those defaults.
|
|
1889
2319
|
* @public
|
|
1890
2320
|
*/
|
|
1891
2321
|
async getEntryPoints(params = {}) {
|
|
@@ -1893,8 +2323,8 @@ class ContactCenter extends _webexCore.WebexPlugin {
|
|
|
1893
2323
|
}
|
|
1894
2324
|
|
|
1895
2325
|
/**
|
|
1896
|
-
* Returns paginated contact service queues
|
|
1897
|
-
*
|
|
2326
|
+
* Returns paginated contact service queues using the Queue service defaults.
|
|
2327
|
+
* Existing request parameters can override those defaults.
|
|
1898
2328
|
* @public
|
|
1899
2329
|
*/
|
|
1900
2330
|
async getQueues(params = {}) {
|