@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,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Post-authentication event name.
|
|
3
|
+
* @type {string}
|
|
4
|
+
* @public
|
|
5
|
+
* @example
|
|
6
|
+
* if (event === POST_AUTH) { ... }
|
|
7
|
+
* @ignore
|
|
8
|
+
*/
|
|
9
|
+
export const POST_AUTH = 'postauth';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* API gateway identifier for Webex Contact Center.
|
|
13
|
+
* @type {string}
|
|
14
|
+
* @public
|
|
15
|
+
* @ignore
|
|
16
|
+
*/
|
|
17
|
+
export const WCC_API_GATEWAY = 'wcc-api-gateway';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Domain identifier for WCC Calling RTMS.
|
|
21
|
+
* @type {string}
|
|
22
|
+
* @public
|
|
23
|
+
* @ignore
|
|
24
|
+
*/
|
|
25
|
+
export const WCC_CALLING_RTMS_DOMAIN = 'wcc-calling-rtms-domain';
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Default RTMS domain for production use.
|
|
29
|
+
* @type {string}
|
|
30
|
+
* @public
|
|
31
|
+
* @ignore
|
|
32
|
+
*/
|
|
33
|
+
export const DEFAULT_RTMS_DOMAIN = 'rtw.prod-us1.rtmsprod.net';
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Timeout in milliseconds for WebSocket events.
|
|
37
|
+
* @type {number}
|
|
38
|
+
* @public
|
|
39
|
+
* @example
|
|
40
|
+
* setTimeout(() => { ... }, WEBSOCKET_EVENT_TIMEOUT);
|
|
41
|
+
* @ignore
|
|
42
|
+
*/
|
|
43
|
+
export const WEBSOCKET_EVENT_TIMEOUT = 20000;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Agent role identifier.
|
|
47
|
+
* @type {string}
|
|
48
|
+
* @public
|
|
49
|
+
* @ignore
|
|
50
|
+
*/
|
|
51
|
+
export const AGENT = 'agent';
|
|
52
|
+
|
|
53
|
+
// CC GATEWAY API URL PATHS
|
|
54
|
+
/**
|
|
55
|
+
* API path for notification subscription.
|
|
56
|
+
* @type {string}
|
|
57
|
+
* @public
|
|
58
|
+
* @ignore
|
|
59
|
+
*/
|
|
60
|
+
export const SUBSCRIBE_API = 'v1/notification/subscribe';
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* API path for agent login.
|
|
64
|
+
* @type {string}
|
|
65
|
+
* @public
|
|
66
|
+
* @ignore
|
|
67
|
+
*/
|
|
68
|
+
export const LOGIN_API = 'v1/agents/login';
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Prefix for WebRTC-related API endpoints.
|
|
72
|
+
* @type {string}
|
|
73
|
+
* @public
|
|
74
|
+
* @ignore
|
|
75
|
+
*/
|
|
76
|
+
export const WEB_RTC_PREFIX = 'webrtc-';
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* API path for agent session state changes.
|
|
80
|
+
* @type {string}
|
|
81
|
+
* @public
|
|
82
|
+
* @ignore
|
|
83
|
+
*/
|
|
84
|
+
export const STATE_CHANGE_API = 'v1/agents/session/state';
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Message for deregistering WebCalling line and cleaning up resources.
|
|
88
|
+
* @type {string}
|
|
89
|
+
* @public
|
|
90
|
+
* @ignore
|
|
91
|
+
*/
|
|
92
|
+
export const DEREGISTER_WEBCALLING_LINE_MSG =
|
|
93
|
+
'Deregistering WebCalling line and cleaning up resources';
|
|
94
|
+
|
|
95
|
+
// WebCallingService method names
|
|
96
|
+
export const METHODS = {
|
|
97
|
+
SET_LOGIN_OPTION: 'setLoginOption',
|
|
98
|
+
HANDLE_MEDIA_EVENT: 'handleMediaEvent',
|
|
99
|
+
HANDLE_DISCONNECT_EVENT: 'handleDisconnectEvent',
|
|
100
|
+
REGISTER_CALL_LISTENERS: 'registerCallListeners',
|
|
101
|
+
CLEAN_UP_CALL: 'cleanUpCall',
|
|
102
|
+
GET_RTMS_DOMAIN: 'getRTMSDomain',
|
|
103
|
+
REGISTER_WEB_CALLING_LINE: 'registerWebCallingLine',
|
|
104
|
+
DEREGISTER_WEB_CALLING_LINE: 'deregisterWebCallingLine',
|
|
105
|
+
ANSWER_CALL: 'answerCall',
|
|
106
|
+
MUTE_UNMUTE_CALL: 'muteUnmuteCall',
|
|
107
|
+
IS_CALL_MUTED: 'isCallMuted',
|
|
108
|
+
DECLINE_CALL: 'declineCall',
|
|
109
|
+
MAP_CALL_TO_TASK: 'mapCallToTask',
|
|
110
|
+
GET_TASK_ID_FOR_CALL: 'getTaskIdForCall',
|
|
111
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {WebexRequestPayload} from '../../types';
|
|
2
|
+
import {Failure} from './GlobalTypes';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Err module provides a structured way to handle errors in the Contact Center plugin.
|
|
6
|
+
* @ignore
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export type ErrDetails = {status: number; type: string; trackingId: string};
|
|
10
|
+
|
|
11
|
+
export type AgentErrorIds =
|
|
12
|
+
| {'Service.aqm.agent.stationLogin': ErrDetails}
|
|
13
|
+
| {'Service.aqm.agent.stationLoginFailed': Failure}
|
|
14
|
+
| {'Service.aqm.agent.stateChange': Failure}
|
|
15
|
+
| {'Service.aqm.agent.reload': Failure}
|
|
16
|
+
| {'Service.aqm.agent.logout': Failure}
|
|
17
|
+
| {'Service.reqs.generic.failure': {trackingId: string}}
|
|
18
|
+
| {'Service.aqm.agent.BuddyAgentsRetrieveFailed': Failure};
|
|
19
|
+
|
|
20
|
+
export type vteamType = 'inboundqueue' | 'inboundentrypoint' | string;
|
|
21
|
+
|
|
22
|
+
export type TaskErrorIds =
|
|
23
|
+
| {'Service.aqm.task.accept': Failure}
|
|
24
|
+
| {'Service.aqm.task.end': Failure}
|
|
25
|
+
| {'Service.aqm.task.wrapup': Failure}
|
|
26
|
+
| {'Service.aqm.task.AgentVteamTransferFailed': Failure}
|
|
27
|
+
| {'Service.aqm.task.AgentBlindTransferFailedEvent': Failure}
|
|
28
|
+
| {'Service.aqm.task.AgentConsultTransferFailed': Failure}
|
|
29
|
+
| {'Service.aqm.task.consult': Failure}
|
|
30
|
+
| {'Service.aqm.err.trackingId': {trackingId: string}}
|
|
31
|
+
| {'Service.aqm.task.consultAccept': Failure}
|
|
32
|
+
| {'Service.aqm.task.consultConference': Failure}
|
|
33
|
+
| {'Service.aqm.task.consultEnd': Failure}
|
|
34
|
+
| {'Service.aqm.task.cancelCtq': Failure}
|
|
35
|
+
| {'Service.aqm.task.hold': Failure}
|
|
36
|
+
| {'Service.aqm.task.unHold': Failure}
|
|
37
|
+
| {'Service.aqm.task.VteamListFailed': Failure}
|
|
38
|
+
| {'Service.aqm.task.pauseRecording': Failure}
|
|
39
|
+
| {'Service.aqm.task.resumeRecording': Failure}
|
|
40
|
+
| {'Service.aqm.dialer.startOutdial': Failure}
|
|
41
|
+
| {'Service.reqs.generic.failure': {trackingId: string}};
|
|
42
|
+
|
|
43
|
+
export type ReqError =
|
|
44
|
+
| 'Service.aqm.reqs.GenericRequestError'
|
|
45
|
+
| {'Service.aqm.reqs.Pending': {key: string; msg: string}}
|
|
46
|
+
| {'Service.aqm.reqs.PendingEvent': {key: string}}
|
|
47
|
+
| {'Service.aqm.reqs.Timeout': {key: string; response: WebexRequestPayload}}
|
|
48
|
+
| {'Service.aqm.reqs.TimeoutEvent': {key: string}};
|
|
49
|
+
|
|
50
|
+
export interface Ids {
|
|
51
|
+
'Service.aqm.agent': AgentErrorIds;
|
|
52
|
+
'Service.aqm.reqs': ReqError;
|
|
53
|
+
'Service.aqm.task': TaskErrorIds;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export type IdsGlobal =
|
|
57
|
+
| 'system' // to handle errors that was not created by 'new Err.WithId()'
|
|
58
|
+
| 'handle'
|
|
59
|
+
| 'fallback';
|
|
60
|
+
|
|
61
|
+
export type IdsSub = Ids[keyof Ids];
|
|
62
|
+
|
|
63
|
+
export type IdsMessage = IdsGlobal | keyof Ids | Exclude<IdsSub, object>;
|
|
64
|
+
|
|
65
|
+
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
|
|
66
|
+
k: infer I
|
|
67
|
+
) => void
|
|
68
|
+
? I
|
|
69
|
+
: never;
|
|
70
|
+
|
|
71
|
+
export type FlattenUnion<T> = {
|
|
72
|
+
[K in keyof UnionToIntersection<T>]: K extends keyof T
|
|
73
|
+
? T[K] extends any[]
|
|
74
|
+
? T[K]
|
|
75
|
+
: T[K] extends object
|
|
76
|
+
? FlattenUnion<T[K]>
|
|
77
|
+
: T[K]
|
|
78
|
+
: UnionToIntersection<T>[K];
|
|
79
|
+
};
|
|
80
|
+
export type IdsDetailsType = FlattenUnion<Exclude<IdsSub, string>>;
|
|
81
|
+
|
|
82
|
+
export type IdsDetails = keyof IdsDetailsType;
|
|
83
|
+
|
|
84
|
+
export type Id = IdsMessage | IdsDetails;
|
|
85
|
+
|
|
86
|
+
export class Message extends Error {
|
|
87
|
+
readonly id: Id;
|
|
88
|
+
|
|
89
|
+
constructor(id: IdsMessage);
|
|
90
|
+
constructor(id: IdsMessage, message: string);
|
|
91
|
+
constructor(id: IdsMessage, errror: Error);
|
|
92
|
+
constructor(id: IdsMessage, value?: string | Error) {
|
|
93
|
+
super();
|
|
94
|
+
|
|
95
|
+
this.id = id;
|
|
96
|
+
this.stack = new Error().stack!;
|
|
97
|
+
|
|
98
|
+
if (typeof value === 'string') {
|
|
99
|
+
this.message = value;
|
|
100
|
+
} else if (value instanceof Error) {
|
|
101
|
+
this.message = value.message;
|
|
102
|
+
this.name = value.name;
|
|
103
|
+
} else {
|
|
104
|
+
this.message = '';
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Marker to distinct Err class from other errors
|
|
109
|
+
private isErr = 'yes';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class Details<T extends IdsDetails> extends Error {
|
|
113
|
+
readonly id: Id;
|
|
114
|
+
readonly details: IdsDetailsType[T];
|
|
115
|
+
|
|
116
|
+
constructor(id: T, details: IdsDetailsType[T]) {
|
|
117
|
+
super();
|
|
118
|
+
|
|
119
|
+
this.id = id;
|
|
120
|
+
this.stack = new Error().stack!;
|
|
121
|
+
this.details = details;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Marker to distinct Err class from other errors
|
|
125
|
+
private isErr = 'yes';
|
|
126
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic message interface used throughout the plugin
|
|
3
|
+
* @template T - Type of the data payload (defaults to any)
|
|
4
|
+
* @private
|
|
5
|
+
* @ignore
|
|
6
|
+
*/
|
|
7
|
+
export type Msg<T = any> = {
|
|
8
|
+
/** Message/Event type identifier */
|
|
9
|
+
type: string;
|
|
10
|
+
/** Organization identifier */
|
|
11
|
+
orgId: string;
|
|
12
|
+
/** Unique tracking identifier for the message/Event */
|
|
13
|
+
trackingId: string;
|
|
14
|
+
/** Message/Event payload data */
|
|
15
|
+
data: T;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Represents a failure message with specific error details
|
|
20
|
+
* @private
|
|
21
|
+
* @ignore
|
|
22
|
+
*/
|
|
23
|
+
export type Failure = Msg<{
|
|
24
|
+
/** Agent identifier associated with the failure */
|
|
25
|
+
agentId: string;
|
|
26
|
+
/** Tracking identifier for the failure event */
|
|
27
|
+
trackingId: string;
|
|
28
|
+
/** Numeric code indicating the reason for failure */
|
|
29
|
+
reasonCode: number;
|
|
30
|
+
/** Organization identifier */
|
|
31
|
+
orgId: string;
|
|
32
|
+
/** Human-readable description of the failure reason */
|
|
33
|
+
reason: string;
|
|
34
|
+
}>;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as Err from './Err';
|
|
2
|
+
import {LoginOption, WebexRequestPayload} from '../../types';
|
|
3
|
+
import {Failure} from './GlobalTypes';
|
|
4
|
+
import LoggerProxy from '../../logger-proxy';
|
|
5
|
+
import WebexRequest from './WebexRequest';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Extracts common error details from a Webex request payload.
|
|
9
|
+
*
|
|
10
|
+
* @param errObj - The Webex request payload object.
|
|
11
|
+
* @returns An object containing the tracking ID and message body.
|
|
12
|
+
* @private
|
|
13
|
+
* @ignore
|
|
14
|
+
*/
|
|
15
|
+
const getCommonErrorDetails = (errObj: WebexRequestPayload) => {
|
|
16
|
+
return {
|
|
17
|
+
trackingId: errObj?.headers?.trackingid || errObj?.headers?.TrackingID,
|
|
18
|
+
msg: errObj?.body,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export const isValidDialNumber = (input: string): boolean => {
|
|
23
|
+
// This regex checks for a valid dial number format for only few countries such as US, Canada.
|
|
24
|
+
const regexForDn = /1[0-9]{3}[2-9][0-9]{6}([,]{1,10}[0-9]+){0,1}/;
|
|
25
|
+
|
|
26
|
+
return regexForDn.test(input);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const getStationLoginErrorData = (failure: Failure, loginOption: LoginOption) => {
|
|
30
|
+
let duplicateLocationMessage = 'This value is already in use';
|
|
31
|
+
|
|
32
|
+
if (loginOption === LoginOption.EXTENSION) {
|
|
33
|
+
duplicateLocationMessage = 'This extension is already in use';
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (loginOption === LoginOption.AGENT_DN) {
|
|
37
|
+
duplicateLocationMessage =
|
|
38
|
+
'Dial number is in use. Try a different one. For help, reach out to your administrator or support team.';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const errorCodeMessageMap = {
|
|
42
|
+
DUPLICATE_LOCATION: {
|
|
43
|
+
message: duplicateLocationMessage,
|
|
44
|
+
fieldName: loginOption,
|
|
45
|
+
},
|
|
46
|
+
INVALID_DIAL_NUMBER: {
|
|
47
|
+
message:
|
|
48
|
+
'Enter a valid US dial number. For help, reach out to your administrator or support team.',
|
|
49
|
+
fieldName: loginOption,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const defaultMessage = 'An error occurred while logging in to the station';
|
|
54
|
+
const defaultFieldName = 'generic';
|
|
55
|
+
|
|
56
|
+
const reason = failure?.data?.reason || '';
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
message: errorCodeMessageMap[reason]?.message || defaultMessage,
|
|
60
|
+
fieldName: errorCodeMessageMap[reason]?.fieldName || defaultFieldName,
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Extracts error details and logs the error. Also uploads logs for the error unless it is a silent relogin agent not found error.
|
|
66
|
+
*
|
|
67
|
+
* @param error - The error object, expected to have a `details` property of type Failure.
|
|
68
|
+
* @param methodName - The name of the method where the error occurred.
|
|
69
|
+
* @param moduleName - The name of the module where the error occurred.
|
|
70
|
+
* @returns An object containing the error instance and the reason string.
|
|
71
|
+
* @public
|
|
72
|
+
* @example
|
|
73
|
+
* const details = getErrorDetails(error, 'fetchData', 'DataModule');
|
|
74
|
+
* if (details.error) { handleError(details.error); }
|
|
75
|
+
* @ignore
|
|
76
|
+
*/
|
|
77
|
+
export const getErrorDetails = (error: any, methodName: string, moduleName: string) => {
|
|
78
|
+
let errData = {message: '', fieldName: ''};
|
|
79
|
+
|
|
80
|
+
const failure = error.details as Failure;
|
|
81
|
+
const reason = failure?.data?.reason ?? `Error while performing ${methodName}`;
|
|
82
|
+
|
|
83
|
+
if (!(reason === 'AGENT_NOT_FOUND' && methodName === 'silentRelogin')) {
|
|
84
|
+
LoggerProxy.error(`${methodName} failed with reason: ${reason}`, {
|
|
85
|
+
module: moduleName,
|
|
86
|
+
method: methodName,
|
|
87
|
+
trackingId: failure?.trackingId,
|
|
88
|
+
});
|
|
89
|
+
// we can add more conditions here if not needed for specific cases eg: silentReLogin
|
|
90
|
+
WebexRequest.getInstance().uploadLogs({
|
|
91
|
+
correlationId: failure?.trackingId,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (methodName === 'stationLogin') {
|
|
96
|
+
errData = getStationLoginErrorData(failure, error.loginOption);
|
|
97
|
+
|
|
98
|
+
LoggerProxy.error(
|
|
99
|
+
`${methodName} failed with reason: ${reason}, message: ${errData.message}, fieldName: ${errData.fieldName}`,
|
|
100
|
+
{
|
|
101
|
+
module: moduleName,
|
|
102
|
+
method: methodName,
|
|
103
|
+
trackingId: failure?.trackingId,
|
|
104
|
+
}
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const err = new Error(reason ?? `Error while performing ${methodName}`);
|
|
109
|
+
// @ts-ignore - add custom property to the error object for backward compatibility
|
|
110
|
+
err.data = errData;
|
|
111
|
+
|
|
112
|
+
return {
|
|
113
|
+
error: err,
|
|
114
|
+
reason,
|
|
115
|
+
};
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Creates an error details object suitable for use with the Err.Details class.
|
|
120
|
+
*
|
|
121
|
+
* @param errObj - The Webex request payload object.
|
|
122
|
+
* @returns An instance of Err.Details with the generic failure message and extracted details.
|
|
123
|
+
* @public
|
|
124
|
+
* @example
|
|
125
|
+
* const errDetails = createErrDetailsObject(webexRequestPayload);
|
|
126
|
+
* @ignore
|
|
127
|
+
*/
|
|
128
|
+
export const createErrDetailsObject = (errObj: WebexRequestPayload) => {
|
|
129
|
+
const details = getCommonErrorDetails(errObj);
|
|
130
|
+
|
|
131
|
+
return new Err.Details('Service.reqs.generic.failure', details);
|
|
132
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import {WEBEX_REQUEST_FILE} from '../../constants';
|
|
2
|
+
import LoggerProxy from '../../logger-proxy';
|
|
3
|
+
import {METHODS} from './constants';
|
|
4
|
+
import {METRIC_EVENT_NAMES} from '../../metrics/constants';
|
|
5
|
+
import MetricsManager from '../../metrics/MetricsManager';
|
|
6
|
+
import {
|
|
7
|
+
WebexSDK,
|
|
8
|
+
HTTP_METHODS,
|
|
9
|
+
IHttpResponse,
|
|
10
|
+
RequestBody,
|
|
11
|
+
UploadLogsResponse,
|
|
12
|
+
LogsMetaData,
|
|
13
|
+
} from '../../types';
|
|
14
|
+
|
|
15
|
+
class WebexRequest {
|
|
16
|
+
private webex: WebexSDK;
|
|
17
|
+
private static instance: WebexRequest;
|
|
18
|
+
|
|
19
|
+
public static getInstance(options?: {webex: WebexSDK}): WebexRequest {
|
|
20
|
+
if (!WebexRequest.instance && options && options.webex) {
|
|
21
|
+
WebexRequest.instance = new WebexRequest(options);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return WebexRequest.instance;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private constructor(options: {webex: WebexSDK}) {
|
|
28
|
+
const {webex} = options;
|
|
29
|
+
this.webex = webex;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public async request(options: {
|
|
33
|
+
service: string;
|
|
34
|
+
resource: string;
|
|
35
|
+
method: HTTP_METHODS;
|
|
36
|
+
body?: RequestBody;
|
|
37
|
+
}): Promise<IHttpResponse> {
|
|
38
|
+
const {service, resource, method, body} = options;
|
|
39
|
+
|
|
40
|
+
return this.webex.request({
|
|
41
|
+
service,
|
|
42
|
+
resource,
|
|
43
|
+
method,
|
|
44
|
+
body,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* This is used for uploading the logs to backend/mats.
|
|
50
|
+
*
|
|
51
|
+
* @param metaData - meta data to be uploaded.
|
|
52
|
+
*/
|
|
53
|
+
public async uploadLogs(metaData: LogsMetaData = {}): Promise<UploadLogsResponse> {
|
|
54
|
+
const feedbackId = crypto.randomUUID();
|
|
55
|
+
try {
|
|
56
|
+
const response = await this.webex.internal.support.submitLogs(
|
|
57
|
+
{...metaData, feedbackId},
|
|
58
|
+
undefined, // we dont send logs but take from webex logger
|
|
59
|
+
{type: 'diff'} // this is to take the diff logs from previous upload
|
|
60
|
+
);
|
|
61
|
+
LoggerProxy.info(`Logs uploaded successfully with feedbackId: ${feedbackId}`, {
|
|
62
|
+
module: WEBEX_REQUEST_FILE,
|
|
63
|
+
method: METHODS.UPLOAD_LOGS,
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
MetricsManager.getInstance().trackEvent(
|
|
67
|
+
METRIC_EVENT_NAMES.UPLOAD_LOGS_SUCCESS,
|
|
68
|
+
{
|
|
69
|
+
trackingId: response?.trackingid,
|
|
70
|
+
feedbackId,
|
|
71
|
+
correlationId: metaData?.correlationId,
|
|
72
|
+
},
|
|
73
|
+
['behavioral']
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
trackingid: response.trackingid,
|
|
78
|
+
...(response.url ? {url: response.url} : {}),
|
|
79
|
+
...(response.userId ? {userId: response.userId} : {}),
|
|
80
|
+
...(response.correlationId ? {correlationId: response.correlationId} : {}),
|
|
81
|
+
feedbackId,
|
|
82
|
+
};
|
|
83
|
+
} catch (error) {
|
|
84
|
+
LoggerProxy.error(`Error uploading logs: ${error}`, {
|
|
85
|
+
module: WEBEX_REQUEST_FILE,
|
|
86
|
+
method: METHODS.UPLOAD_LOGS,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
MetricsManager.getInstance().trackEvent(
|
|
90
|
+
METRIC_EVENT_NAMES.UPLOAD_LOGS_FAILED,
|
|
91
|
+
{
|
|
92
|
+
stack: error?.stack,
|
|
93
|
+
feedbackId,
|
|
94
|
+
correlationId: metaData?.correlationId,
|
|
95
|
+
},
|
|
96
|
+
['behavioral']
|
|
97
|
+
);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export default WebexRequest;
|