@webex/contact-center 3.12.0-next.13 → 3.12.0-next.130
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 +884 -0
- package/AGENTS.md +94 -0
- package/ai-docs/ARCHITECTURE.md +168 -0
- package/ai-docs/CONTRACTS.md +53 -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 +52 -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 +382 -0
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -0
- package/ai-docs/features/contact-owner-change-refactor.md +78 -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 +971 -42
- package/dist/cc.js.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/constants.js +31 -3
- package/dist/constants.js.map +1 -1
- package/dist/index.js +45 -15
- package/dist/index.js.map +1 -1
- package/dist/metrics/MetricsManager.js +16 -0
- package/dist/metrics/MetricsManager.js.map +1 -1
- package/dist/metrics/behavioral-events.js +205 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +48 -4
- 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 +202 -0
- package/dist/services/AnswerCallOnWebexService.js.map +1 -0
- package/dist/services/ApiAiAssistant.js +269 -9
- package/dist/services/ApiAiAssistant.js.map +1 -1
- 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/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- package/dist/services/WebexCrossClientService.js +222 -0
- package/dist/services/WebexCrossClientService.js.map +1 -0
- package/dist/services/WxAppTelephonyMercurySync.js +108 -0
- package/dist/services/WxAppTelephonyMercurySync.js.map +1 -0
- package/dist/services/config/Util.js +11 -4
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +41 -7
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +51 -0
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +57 -12
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +111 -32
- package/dist/services/core/Utils.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/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 +754 -0
- package/dist/services/task/Task.js.map +1 -0
- package/dist/services/task/TaskFactory.js +49 -0
- package/dist/services/task/TaskFactory.js.map +1 -0
- package/dist/services/task/TaskManager.js +1172 -521
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +211 -27
- package/dist/services/task/TaskUtils.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 +12 -2
- 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/dialer.js +78 -0
- package/dist/services/task/dialer.js.map +1 -1
- package/dist/services/task/digital/Digital.js +78 -0
- package/dist/services/task/digital/Digital.js.map +1 -0
- package/dist/services/task/state-machine/TaskStateMachine.js +982 -0
- package/dist/services/task/state-machine/TaskStateMachine.js.map +1 -0
- package/dist/services/task/state-machine/actions.js +572 -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 +379 -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 +703 -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 +228 -5
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1485 -0
- package/dist/services/task/voice/Voice.js.map +1 -0
- package/dist/services/task/voice/WebRTC.js +152 -0
- package/dist/services/task/voice/WebRTC.js.map +1 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js +354 -0
- package/dist/services/task/voice/wxAppVoiceMethods.js.map +1 -0
- package/dist/services/wxAppDiagnosticLogging.js +122 -0
- package/dist/services/wxAppDiagnosticLogging.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 +193 -6
- package/dist/types/config.d.ts +13 -0
- package/dist/types/constants.d.ts +29 -1
- package/dist/types/index.d.ts +35 -8
- package/dist/types/metrics/MetricsManager.d.ts +6 -0
- package/dist/types/metrics/constants.d.ts +43 -1
- package/dist/types/services/AddressBook.d.ts +2 -1
- package/dist/types/services/AnswerCallOnWebexService.d.ts +38 -0
- package/dist/types/services/ApiAiAssistant.d.ts +56 -5
- package/dist/types/services/EntryPoint.d.ts +7 -5
- package/dist/types/services/Queue.d.ts +5 -3
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/WebexCrossClientService.d.ts +32 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/config/constants.d.ts +34 -5
- package/dist/types/services/config/types.d.ts +197 -12
- package/dist/types/services/core/Err.d.ts +6 -0
- package/dist/types/services/core/Utils.d.ts +35 -13
- package/dist/types/services/core/WebexRequest.d.ts +1 -0
- package/dist/types/services/core/types.d.ts +2 -0
- 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 +175 -0
- package/dist/types/services/task/TaskFactory.d.ts +13 -0
- package/dist/types/services/task/TaskUtils.d.ts +48 -2
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +10 -0
- package/dist/types/services/task/contact.d.ts +4 -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 +1442 -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 +103 -0
- package/dist/types/services/task/state-machine/index.d.ts +13 -0
- package/dist/types/services/task/state-machine/types.d.ts +277 -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 +680 -66
- package/dist/types/services/task/voice/Voice.d.ts +227 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- package/dist/types/services/task/voice/wxAppVoiceMethods.d.ts +55 -0
- package/dist/types/services/wxAppDiagnosticLogging.d.ts +51 -0
- package/dist/types/services/wxAppTelephonyUtils.d.ts +5 -0
- package/dist/types/types.d.ts +205 -9
- package/dist/types/utils/PageCache.d.ts +20 -3
- package/dist/types/webex.d.ts +1 -0
- package/dist/types.js +162 -4
- 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 +22 -2
- package/dist/webex.js.map +1 -1
- package/package.json +16 -12
- package/src/cc.ts +1289 -112
- package/src/config.ts +13 -0
- package/src/constants.ts +29 -1
- package/src/index.ts +36 -5
- package/src/metrics/MetricsManager.ts +16 -0
- 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 +921 -0
- package/src/metrics/behavioral-events.ts +212 -0
- package/src/metrics/constants.ts +52 -4
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +239 -0
- package/src/services/ApiAiAssistant.ts +356 -9
- package/src/services/EntryPoint.ts +59 -60
- package/src/services/Queue.ts +29 -12
- package/src/services/UserPreference.ts +509 -0
- package/src/services/WebexCrossClientService.ts +293 -0
- package/src/services/WxAppTelephonyMercurySync.ts +142 -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 +505 -0
- package/src/services/ai-docs/AGENTS.md +386 -0
- package/src/services/ai-docs/services-spec.md +505 -0
- package/src/services/config/Util.ts +12 -3
- 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 +686 -0
- package/src/services/config/constants.ts +46 -6
- package/src/services/config/index.ts +65 -0
- package/src/services/config/types.ts +197 -13
- package/src/services/core/Err.ts +3 -0
- package/src/services/core/Utils.ts +127 -37
- package/src/services/core/WebexRequest.ts +3 -1
- 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 +787 -0
- package/src/services/core/aqm-reqs.ts +30 -15
- package/src/services/core/types.ts +2 -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 +908 -0
- package/src/services/task/TaskFactory.ts +60 -0
- package/src/services/task/TaskManager.ts +1419 -608
- package/src/services/task/TaskUtils.ts +303 -25
- package/src/services/task/WebexCallingUtils.ts +136 -0
- package/src/services/task/ai-docs/AGENTS.md +457 -0
- package/src/services/task/ai-docs/ARCHITECTURE.md +595 -0
- package/src/services/task/ai-docs/task-spec.md +1474 -0
- package/src/services/task/constants.ts +10 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/dialer.ts +80 -0
- package/src/services/task/digital/Digital.ts +97 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1320 -0
- package/src/services/task/state-machine/actions.ts +741 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +460 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1156 -0
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2247 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +442 -0
- package/src/services/task/state-machine/index.ts +28 -0
- package/src/services/task/state-machine/types.ts +258 -0
- package/src/services/task/state-machine/uiControlsComputer.ts +1135 -0
- package/src/services/task/taskDataNormalizer.ts +137 -0
- package/src/services/task/types.ts +819 -70
- package/src/services/task/voice/Voice.ts +1851 -0
- package/src/services/task/voice/WebRTC.ts +191 -0
- package/src/services/task/voice/wxAppVoiceMethods.ts +516 -0
- package/src/services/wxAppDiagnosticLogging.ts +174 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +262 -11
- package/src/utils/AGENTS.md +289 -0
- package/src/utils/PageCache.ts +38 -5
- package/src/utils/ai-docs/utils-spec.md +391 -0
- package/src/webex.js +10 -0
- package/test/unit/spec/cc.ts +2210 -119
- package/test/unit/spec/logger-proxy.ts +70 -0
- package/test/unit/spec/metrics/MetricsManager.ts +25 -0
- package/test/unit/spec/metrics/behavioral-events.ts +60 -0
- package/test/unit/spec/services/AddressBook.ts +37 -6
- package/test/unit/spec/services/AnswerCallOnWebexService.ts +264 -0
- package/test/unit/spec/services/ApiAiAssistant.ts +311 -21
- package/test/unit/spec/services/EntryPoint.ts +87 -40
- package/test/unit/spec/services/Queue.ts +123 -12
- package/test/unit/spec/services/UserPreference.ts +401 -0
- package/test/unit/spec/services/WebCallingService.ts +7 -1
- package/test/unit/spec/services/WebexCrossClientService.ts +467 -0
- package/test/unit/spec/services/WxAppTelephonyMercurySync.ts +136 -0
- package/test/unit/spec/services/config/Util.ts +129 -0
- package/test/unit/spec/services/config/index.ts +97 -29
- package/test/unit/spec/services/core/Utils.ts +425 -8
- 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/core/websocket/WebSocketManager.ts +66 -40
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +745 -0
- package/test/unit/spec/services/task/TaskFactory.ts +99 -0
- package/test/unit/spec/services/task/TaskManager.ts +2518 -1494
- package/test/unit/spec/services/task/TaskUtils.ts +235 -0
- 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/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 +4060 -0
- package/test/unit/spec/services/task/state-machine/guards.ts +839 -0
- package/test/unit/spec/services/task/state-machine/types.ts +18 -0
- package/test/unit/spec/services/task/state-machine/uiControlsComputer.ts +3101 -0
- package/test/unit/spec/services/task/taskTestUtils.ts +87 -0
- package/test/unit/spec/services/task/voice/Voice.ts +2061 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -0
- package/test/unit/spec/services/task/voice/wxAppVoiceMethods.ts +603 -0
- package/test/unit/spec/services/wxAppDiagnosticLogging.ts +143 -0
- package/test/unit/spec/wellnessSampleUtils.ts +288 -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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {v4 as uuidv4} from 'uuid';
|
|
1
2
|
import LoggerProxy from '../logger-proxy';
|
|
2
3
|
import MetricsManager from '../metrics/MetricsManager';
|
|
3
4
|
import {METRIC_EVENT_NAMES} from '../metrics/constants';
|
|
@@ -6,10 +7,15 @@ import {
|
|
|
6
7
|
HTTP_METHODS,
|
|
7
8
|
WebexSDK,
|
|
8
9
|
IHttpResponse,
|
|
9
|
-
TranscriptAction,
|
|
10
10
|
AIAssistantEventType,
|
|
11
11
|
AIAssistantEventName,
|
|
12
12
|
HistoricTranscriptsResponse,
|
|
13
|
+
RealTimeAssistanceParams,
|
|
14
|
+
RealTimeAssistanceUserActionParams,
|
|
15
|
+
RespondToWellnessBreakParams,
|
|
16
|
+
WellnessBreakUserAction,
|
|
17
|
+
WELLNESS_BREAK_USER_ACTIONS,
|
|
18
|
+
GenericError,
|
|
13
19
|
} from '../types';
|
|
14
20
|
import {getErrorDetails} from './core/Utils';
|
|
15
21
|
import {
|
|
@@ -20,6 +26,12 @@ import {
|
|
|
20
26
|
} from './constants';
|
|
21
27
|
import {AIFeatureFlags} from './config/types';
|
|
22
28
|
|
|
29
|
+
type WellnessBreakContextProvider = () => {
|
|
30
|
+
isWellnessBreakEnabled: boolean;
|
|
31
|
+
agentId?: string;
|
|
32
|
+
agentSessionId?: string;
|
|
33
|
+
};
|
|
34
|
+
|
|
23
35
|
/**
|
|
24
36
|
* ApiAIAssistant provides AI Assistant APIs for transcript controls.
|
|
25
37
|
* @public
|
|
@@ -27,10 +39,24 @@ import {AIFeatureFlags} from './config/types';
|
|
|
27
39
|
export class ApiAIAssistant {
|
|
28
40
|
private webex: WebexSDK;
|
|
29
41
|
private metricsManager: MetricsManager;
|
|
30
|
-
|
|
42
|
+
private aiFeature: AIFeatureFlags;
|
|
43
|
+
private readonly wellnessContextProvider?: WellnessBreakContextProvider;
|
|
44
|
+
|
|
45
|
+
private createWellnessError(reason: string): GenericError {
|
|
46
|
+
const error = new Error(reason) as GenericError;
|
|
47
|
+
error.details = {
|
|
48
|
+
type: 'SDK_VALIDATION_ERROR',
|
|
49
|
+
orgId: this.webex.credentials.getOrgId(),
|
|
50
|
+
trackingId: '',
|
|
51
|
+
data: {reason},
|
|
52
|
+
};
|
|
31
53
|
|
|
32
|
-
|
|
54
|
+
return error;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
constructor(webex: WebexSDK, wellnessContextProvider?: WellnessBreakContextProvider) {
|
|
33
58
|
this.webex = webex;
|
|
59
|
+
this.wellnessContextProvider = wellnessContextProvider;
|
|
34
60
|
this.metricsManager = MetricsManager.getInstance({webex});
|
|
35
61
|
}
|
|
36
62
|
|
|
@@ -38,6 +64,134 @@ export class ApiAIAssistant {
|
|
|
38
64
|
this.aiFeature = aiFeature;
|
|
39
65
|
}
|
|
40
66
|
|
|
67
|
+
private async sendWellnessBreakAction(
|
|
68
|
+
action: WellnessBreakUserAction,
|
|
69
|
+
method: string
|
|
70
|
+
): Promise<void> {
|
|
71
|
+
this.metricsManager.timeEvent([
|
|
72
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED,
|
|
73
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_FAILED,
|
|
74
|
+
]);
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const context = this.wellnessContextProvider?.();
|
|
78
|
+
const agentId = context?.agentId?.trim();
|
|
79
|
+
const agentSessionId = context?.agentSessionId?.trim();
|
|
80
|
+
const orgId = this.webex.credentials.getOrgId()?.trim();
|
|
81
|
+
|
|
82
|
+
if (context?.isWellnessBreakEnabled !== true) {
|
|
83
|
+
throw this.createWellnessError('WELLNESS_BREAK_NOT_ENABLED');
|
|
84
|
+
}
|
|
85
|
+
if (!orgId) {
|
|
86
|
+
throw this.createWellnessError('WELLNESS_BREAK_ORG_ID_REQUIRED');
|
|
87
|
+
}
|
|
88
|
+
if (!agentId) {
|
|
89
|
+
throw this.createWellnessError('WELLNESS_BREAK_AGENT_ID_REQUIRED');
|
|
90
|
+
}
|
|
91
|
+
if (!agentSessionId) {
|
|
92
|
+
throw this.createWellnessError('WELLNESS_BREAK_AGENT_SESSION_REQUIRED');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const baseUrl = this.getBaseUrl();
|
|
96
|
+
const response = (await this.webex.request({
|
|
97
|
+
uri: `${baseUrl}${AI_ASSISTANT_API_URLS.EVENT}`,
|
|
98
|
+
method: HTTP_METHODS.POST,
|
|
99
|
+
addAuthHeader: true,
|
|
100
|
+
body: {
|
|
101
|
+
agentId,
|
|
102
|
+
orgId,
|
|
103
|
+
eventType: AIAssistantEventType.CUSTOM_EVENT,
|
|
104
|
+
eventName: AIAssistantEventName.WELLNESS_BREAK_ACTION,
|
|
105
|
+
eventDetails: {
|
|
106
|
+
data: {
|
|
107
|
+
action,
|
|
108
|
+
agentSessionId,
|
|
109
|
+
actionTimeStamp: Date.now(),
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
})) as IHttpResponse;
|
|
114
|
+
|
|
115
|
+
if (response.statusCode !== 202) {
|
|
116
|
+
throw this.createWellnessError(
|
|
117
|
+
`WELLNESS_BREAK_ACTION_UNEXPECTED_STATUS_${response.statusCode}`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
this.metricsManager.trackEvent(
|
|
122
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_ACCEPTED,
|
|
123
|
+
{action},
|
|
124
|
+
['operational']
|
|
125
|
+
);
|
|
126
|
+
LoggerProxy.log('Wellness action accepted by AI Assistant', {
|
|
127
|
+
module: CC_FILE,
|
|
128
|
+
method,
|
|
129
|
+
data: {action},
|
|
130
|
+
});
|
|
131
|
+
} catch (error) {
|
|
132
|
+
this.metricsManager.trackEvent(
|
|
133
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_WELLNESS_ACTION_FAILED,
|
|
134
|
+
{
|
|
135
|
+
action,
|
|
136
|
+
error: error instanceof Error ? error.message : String(error),
|
|
137
|
+
},
|
|
138
|
+
['operational']
|
|
139
|
+
);
|
|
140
|
+
const {error: detailedError} = getErrorDetails(error, method, CC_FILE);
|
|
141
|
+
throw detailedError;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Requests an Agent Wellness Break.
|
|
147
|
+
* The promise resolves when the HTTP request is accepted with status 202; the later
|
|
148
|
+
* approval or denial is delivered independently through a wellness notification.
|
|
149
|
+
* @returns A promise that resolves with no value after HTTP acceptance
|
|
150
|
+
* @throws Structured Contact Center error when disabled, stale, invalid, or delivery fails
|
|
151
|
+
* @example
|
|
152
|
+
* await webex.cc.apiAIAssistant.requestWellnessBreak();
|
|
153
|
+
* @public
|
|
154
|
+
*/
|
|
155
|
+
public async requestWellnessBreak(): Promise<void> {
|
|
156
|
+
return this.sendWellnessBreakAction(
|
|
157
|
+
WELLNESS_BREAK_USER_ACTIONS.REQUESTED,
|
|
158
|
+
METHODS.REQUEST_WELLNESS_BREAK
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Responds to a backend-provided Agent Wellness Break offer.
|
|
164
|
+
* The promise resolves when the HTTP request is accepted with status 202 and does not
|
|
165
|
+
* wait for a WebSocket completion event.
|
|
166
|
+
* @param params - ACCEPTED, REJECTED, or NO_RESPONSE
|
|
167
|
+
* @returns A promise that resolves with no value after HTTP acceptance
|
|
168
|
+
* @throws Structured Contact Center error when disabled, stale, invalid, or delivery fails
|
|
169
|
+
* @example
|
|
170
|
+
* await webex.cc.apiAIAssistant.respondToWellnessBreak({
|
|
171
|
+
* action: WELLNESS_BREAK_USER_ACTIONS.ACCEPTED,
|
|
172
|
+
* });
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
public async respondToWellnessBreak(params: RespondToWellnessBreakParams): Promise<void> {
|
|
176
|
+
const {action} = params;
|
|
177
|
+
if (
|
|
178
|
+
![
|
|
179
|
+
WELLNESS_BREAK_USER_ACTIONS.ACCEPTED,
|
|
180
|
+
WELLNESS_BREAK_USER_ACTIONS.REJECTED,
|
|
181
|
+
WELLNESS_BREAK_USER_ACTIONS.NO_RESPONSE,
|
|
182
|
+
].includes(action)
|
|
183
|
+
) {
|
|
184
|
+
const {error} = getErrorDetails(
|
|
185
|
+
this.createWellnessError('WELLNESS_BREAK_ACTION_INVALID'),
|
|
186
|
+
METHODS.RESPOND_TO_WELLNESS_BREAK,
|
|
187
|
+
CC_FILE
|
|
188
|
+
);
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return this.sendWellnessBreakAction(action, METHODS.RESPOND_TO_WELLNESS_BREAK);
|
|
193
|
+
}
|
|
194
|
+
|
|
41
195
|
private getBaseUrl(): string {
|
|
42
196
|
const wccApiGatewayUrl = this.webex.internal.services.get(WCC_API_GATEWAY) || '';
|
|
43
197
|
|
|
@@ -76,20 +230,24 @@ export class ApiAIAssistant {
|
|
|
76
230
|
* @param interactionId - interaction/conversation identifier
|
|
77
231
|
* @param eventType - the type of event (e.g. 'CUSTOM_EVENT')
|
|
78
232
|
* @param eventName - the name of the event (e.g. 'GET_TRANSCRIPTS')
|
|
79
|
-
* @param
|
|
233
|
+
* @param eventMetaData - event-specific fields to include in eventDetails.data
|
|
234
|
+
* @param languageCode - language code within eventDetails.data
|
|
235
|
+
* @param trackingId - tracking identifier within eventDetails.data
|
|
80
236
|
*/
|
|
81
237
|
public async sendEvent(
|
|
82
238
|
agentId: string,
|
|
83
239
|
interactionId: string,
|
|
84
240
|
eventType: AIAssistantEventType,
|
|
85
241
|
eventName: AIAssistantEventName,
|
|
86
|
-
|
|
242
|
+
eventMetaData?: Record<string, unknown>,
|
|
243
|
+
languageCode?: string,
|
|
244
|
+
trackingId?: string
|
|
87
245
|
): Promise<Record<string, unknown>> {
|
|
88
246
|
LoggerProxy.info('Sending event', {
|
|
89
247
|
module: CC_FILE,
|
|
90
248
|
method: METHODS.SEND_EVENT,
|
|
91
249
|
interactionId,
|
|
92
|
-
data: {eventType, eventName,
|
|
250
|
+
data: {eventType, eventName, eventMetaData},
|
|
93
251
|
});
|
|
94
252
|
this.metricsManager.timeEvent([
|
|
95
253
|
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_EVENT_SUCCESS,
|
|
@@ -110,9 +268,11 @@ export class ApiAIAssistant {
|
|
|
110
268
|
eventName,
|
|
111
269
|
eventDetails: {
|
|
112
270
|
data: {
|
|
271
|
+
...eventMetaData,
|
|
113
272
|
interactionId,
|
|
114
|
-
action,
|
|
115
273
|
actionTimeStamp: String(Date.now()),
|
|
274
|
+
languageCode,
|
|
275
|
+
trackingId,
|
|
116
276
|
},
|
|
117
277
|
},
|
|
118
278
|
},
|
|
@@ -120,7 +280,7 @@ export class ApiAIAssistant {
|
|
|
120
280
|
|
|
121
281
|
this.metricsManager.trackEvent(
|
|
122
282
|
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_EVENT_SUCCESS,
|
|
123
|
-
{agentId, orgId, interactionId, eventType, eventName
|
|
283
|
+
{agentId, orgId, interactionId, eventType, eventName},
|
|
124
284
|
['operational']
|
|
125
285
|
);
|
|
126
286
|
|
|
@@ -132,7 +292,6 @@ export class ApiAIAssistant {
|
|
|
132
292
|
interactionId,
|
|
133
293
|
eventType,
|
|
134
294
|
eventName,
|
|
135
|
-
action,
|
|
136
295
|
error: error instanceof Error ? error.message : String(error),
|
|
137
296
|
},
|
|
138
297
|
['operational']
|
|
@@ -143,6 +302,193 @@ export class ApiAIAssistant {
|
|
|
143
302
|
}
|
|
144
303
|
}
|
|
145
304
|
|
|
305
|
+
/**
|
|
306
|
+
* Requests real-time assistance for an interaction.
|
|
307
|
+
*
|
|
308
|
+
* @param params - Real-time assistance request parameters
|
|
309
|
+
* @returns HTTP response body from the AI Assistant event API
|
|
310
|
+
* @public
|
|
311
|
+
*/
|
|
312
|
+
public async getRealTimeAssistance(params: RealTimeAssistanceParams) {
|
|
313
|
+
const {agentId, interactionId, context} = params;
|
|
314
|
+
const trimmedContext = context?.trim();
|
|
315
|
+
const languageCode = params.languageCode ?? 'en';
|
|
316
|
+
const trackingId = `WX_CC_SDK_${uuidv4()}`;
|
|
317
|
+
const eventName = trimmedContext
|
|
318
|
+
? AIAssistantEventName.ADD_SUGGESTIONS_EXTRA_CONTEXT
|
|
319
|
+
: AIAssistantEventName.GET_SUGGESTIONS;
|
|
320
|
+
|
|
321
|
+
const loggerContext = {
|
|
322
|
+
module: CC_FILE,
|
|
323
|
+
method: METHODS.GET_REAL_TIME_ASSISTANCE,
|
|
324
|
+
interactionId,
|
|
325
|
+
trackingId,
|
|
326
|
+
data: {eventName},
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
LoggerProxy.info('Requesting real-time assistance', loggerContext);
|
|
330
|
+
|
|
331
|
+
this.metricsManager.timeEvent([
|
|
332
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS,
|
|
333
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED,
|
|
334
|
+
]);
|
|
335
|
+
|
|
336
|
+
try {
|
|
337
|
+
if (!this.aiFeature?.suggestedResponses?.enable) {
|
|
338
|
+
const {error: detailedError} = getErrorDetails(
|
|
339
|
+
new Error('SUGGESTED_RESPONSES_NOT_ENABLED'),
|
|
340
|
+
METHODS.GET_REAL_TIME_ASSISTANCE,
|
|
341
|
+
CC_FILE
|
|
342
|
+
);
|
|
343
|
+
throw detailedError;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const orgId = this.webex.credentials.getOrgId();
|
|
347
|
+
|
|
348
|
+
const response = await this.sendEvent(
|
|
349
|
+
agentId,
|
|
350
|
+
interactionId,
|
|
351
|
+
AIAssistantEventType.CUSTOM_EVENT,
|
|
352
|
+
eventName,
|
|
353
|
+
trimmedContext !== undefined ? {context: trimmedContext} : undefined,
|
|
354
|
+
languageCode,
|
|
355
|
+
trackingId
|
|
356
|
+
);
|
|
357
|
+
|
|
358
|
+
this.metricsManager.trackEvent(
|
|
359
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS,
|
|
360
|
+
{
|
|
361
|
+
agentId,
|
|
362
|
+
orgId,
|
|
363
|
+
interactionId,
|
|
364
|
+
eventName,
|
|
365
|
+
trackingId,
|
|
366
|
+
context,
|
|
367
|
+
},
|
|
368
|
+
['operational']
|
|
369
|
+
);
|
|
370
|
+
LoggerProxy.log('Real-time assistance request succeeded', loggerContext);
|
|
371
|
+
|
|
372
|
+
return response;
|
|
373
|
+
} catch (error) {
|
|
374
|
+
LoggerProxy.error('Real-time assistance request failed', {...loggerContext, error});
|
|
375
|
+
this.metricsManager.trackEvent(
|
|
376
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED,
|
|
377
|
+
{
|
|
378
|
+
agentId,
|
|
379
|
+
interactionId,
|
|
380
|
+
trackingId,
|
|
381
|
+
eventName,
|
|
382
|
+
error: error instanceof Error ? error.message : String(error),
|
|
383
|
+
},
|
|
384
|
+
['operational']
|
|
385
|
+
);
|
|
386
|
+
|
|
387
|
+
const {error: detailedError} = getErrorDetails(
|
|
388
|
+
error,
|
|
389
|
+
METHODS.GET_REAL_TIME_ASSISTANCE,
|
|
390
|
+
CC_FILE
|
|
391
|
+
);
|
|
392
|
+
throw detailedError;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Sends user action feedback for a real-time assistance adaptive card.
|
|
398
|
+
*
|
|
399
|
+
* @param params - Real-time assistance user action parameters
|
|
400
|
+
* @returns HTTP response body from the AI Assistant event API
|
|
401
|
+
* @public
|
|
402
|
+
*/
|
|
403
|
+
public async sendRealTimeAssistanceUserAction(
|
|
404
|
+
params: RealTimeAssistanceUserActionParams
|
|
405
|
+
): Promise<Record<string, unknown>> {
|
|
406
|
+
const {agentId, interactionId, adaptiveCardId, actionId} = params;
|
|
407
|
+
const actionType = 'Action.Submit';
|
|
408
|
+
const languageCode = params.languageCode ?? 'en';
|
|
409
|
+
const trackingId = `WX_CC_SDK_${uuidv4()}`;
|
|
410
|
+
|
|
411
|
+
const loggerContext = {
|
|
412
|
+
module: CC_FILE,
|
|
413
|
+
method: METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
|
|
414
|
+
interactionId,
|
|
415
|
+
trackingId,
|
|
416
|
+
data: {actionId, adaptiveCardId},
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
LoggerProxy.info('Sending real-time assistance user action', loggerContext);
|
|
420
|
+
|
|
421
|
+
this.metricsManager.timeEvent([
|
|
422
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS,
|
|
423
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED,
|
|
424
|
+
]);
|
|
425
|
+
|
|
426
|
+
try {
|
|
427
|
+
if (!this.aiFeature?.suggestedResponses?.enable) {
|
|
428
|
+
const {error: detailedError} = getErrorDetails(
|
|
429
|
+
new Error('SUGGESTED_RESPONSES_NOT_ENABLED'),
|
|
430
|
+
METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
|
|
431
|
+
CC_FILE
|
|
432
|
+
);
|
|
433
|
+
throw detailedError;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const orgId = this.webex.credentials.getOrgId();
|
|
437
|
+
const response = await this.sendEvent(
|
|
438
|
+
agentId,
|
|
439
|
+
interactionId,
|
|
440
|
+
AIAssistantEventType.CUSTOM_EVENT,
|
|
441
|
+
AIAssistantEventName.SUGGESTED_RESPONSES_USER_ACTION,
|
|
442
|
+
{
|
|
443
|
+
adaptiveCardId,
|
|
444
|
+
userAction: {
|
|
445
|
+
actionType,
|
|
446
|
+
actionId,
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
languageCode,
|
|
450
|
+
trackingId
|
|
451
|
+
);
|
|
452
|
+
|
|
453
|
+
this.metricsManager.trackEvent(
|
|
454
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS,
|
|
455
|
+
{
|
|
456
|
+
agentId,
|
|
457
|
+
orgId,
|
|
458
|
+
interactionId,
|
|
459
|
+
adaptiveCardId,
|
|
460
|
+
actionId,
|
|
461
|
+
trackingId,
|
|
462
|
+
},
|
|
463
|
+
['operational']
|
|
464
|
+
);
|
|
465
|
+
LoggerProxy.log('Real-time assistance user action sent', loggerContext);
|
|
466
|
+
|
|
467
|
+
return response;
|
|
468
|
+
} catch (error) {
|
|
469
|
+
LoggerProxy.error('Real-time assistance user action failed', {...loggerContext, error});
|
|
470
|
+
this.metricsManager.trackEvent(
|
|
471
|
+
METRIC_EVENT_NAMES.AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED,
|
|
472
|
+
{
|
|
473
|
+
agentId,
|
|
474
|
+
interactionId,
|
|
475
|
+
adaptiveCardId,
|
|
476
|
+
actionId,
|
|
477
|
+
trackingId,
|
|
478
|
+
error: error instanceof Error ? error.message : String(error),
|
|
479
|
+
},
|
|
480
|
+
['operational']
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
const {error: detailedError} = getErrorDetails(
|
|
484
|
+
error,
|
|
485
|
+
METHODS.SEND_REAL_TIME_ASSISTANCE_USER_ACTION,
|
|
486
|
+
CC_FILE
|
|
487
|
+
);
|
|
488
|
+
throw detailedError;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
146
492
|
/**
|
|
147
493
|
* Fetches historic transcripts for an interaction.
|
|
148
494
|
* This API is allowed only when real-time transcription feature is enabled.
|
|
@@ -201,6 +547,7 @@ export class ApiAIAssistant {
|
|
|
201
547
|
},
|
|
202
548
|
['operational']
|
|
203
549
|
);
|
|
550
|
+
|
|
204
551
|
if (error instanceof Error) {
|
|
205
552
|
throw error;
|
|
206
553
|
}
|
|
@@ -2,12 +2,40 @@ import {HTTP_METHODS, WebexSDK} from '../types';
|
|
|
2
2
|
import type {EntryPointRecord, EntryPointListResponse, EntryPointSearchParams} from '../types';
|
|
3
3
|
import LoggerProxy from '../logger-proxy';
|
|
4
4
|
import WebexRequest from './core/WebexRequest';
|
|
5
|
-
import
|
|
5
|
+
import {PAGINATION_DEFAULTS} from '../utils/PageCache';
|
|
6
6
|
import MetricsManager from '../metrics/MetricsManager';
|
|
7
7
|
import {WCC_API_GATEWAY} from './constants';
|
|
8
8
|
import {endPointMap} from './config/constants';
|
|
9
9
|
import {METRIC_EVENT_NAMES} from '../metrics/constants';
|
|
10
10
|
|
|
11
|
+
const DEFAULT_ENTRY_POINT_ATTRIBUTES = 'id,dialledNumber,entryPointId,entryPointName';
|
|
12
|
+
const DEFAULT_ENTRY_POINT_SORT_FIELD = 'entryPointName';
|
|
13
|
+
|
|
14
|
+
type DialNumberEntryPointRecord = {
|
|
15
|
+
id: string;
|
|
16
|
+
dialledNumber?: string;
|
|
17
|
+
entryPointId: string;
|
|
18
|
+
entryPointName: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const mergeEntryPointAttributes = (attributes?: string): string => {
|
|
22
|
+
const mergedAttributes = new Set(DEFAULT_ENTRY_POINT_ATTRIBUTES.split(','));
|
|
23
|
+
|
|
24
|
+
attributes
|
|
25
|
+
?.split(',')
|
|
26
|
+
.map((attribute) => attribute.trim())
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.forEach((attribute) => mergedAttributes.add(attribute));
|
|
29
|
+
|
|
30
|
+
return Array.from(mergedAttributes).join(',');
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const mapDialNumberEntryPoint = (item: DialNumberEntryPointRecord): EntryPointRecord => ({
|
|
34
|
+
id: item.entryPointId,
|
|
35
|
+
name: item.entryPointName,
|
|
36
|
+
...(item.dialledNumber ? {number: item.dialledNumber} : {}),
|
|
37
|
+
});
|
|
38
|
+
|
|
11
39
|
/**
|
|
12
40
|
* EntryPoint class for managing Webex Contact Center entry points.
|
|
13
41
|
* Provides functionality to fetch, search, and paginate through entry points.
|
|
@@ -35,7 +63,7 @@ import {METRIC_EVENT_NAMES} from '../metrics/constants';
|
|
|
35
63
|
* });
|
|
36
64
|
*
|
|
37
65
|
* // Search for specific entry points
|
|
38
|
-
* const searchResults = await entryPointAPI.
|
|
66
|
+
* const searchResults = await entryPointAPI.getEntryPoints({
|
|
39
67
|
* search: 'support',
|
|
40
68
|
* filter: 'type=="voice"'
|
|
41
69
|
* });
|
|
@@ -46,9 +74,6 @@ export class EntryPoint {
|
|
|
46
74
|
private webex: WebexSDK;
|
|
47
75
|
private metricsManager: MetricsManager;
|
|
48
76
|
|
|
49
|
-
// Page cache using the common utility
|
|
50
|
-
private pageCache: PageCache<EntryPointRecord>;
|
|
51
|
-
|
|
52
77
|
/**
|
|
53
78
|
* Creates an instance of EntryPoint
|
|
54
79
|
* @param {WebexSDK} webex - The Webex SDK instance
|
|
@@ -57,19 +82,21 @@ export class EntryPoint {
|
|
|
57
82
|
constructor(webex: WebexSDK) {
|
|
58
83
|
this.webex = webex;
|
|
59
84
|
this.webexRequest = WebexRequest.getInstance({webex});
|
|
60
|
-
this.pageCache = new PageCache<EntryPointRecord>('EntryPoint');
|
|
61
85
|
this.metricsManager = MetricsManager.getInstance({webex});
|
|
62
86
|
}
|
|
63
87
|
|
|
64
88
|
/**
|
|
65
|
-
* Fetches entry
|
|
66
|
-
*
|
|
89
|
+
* Fetches entry-point dial-number mappings for the organization with pagination support. By
|
|
90
|
+
* default, returns the agent's desktop-profile-filtered mappings in backend entry-point-name order.
|
|
91
|
+
* Search, filter, attribute, and sort parameters can customize the request while desktop-profile
|
|
92
|
+
* scoping and required mapping fields remain SDK-owned.
|
|
93
|
+
* @param {EntryPointSearchParams} [params] - Search, pagination, and compatible override parameters.
|
|
67
94
|
* @returns {Promise<EntryPointListResponse>} Promise resolving to paginated entry points
|
|
68
95
|
* @throws {Error} If the API call fails
|
|
69
96
|
* @public
|
|
70
97
|
* @example
|
|
71
98
|
* ```typescript
|
|
72
|
-
* // Get first page
|
|
99
|
+
* // Get the first page using the default entry-point policy
|
|
73
100
|
* const response = await entryPointAPI.getEntryPoints();
|
|
74
101
|
*
|
|
75
102
|
* // Get specific page with custom page size
|
|
@@ -89,12 +116,14 @@ export class EntryPoint {
|
|
|
89
116
|
search,
|
|
90
117
|
filter,
|
|
91
118
|
attributes,
|
|
92
|
-
sortBy,
|
|
119
|
+
sortBy = 'name',
|
|
93
120
|
sortOrder = 'asc',
|
|
94
121
|
} = params;
|
|
95
122
|
|
|
96
123
|
const orgId = this.webex.credentials.getOrgId();
|
|
97
|
-
const
|
|
124
|
+
const hasCustomSort = sortBy !== 'name' || sortOrder !== 'asc';
|
|
125
|
+
const isSearchRequest = !!(search || filter || attributes || hasCustomSort);
|
|
126
|
+
const effectiveSortBy = sortBy === 'name' ? DEFAULT_ENTRY_POINT_SORT_FIELD : sortBy;
|
|
98
127
|
|
|
99
128
|
LoggerProxy.info(
|
|
100
129
|
`Fetching entry points - orgId: ${orgId}, page: ${page}, pageSize: ${pageSize}, isSearchRequest: ${isSearchRequest}`,
|
|
@@ -104,51 +133,24 @@ export class EntryPoint {
|
|
|
104
133
|
}
|
|
105
134
|
);
|
|
106
135
|
|
|
107
|
-
// Check if we can use cache for simple pagination (no search/filter/attributes/sort)
|
|
108
|
-
if (this.pageCache.canUseCache({search, filter, attributes, sortBy})) {
|
|
109
|
-
const cacheKey = this.pageCache.buildCacheKey(orgId, page, pageSize);
|
|
110
|
-
const cachedPage = this.pageCache.getCachedPage(cacheKey);
|
|
111
|
-
|
|
112
|
-
if (cachedPage) {
|
|
113
|
-
const duration = Date.now() - startTime;
|
|
114
|
-
|
|
115
|
-
LoggerProxy.log(
|
|
116
|
-
`Returning page ${page} from cache - cacheHit: true, duration: ${duration}ms, recordCount: ${cachedPage.data.length}, pageSize: ${pageSize}`,
|
|
117
|
-
{
|
|
118
|
-
module: 'EntryPoint',
|
|
119
|
-
method: 'getEntryPoints',
|
|
120
|
-
}
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
return {
|
|
124
|
-
data: cachedPage.data,
|
|
125
|
-
meta: {
|
|
126
|
-
page,
|
|
127
|
-
pageSize,
|
|
128
|
-
totalPages: cachedPage.totalMeta?.totalPages,
|
|
129
|
-
totalRecords: cachedPage.totalMeta?.totalRecords,
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Start timing only for actual API calls (not cache hits)
|
|
136
136
|
this.metricsManager.timeEvent(METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS);
|
|
137
137
|
|
|
138
138
|
try {
|
|
139
|
-
// Build query parameters
|
|
140
139
|
const queryParams = new URLSearchParams({
|
|
141
140
|
page: page.toString(),
|
|
142
141
|
pageSize: pageSize.toString(),
|
|
143
|
-
|
|
142
|
+
attributes: mergeEntryPointAttributes(attributes),
|
|
144
143
|
});
|
|
145
144
|
|
|
146
145
|
if (search) queryParams.append('search', search);
|
|
147
146
|
if (filter) queryParams.append('filter', filter);
|
|
148
|
-
if (
|
|
149
|
-
|
|
147
|
+
if (effectiveSortBy) {
|
|
148
|
+
queryParams.append('sort', `${effectiveSortBy},${sortOrder.toUpperCase()}`);
|
|
149
|
+
}
|
|
150
|
+
queryParams.append('desktopProfileFilter', 'true');
|
|
151
|
+
queryParams.append('includeEntryPointName', 'true');
|
|
150
152
|
|
|
151
|
-
const resource = endPointMap.
|
|
153
|
+
const resource = endPointMap.entryPointDialNumberList(orgId, queryParams.toString());
|
|
152
154
|
|
|
153
155
|
LoggerProxy.log(
|
|
154
156
|
`Making API request to fetch entry points - resource: ${resource}, service: ${WCC_API_GATEWAY}`,
|
|
@@ -162,12 +164,21 @@ export class EntryPoint {
|
|
|
162
164
|
service: WCC_API_GATEWAY,
|
|
163
165
|
resource,
|
|
164
166
|
method: HTTP_METHODS.GET,
|
|
167
|
+
headers: {
|
|
168
|
+
'X-ORGANIZATION-ID': orgId,
|
|
169
|
+
'x-ignore-internal-data': 'false',
|
|
170
|
+
},
|
|
165
171
|
});
|
|
166
172
|
|
|
173
|
+
const responseBody: EntryPointListResponse = {
|
|
174
|
+
...response.body,
|
|
175
|
+
data: (response.body?.data ?? []).map(mapDialNumberEntryPoint),
|
|
176
|
+
};
|
|
177
|
+
|
|
167
178
|
const duration = Date.now() - startTime;
|
|
168
179
|
|
|
169
|
-
const recordCount =
|
|
170
|
-
const totalRecords =
|
|
180
|
+
const recordCount = responseBody.data.length;
|
|
181
|
+
const totalRecords = responseBody.meta?.totalRecords;
|
|
171
182
|
|
|
172
183
|
LoggerProxy.log(`Successfully retrieved ${recordCount} entry points`, {
|
|
173
184
|
module: 'EntryPoint',
|
|
@@ -199,19 +210,7 @@ export class EntryPoint {
|
|
|
199
210
|
);
|
|
200
211
|
}
|
|
201
212
|
|
|
202
|
-
|
|
203
|
-
if (this.pageCache.canUseCache({search, filter, attributes, sortBy}) && response.body?.data) {
|
|
204
|
-
const cacheKey = this.pageCache.buildCacheKey(orgId, page, pageSize);
|
|
205
|
-
this.pageCache.cachePage(cacheKey, response.body.data, response.body.meta);
|
|
206
|
-
|
|
207
|
-
LoggerProxy.log('Cached entry points data for future requests', {
|
|
208
|
-
module: 'EntryPoint',
|
|
209
|
-
method: 'getEntryPoints',
|
|
210
|
-
data: {cacheKey, recordCount},
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return response.body;
|
|
213
|
+
return responseBody;
|
|
215
214
|
} catch (error) {
|
|
216
215
|
const errorData = {
|
|
217
216
|
orgId,
|