@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
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import LoggerProxy from '../logger-proxy';
|
|
2
|
+
import {METHODS} from '../constants';
|
|
3
|
+
import {WebexSDK} from '../types';
|
|
4
|
+
|
|
5
|
+
const WEBEX_CROSS_CLIENT_FILE = 'WebexCrossClientService';
|
|
6
|
+
const DEFAULT_CROSS_CLIENT_STATE_TTL = 900;
|
|
7
|
+
const EXPIRATION_OFFSET_MS = 60_000;
|
|
8
|
+
/** Must match Agent Desktop usersub publish — Webex App reads `wxcc` cross-client state. */
|
|
9
|
+
const DEFAULT_APP_NAME = 'wxcc';
|
|
10
|
+
const REFRESH_RETRY_DELAY_MS = 30_000;
|
|
11
|
+
const MAX_REFRESH_RETRIES = 3;
|
|
12
|
+
|
|
13
|
+
type RefreshTimer = ReturnType<typeof setTimeout>;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Publishes usersub cross-client state so Webex App suppresses native calling toasts (WXCC-6026).
|
|
17
|
+
*/
|
|
18
|
+
export default class WebexCrossClientService {
|
|
19
|
+
private webex: WebexSDK;
|
|
20
|
+
private refreshTimer?: RefreshTimer;
|
|
21
|
+
private refreshRetryTimer?: RefreshTimer;
|
|
22
|
+
private answerCallsState = false;
|
|
23
|
+
private appName = DEFAULT_APP_NAME;
|
|
24
|
+
/** Incremented on teardown/disable to ignore stale refresh timer callbacks. */
|
|
25
|
+
private refreshGeneration = 0;
|
|
26
|
+
|
|
27
|
+
constructor(webex: WebexSDK) {
|
|
28
|
+
this.webex = webex;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private extractDeviceIdFromUrl(url: string): string {
|
|
32
|
+
const match = url.match(/\/devices\/([^/?]+)/);
|
|
33
|
+
|
|
34
|
+
return match ? match[1] : '';
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private getDeviceUrl(): string | undefined {
|
|
38
|
+
return this.webex.internal.device?.url;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
private clearRefreshTimer(): void {
|
|
42
|
+
if (this.refreshTimer) {
|
|
43
|
+
clearTimeout(this.refreshTimer);
|
|
44
|
+
this.refreshTimer = undefined;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (this.refreshRetryTimer) {
|
|
48
|
+
clearTimeout(this.refreshRetryTimer);
|
|
49
|
+
this.refreshRetryTimer = undefined;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
private scheduleRefreshRetry(
|
|
54
|
+
userId: string,
|
|
55
|
+
ttl: number,
|
|
56
|
+
scheduledGeneration: number,
|
|
57
|
+
retryAttempt: number
|
|
58
|
+
): void {
|
|
59
|
+
if (
|
|
60
|
+
retryAttempt >= MAX_REFRESH_RETRIES ||
|
|
61
|
+
scheduledGeneration !== this.refreshGeneration ||
|
|
62
|
+
!this.answerCallsState
|
|
63
|
+
) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
this.refreshRetryTimer = setTimeout(async () => {
|
|
68
|
+
if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});
|
|
74
|
+
} catch (error) {
|
|
75
|
+
LoggerProxy.error(`WebexCrossClientService refresh retry failed: ${error}`, {
|
|
76
|
+
module: WEBEX_CROSS_CLIENT_FILE,
|
|
77
|
+
method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,
|
|
78
|
+
});
|
|
79
|
+
this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, retryAttempt + 1);
|
|
80
|
+
}
|
|
81
|
+
}, REFRESH_RETRY_DELAY_MS);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private startRefreshTimer(userId: string, ttl: number): void {
|
|
85
|
+
this.clearRefreshTimer();
|
|
86
|
+
|
|
87
|
+
if (!this.answerCallsState) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const refreshTime = ttl * 1000 - EXPIRATION_OFFSET_MS;
|
|
92
|
+
const scheduledGeneration = this.refreshGeneration;
|
|
93
|
+
this.refreshTimer = setTimeout(async () => {
|
|
94
|
+
if (scheduledGeneration !== this.refreshGeneration || !this.answerCallsState) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
await this.setManageWebexCallingInWxcc(true, {userId, ttl, appName: this.appName});
|
|
100
|
+
} catch (error) {
|
|
101
|
+
LoggerProxy.error(`WebexCrossClientService refresh failed: ${error}`, {
|
|
102
|
+
module: WEBEX_CROSS_CLIENT_FILE,
|
|
103
|
+
method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,
|
|
104
|
+
});
|
|
105
|
+
this.scheduleRefreshRetry(userId, ttl, scheduledGeneration, 0);
|
|
106
|
+
}
|
|
107
|
+
}, refreshTime);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private publishCrossClientState(
|
|
111
|
+
users: string[],
|
|
112
|
+
ttl: number,
|
|
113
|
+
composition: Record<string, unknown>,
|
|
114
|
+
logContext: string
|
|
115
|
+
): Promise<unknown> {
|
|
116
|
+
const body = {
|
|
117
|
+
users,
|
|
118
|
+
compositions: [
|
|
119
|
+
{
|
|
120
|
+
type: 'cross-client-state',
|
|
121
|
+
ttl,
|
|
122
|
+
composition,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
return this.webex
|
|
128
|
+
.request({
|
|
129
|
+
method: 'POST',
|
|
130
|
+
service: 'usersub',
|
|
131
|
+
resource: 'publish',
|
|
132
|
+
body,
|
|
133
|
+
})
|
|
134
|
+
.then((response: {body?: unknown}) => response?.body)
|
|
135
|
+
.catch((error: unknown) => {
|
|
136
|
+
LoggerProxy.error(`WebexCrossClientService.${logContext} failed: ${error}`, {
|
|
137
|
+
module: WEBEX_CROSS_CLIENT_FILE,
|
|
138
|
+
method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
return Promise.reject(error);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
public async setManageWebexCallingInWxcc(
|
|
146
|
+
enable: boolean,
|
|
147
|
+
options?: {userId?: string; ttl?: number; appName?: string}
|
|
148
|
+
): Promise<void> {
|
|
149
|
+
const operationGeneration = this.refreshGeneration;
|
|
150
|
+
const userId = options?.userId ?? this.webex.internal.device?.userId;
|
|
151
|
+
const ttl = options?.ttl ?? DEFAULT_CROSS_CLIENT_STATE_TTL;
|
|
152
|
+
const appName = options?.appName ?? DEFAULT_APP_NAME;
|
|
153
|
+
this.appName = appName;
|
|
154
|
+
|
|
155
|
+
if (!userId) {
|
|
156
|
+
throw new Error('User ID is unavailable for cross-client publish');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const deviceUrl = this.getDeviceUrl();
|
|
160
|
+
if (!deviceUrl) {
|
|
161
|
+
throw new Error('Device URL is unavailable for cross-client publish');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const composition = {
|
|
165
|
+
devices: [
|
|
166
|
+
{
|
|
167
|
+
deviceId: this.extractDeviceIdFromUrl(deviceUrl),
|
|
168
|
+
appName,
|
|
169
|
+
state: {
|
|
170
|
+
'answer-calls-on-wxcc': enable,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
await this.publishCrossClientState([userId], ttl, composition, 'setManageWebexCallingInWxcc');
|
|
177
|
+
|
|
178
|
+
if (operationGeneration !== this.refreshGeneration) {
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
this.answerCallsState = enable;
|
|
183
|
+
|
|
184
|
+
if (enable) {
|
|
185
|
+
this.startRefreshTimer(userId, ttl);
|
|
186
|
+
} else {
|
|
187
|
+
this.refreshGeneration += 1;
|
|
188
|
+
this.clearRefreshTimer();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
LoggerProxy.info(`Cross-client answer-calls-on-wxcc set to ${enable}`, {
|
|
192
|
+
module: WEBEX_CROSS_CLIENT_FILE,
|
|
193
|
+
method: METHODS.SET_MANAGE_WEBEX_CALLING_IN_WXCC,
|
|
194
|
+
data: {
|
|
195
|
+
appName,
|
|
196
|
+
deviceId: this.extractDeviceIdFromUrl(deviceUrl),
|
|
197
|
+
ttl,
|
|
198
|
+
},
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public teardown(): void {
|
|
203
|
+
this.refreshGeneration += 1;
|
|
204
|
+
this.clearRefreshTimer();
|
|
205
|
+
this.answerCallsState = false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/** Whether usersub `answer-calls-on-wxcc: true` was successfully published this session. */
|
|
209
|
+
public isAnswerCallsStateActive(): boolean {
|
|
210
|
+
return this.answerCallsState;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import LoggerProxy from '../logger-proxy';
|
|
2
|
+
import {METHODS} from '../constants';
|
|
3
|
+
import {WebexSDK} from '../types';
|
|
4
|
+
|
|
5
|
+
const WXAPP_TELEPHONY_MERCURY_SYNC_FILE = 'WxAppTelephonyMercurySync';
|
|
6
|
+
|
|
7
|
+
export const TELEPHONY_CALL_MUTED = 'event:telephony_calls.muted';
|
|
8
|
+
export const TELEPHONY_CALL_UNMUTED = 'event:telephony_calls.unmuted';
|
|
9
|
+
|
|
10
|
+
export type UpdatedCallMuteStateEvent = {
|
|
11
|
+
data: {
|
|
12
|
+
actorId: string;
|
|
13
|
+
callId: string;
|
|
14
|
+
muted: boolean;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type MuteChangeHandler = (callId: string, muted: boolean) => void;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Subscribes to Mercury telephony mute/unmute events for wxApp thick-client sync (AD parity).
|
|
22
|
+
*/
|
|
23
|
+
export default class WxAppTelephonyMercurySync {
|
|
24
|
+
private webex: WebexSDK;
|
|
25
|
+
private subscribedAgentId?: string;
|
|
26
|
+
private muteChangeHandler?: MuteChangeHandler;
|
|
27
|
+
private boundMuteHandler?: (event: UpdatedCallMuteStateEvent) => void;
|
|
28
|
+
private boundUnmuteHandler?: (event: UpdatedCallMuteStateEvent) => void;
|
|
29
|
+
|
|
30
|
+
constructor(webex: WebexSDK) {
|
|
31
|
+
this.webex = webex;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private decodeBase64(value: string): string {
|
|
35
|
+
try {
|
|
36
|
+
return atob(value);
|
|
37
|
+
} catch {
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private handleMuteStateEvent = (agentId: string, event: UpdatedCallMuteStateEvent): void => {
|
|
43
|
+
const {actorId, callId, muted} = event?.data ?? {};
|
|
44
|
+
if (!actorId || !callId || muted === undefined) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const decodedActorId = this.decodeBase64(actorId);
|
|
49
|
+
const decodedCallId = this.decodeBase64(callId);
|
|
50
|
+
|
|
51
|
+
if (!decodedActorId.endsWith(agentId)) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
LoggerProxy.info('WxApp telephony mute state sync received', {
|
|
56
|
+
module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
|
|
57
|
+
method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,
|
|
58
|
+
data: {muted},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
this.muteChangeHandler?.(decodedCallId, muted);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
public subscribe(agentId: string, onMuteChange: MuteChangeHandler): void {
|
|
65
|
+
this.unsubscribe();
|
|
66
|
+
|
|
67
|
+
const mercury = this.webex.internal.mercury;
|
|
68
|
+
if (!mercury) {
|
|
69
|
+
LoggerProxy.error('Mercury is unavailable for wxApp mute sync', {
|
|
70
|
+
module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
|
|
71
|
+
method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
this.subscribedAgentId = agentId;
|
|
78
|
+
this.muteChangeHandler = onMuteChange;
|
|
79
|
+
|
|
80
|
+
this.boundMuteHandler = (event: UpdatedCallMuteStateEvent) => {
|
|
81
|
+
this.handleMuteStateEvent(agentId, event);
|
|
82
|
+
};
|
|
83
|
+
this.boundUnmuteHandler = (event: UpdatedCallMuteStateEvent) => {
|
|
84
|
+
this.handleMuteStateEvent(agentId, event);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
mercury.on(TELEPHONY_CALL_MUTED, this.boundMuteHandler);
|
|
88
|
+
mercury.on(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);
|
|
89
|
+
|
|
90
|
+
LoggerProxy.info('Subscribed to wxApp telephony Mercury mute sync', {
|
|
91
|
+
module: WXAPP_TELEPHONY_MERCURY_SYNC_FILE,
|
|
92
|
+
method: METHODS.SYNC_WXAPP_MUTE_FROM_MERCURY,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public unsubscribe(): void {
|
|
97
|
+
const mercury = this.webex.internal.mercury;
|
|
98
|
+
|
|
99
|
+
if (mercury && this.boundMuteHandler) {
|
|
100
|
+
mercury.off(TELEPHONY_CALL_MUTED, this.boundMuteHandler);
|
|
101
|
+
}
|
|
102
|
+
if (mercury && this.boundUnmuteHandler) {
|
|
103
|
+
mercury.off(TELEPHONY_CALL_UNMUTED, this.boundUnmuteHandler);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this.subscribedAgentId = undefined;
|
|
107
|
+
this.muteChangeHandler = undefined;
|
|
108
|
+
this.boundMuteHandler = undefined;
|
|
109
|
+
this.boundUnmuteHandler = undefined;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
public isSubscribed(): boolean {
|
|
113
|
+
return Boolean(this.subscribedAgentId && this.muteChangeHandler);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -109,12 +109,12 @@ src/services/
|
|
|
109
109
|
│ └── ARCHITECTURE.md
|
|
110
110
|
│
|
|
111
111
|
├── AddressBook.ts # Address book entries — getEntries() with pagination/cache
|
|
112
|
-
├── EntryPoint.ts #
|
|
112
|
+
├── EntryPoint.ts # Profile-scoped entry-point dial-number mappings (uncached)
|
|
113
113
|
├── Queue.ts # Queues — getQueues() with pagination/cache
|
|
114
114
|
└── WebCallingService.ts # WebRTC calling — register/deregister line, answer/mute/decline
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
-
Note: The `src/utils/` folder (sibling to `src/services/`) contains
|
|
117
|
+
Note: The `src/utils/` folder (sibling to `src/services/`) contains [`PageCache.ts`](../../utils/PageCache.ts), which provides pagination contracts/defaults shared by data-service types and optional page caching used by AddressBook and Queue. EntryPoint deliberately bypasses PageCache because every request is profile-scoped.
|
|
118
118
|
|
|
119
119
|
### Shared Constants (`src/services/constants.ts`)
|
|
120
120
|
|
|
@@ -137,8 +137,8 @@ Use [`constants.ts`](../constants.ts) as the canonical source for service-level
|
|
|
137
137
|
| **Task Management** | [`task/`](../task/TaskManager.ts) | Task lifecycle (accept, hold, transfer, conference, wrapup), Task state machine, contact operations, outbound dialing |
|
|
138
138
|
| **Configuration** | [`config/`](../config/index.ts) | Agent profile aggregation from 8+ API endpoints, org settings, teams, aux codes, dial plans |
|
|
139
139
|
| **Core Infrastructure** | [`core/`](../core/WebexRequest.ts) | HTTP requests (`WebexRequest`), WebSocket management (`WebSocketManager`), connection lifecycle (`ConnectionService`), AQM request/response correlation (`AqmReqs`), error handling (`Utils`, `Err`) |
|
|
140
|
-
| **Data Services** | [`AddressBook.ts`](../AddressBook.ts), [`Queue.ts`](../Queue.ts), [`EntryPoint.ts`](../EntryPoint.ts) | Standalone REST-based
|
|
141
|
-
| **Utilities** | [`src/utils/PageCache.ts`](../../utils/PageCache.ts) | Shared `PageCache<T>`
|
|
140
|
+
| **Data Services** | [`AddressBook.ts`](../AddressBook.ts), [`Queue.ts`](../Queue.ts), [`EntryPoint.ts`](../EntryPoint.ts) | Standalone REST-based paginated services; AddressBook and Queue optionally cache eligible pages, while profile-scoped EntryPoint requests are always fetched |
|
|
141
|
+
| **Utilities** | [`src/utils/PageCache.ts`](../../utils/PageCache.ts) | Shared pagination contracts/defaults plus optional `PageCache<T>` reuse for AddressBook and Queue |
|
|
142
142
|
| **WebRTC Calling** | [`WebCallingService.ts`](../WebCallingService.ts) | Browser-based voice calling via `@webex/calling`, line registration, call answer/mute/decline |
|
|
143
143
|
|
|
144
144
|
---
|
|
@@ -156,7 +156,7 @@ Each service folder contains its own `ai-docs/` with detailed documentation. **A
|
|
|
156
156
|
|
|
157
157
|
> **Note**: The task state machine (`task/state-machine/`) is part of the Task service, not a separate service. Its dedicated docs live at [`task/state-machine/ai-docs/AGENTS.md`](../task/state-machine/ai-docs/AGENTS.md) and [`ARCHITECTURE.md`](../task/state-machine/ai-docs/ARCHITECTURE.md). Load these when working on state transitions, guards, or actions.
|
|
158
158
|
|
|
159
|
-
**Data services** (AddressBook, Queue, EntryPoint) do not have dedicated ai-docs. Read their source files directly
|
|
159
|
+
**Data services** (AddressBook, Queue, EntryPoint) do not have dedicated ai-docs. Read their source files directly. They share direct REST, pagination, logging, metrics, and error propagation, but cache policy is service-owned: AddressBook/Queue use PageCache when eligible and EntryPoint always fetches its profile-scoped mapping.
|
|
160
160
|
|
|
161
161
|
**WebCallingService** also has no dedicated ai-docs, but it follows a different pattern: EventEmitter-based call lifecycle orchestration around `@webex/calling` (`createClient`, line registration/deregistration, `ICall` events), `callTaskMap` tracking, and async registration flows with timeout handling. Read [`WebCallingService.ts`](../WebCallingService.ts) directly when changing browser calling behavior.
|
|
162
162
|
|
|
@@ -271,16 +271,16 @@ const services = Services.getInstance({
|
|
|
271
271
|
|
|
272
272
|
## Data Services Pattern (AddressBook, Queue, EntryPoint)
|
|
273
273
|
|
|
274
|
-
These
|
|
274
|
+
These services share the direct REST and pagination pattern, with service-specific request mapping and cache policy:
|
|
275
275
|
|
|
276
276
|
| Aspect | Pattern |
|
|
277
277
|
|---|---|
|
|
278
|
-
| **Class structure** | Standalone class with `WebexRequest`, `WebexSDK`, `MetricsManager
|
|
278
|
+
| **Class structure** | Standalone class with `WebexRequest`, `WebexSDK`, and `MetricsManager`; cache-enabled services additionally own `PageCache` |
|
|
279
279
|
| **Constructor** | `constructor(webex: WebexSDK)` — gets singletons via `.getInstance()` |
|
|
280
280
|
| **HTTP calls** | `this.webexRequest.request({service: WCC_API_GATEWAY, resource, method: HTTP_METHODS.GET})` |
|
|
281
281
|
| **Endpoints** | Uses `endPointMap` functions from `config/constants.ts` to build URL paths |
|
|
282
|
-
| **Pagination** | Query params with `page
|
|
283
|
-
| **Caching** | `PageCache<T>`
|
|
282
|
+
| **Pagination** | Query params with `page` and `pageSize` |
|
|
283
|
+
| **Caching** | AddressBook/Queue may use `PageCache<T>` for eligible pages; EntryPoint always fetches because its request is desktop-profile scoped |
|
|
284
284
|
| **Metrics** | `timeEvent` on API call start, `trackEvent` on success/failure |
|
|
285
285
|
| **Logging** | `LoggerProxy` with `{module: 'ClassName', method: 'methodName'}` context |
|
|
286
286
|
| **Error handling** | try/catch with `LoggerProxy.error` + `metricsManager.trackEvent` for failures, then re-throw so callers receive the error |
|
|
@@ -288,7 +288,7 @@ These three services share an identical pattern. Use any one as a reference when
|
|
|
288
288
|
Reference files:
|
|
289
289
|
- [`AddressBook.ts`](../AddressBook.ts) — includes `addressBookId` parameter
|
|
290
290
|
- [`Queue.ts`](../Queue.ts) — includes additional query params (sortBy, sortOrder, etc.)
|
|
291
|
-
- [`EntryPoint.ts`](../EntryPoint.ts) —
|
|
291
|
+
- [`EntryPoint.ts`](../EntryPoint.ts) — profile-scoped dial-number mapping without PageCache
|
|
292
292
|
|
|
293
293
|
---
|
|
294
294
|
|
|
@@ -54,6 +54,7 @@ The `src/services/` directory is the service layer of the `@webex/contact-center
|
|
|
54
54
|
| **User Preferences** | [`UserPreference.ts`](../UserPreference.ts) | Direct REST CRUD service exposed as `cc.userPreference`; it resolves the default user from agent configuration and does not use PageCache |
|
|
55
55
|
| **Utilities** | [`src/utils/PageCache.ts`](../../utils/PageCache.ts) | Shared `PageCache<T>` generic class for pagination caching, plus `BaseSearchParams`, `PaginatedResponse`, and `PaginationMeta` types used by all data services |
|
|
56
56
|
| **WebRTC Calling** | [`WebCallingService.ts`](../WebCallingService.ts) | Browser-based voice calling via `@webex/calling`, line registration, call answer/mute/decline |
|
|
57
|
+
| **WxApp Better Together** | [`WebexCrossClientService.ts`](../WebexCrossClientService.ts), [`AnswerCallOnWebexService.ts`](../AnswerCallOnWebexService.ts), [`WxAppTelephonyMercurySync.ts`](../WxAppTelephonyMercurySync.ts) | usersub cross-client publish (`answer-calls-on-wxcc`), Hydra telephony REST (answer/reject/mute/DTMF/GET call), Mercury mute sync — orchestrated from `cc.ts` when `enableWxBetterTogether` is active |
|
|
57
58
|
|
|
58
59
|
Each service folder contains its own `ai-docs/` with detailed documentation. **Always load the relevant service docs before making changes.**
|
|
59
60
|
|
|
@@ -227,6 +228,7 @@ Use [`constants.ts`](../constants.ts) as the canonical source for service-level
|
|
|
227
228
|
| Contract ID | Type | Surface | Purpose | Compatibility / deprecation | Schema / detail link | Root index |
|
|
228
229
|
|---|---|---|---|---|---|---|
|
|
229
230
|
| `services.surface` | SDK / event / internal API | Internal `Services.getInstance()` composition root plus data-service and calling collaborators consumed by `ContactCenter`. | Stable module consumption boundary. | Additive changes by default; breaking package exports require a major-version transition. | `src/services/index.ts` | `../../../ai-docs/CONTRACTS.md` |
|
|
231
|
+
| `services.destination-lists` | SDK data API | Existing `Queue.getQueues(ContactServiceQueueSearchParams)` and `EntryPoint.getEntryPoints(EntryPointSearchParams)` methods with full-record paginated responses. | Apply consult/transfer telephony eligibility, profile views, and backend name ordering as overridable defaults. | Behavioral default correction on existing methods; no specialized method, projected response, or replacement signature. | `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/types.ts` | `../../../ai-docs/CONTRACTS.md` |
|
|
230
232
|
| `services.user-preference` | SDK data API | `UserPreference` and `cc.userPreference`. | Direct REST CRUD for user preferences; separate from PageCache-based pagination services. | Additive semver-public API; removals or signature changes are breaking. | `src/services/UserPreference.ts`, `src/services/config/types.ts` | `../../../ai-docs/CONTRACTS.md` |
|
|
231
233
|
|
|
232
234
|
Compatibility notes:
|
|
@@ -261,6 +263,7 @@ ContactCenter READY callback
|
|
|
261
263
|
| SERVICES-R-004 | Pass ApiAIAssistant, contact routing, WebCallingService, primary WebSocket, and RTD WebSocket into TaskManager. | Voice, task, transcript, and suggestion behavior depend on the complete collaborator set. | `src/cc.ts` | `test/unit/spec/services/task/TaskManager.ts` | None; source and test evidence rechecked during the 2026-07-09 remediation; independent document revalidation pending. | PRESENT |
|
|
262
264
|
| SERVICES-R-005 | Inherit authenticated request identity from the host Webex SDK through Core/WebexRequest; Services must not store, parse, or refresh credentials. | One host-owned authentication boundary avoids duplicate token handling and credential leakage across composed services. | `src/services/index.ts`, `src/services/core/WebexRequest.ts` | `test/unit/spec/services/core/WebexRequest.ts` | None; authentication ownership is explicit. | PRESENT |
|
|
263
265
|
| SERVICES-R-006 | Treat Services composition as unconditionally created by the ContactCenter READY callback; Services owns no rollout or feature-flag decision. | Capability flags belong to the consuming config/task/calling collaborators, so the composition root must not silently gate construction. | `src/services/index.ts`, `src/cc.ts` | `test/unit/spec/cc.ts` | None; rollout applicability is explicitly N/A for Services. | PRESENT |
|
|
266
|
+
| SERVICES-R-007 | Existing Queue and EntryPoint list methods must apply inbound, active, telephony, profile/agent-view, and `name,ASC` defaults while retaining their established parameter and full-record response types. Caller-supplied existing filter, sort, or profile inputs override defaults. Queue must also treat `sortOrder` without `sortBy` as a name sort and bypass the simple-page cache. | Defaults on the established methods let thin consumers request lists without a parallel API, while existing parameters preserve specialized behavior for other consumers and full-record types remain truthful because no field projection is requested. | `src/services/Queue.ts`, `src/services/EntryPoint.ts`, `src/types.ts` | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/cc.ts` | The backend honors the view flags and combined CMS sort value. | PRESENT |
|
|
264
267
|
|
|
265
268
|
## Design Overview
|
|
266
269
|
`Services` is a singleton composition root for transport-facing capabilities only. It constructs two `WebSocketManager` instances (primary Contact Center and RTD), creates `AqmReqs` on the primary manager, then creates config, agent, contact, dialer, and ConnectionService collaborators.
|
|
@@ -419,7 +422,8 @@ These three services share an identical pattern. Use any one as a reference when
|
|
|
419
422
|
| **HTTP calls** | `this.webexRequest.request({service: WCC_API_GATEWAY, resource, method: HTTP_METHODS.GET})` |
|
|
420
423
|
| **Endpoints** | Uses `endPointMap` functions from `config/constants.ts` to build URL paths |
|
|
421
424
|
| **Pagination** | Query params with `page`, `pageSize`; uses `PageCache` for caching |
|
|
422
|
-
| **Caching** | `PageCache<T>` — caches pages for simple pagination
|
|
425
|
+
| **Caching** | `PageCache<T>` — caches pages for simple pagination and bypasses cache for result/shape variants, including an effective Queue sort |
|
|
426
|
+
| **Consult/transfer policy** | Existing Queue and EntryPoint methods apply telephony eligibility, profile views, and backend name ordering by default, accept overrides through their existing query parameters, and return full-record responses unchanged |
|
|
423
427
|
| **Metrics** | `timeEvent` on API call start, `trackEvent` on success/failure |
|
|
424
428
|
| **Logging** | `LoggerProxy` with `{module: 'ClassName', method: 'methodName'}` context |
|
|
425
429
|
| **Error handling** | try/catch with `LoggerProxy.error` + `metricsManager.trackEvent` for failures, then re-throw so callers receive the error |
|
|
@@ -476,6 +480,7 @@ Unit tests mirror module paths under `test/unit/spec/services`. Preserve positiv
|
|
|
476
480
|
| `SERVICES-R-004` | `test/unit/spec/services/task/TaskManager.ts`, `test/unit/spec/cc.ts` | None. |
|
|
477
481
|
| `SERVICES-R-005` | `test/unit/spec/services/core/WebexRequest.ts` | None. |
|
|
478
482
|
| `SERVICES-R-006` | `test/unit/spec/cc.ts` | None. |
|
|
483
|
+
| `SERVICES-R-007` | `test/unit/spec/services/Queue.ts`, `test/unit/spec/services/EntryPoint.ts`, `test/unit/spec/cc.ts` | None. |
|
|
479
484
|
|
|
480
485
|
## Traceability
|
|
481
486
|
- Repo architecture: `../../../ai-docs/ARCHITECTURE.md` · Registry: `../../../ai-docs/SPEC_INDEX.md`
|
|
@@ -238,6 +238,9 @@ function parseAgentConfigs(profileData: {
|
|
|
238
238
|
callVariablesSuppressed: tenantData.callVariablesSuppressed,
|
|
239
239
|
agentDbId: userData.dbId,
|
|
240
240
|
allowConsultToQueue: agentProfileData.consultToQueue,
|
|
241
|
+
accessQueue: agentProfileData.accessQueue,
|
|
242
|
+
accessEntryPoint: agentProfileData.accessEntryPoint,
|
|
243
|
+
accessBuddyTeam: agentProfileData.accessBuddyTeam,
|
|
241
244
|
agentPersonalStatsEnabled: agentProfileData.viewableStatistics
|
|
242
245
|
? agentProfileData.viewableStatistics.agentStats
|
|
243
246
|
: false,
|
|
@@ -156,7 +156,7 @@ Additionally, the following endpoints are defined in `constants.ts` `endPointMap
|
|
|
156
156
|
| Endpoint | Used By | Description |
|
|
157
157
|
|----------|---------|-------------|
|
|
158
158
|
| `queueList` | [`Queue.ts`](../../Queue.ts) | Fetch contact service queues |
|
|
159
|
-
| `
|
|
159
|
+
| `entryPointDialNumberList` | [`EntryPoint.ts`](../../EntryPoint.ts) | Fetch profile-scoped entry-point dial-number mappings |
|
|
160
160
|
| `addressBookEntries` | [`AddressBook.ts`](../../AddressBook.ts) | Fetch address book entries |
|
|
161
161
|
|
|
162
162
|
---
|
|
@@ -132,8 +132,8 @@ export const endPointMap = {
|
|
|
132
132
|
queueList: (orgId: string, queryParams: string) =>
|
|
133
133
|
`/organization/${orgId}/v2/contact-service-queue?${queryParams}`,
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
`/organization/${orgId}/
|
|
135
|
+
entryPointDialNumberList: (orgId: string, queryParams: string) =>
|
|
136
|
+
`/organization/${orgId}/v3/dial-number?${queryParams}`,
|
|
137
137
|
|
|
138
138
|
addressBookEntries: (orgId: string, addressBookId: string, queryParams: string) =>
|
|
139
139
|
`/organization/${orgId}/v2/address-book/${addressBookId}/entry?${queryParams}`,
|
|
@@ -158,6 +158,12 @@ The AgentProfile is defined as the [`Profile`](../types.ts) type. This is not an
|
|
|
158
158
|
| `dialPlan` | [`DialPlan`](../types.ts) | Number transformation rules |
|
|
159
159
|
| `isOutboundEnabledForAgent` | boolean | Outbound calling allowed |
|
|
160
160
|
| `outDialEp` | string | Outbound entry point ID |
|
|
161
|
+
| `allowConsultToQueue` | boolean | Whether consult-to-queue is enabled on the Desktop Profile |
|
|
162
|
+
| `accessQueue` | `'ALL' \| 'SPECIFIC' \| 'NONE'` | Collaboration tab queue access scope from Desktop Profile |
|
|
163
|
+
| `accessEntryPoint` | `'ALL' \| 'SPECIFIC' \| 'NONE'` | Collaboration tab entry-point access scope from Desktop Profile |
|
|
164
|
+
| `accessBuddyTeam` | `'ALL' \| 'SPECIFIC' \| 'NONE'` | Collaboration tab buddy-team access scope from Desktop Profile |
|
|
165
|
+
|
|
166
|
+
`parseAgentConfigs()` maps the three `access*` fields from `DesktopProfileResponse` onto the public `Profile` returned by `cc.register()`.
|
|
161
167
|
|
|
162
168
|
The following diagram shows how `getAgentConfig` orchestrates multiple API calls and combines their results into the AgentProfile via `parseAgentConfigs()`:
|
|
163
169
|
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
// making query params configurable for List Teams and List Aux Codes API
|
|
2
2
|
export const DEFAULT_PAGE = 0;
|
|
3
3
|
|
|
4
|
+
/** Desktop Profile access levels for collaboration destination categories. */
|
|
5
|
+
export const COLLABORATION_ACCESS = {
|
|
6
|
+
ALL: 'ALL',
|
|
7
|
+
SPECIFIC: 'SPECIFIC',
|
|
8
|
+
NONE: 'NONE',
|
|
9
|
+
} as const;
|
|
10
|
+
|
|
4
11
|
/**
|
|
5
12
|
* Default page size for paginated API requests.
|
|
6
13
|
* @type {number}
|
|
@@ -258,17 +265,14 @@ export const endPointMap = {
|
|
|
258
265
|
queueList: (orgId: string, queryParams: string) =>
|
|
259
266
|
`/organization/${orgId}/v2/contact-service-queue?${queryParams}`,
|
|
260
267
|
/**
|
|
261
|
-
* Gets the
|
|
268
|
+
* Gets the desktop-profile-filtered dial-number mappings used by entry-point destination lists.
|
|
262
269
|
* @param orgId - Organization ID.
|
|
263
270
|
* @param queryParams - Query parameters string.
|
|
264
271
|
* @returns The endpoint URL string.
|
|
265
|
-
* @public
|
|
266
|
-
* @example
|
|
267
|
-
* const url = endPointMap.entryPointList('org123', 'page=0&pageSize=10');
|
|
268
272
|
* @ignore
|
|
269
273
|
*/
|
|
270
|
-
|
|
271
|
-
`/organization/${orgId}/
|
|
274
|
+
entryPointDialNumberList: (orgId: string, queryParams: string) =>
|
|
275
|
+
`/organization/${orgId}/v3/dial-number?${queryParams}`,
|
|
272
276
|
/**
|
|
273
277
|
* Gets the endpoint for address book entries with custom query parameters.
|
|
274
278
|
* @param orgId - Organization ID.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Agent from '../agent/types';
|
|
2
|
+
import {COLLABORATION_ACCESS} from './constants';
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Generic type for converting a const enum object into a union type of its values
|
|
@@ -6,6 +7,9 @@ import * as Agent from '../agent/types';
|
|
|
6
7
|
*/
|
|
7
8
|
type Enum<T extends Record<string, unknown>> = T[keyof T];
|
|
8
9
|
|
|
10
|
+
/** Desktop Profile access level for a collaboration destination category. */
|
|
11
|
+
export type CollaborationAccess = Enum<typeof COLLABORATION_ACCESS>;
|
|
12
|
+
|
|
9
13
|
/**
|
|
10
14
|
* Events emitted on task objects
|
|
11
15
|
* @enum {string}
|
|
@@ -57,6 +61,8 @@ export const CC_TASK_EVENTS = {
|
|
|
57
61
|
PARTICIPANT_LEFT_CONFERENCE: 'ParticipantLeftConference',
|
|
58
62
|
/** Event emitted when participant leaving conference fails */
|
|
59
63
|
PARTICIPANT_LEFT_CONFERENCE_FAILED: 'ParticipantLeftConferenceFailed',
|
|
64
|
+
/** Event emitted when dropping another conference participant fails */
|
|
65
|
+
PARTICIPANT_DROP_CONFERENCE_FAILED: 'ParticipantDropConferenceFailed',
|
|
60
66
|
/** Event emitted when consultation conference end fails */
|
|
61
67
|
AGENT_CONSULT_CONFERENCE_END_FAILED: 'AgentConsultConferenceEndFailed',
|
|
62
68
|
/** Event emitted when conference is successfully transferred */
|
|
@@ -404,9 +410,9 @@ export type DesktopProfileResponse = {
|
|
|
404
410
|
allowAutoWrapUpExtension: boolean;
|
|
405
411
|
|
|
406
412
|
/**
|
|
407
|
-
* Access control for queues assigned to the agent (ALL or
|
|
413
|
+
* Access control for queues assigned to the agent (ALL, SPECIFIC, or NONE).
|
|
408
414
|
*/
|
|
409
|
-
accessQueue:
|
|
415
|
+
accessQueue: CollaborationAccess;
|
|
410
416
|
|
|
411
417
|
/**
|
|
412
418
|
* Queue identifiers available to the agent when access is SPECIFIC.
|
|
@@ -416,7 +422,7 @@ export type DesktopProfileResponse = {
|
|
|
416
422
|
/**
|
|
417
423
|
* Access control for entry points assigned to the agent.
|
|
418
424
|
*/
|
|
419
|
-
accessEntryPoint:
|
|
425
|
+
accessEntryPoint: CollaborationAccess;
|
|
420
426
|
|
|
421
427
|
/**
|
|
422
428
|
* Entry point identifiers available to the agent when access is SPECIFIC.
|
|
@@ -426,7 +432,7 @@ export type DesktopProfileResponse = {
|
|
|
426
432
|
/**
|
|
427
433
|
* Access control for buddy teams assigned to the agent.
|
|
428
434
|
*/
|
|
429
|
-
accessBuddyTeam:
|
|
435
|
+
accessBuddyTeam: CollaborationAccess;
|
|
430
436
|
|
|
431
437
|
/**
|
|
432
438
|
* Buddy team identifiers available to the agent when access is SPECIFIC.
|
|
@@ -1169,6 +1175,12 @@ export type Profile = {
|
|
|
1169
1175
|
agentAnalyzerId?: string;
|
|
1170
1176
|
/** Whether consult to queue is allowed */
|
|
1171
1177
|
allowConsultToQueue: boolean;
|
|
1178
|
+
/** Access control for queues on Desktop Profile Collaboration tab */
|
|
1179
|
+
accessQueue?: CollaborationAccess;
|
|
1180
|
+
/** Access control for entry points on Desktop Profile Collaboration tab */
|
|
1181
|
+
accessEntryPoint?: CollaborationAccess;
|
|
1182
|
+
/** Access control for buddy teams on Desktop Profile Collaboration tab */
|
|
1183
|
+
accessBuddyTeam?: CollaborationAccess;
|
|
1172
1184
|
/** Additional campaign manager information */
|
|
1173
1185
|
campaignManagerAdditionalInfo?: string;
|
|
1174
1186
|
/** Whether personal statistics are enabled */
|
package/src/services/core/Err.ts
CHANGED
|
@@ -30,6 +30,7 @@ export type TaskErrorIds =
|
|
|
30
30
|
| {'Service.aqm.err.trackingId': {trackingId: string}}
|
|
31
31
|
| {'Service.aqm.task.consultAccept': Failure}
|
|
32
32
|
| {'Service.aqm.task.consultConference': Failure}
|
|
33
|
+
| {'Service.aqm.task.dropConferenceParticipant': Failure}
|
|
33
34
|
| {'Service.aqm.task.consultEnd': Failure}
|
|
34
35
|
| {'Service.aqm.task.cancelCtq': Failure}
|
|
35
36
|
| {'Service.aqm.task.hold': Failure}
|
|
@@ -34,14 +34,16 @@ class WebexRequest {
|
|
|
34
34
|
resource: string;
|
|
35
35
|
method: HTTP_METHODS;
|
|
36
36
|
body?: RequestBody;
|
|
37
|
+
headers?: Record<string, string | null>;
|
|
37
38
|
}): Promise<IHttpResponse> {
|
|
38
|
-
const {service, resource, method, body} = options;
|
|
39
|
+
const {service, resource, method, body, headers} = options;
|
|
39
40
|
|
|
40
41
|
return this.webex.request({
|
|
41
42
|
service,
|
|
42
43
|
resource,
|
|
43
44
|
method,
|
|
44
45
|
body,
|
|
46
|
+
...(headers ? {headers} : {}),
|
|
45
47
|
});
|
|
46
48
|
}
|
|
47
49
|
|