@webex/contact-center 3.11.0 → 3.12.0-auth-prejoin-fetch.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.sdd/manifest.json +883 -0
- package/AGENTS.md +94 -0
- package/ai-docs/ARCHITECTURE.md +168 -0
- package/ai-docs/CONTRACTS.md +50 -0
- package/ai-docs/GETTING_STARTED.md +168 -0
- package/ai-docs/GLOSSARY.md +43 -0
- package/ai-docs/README.md +138 -0
- package/ai-docs/REVIEW_CHECKLIST.md +41 -0
- package/ai-docs/RULES.md +444 -0
- package/ai-docs/SECURITY.md +52 -0
- package/ai-docs/SERVICE_STATE.md +48 -0
- package/ai-docs/SPEC_INDEX.md +65 -0
- package/ai-docs/adr/0001-spec-source-policy.md +55 -0
- package/ai-docs/adr/README.md +8 -0
- package/ai-docs/adr/_adr-template.md +31 -0
- package/ai-docs/contact-center-spec.md +359 -0
- package/ai-docs/features/consult-transfer-list-policy/spec/feature-spec.md +362 -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 +818 -59
- 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 +27 -5
- package/dist/index.js.map +1 -1
- package/dist/metrics/behavioral-events.js +127 -0
- package/dist/metrics/behavioral-events.js.map +1 -1
- package/dist/metrics/constants.js +34 -3
- 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/ApiAiAssistant.js +318 -0
- package/dist/services/ApiAiAssistant.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/UserPreference.js +427 -0
- package/dist/services/UserPreference.js.map +1 -0
- 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/agent/types.js.map +1 -1
- package/dist/services/config/Util.js +11 -4
- package/dist/services/config/Util.js.map +1 -1
- package/dist/services/config/constants.js +45 -8
- package/dist/services/config/constants.js.map +1 -1
- package/dist/services/config/index.js +41 -2
- package/dist/services/config/index.js.map +1 -1
- package/dist/services/config/types.js +70 -8
- package/dist/services/config/types.js.map +1 -1
- package/dist/services/constants.js +27 -1
- package/dist/services/constants.js.map +1 -1
- package/dist/services/core/Err.js.map +1 -1
- package/dist/services/core/Utils.js +122 -25
- package/dist/services/core/Utils.js.map +1 -1
- package/dist/services/core/WebexRequest.js +6 -2
- package/dist/services/core/WebexRequest.js.map +1 -1
- package/dist/services/core/aqm-reqs.js +119 -30
- 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 +22 -6
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
- package/dist/services/core/websocket/connection-service.js +3 -1
- package/dist/services/core/websocket/connection-service.js.map +1 -1
- package/dist/services/core/websocket/types.js.map +1 -1
- package/dist/services/index.js +6 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/task/Task.js +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 +1073 -447
- package/dist/services/task/TaskManager.js.map +1 -1
- package/dist/services/task/TaskUtils.js +220 -23
- package/dist/services/task/TaskUtils.js.map +1 -1
- package/dist/services/task/WebexCallingUtils.js +70 -0
- package/dist/services/task/WebexCallingUtils.js.map +1 -0
- package/dist/services/task/constants.js +26 -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 +129 -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 +971 -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 +409 -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 +243 -5
- package/dist/services/task/types.js.map +1 -1
- package/dist/services/task/voice/Voice.js +1380 -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 +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 +967 -0
- package/dist/types/config.d.ts +79 -0
- package/dist/types/constants.d.ts +74 -0
- package/dist/types/index.d.ts +201 -0
- package/dist/types/logger-proxy.d.ts +71 -0
- package/dist/types/metrics/MetricsManager.d.ts +223 -0
- package/dist/types/metrics/behavioral-events.d.ts +29 -0
- package/dist/types/metrics/constants.d.ts +183 -0
- package/dist/types/services/AddressBook.d.ts +75 -0
- package/dist/types/services/AnswerCallOnWebexService.d.ts +37 -0
- package/dist/types/services/ApiAiAssistant.d.ts +49 -0
- package/dist/types/services/EntryPoint.d.ts +69 -0
- package/dist/types/services/Queue.d.ts +78 -0
- package/dist/types/services/UserPreference.d.ts +118 -0
- package/dist/types/services/WebCallingService.d.ts +1 -0
- package/dist/types/services/WebexCrossClientService.d.ts +28 -0
- package/dist/types/services/WxAppTelephonyMercurySync.d.ts +28 -0
- package/dist/types/services/agent/index.d.ts +46 -0
- package/dist/types/services/agent/types.d.ts +413 -0
- package/dist/types/services/config/Util.d.ts +20 -0
- package/dist/types/services/config/constants.d.ts +273 -0
- package/dist/types/services/config/index.d.ts +177 -0
- package/dist/types/services/config/types.d.ts +1381 -0
- package/dist/types/services/constants.d.ts +110 -0
- package/dist/types/services/core/Err.d.ts +127 -0
- package/dist/types/services/core/GlobalTypes.d.ts +58 -0
- package/dist/types/services/core/Utils.d.ts +121 -0
- package/dist/types/services/core/WebexRequest.d.ts +23 -0
- package/dist/types/services/core/aqm-reqs.d.ts +65 -0
- package/dist/types/services/core/constants.d.ts +99 -0
- package/dist/types/services/core/types.d.ts +49 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +36 -0
- package/dist/types/services/core/websocket/connection-service.d.ts +27 -0
- package/dist/types/services/core/websocket/keepalive.worker.d.ts +2 -0
- package/dist/types/services/core/websocket/types.d.ts +37 -0
- package/dist/types/services/index.d.ts +54 -0
- package/dist/types/services/task/AutoWrapup.d.ts +40 -0
- package/dist/types/services/task/Task.d.ts +175 -0
- package/dist/types/services/task/TaskFactory.d.ts +13 -0
- package/dist/types/services/task/TaskManager.d.ts +1 -0
- package/dist/types/services/task/TaskUtils.d.ts +138 -0
- package/dist/types/services/task/WebexCallingUtils.d.ts +11 -0
- package/dist/types/services/task/constants.d.ts +94 -0
- package/dist/types/services/task/contact.d.ts +73 -0
- package/dist/types/services/task/dialer.d.ts +73 -0
- package/dist/types/services/task/digital/Digital.d.ts +22 -0
- package/dist/types/services/task/state-machine/TaskStateMachine.d.ts +1398 -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 +1933 -0
- package/dist/types/services/task/voice/Voice.d.ts +223 -0
- package/dist/types/services/task/voice/WebRTC.d.ts +53 -0
- 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 +784 -0
- package/dist/types/utils/PageCache.d.ts +190 -0
- package/dist/types/webex-config.d.ts +53 -0
- package/dist/types/webex.d.ts +8 -0
- package/dist/types.js +137 -3
- 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 +14 -2
- package/dist/webex.js.map +1 -1
- package/package.json +16 -12
- package/src/cc.ts +983 -60
- package/src/config.ts +13 -0
- package/src/constants.ts +29 -1
- package/src/index.ts +26 -5
- package/src/metrics/ai-docs/AGENTS.md +350 -0
- package/src/metrics/ai-docs/ARCHITECTURE.md +338 -0
- package/src/metrics/ai-docs/metrics-spec.md +860 -0
- package/src/metrics/behavioral-events.ts +134 -0
- package/src/metrics/constants.ts +39 -3
- package/src/services/AddressBook.ts +17 -6
- package/src/services/AnswerCallOnWebexService.ts +206 -0
- package/src/services/ApiAiAssistant.ts +412 -0
- 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 +212 -0
- package/src/services/WxAppTelephonyMercurySync.ts +115 -0
- package/src/services/agent/ai-docs/AGENTS.md +240 -0
- package/src/services/agent/ai-docs/ARCHITECTURE.md +304 -0
- package/src/services/agent/ai-docs/agent-spec.md +504 -0
- package/src/services/agent/types.ts +1 -1
- package/src/services/ai-docs/AGENTS.md +386 -0
- package/src/services/ai-docs/services-spec.md +497 -0
- package/src/services/config/Util.ts +13 -2
- package/src/services/config/ai-docs/AGENTS.md +255 -0
- package/src/services/config/ai-docs/ARCHITECTURE.md +426 -0
- package/src/services/config/ai-docs/config-spec.md +675 -0
- package/src/services/config/constants.ts +47 -7
- package/src/services/config/index.ts +45 -1
- package/src/services/config/types.ts +253 -11
- package/src/services/constants.ts +29 -0
- package/src/services/core/Err.ts +4 -0
- package/src/services/core/Utils.ts +143 -30
- 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 +125 -32
- package/src/services/core/types.ts +2 -0
- package/src/services/core/websocket/WebSocketManager.ts +23 -6
- package/src/services/core/websocket/connection-service.ts +5 -1
- package/src/services/core/websocket/types.ts +1 -1
- package/src/services/index.ts +4 -0
- package/src/services/task/Task.ts +908 -0
- package/src/services/task/TaskFactory.ts +60 -0
- package/src/services/task/TaskManager.ts +1291 -513
- package/src/services/task/TaskUtils.ts +314 -24
- 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 +1469 -0
- package/src/services/task/constants.ts +26 -0
- package/src/services/task/contact.ts +30 -0
- package/src/services/task/dialer.ts +136 -1
- package/src/services/task/digital/Digital.ts +97 -0
- package/src/services/task/state-machine/TaskStateMachine.ts +1313 -0
- package/src/services/task/state-machine/actions.ts +741 -0
- package/src/services/task/state-machine/ai-docs/AGENTS.md +462 -0
- package/src/services/task/state-machine/ai-docs/ARCHITECTURE.md +1146 -0
- package/src/services/task/state-machine/ai-docs/task-state-machine-spec.md +2209 -0
- package/src/services/task/state-machine/constants.ts +172 -0
- package/src/services/task/state-machine/guards.ts +498 -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 +843 -70
- package/src/services/task/voice/Voice.ts +1720 -0
- package/src/services/task/voice/WebRTC.ts +191 -0
- package/src/services/task/voice/wxAppVoiceMethods.ts +307 -0
- package/src/services/wxAppTelephonyUtils.ts +14 -0
- package/src/types.ts +238 -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 +2 -0
- package/test/unit/spec/cc.ts +1856 -122
- package/test/unit/spec/logger-proxy.ts +70 -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/ApiAiAssistant.ts +273 -0
- 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 +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/config/index.ts +85 -29
- package/test/unit/spec/services/core/Utils.ts +481 -2
- 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 +137 -41
- package/test/unit/spec/services/core/websocket/connection-service.ts +3 -1
- package/test/unit/spec/services/task/AutoWrapup.ts +63 -0
- package/test/unit/spec/services/task/Task.ts +677 -0
- package/test/unit/spec/services/task/TaskFactory.ts +99 -0
- package/test/unit/spec/services/task/TaskManager.ts +2209 -918
- 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 +372 -96
- package/test/unit/spec/services/task/digital/Digital.ts +105 -0
- package/test/unit/spec/services/task/state-machine/TaskStateMachine.ts +3433 -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 +1523 -0
- package/test/unit/spec/services/task/voice/WebRTC.ts +235 -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/services/task/index.js +0 -1525
- package/dist/services/task/index.js.map +0 -1
- package/src/services/task/index.ts +0 -1801
- package/test/unit/spec/services/task/index.ts +0 -2184
|
@@ -352,6 +352,48 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
|
|
|
352
352
|
verb: 'fail',
|
|
353
353
|
},
|
|
354
354
|
|
|
355
|
+
// Conference Exit
|
|
356
|
+
[METRIC_EVENT_NAMES.TASK_CONFERENCE_EXIT_SUCCESS]: {
|
|
357
|
+
product,
|
|
358
|
+
agent: 'user',
|
|
359
|
+
target: 'task_conference_exit',
|
|
360
|
+
verb: 'complete',
|
|
361
|
+
},
|
|
362
|
+
[METRIC_EVENT_NAMES.TASK_CONFERENCE_EXIT_FAILED]: {
|
|
363
|
+
product,
|
|
364
|
+
agent: 'user',
|
|
365
|
+
target: 'task_conference_exit',
|
|
366
|
+
verb: 'fail',
|
|
367
|
+
},
|
|
368
|
+
|
|
369
|
+
// Conference Participant Drop
|
|
370
|
+
[METRIC_EVENT_NAMES.TASK_CONFERENCE_PARTICIPANT_DROP_SUCCESS]: {
|
|
371
|
+
product,
|
|
372
|
+
agent: 'user',
|
|
373
|
+
target: 'task_conference_participant_drop',
|
|
374
|
+
verb: 'complete',
|
|
375
|
+
},
|
|
376
|
+
[METRIC_EVENT_NAMES.TASK_CONFERENCE_PARTICIPANT_DROP_FAILED]: {
|
|
377
|
+
product,
|
|
378
|
+
agent: 'user',
|
|
379
|
+
target: 'task_conference_participant_drop',
|
|
380
|
+
verb: 'fail',
|
|
381
|
+
},
|
|
382
|
+
|
|
383
|
+
// Switch Call
|
|
384
|
+
[METRIC_EVENT_NAMES.TASK_SWITCH_CALL_SUCCESS]: {
|
|
385
|
+
product,
|
|
386
|
+
agent: 'user',
|
|
387
|
+
target: 'task_switch_call',
|
|
388
|
+
verb: 'complete',
|
|
389
|
+
},
|
|
390
|
+
[METRIC_EVENT_NAMES.TASK_SWITCH_CALL_FAILED]: {
|
|
391
|
+
product,
|
|
392
|
+
agent: 'user',
|
|
393
|
+
target: 'task_switch_call',
|
|
394
|
+
verb: 'fail',
|
|
395
|
+
},
|
|
396
|
+
|
|
355
397
|
// upload logs
|
|
356
398
|
[METRIC_EVENT_NAMES.UPLOAD_LOGS_SUCCESS]: {
|
|
357
399
|
product,
|
|
@@ -435,6 +477,98 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
|
|
|
435
477
|
target: 'outdial_ani_ep_fetch',
|
|
436
478
|
verb: 'fail',
|
|
437
479
|
},
|
|
480
|
+
|
|
481
|
+
// Campaign Preview API Events
|
|
482
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_SUCCESS]: {
|
|
483
|
+
product,
|
|
484
|
+
agent: 'user',
|
|
485
|
+
target: 'campaign_preview_accept',
|
|
486
|
+
verb: 'complete',
|
|
487
|
+
},
|
|
488
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_ACCEPT_FAILED]: {
|
|
489
|
+
product,
|
|
490
|
+
agent: 'user',
|
|
491
|
+
target: 'campaign_preview_accept',
|
|
492
|
+
verb: 'fail',
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
// Campaign Preview Skip API Events
|
|
496
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_SUCCESS]: {
|
|
497
|
+
product,
|
|
498
|
+
agent: 'user',
|
|
499
|
+
target: 'campaign_preview_skip',
|
|
500
|
+
verb: 'complete',
|
|
501
|
+
},
|
|
502
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_SKIP_FAILED]: {
|
|
503
|
+
product,
|
|
504
|
+
agent: 'user',
|
|
505
|
+
target: 'campaign_preview_skip',
|
|
506
|
+
verb: 'fail',
|
|
507
|
+
},
|
|
508
|
+
|
|
509
|
+
// Campaign Preview Remove API Events
|
|
510
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_SUCCESS]: {
|
|
511
|
+
product,
|
|
512
|
+
agent: 'user',
|
|
513
|
+
target: 'campaign_preview_remove',
|
|
514
|
+
verb: 'complete',
|
|
515
|
+
},
|
|
516
|
+
[METRIC_EVENT_NAMES.CAMPAIGN_PREVIEW_REMOVE_FAILED]: {
|
|
517
|
+
product,
|
|
518
|
+
agent: 'user',
|
|
519
|
+
target: 'campaign_preview_remove',
|
|
520
|
+
verb: 'fail',
|
|
521
|
+
},
|
|
522
|
+
|
|
523
|
+
// User Preference API Events
|
|
524
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_GET_SUCCESS]: {
|
|
525
|
+
product,
|
|
526
|
+
agent: 'user',
|
|
527
|
+
target: 'user_preference_get',
|
|
528
|
+
verb: 'complete',
|
|
529
|
+
},
|
|
530
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_GET_FAILED]: {
|
|
531
|
+
product,
|
|
532
|
+
agent: 'user',
|
|
533
|
+
target: 'user_preference_get',
|
|
534
|
+
verb: 'fail',
|
|
535
|
+
},
|
|
536
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_CREATE_SUCCESS]: {
|
|
537
|
+
product,
|
|
538
|
+
agent: 'user',
|
|
539
|
+
target: 'user_preference_create',
|
|
540
|
+
verb: 'complete',
|
|
541
|
+
},
|
|
542
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_CREATE_FAILED]: {
|
|
543
|
+
product,
|
|
544
|
+
agent: 'user',
|
|
545
|
+
target: 'user_preference_create',
|
|
546
|
+
verb: 'fail',
|
|
547
|
+
},
|
|
548
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_UPDATE_SUCCESS]: {
|
|
549
|
+
product,
|
|
550
|
+
agent: 'user',
|
|
551
|
+
target: 'user_preference_update',
|
|
552
|
+
verb: 'complete',
|
|
553
|
+
},
|
|
554
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_UPDATE_FAILED]: {
|
|
555
|
+
product,
|
|
556
|
+
agent: 'user',
|
|
557
|
+
target: 'user_preference_update',
|
|
558
|
+
verb: 'fail',
|
|
559
|
+
},
|
|
560
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_DELETE_SUCCESS]: {
|
|
561
|
+
product,
|
|
562
|
+
agent: 'user',
|
|
563
|
+
target: 'user_preference_delete',
|
|
564
|
+
verb: 'complete',
|
|
565
|
+
},
|
|
566
|
+
[METRIC_EVENT_NAMES.USER_PREFERENCE_DELETE_FAILED]: {
|
|
567
|
+
product,
|
|
568
|
+
agent: 'user',
|
|
569
|
+
target: 'user_preference_delete',
|
|
570
|
+
verb: 'fail',
|
|
571
|
+
},
|
|
438
572
|
};
|
|
439
573
|
|
|
440
574
|
/**
|
package/src/metrics/constants.ts
CHANGED
|
@@ -129,6 +129,12 @@ export const METRIC_EVENT_NAMES = {
|
|
|
129
129
|
TASK_CONFERENCE_END_FAILED: 'Task Conference End Failed',
|
|
130
130
|
TASK_CONFERENCE_TRANSFER_SUCCESS: 'Task Conference Transfer Success',
|
|
131
131
|
TASK_CONFERENCE_TRANSFER_FAILED: 'Task Conference Transfer Failed',
|
|
132
|
+
TASK_CONFERENCE_EXIT_SUCCESS: 'Task Conference Exit Success',
|
|
133
|
+
TASK_CONFERENCE_EXIT_FAILED: 'Task Conference Exit Failed',
|
|
134
|
+
TASK_CONFERENCE_PARTICIPANT_DROP_SUCCESS: 'Task Conference Participant Drop Success',
|
|
135
|
+
TASK_CONFERENCE_PARTICIPANT_DROP_FAILED: 'Task Conference Participant Drop Failed',
|
|
136
|
+
TASK_SWITCH_CALL_SUCCESS: 'Task Switch Call Success',
|
|
137
|
+
TASK_SWITCH_CALL_FAILED: 'Task Switch Call Failed',
|
|
132
138
|
|
|
133
139
|
TASK_OUTDIAL_SUCCESS: 'Task Outdial Success',
|
|
134
140
|
TASK_OUTDIAL_FAILED: 'Task Outdial Failed',
|
|
@@ -138,11 +144,10 @@ export const METRIC_EVENT_NAMES = {
|
|
|
138
144
|
WEBSOCKET_DEREGISTER_SUCCESS: 'Websocket Deregister Success',
|
|
139
145
|
WEBSOCKET_DEREGISTER_FAIL: 'Websocket Deregister Failed',
|
|
140
146
|
|
|
141
|
-
// WebSocket message events
|
|
142
|
-
WEBSOCKET_EVENT_RECEIVED: 'Websocket Event Received',
|
|
143
|
-
|
|
144
147
|
AGENT_DEVICE_TYPE_UPDATE_SUCCESS: 'Agent Device Type Update Success',
|
|
145
148
|
AGENT_DEVICE_TYPE_UPDATE_FAILED: 'Agent Device Type Update Failed',
|
|
149
|
+
// WebSocket message events
|
|
150
|
+
WEBSOCKET_EVENT_RECEIVED: 'Websocket Event Received',
|
|
146
151
|
|
|
147
152
|
// EntryPoint API Events
|
|
148
153
|
ENTRYPOINT_FETCH_SUCCESS: 'Entrypoint Fetch Success',
|
|
@@ -159,6 +164,37 @@ export const METRIC_EVENT_NAMES = {
|
|
|
159
164
|
// Outdial ANI Entries API Events
|
|
160
165
|
OUTDIAL_ANI_EP_FETCH_SUCCESS: 'Outdial ANI Entries Fetch Success',
|
|
161
166
|
OUTDIAL_ANI_EP_FETCH_FAILED: 'Outdial ANI Entries Fetch Failed',
|
|
167
|
+
|
|
168
|
+
// Campaign Preview API Events
|
|
169
|
+
CAMPAIGN_PREVIEW_ACCEPT_SUCCESS: 'Campaign Preview Accept Success',
|
|
170
|
+
CAMPAIGN_PREVIEW_ACCEPT_FAILED: 'Campaign Preview Accept Failed',
|
|
171
|
+
CAMPAIGN_PREVIEW_SKIP_SUCCESS: 'Campaign Preview Skip Success',
|
|
172
|
+
CAMPAIGN_PREVIEW_SKIP_FAILED: 'Campaign Preview Skip Failed',
|
|
173
|
+
CAMPAIGN_PREVIEW_REMOVE_SUCCESS: 'Campaign Preview Remove Success',
|
|
174
|
+
CAMPAIGN_PREVIEW_REMOVE_FAILED: 'Campaign Preview Remove Failed',
|
|
175
|
+
|
|
176
|
+
// AI Assistant Transcript events
|
|
177
|
+
AI_ASSISTANT_SEND_EVENT_SUCCESS: 'AI Assistant Send Event Success',
|
|
178
|
+
AI_ASSISTANT_SEND_EVENT_FAILED: 'AI Assistant Send Event Failed',
|
|
179
|
+
AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_SUCCESS: 'AI Assistant Get Real Time Assistance Success',
|
|
180
|
+
AI_ASSISTANT_GET_REAL_TIME_ASSISTANCE_FAILED: 'AI Assistant Get Real Time Assistance Failed',
|
|
181
|
+
AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_SUCCESS:
|
|
182
|
+
'AI Assistant Send Real Time Assistance User Action Success',
|
|
183
|
+
AI_ASSISTANT_SEND_REAL_TIME_ASSISTANCE_USER_ACTION_FAILED:
|
|
184
|
+
'AI Assistant Send Real Time Assistance User Action Failed',
|
|
185
|
+
AI_ASSISTANT_FETCH_HISTORIC_TRANSCRIPTS_SUCCESS:
|
|
186
|
+
'AI Assistant Fetch Historic Transcripts Success',
|
|
187
|
+
AI_ASSISTANT_FETCH_HISTORIC_TRANSCRIPTS_FAILED: 'AI Assistant Fetch Historic Transcripts Failed',
|
|
188
|
+
|
|
189
|
+
// User Preference API Events
|
|
190
|
+
USER_PREFERENCE_GET_SUCCESS: 'User Preference Get Success',
|
|
191
|
+
USER_PREFERENCE_GET_FAILED: 'User Preference Get Failed',
|
|
192
|
+
USER_PREFERENCE_CREATE_SUCCESS: 'User Preference Create Success',
|
|
193
|
+
USER_PREFERENCE_CREATE_FAILED: 'User Preference Create Failed',
|
|
194
|
+
USER_PREFERENCE_UPDATE_SUCCESS: 'User Preference Update Success',
|
|
195
|
+
USER_PREFERENCE_UPDATE_FAILED: 'User Preference Update Failed',
|
|
196
|
+
USER_PREFERENCE_DELETE_SUCCESS: 'User Preference Delete Success',
|
|
197
|
+
USER_PREFERENCE_DELETE_FAILED: 'User Preference Delete Failed',
|
|
162
198
|
} as const;
|
|
163
199
|
|
|
164
200
|
/**
|
|
@@ -74,7 +74,8 @@ export class AddressBook {
|
|
|
74
74
|
|
|
75
75
|
/**
|
|
76
76
|
* Fetches address book entries for a specific address book using the entry API
|
|
77
|
-
* @param {AddressBookEntrySearchParams} [params] - Search and
|
|
77
|
+
* @param {AddressBookEntrySearchParams} [params] - Search, pagination, and optional sort parameters
|
|
78
|
+
* including addressBookId. Sorting defaults to name ascending.
|
|
78
79
|
* @returns {Promise<AddressBookEntriesResponse>} Promise resolving to address book entries
|
|
79
80
|
* @throws {Error} If the API call fails
|
|
80
81
|
* @public
|
|
@@ -102,12 +103,21 @@ export class AddressBook {
|
|
|
102
103
|
search,
|
|
103
104
|
filter,
|
|
104
105
|
attributes,
|
|
106
|
+
sortBy = 'name',
|
|
107
|
+
sortOrder = 'asc',
|
|
105
108
|
} = params;
|
|
106
109
|
|
|
107
110
|
// Use provided addressBookId or fall back to agent's address book
|
|
108
111
|
const bookId = addressBookId || this.getAddressBookId();
|
|
109
112
|
const orgId = this.webex.credentials.getOrgId();
|
|
110
|
-
const
|
|
113
|
+
const hasCustomSort = sortBy !== 'name' || sortOrder !== 'asc';
|
|
114
|
+
const isSearchRequest = !!(search || filter || attributes || hasCustomSort);
|
|
115
|
+
const canUseCache = this.pageCache.canUseCache({
|
|
116
|
+
search,
|
|
117
|
+
filter,
|
|
118
|
+
attributes,
|
|
119
|
+
sortBy: hasCustomSort ? sortBy : undefined,
|
|
120
|
+
});
|
|
111
121
|
|
|
112
122
|
LoggerProxy.info('Fetching address book entries', {
|
|
113
123
|
module: 'AddressBook',
|
|
@@ -121,8 +131,8 @@ export class AddressBook {
|
|
|
121
131
|
},
|
|
122
132
|
});
|
|
123
133
|
|
|
124
|
-
//
|
|
125
|
-
if (
|
|
134
|
+
// Default name-ascending pagination is cache-compatible; result-changing overrides are not.
|
|
135
|
+
if (canUseCache) {
|
|
126
136
|
const cacheKey = this.pageCache.buildCacheKey(bookId, page, pageSize);
|
|
127
137
|
const cachedPage = this.pageCache.getCachedPage(cacheKey);
|
|
128
138
|
|
|
@@ -190,6 +200,7 @@ export class AddressBook {
|
|
|
190
200
|
if (filter) queryParams.append('filter', filter);
|
|
191
201
|
if (attributes) queryParams.append('attributes', attributes);
|
|
192
202
|
if (search) queryParams.append('search', search);
|
|
203
|
+
if (sortBy) queryParams.append('sort', `${sortBy},${sortOrder.toUpperCase()}`);
|
|
193
204
|
|
|
194
205
|
const resource = endPointMap.addressBookEntries(orgId, bookId, queryParams.toString());
|
|
195
206
|
|
|
@@ -244,8 +255,8 @@ export class AddressBook {
|
|
|
244
255
|
);
|
|
245
256
|
}
|
|
246
257
|
|
|
247
|
-
// Cache the
|
|
248
|
-
if (
|
|
258
|
+
// Cache only the invariant default-order pagination shape.
|
|
259
|
+
if (canUseCache && response.body?.data) {
|
|
249
260
|
const cacheKey = this.pageCache.buildCacheKey(bookId, page, pageSize);
|
|
250
261
|
this.pageCache.cachePage(cacheKey, response.body.data, response.body.meta);
|
|
251
262
|
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import LoggerProxy from '../logger-proxy';
|
|
2
|
+
import {CC_FILE, METHODS} from '../constants';
|
|
3
|
+
import {HTTP_METHODS, IHttpResponse, WebexSDK} from '../types';
|
|
4
|
+
import {getErrorDetails} from './core/Utils';
|
|
5
|
+
import {isWxAppCallNotFoundError} from './wxAppTelephonyUtils';
|
|
6
|
+
|
|
7
|
+
const ANSWER_CALL_ON_WEBEX_FILE = 'AnswerCallOnWebexService';
|
|
8
|
+
|
|
9
|
+
export type WxAppTelephonyError = Error & {
|
|
10
|
+
isWxAppTelephonyError: true;
|
|
11
|
+
trackingId?: string;
|
|
12
|
+
status?: number | string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const markWxAppTelephonyError = (error: Error, source: unknown): WxAppTelephonyError => {
|
|
16
|
+
const marked = error as WxAppTelephonyError;
|
|
17
|
+
marked.isWxAppTelephonyError = true;
|
|
18
|
+
const sourceObj = source as {
|
|
19
|
+
details?: {trackingId?: string; status?: number | string};
|
|
20
|
+
statusCode?: number;
|
|
21
|
+
status?: number | string;
|
|
22
|
+
};
|
|
23
|
+
const trackingId = sourceObj?.details?.trackingId;
|
|
24
|
+
if (trackingId) {
|
|
25
|
+
marked.trackingId = trackingId;
|
|
26
|
+
}
|
|
27
|
+
const status = sourceObj?.statusCode ?? sourceObj?.details?.status ?? sourceObj?.status;
|
|
28
|
+
if (status !== undefined) {
|
|
29
|
+
marked.status = status;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return marked;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export type AnswerCallParams = {
|
|
36
|
+
callId: string;
|
|
37
|
+
endpointId: string;
|
|
38
|
+
lineOwnerId?: string;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export type CallIdParams = {
|
|
42
|
+
callId: string;
|
|
43
|
+
lineOwnerId?: string;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type TransmitDtmfParams = CallIdParams & {
|
|
47
|
+
dtmf: string;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export type CallDetailsResponse = {
|
|
51
|
+
muted?: boolean;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* REST telephony client for wxApp thick-client answer (WXCC-6026).
|
|
56
|
+
* Separate from WebCallingService (WebRTC/Mobius).
|
|
57
|
+
*/
|
|
58
|
+
export default class AnswerCallOnWebexService {
|
|
59
|
+
private webex: WebexSDK;
|
|
60
|
+
|
|
61
|
+
constructor(webex: WebexSDK) {
|
|
62
|
+
this.webex = webex;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private getTelephonyBaseUrl(): string {
|
|
66
|
+
const services = this.webex.internal.services;
|
|
67
|
+
const hydraUrl = services._serviceUrls?.hydra || services.get('hydra');
|
|
68
|
+
|
|
69
|
+
if (!hydraUrl) {
|
|
70
|
+
throw new Error('Telephony base URL is unavailable');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return `${hydraUrl.replace(/\/$/, '')}/telephony/calls`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private async telephonyRequest(
|
|
77
|
+
resource: string,
|
|
78
|
+
method: HTTP_METHODS,
|
|
79
|
+
body: Record<string, unknown>,
|
|
80
|
+
logMethod: string
|
|
81
|
+
): Promise<IHttpResponse> {
|
|
82
|
+
try {
|
|
83
|
+
const uri = `${this.getTelephonyBaseUrl()}${resource}`;
|
|
84
|
+
|
|
85
|
+
LoggerProxy.info(`AnswerCallOnWebexService.${logMethod} request`, {
|
|
86
|
+
module: ANSWER_CALL_ON_WEBEX_FILE,
|
|
87
|
+
method: logMethod,
|
|
88
|
+
data: {uri, bodyKeys: Object.keys(body)},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return (await this.webex.request({
|
|
92
|
+
uri,
|
|
93
|
+
method,
|
|
94
|
+
body,
|
|
95
|
+
addAuthHeader: true,
|
|
96
|
+
})) as IHttpResponse;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
LoggerProxy.error(`AnswerCallOnWebexService.${logMethod} failed: ${error}`, {
|
|
99
|
+
module: ANSWER_CALL_ON_WEBEX_FILE,
|
|
100
|
+
method: logMethod,
|
|
101
|
+
});
|
|
102
|
+
const {error: detailedError} = getErrorDetails(error, logMethod, CC_FILE);
|
|
103
|
+
throw markWxAppTelephonyError(detailedError, error);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
public answerCall(params: AnswerCallParams): Promise<IHttpResponse> {
|
|
108
|
+
const {callId, endpointId, lineOwnerId} = params;
|
|
109
|
+
|
|
110
|
+
return this.telephonyRequest(
|
|
111
|
+
'/answer',
|
|
112
|
+
HTTP_METHODS.POST,
|
|
113
|
+
{
|
|
114
|
+
callId,
|
|
115
|
+
endpointId,
|
|
116
|
+
...(lineOwnerId ? {lineOwnerId} : {}),
|
|
117
|
+
},
|
|
118
|
+
METHODS.ACCEPT
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
public rejectCall(params: CallIdParams): Promise<IHttpResponse> {
|
|
123
|
+
const {callId, lineOwnerId} = params;
|
|
124
|
+
|
|
125
|
+
return this.telephonyRequest(
|
|
126
|
+
'/reject',
|
|
127
|
+
HTTP_METHODS.POST,
|
|
128
|
+
{callId, ...(lineOwnerId ? {lineOwnerId} : {})},
|
|
129
|
+
METHODS.REJECT
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public muteCall(params: CallIdParams): Promise<IHttpResponse> {
|
|
134
|
+
const {callId, lineOwnerId} = params;
|
|
135
|
+
|
|
136
|
+
return this.telephonyRequest(
|
|
137
|
+
'/mute',
|
|
138
|
+
HTTP_METHODS.POST,
|
|
139
|
+
{callId, ...(lineOwnerId ? {lineOwnerId} : {})},
|
|
140
|
+
METHODS.TOGGLE_MUTE
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
public unmuteCall(params: CallIdParams): Promise<IHttpResponse> {
|
|
145
|
+
const {callId, lineOwnerId} = params;
|
|
146
|
+
|
|
147
|
+
return this.telephonyRequest(
|
|
148
|
+
'/unmute',
|
|
149
|
+
HTTP_METHODS.POST,
|
|
150
|
+
{callId, ...(lineOwnerId ? {lineOwnerId} : {})},
|
|
151
|
+
METHODS.TOGGLE_MUTE
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public transmitDtmf(params: TransmitDtmfParams): Promise<IHttpResponse> {
|
|
156
|
+
const {callId, dtmf, lineOwnerId} = params;
|
|
157
|
+
|
|
158
|
+
return this.telephonyRequest(
|
|
159
|
+
'/transmitDtmf',
|
|
160
|
+
HTTP_METHODS.POST,
|
|
161
|
+
{callId, dtmf, ...(lineOwnerId ? {lineOwnerId} : {})},
|
|
162
|
+
METHODS.TRANSMIT_DTMF
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public async getCallDetails(params: CallIdParams): Promise<CallDetailsResponse> {
|
|
167
|
+
const {callId, lineOwnerId} = params;
|
|
168
|
+
const lineOwnerIdQuery = lineOwnerId ? `?lineOwnerId=${encodeURIComponent(lineOwnerId)}` : '';
|
|
169
|
+
const uri = `${this.getTelephonyBaseUrl()}/${callId}${lineOwnerIdQuery}`;
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
LoggerProxy.info('AnswerCallOnWebexService.getCallDetails request', {
|
|
173
|
+
module: ANSWER_CALL_ON_WEBEX_FILE,
|
|
174
|
+
method: METHODS.GET_CALL_DETAILS_ON_WEBEX,
|
|
175
|
+
data: {callId},
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
const response = (await this.webex.request({
|
|
179
|
+
uri,
|
|
180
|
+
method: HTTP_METHODS.GET,
|
|
181
|
+
addAuthHeader: true,
|
|
182
|
+
})) as IHttpResponse;
|
|
183
|
+
|
|
184
|
+
return (response.body ?? {}) as CallDetailsResponse;
|
|
185
|
+
} catch (error) {
|
|
186
|
+
if (isWxAppCallNotFoundError(error)) {
|
|
187
|
+
const err =
|
|
188
|
+
error instanceof Error
|
|
189
|
+
? error
|
|
190
|
+
: new Error(String((error as {message?: string})?.message ?? error));
|
|
191
|
+
throw markWxAppTelephonyError(err, error);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
LoggerProxy.error(`AnswerCallOnWebexService.getCallDetails failed: ${error}`, {
|
|
195
|
+
module: ANSWER_CALL_ON_WEBEX_FILE,
|
|
196
|
+
method: METHODS.GET_CALL_DETAILS_ON_WEBEX,
|
|
197
|
+
});
|
|
198
|
+
const {error: detailedError} = getErrorDetails(
|
|
199
|
+
error,
|
|
200
|
+
METHODS.GET_CALL_DETAILS_ON_WEBEX,
|
|
201
|
+
CC_FILE
|
|
202
|
+
);
|
|
203
|
+
throw markWxAppTelephonyError(detailedError, error);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|