@webex/contact-center 0.0.0-next.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/README.md +81 -0
- package/__mocks__/workerMock.js +15 -0
- package/babel.config.js +15 -0
- package/dist/cc.js +1416 -0
- package/dist/cc.js.map +1 -0
- package/dist/config.js +72 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.js +58 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -0
- package/dist/logger-proxy.js +115 -0
- package/dist/logger-proxy.js.map +1 -0
- package/dist/metrics/MetricsManager.js +474 -0
- package/dist/metrics/MetricsManager.js.map +1 -0
- package/dist/metrics/behavioral-events.js +322 -0
- package/dist/metrics/behavioral-events.js.map +1 -0
- package/dist/metrics/constants.js +134 -0
- package/dist/metrics/constants.js.map +1 -0
- package/dist/services/WebCallingService.js +323 -0
- package/dist/services/WebCallingService.js.map +1 -0
- package/dist/services/agent/index.js +177 -0
- package/dist/services/agent/index.js.map +1 -0
- package/dist/services/agent/types.js +137 -0
- package/dist/services/agent/types.js.map +1 -0
- package/dist/services/config/Util.js +203 -0
- package/dist/services/config/Util.js.map +1 -0
- package/dist/services/config/constants.js +221 -0
- package/dist/services/config/constants.js.map +1 -0
- package/dist/services/config/index.js +607 -0
- package/dist/services/config/index.js.map +1 -0
- package/dist/services/config/types.js +334 -0
- package/dist/services/config/types.js.map +1 -0
- package/dist/services/constants.js +117 -0
- package/dist/services/constants.js.map +1 -0
- package/dist/services/core/Err.js +43 -0
- package/dist/services/core/Err.js.map +1 -0
- package/dist/services/core/GlobalTypes.js +6 -0
- package/dist/services/core/GlobalTypes.js.map +1 -0
- package/dist/services/core/Utils.js +126 -0
- package/dist/services/core/Utils.js.map +1 -0
- package/dist/services/core/WebexRequest.js +96 -0
- package/dist/services/core/WebexRequest.js.map +1 -0
- package/dist/services/core/aqm-reqs.js +246 -0
- package/dist/services/core/aqm-reqs.js.map +1 -0
- package/dist/services/core/constants.js +109 -0
- package/dist/services/core/constants.js.map +1 -0
- package/dist/services/core/types.js +6 -0
- package/dist/services/core/types.js.map +1 -0
- package/dist/services/core/websocket/WebSocketManager.js +187 -0
- package/dist/services/core/websocket/WebSocketManager.js.map +1 -0
- package/dist/services/core/websocket/connection-service.js +111 -0
- package/dist/services/core/websocket/connection-service.js.map +1 -0
- package/dist/services/core/websocket/keepalive.worker.js +94 -0
- package/dist/services/core/websocket/keepalive.worker.js.map +1 -0
- package/dist/services/core/websocket/types.js +6 -0
- package/dist/services/core/websocket/types.js.map +1 -0
- package/dist/services/index.js +78 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/task/AutoWrapup.js +88 -0
- package/dist/services/task/AutoWrapup.js.map +1 -0
- package/dist/services/task/TaskManager.js +369 -0
- package/dist/services/task/TaskManager.js.map +1 -0
- package/dist/services/task/constants.js +58 -0
- package/dist/services/task/constants.js.map +1 -0
- package/dist/services/task/contact.js +464 -0
- package/dist/services/task/contact.js.map +1 -0
- package/dist/services/task/dialer.js +60 -0
- package/dist/services/task/dialer.js.map +1 -0
- package/dist/services/task/index.js +1188 -0
- package/dist/services/task/index.js.map +1 -0
- package/dist/services/task/types.js +214 -0
- package/dist/services/task/types.js.map +1 -0
- package/dist/types/cc.d.ts +676 -0
- package/dist/types/config.d.ts +66 -0
- package/dist/types/constants.d.ts +45 -0
- package/dist/types/index.d.ts +178 -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 +127 -0
- package/dist/types/services/WebCallingService.d.ts +1 -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 +19 -0
- package/dist/types/services/config/constants.d.ts +203 -0
- package/dist/types/services/config/index.d.ts +171 -0
- package/dist/types/services/config/types.d.ts +1113 -0
- package/dist/types/services/constants.d.ts +97 -0
- package/dist/types/services/core/Err.d.ts +119 -0
- package/dist/types/services/core/GlobalTypes.d.ts +33 -0
- package/dist/types/services/core/Utils.d.ts +36 -0
- package/dist/types/services/core/WebexRequest.d.ts +22 -0
- package/dist/types/services/core/aqm-reqs.d.ts +16 -0
- package/dist/types/services/core/constants.d.ts +85 -0
- package/dist/types/services/core/types.d.ts +47 -0
- package/dist/types/services/core/websocket/WebSocketManager.d.ts +34 -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 +52 -0
- package/dist/types/services/task/AutoWrapup.d.ts +40 -0
- package/dist/types/services/task/TaskManager.d.ts +1 -0
- package/dist/types/services/task/constants.d.ts +46 -0
- package/dist/types/services/task/contact.d.ts +59 -0
- package/dist/types/services/task/dialer.d.ts +28 -0
- package/dist/types/services/task/index.d.ts +569 -0
- package/dist/types/services/task/types.d.ts +1041 -0
- package/dist/types/types.d.ts +452 -0
- package/dist/types/webex-config.d.ts +53 -0
- package/dist/types/webex.d.ts +7 -0
- package/dist/types.js +292 -0
- package/dist/types.js.map +1 -0
- package/dist/webex-config.js +60 -0
- package/dist/webex-config.js.map +1 -0
- package/dist/webex.js +99 -0
- package/dist/webex.js.map +1 -0
- package/jest.config.js +45 -0
- package/package.json +83 -0
- package/src/cc.ts +1618 -0
- package/src/config.ts +65 -0
- package/src/constants.ts +51 -0
- package/src/index.ts +220 -0
- package/src/logger-proxy.ts +110 -0
- package/src/metrics/MetricsManager.ts +512 -0
- package/src/metrics/behavioral-events.ts +332 -0
- package/src/metrics/constants.ts +135 -0
- package/src/services/WebCallingService.ts +351 -0
- package/src/services/agent/index.ts +149 -0
- package/src/services/agent/types.ts +440 -0
- package/src/services/config/Util.ts +261 -0
- package/src/services/config/constants.ts +249 -0
- package/src/services/config/index.ts +743 -0
- package/src/services/config/types.ts +1117 -0
- package/src/services/constants.ts +111 -0
- package/src/services/core/Err.ts +126 -0
- package/src/services/core/GlobalTypes.ts +34 -0
- package/src/services/core/Utils.ts +132 -0
- package/src/services/core/WebexRequest.ts +103 -0
- package/src/services/core/aqm-reqs.ts +272 -0
- package/src/services/core/constants.ts +106 -0
- package/src/services/core/types.ts +48 -0
- package/src/services/core/websocket/WebSocketManager.ts +196 -0
- package/src/services/core/websocket/connection-service.ts +142 -0
- package/src/services/core/websocket/keepalive.worker.js +88 -0
- package/src/services/core/websocket/types.ts +40 -0
- package/src/services/index.ts +71 -0
- package/src/services/task/AutoWrapup.ts +86 -0
- package/src/services/task/TaskManager.ts +420 -0
- package/src/services/task/constants.ts +52 -0
- package/src/services/task/contact.ts +429 -0
- package/src/services/task/dialer.ts +52 -0
- package/src/services/task/index.ts +1375 -0
- package/src/services/task/types.ts +1113 -0
- package/src/types.ts +639 -0
- package/src/webex-config.ts +54 -0
- package/src/webex.js +96 -0
- package/test/unit/spec/cc.ts +1985 -0
- package/test/unit/spec/metrics/MetricsManager.ts +491 -0
- package/test/unit/spec/metrics/behavioral-events.ts +102 -0
- package/test/unit/spec/services/WebCallingService.ts +416 -0
- package/test/unit/spec/services/agent/index.ts +65 -0
- package/test/unit/spec/services/config/index.ts +1035 -0
- package/test/unit/spec/services/core/Utils.ts +279 -0
- package/test/unit/spec/services/core/WebexRequest.ts +144 -0
- package/test/unit/spec/services/core/aqm-reqs.ts +570 -0
- package/test/unit/spec/services/core/websocket/WebSocketManager.ts +378 -0
- package/test/unit/spec/services/core/websocket/connection-service.ts +178 -0
- package/test/unit/spec/services/task/TaskManager.ts +1351 -0
- package/test/unit/spec/services/task/contact.ts +204 -0
- package/test/unit/spec/services/task/dialer.ts +157 -0
- package/test/unit/spec/services/task/index.ts +1474 -0
- package/tsconfig.json +6 -0
- package/typedoc.json +37 -0
- package/typedoc.md +240 -0
- package/umd/contact-center.min.js +3 -0
- package/umd/contact-center.min.js.map +1 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import {EventEmitter} from 'events';
|
|
2
|
+
import {WebSocketManager} from './WebSocketManager';
|
|
3
|
+
import LoggerProxy from '../../../logger-proxy';
|
|
4
|
+
import {ConnectionServiceOptions, ConnectionLostDetails, ConnectionProp} from './types';
|
|
5
|
+
import {
|
|
6
|
+
LOST_CONNECTION_RECOVERY_TIMEOUT,
|
|
7
|
+
WS_DISCONNECT_ALLOWED,
|
|
8
|
+
CONNECTIVITY_CHECK_INTERVAL,
|
|
9
|
+
METHODS,
|
|
10
|
+
} from '../constants';
|
|
11
|
+
import {CONNECTION_SERVICE_FILE} from '../../../constants';
|
|
12
|
+
import {SubscribeRequest} from '../../../types';
|
|
13
|
+
|
|
14
|
+
export class ConnectionService extends EventEmitter {
|
|
15
|
+
private connectionProp: ConnectionProp = {
|
|
16
|
+
lostConnectionRecoveryTimeout: LOST_CONNECTION_RECOVERY_TIMEOUT,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
private wsDisconnectAllowed = WS_DISCONNECT_ALLOWED;
|
|
20
|
+
private reconnectingTimer: ReturnType<typeof setTimeout>;
|
|
21
|
+
private restoreTimer: ReturnType<typeof setTimeout>;
|
|
22
|
+
private isConnectionLost: boolean;
|
|
23
|
+
private isRestoreFailed: boolean;
|
|
24
|
+
private isSocketReconnected: boolean;
|
|
25
|
+
private isKeepAlive: boolean;
|
|
26
|
+
private reconnectInterval: ReturnType<typeof setInterval>;
|
|
27
|
+
private webSocketManager: WebSocketManager;
|
|
28
|
+
private subscribeRequest: SubscribeRequest;
|
|
29
|
+
|
|
30
|
+
constructor(options: ConnectionServiceOptions) {
|
|
31
|
+
super();
|
|
32
|
+
this.webSocketManager = options.webSocketManager;
|
|
33
|
+
this.subscribeRequest = options.subscribeRequest;
|
|
34
|
+
|
|
35
|
+
this.isConnectionLost = false;
|
|
36
|
+
this.isRestoreFailed = false;
|
|
37
|
+
this.isSocketReconnected = false;
|
|
38
|
+
this.isKeepAlive = false;
|
|
39
|
+
|
|
40
|
+
this.setupEventListeners();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private setupEventListeners() {
|
|
44
|
+
this.webSocketManager.on('message', this.onPing.bind(this));
|
|
45
|
+
this.webSocketManager.on('socketClose', this.onSocketClose.bind(this));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private dispatchConnectionEvent(socketReconnected = false): void {
|
|
49
|
+
const event: ConnectionLostDetails = {
|
|
50
|
+
isConnectionLost: this.isConnectionLost,
|
|
51
|
+
isRestoreFailed: this.isRestoreFailed,
|
|
52
|
+
isSocketReconnected:
|
|
53
|
+
!this.webSocketManager.isSocketClosed && (socketReconnected || this.isSocketReconnected),
|
|
54
|
+
isKeepAlive: this.isKeepAlive,
|
|
55
|
+
};
|
|
56
|
+
this.webSocketManager.handleConnectionLost(event);
|
|
57
|
+
LoggerProxy.info(`Dispatching connection event`, {
|
|
58
|
+
module: CONNECTION_SERVICE_FILE,
|
|
59
|
+
method: METHODS.DISPATCH_CONNECTION_EVENT,
|
|
60
|
+
});
|
|
61
|
+
this.emit('connectionLost', event);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private handleConnectionLost = (): void => {
|
|
65
|
+
this.isConnectionLost = true;
|
|
66
|
+
this.dispatchConnectionEvent();
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
private clearTimerOnRestoreFailed = async () => {
|
|
70
|
+
if (this.reconnectInterval) {
|
|
71
|
+
clearInterval(this.reconnectInterval);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
private handleRestoreFailed = async () => {
|
|
76
|
+
this.isRestoreFailed = true;
|
|
77
|
+
this.webSocketManager.shouldReconnect = false;
|
|
78
|
+
this.dispatchConnectionEvent();
|
|
79
|
+
await this.clearTimerOnRestoreFailed();
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
private updateConnectionData = (): void => {
|
|
83
|
+
this.isRestoreFailed = false;
|
|
84
|
+
this.isConnectionLost = false;
|
|
85
|
+
this.isSocketReconnected = false;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
public setConnectionProp(prop: ConnectionProp): void {
|
|
89
|
+
this.connectionProp = prop;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
private onPing = (event: any): void => {
|
|
93
|
+
const parsedEvent = JSON.parse(event);
|
|
94
|
+
if (this.reconnectingTimer) {
|
|
95
|
+
clearTimeout(this.reconnectingTimer);
|
|
96
|
+
}
|
|
97
|
+
if (this.restoreTimer) {
|
|
98
|
+
clearTimeout(this.restoreTimer);
|
|
99
|
+
}
|
|
100
|
+
this.isKeepAlive = parsedEvent.keepalive === 'true';
|
|
101
|
+
|
|
102
|
+
if (
|
|
103
|
+
((this.isConnectionLost && !this.isRestoreFailed) || this.isKeepAlive) &&
|
|
104
|
+
!this.isSocketReconnected
|
|
105
|
+
) {
|
|
106
|
+
this.updateConnectionData();
|
|
107
|
+
this.dispatchConnectionEvent();
|
|
108
|
+
} else if (this.isSocketReconnected && this.isKeepAlive) {
|
|
109
|
+
this.updateConnectionData();
|
|
110
|
+
this.dispatchConnectionEvent(true);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
this.reconnectingTimer = setTimeout(this.handleConnectionLost, this.wsDisconnectAllowed);
|
|
114
|
+
this.restoreTimer = setTimeout(
|
|
115
|
+
this.handleRestoreFailed,
|
|
116
|
+
this.connectionProp && this.connectionProp.lostConnectionRecoveryTimeout
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
private handleSocketClose = async (): Promise<void> => {
|
|
121
|
+
LoggerProxy.info(`event=socketConnectionRetry | Trying to reconnect to websocket`, {
|
|
122
|
+
module: CONNECTION_SERVICE_FILE,
|
|
123
|
+
method: METHODS.HANDLE_SOCKET_CLOSE,
|
|
124
|
+
});
|
|
125
|
+
const onlineStatus = navigator.onLine;
|
|
126
|
+
if (onlineStatus) {
|
|
127
|
+
await this.webSocketManager.initWebSocket({body: this.subscribeRequest});
|
|
128
|
+
await this.clearTimerOnRestoreFailed();
|
|
129
|
+
this.isSocketReconnected = true;
|
|
130
|
+
} else {
|
|
131
|
+
throw new Error('event=socketConnectionRetry | browser network not available');
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
private onSocketClose = (): void => {
|
|
136
|
+
this.clearTimerOnRestoreFailed();
|
|
137
|
+
|
|
138
|
+
this.reconnectInterval = setInterval(async () => {
|
|
139
|
+
await this.handleSocketClose();
|
|
140
|
+
}, CONNECTIVITY_CHECK_INTERVAL);
|
|
141
|
+
};
|
|
142
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// TODO: Try to find alternative to using Blob and script here
|
|
2
|
+
const workerScript = `
|
|
3
|
+
console.log("*** Keepalive Worker Thread ***");
|
|
4
|
+
let intervalId, intervalDuration, timeOutId, isSocketClosed, closeSocketTimeout;
|
|
5
|
+
let initialised = false;
|
|
6
|
+
let initiateWebSocketClosure = false;
|
|
7
|
+
|
|
8
|
+
const resetOfflineHandler = function () {
|
|
9
|
+
if (timeOutId) {
|
|
10
|
+
initialised = false;
|
|
11
|
+
clearTimeout(timeOutId);
|
|
12
|
+
timeOutId = null;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const checkOnlineStatus = function () {
|
|
17
|
+
const onlineStatus = navigator.onLine;
|
|
18
|
+
console.log(
|
|
19
|
+
\`[WebSocketStatus] event=checkOnlineStatus | online status=\`,
|
|
20
|
+
onlineStatus
|
|
21
|
+
);
|
|
22
|
+
return onlineStatus;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// Checks network status and if it's offline then force closes WebSocket
|
|
26
|
+
const checkNetworkStatus = function () {
|
|
27
|
+
const onlineStatus = checkOnlineStatus();
|
|
28
|
+
postMessage({ type: "keepalive", onlineStatus });
|
|
29
|
+
if (!onlineStatus && !initialised) {
|
|
30
|
+
initialised = true;
|
|
31
|
+
// Sets a timeout of 16s, checks if socket didn't close then it closes forcefully
|
|
32
|
+
timeOutId = setTimeout(() => {
|
|
33
|
+
if (!isSocketClosed) {
|
|
34
|
+
initiateWebSocketClosure = true;
|
|
35
|
+
postMessage({ type: "closeSocket" });
|
|
36
|
+
}
|
|
37
|
+
}, closeSocketTimeout);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (onlineStatus && initialised) {
|
|
41
|
+
initialised = false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (initiateWebSocketClosure) {
|
|
45
|
+
initiateWebSocketClosure = false;
|
|
46
|
+
clearTimeout(timeOutId);
|
|
47
|
+
timeOutId = null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
addEventListener("message", (event) => {
|
|
52
|
+
if (event.data?.type === "start") {
|
|
53
|
+
intervalDuration = event.data?.intervalDuration || 4000;
|
|
54
|
+
closeSocketTimeout = event.data?.closeSocketTimeout || 5000;
|
|
55
|
+
console.log("event=Websocket startWorker | keepalive Worker started");
|
|
56
|
+
intervalId = setInterval(
|
|
57
|
+
(checkIfSocketClosed) => {
|
|
58
|
+
checkNetworkStatus();
|
|
59
|
+
isSocketClosed = checkIfSocketClosed;
|
|
60
|
+
},
|
|
61
|
+
intervalDuration,
|
|
62
|
+
event.data?.isSocketClosed
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
resetOfflineHandler();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (event.data?.type === "terminate" && intervalId) {
|
|
69
|
+
console.log("event=Websocket terminateWorker | keepalive Worker stopped");
|
|
70
|
+
clearInterval(intervalId);
|
|
71
|
+
intervalId = null;
|
|
72
|
+
resetOfflineHandler();
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Listen for online and offline events
|
|
77
|
+
self.addEventListener('online', () => {
|
|
78
|
+
console.log('Network status: online');
|
|
79
|
+
checkNetworkStatus();
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
self.addEventListener('offline', () => {
|
|
83
|
+
console.log('Network status: offline');
|
|
84
|
+
checkNetworkStatus();
|
|
85
|
+
});
|
|
86
|
+
`;
|
|
87
|
+
|
|
88
|
+
export default workerScript;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {SubscribeRequest} from '../../../types';
|
|
2
|
+
import {WebSocketManager} from './WebSocketManager';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Options for initializing a connection service.
|
|
6
|
+
* @typedef ConnectionServiceOptions
|
|
7
|
+
* @property {WebSocketManager} webSocketManager - The WebSocket manager instance.
|
|
8
|
+
* @property {SubscribeRequest} subscribeRequest - The subscribe request payload.
|
|
9
|
+
* @ignore
|
|
10
|
+
*/
|
|
11
|
+
export type ConnectionServiceOptions = {
|
|
12
|
+
webSocketManager: WebSocketManager;
|
|
13
|
+
subscribeRequest: SubscribeRequest;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Details about the state of a lost connection and recovery attempts.
|
|
18
|
+
* @typedef ConnectionLostDetails
|
|
19
|
+
* @property {boolean} isConnectionLost - Indicates if the connection is currently lost.
|
|
20
|
+
* @property {boolean} isRestoreFailed - Indicates if restoring the connection has failed.
|
|
21
|
+
* @property {boolean} isSocketReconnected - Indicates if the socket has been reconnected.
|
|
22
|
+
* @property {boolean} isKeepAlive - Indicates if the keep-alive mechanism is active.
|
|
23
|
+
* @ignore
|
|
24
|
+
*/
|
|
25
|
+
export type ConnectionLostDetails = {
|
|
26
|
+
isConnectionLost: boolean;
|
|
27
|
+
isRestoreFailed: boolean;
|
|
28
|
+
isSocketReconnected: boolean;
|
|
29
|
+
isKeepAlive: boolean;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Properties for connection configuration.
|
|
34
|
+
* @typedef ConnectionProp
|
|
35
|
+
* @property {number} lostConnectionRecoveryTimeout - Timeout in milliseconds for lost connection recovery.
|
|
36
|
+
* @ignore
|
|
37
|
+
*/
|
|
38
|
+
export type ConnectionProp = {
|
|
39
|
+
lostConnectionRecoveryTimeout: number;
|
|
40
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import routingAgent from './agent';
|
|
2
|
+
import routingContact from './task/contact';
|
|
3
|
+
import AgentConfigService from './config';
|
|
4
|
+
import AqmReqs from './core/aqm-reqs';
|
|
5
|
+
import {WebSocketManager} from './core/websocket/WebSocketManager';
|
|
6
|
+
import {ConnectionService} from './core/websocket/connection-service';
|
|
7
|
+
import {WebexSDK, SubscribeRequest} from '../types';
|
|
8
|
+
import aqmDialer from './task/dialer';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Services class provides centralized access to all contact center plugin services
|
|
12
|
+
* using a singleton pattern to ensure a single instance throughout the application.
|
|
13
|
+
* @private
|
|
14
|
+
* @ignore
|
|
15
|
+
* @class
|
|
16
|
+
*/
|
|
17
|
+
export default class Services {
|
|
18
|
+
/** Agent services for managing agent state and capabilities */
|
|
19
|
+
public readonly agent: ReturnType<typeof routingAgent>;
|
|
20
|
+
/** Configuration services for agent settings */
|
|
21
|
+
public readonly config: AgentConfigService;
|
|
22
|
+
/** Contact services for managing customer interactions */
|
|
23
|
+
public readonly contact: ReturnType<typeof routingContact>;
|
|
24
|
+
/** Dialer services for outbound calling features */
|
|
25
|
+
public readonly dialer: ReturnType<typeof aqmDialer>;
|
|
26
|
+
/** WebSocket manager for handling real-time communications */
|
|
27
|
+
public readonly webSocketManager: WebSocketManager;
|
|
28
|
+
/** Connection service for managing websocket connections */
|
|
29
|
+
public readonly connectionService: ConnectionService;
|
|
30
|
+
/** Singleton instance of the Services class */
|
|
31
|
+
private static instance: Services;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Creates a new Services instance
|
|
35
|
+
* @param options - Configuration options
|
|
36
|
+
* @param options.webex - WebexSDK instance
|
|
37
|
+
* @param options.connectionConfig - Subscription configuration for websocket connection
|
|
38
|
+
*/
|
|
39
|
+
constructor(options: {webex: WebexSDK; connectionConfig: SubscribeRequest}) {
|
|
40
|
+
const {webex, connectionConfig} = options;
|
|
41
|
+
this.webSocketManager = new WebSocketManager({webex});
|
|
42
|
+
const aqmReq = new AqmReqs(this.webSocketManager);
|
|
43
|
+
this.config = new AgentConfigService();
|
|
44
|
+
this.agent = routingAgent(aqmReq);
|
|
45
|
+
this.contact = routingContact(aqmReq);
|
|
46
|
+
this.dialer = aqmDialer(aqmReq);
|
|
47
|
+
this.connectionService = new ConnectionService({
|
|
48
|
+
webSocketManager: this.webSocketManager,
|
|
49
|
+
subscribeRequest: connectionConfig,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Gets singleton instance of Services class
|
|
55
|
+
* Creates a new instance if one doesn't exist
|
|
56
|
+
* @param options - Configuration options
|
|
57
|
+
* @param options.webex - WebexSDK instance
|
|
58
|
+
* @param options.connectionConfig - Subscription configuration for websocket connection
|
|
59
|
+
* @returns The singleton Services instance
|
|
60
|
+
*/
|
|
61
|
+
public static getInstance(options: {
|
|
62
|
+
webex: WebexSDK;
|
|
63
|
+
connectionConfig: SubscribeRequest;
|
|
64
|
+
}): Services {
|
|
65
|
+
if (!this.instance) {
|
|
66
|
+
this.instance = new Services(options);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return this.instance;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import LoggerProxy from '../../logger-proxy';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* AutoWrapup class implements a timer for automatic wrap-up functionality.
|
|
5
|
+
* It handles timing the wrap-up period and executing a callback when the timer completes.
|
|
6
|
+
*/
|
|
7
|
+
export default class AutoWrapup {
|
|
8
|
+
private timer: ReturnType<typeof setTimeout> | null = null;
|
|
9
|
+
private startTime = 0;
|
|
10
|
+
private readonly interval: number;
|
|
11
|
+
public allowCancelAutoWrapup = false;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new AutoWrapup timer
|
|
15
|
+
* @param interval - Time in milliseconds before auto wrap-up executes
|
|
16
|
+
* @param allowCancelAutoWrapup - Whether to allow canceling the auto wrap-up
|
|
17
|
+
*/
|
|
18
|
+
constructor(interval: number, allowCancelAutoWrapup = false) {
|
|
19
|
+
this.interval = interval;
|
|
20
|
+
this.allowCancelAutoWrapup = allowCancelAutoWrapup;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Starts the auto wrap-up timer
|
|
25
|
+
* @param onComplete - Callback function to execute when timer completes
|
|
26
|
+
*/
|
|
27
|
+
public start(onComplete: () => void): void {
|
|
28
|
+
LoggerProxy.info('AutoWrapup: clear called', {
|
|
29
|
+
module: 'AutoWrapup',
|
|
30
|
+
method: 'clear',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
if (this.timer) {
|
|
34
|
+
this.clear();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
this.startTime = Date.now();
|
|
38
|
+
|
|
39
|
+
this.timer = setTimeout(() => {
|
|
40
|
+
onComplete();
|
|
41
|
+
this.timer = null;
|
|
42
|
+
}, this.interval);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Clears the auto wrap-up timer if it's running
|
|
47
|
+
*/
|
|
48
|
+
public clear(): void {
|
|
49
|
+
LoggerProxy.info('AutoWrapup: clear called', {
|
|
50
|
+
module: 'AutoWrapup',
|
|
51
|
+
method: 'clear',
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
if (this.timer) {
|
|
55
|
+
clearTimeout(this.timer);
|
|
56
|
+
this.timer = null;
|
|
57
|
+
this.startTime = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Gets the remaining time in milliseconds
|
|
63
|
+
* @returns Time left in milliseconds
|
|
64
|
+
*/
|
|
65
|
+
public getTimeLeft(): number {
|
|
66
|
+
const elapsed = Date.now() - this.startTime;
|
|
67
|
+
|
|
68
|
+
return Math.max(0, this.interval - elapsed);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Checks if the timer is currently running
|
|
73
|
+
* @returns True if the timer is running, false otherwise
|
|
74
|
+
*/
|
|
75
|
+
public isRunning(): boolean {
|
|
76
|
+
return this.timer !== null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Gets the remaining time in seconds (rounded)
|
|
81
|
+
* @returns Time left in seconds
|
|
82
|
+
*/
|
|
83
|
+
public getTimeLeftSeconds(): number {
|
|
84
|
+
return Math.ceil(this.getTimeLeft() / 1000);
|
|
85
|
+
}
|
|
86
|
+
}
|