@webex/contact-center 3.8.1 → 3.9.0-next.10

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.
Files changed (89) hide show
  1. package/dist/cc.js +105 -63
  2. package/dist/cc.js.map +1 -1
  3. package/dist/index.js +13 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/logger-proxy.js +24 -1
  6. package/dist/logger-proxy.js.map +1 -1
  7. package/dist/metrics/MetricsManager.js +1 -1
  8. package/dist/metrics/MetricsManager.js.map +1 -1
  9. package/dist/metrics/behavioral-events.js +51 -0
  10. package/dist/metrics/behavioral-events.js.map +1 -1
  11. package/dist/metrics/constants.js +12 -1
  12. package/dist/metrics/constants.js.map +1 -1
  13. package/dist/services/AddressBook.js +271 -0
  14. package/dist/services/AddressBook.js.map +1 -0
  15. package/dist/services/EntryPoint.js +227 -0
  16. package/dist/services/EntryPoint.js.map +1 -0
  17. package/dist/services/Queue.js +261 -0
  18. package/dist/services/Queue.js.map +1 -0
  19. package/dist/services/config/constants.js +24 -2
  20. package/dist/services/config/constants.js.map +1 -1
  21. package/dist/services/config/index.js +1 -43
  22. package/dist/services/config/index.js.map +1 -1
  23. package/dist/services/config/types.js +0 -5
  24. package/dist/services/config/types.js.map +1 -1
  25. package/dist/services/core/GlobalTypes.js.map +1 -1
  26. package/dist/services/core/Utils.js +121 -2
  27. package/dist/services/core/Utils.js.map +1 -1
  28. package/dist/services/core/aqm-reqs.js +0 -4
  29. package/dist/services/core/aqm-reqs.js.map +1 -1
  30. package/dist/services/core/websocket/WebSocketManager.js +0 -4
  31. package/dist/services/core/websocket/WebSocketManager.js.map +1 -1
  32. package/dist/services/task/TaskManager.js +1 -0
  33. package/dist/services/task/TaskManager.js.map +1 -1
  34. package/dist/services/task/index.js +145 -71
  35. package/dist/services/task/index.js.map +1 -1
  36. package/dist/types/cc.d.ts +77 -43
  37. package/dist/types/index.d.ts +8 -3
  38. package/dist/types/metrics/constants.d.ts +7 -0
  39. package/dist/types/services/AddressBook.d.ts +74 -0
  40. package/dist/types/services/EntryPoint.d.ts +67 -0
  41. package/dist/types/services/Queue.d.ts +76 -0
  42. package/dist/types/services/config/constants.d.ts +23 -1
  43. package/dist/types/services/config/index.d.ts +1 -14
  44. package/dist/types/services/config/types.d.ts +0 -64
  45. package/dist/types/services/core/GlobalTypes.d.ts +25 -0
  46. package/dist/types/services/core/Utils.d.ts +27 -1
  47. package/dist/types/services/task/index.d.ts +1 -1
  48. package/dist/types/types.d.ts +162 -0
  49. package/dist/types/utils/PageCache.d.ts +173 -0
  50. package/dist/types.js +17 -0
  51. package/dist/types.js.map +1 -1
  52. package/dist/utils/PageCache.js +192 -0
  53. package/dist/utils/PageCache.js.map +1 -0
  54. package/dist/webex.js +1 -1
  55. package/package.json +10 -10
  56. package/src/cc.ts +121 -81
  57. package/src/index.ts +19 -3
  58. package/src/logger-proxy.ts +24 -1
  59. package/src/metrics/MetricsManager.ts +1 -1
  60. package/src/metrics/behavioral-events.ts +54 -0
  61. package/src/metrics/constants.ts +15 -0
  62. package/src/services/AddressBook.ts +291 -0
  63. package/src/services/EntryPoint.ts +241 -0
  64. package/src/services/Queue.ts +277 -0
  65. package/src/services/config/constants.ts +26 -2
  66. package/src/services/config/index.ts +1 -55
  67. package/src/services/config/types.ts +0 -65
  68. package/src/services/core/GlobalTypes.ts +27 -0
  69. package/src/services/core/Utils.ts +155 -1
  70. package/src/services/core/aqm-reqs.ts +0 -5
  71. package/src/services/core/websocket/WebSocketManager.ts +0 -4
  72. package/src/services/task/TaskManager.ts +1 -0
  73. package/src/services/task/index.ts +172 -56
  74. package/src/types.ts +180 -0
  75. package/src/utils/PageCache.ts +252 -0
  76. package/test/unit/spec/cc.ts +30 -82
  77. package/test/unit/spec/metrics/MetricsManager.ts +0 -1
  78. package/test/unit/spec/metrics/behavioral-events.ts +14 -0
  79. package/test/unit/spec/services/AddressBook.ts +332 -0
  80. package/test/unit/spec/services/EntryPoint.ts +259 -0
  81. package/test/unit/spec/services/Queue.ts +323 -0
  82. package/test/unit/spec/services/config/index.ts +0 -71
  83. package/test/unit/spec/services/core/Utils.ts +50 -0
  84. package/test/unit/spec/services/core/aqm-reqs.ts +1 -3
  85. package/test/unit/spec/services/core/websocket/WebSocketManager.ts +0 -4
  86. package/test/unit/spec/services/task/TaskManager.ts +8 -1
  87. package/test/unit/spec/services/task/index.ts +226 -122
  88. package/umd/contact-center.min.js +2 -2
  89. package/umd/contact-center.min.js.map +1 -1
package/src/cc.ts CHANGED
@@ -44,13 +44,8 @@ import WebexRequest from './services/core/WebexRequest';
44
44
  import LoggerProxy from './logger-proxy';
45
45
  import {StateChange, Logout, StateChangeSuccess, AGENT_EVENTS} from './services/agent/types';
46
46
  import {getErrorDetails, isValidDialNumber} from './services/core/Utils';
47
- import {Profile, WelcomeEvent, CC_EVENTS, ContactServiceQueue} from './services/config/types';
48
- import {
49
- AGENT_STATE_AVAILABLE,
50
- AGENT_STATE_AVAILABLE_ID,
51
- DEFAULT_PAGE,
52
- DEFAULT_PAGE_SIZE,
53
- } from './services/config/constants';
47
+ import {Profile, WelcomeEvent, CC_EVENTS} from './services/config/types';
48
+ import {AGENT_STATE_AVAILABLE, AGENT_STATE_AVAILABLE_ID} from './services/config/constants';
54
49
  import {ConnectionLostDetails} from './services/core/websocket/types';
55
50
  import TaskManager from './services/task/TaskManager';
56
51
  import WebCallingService from './services/WebCallingService';
@@ -58,6 +53,15 @@ import {ITask, TASK_EVENTS, TaskResponse, DialerPayload} from './services/task/t
58
53
  import MetricsManager from './metrics/MetricsManager';
59
54
  import {METRIC_EVENT_NAMES} from './metrics/constants';
60
55
  import {Failure} from './services/core/GlobalTypes';
56
+ import EntryPoint from './services/EntryPoint';
57
+ import AddressBook from './services/AddressBook';
58
+ import Queue from './services/Queue';
59
+ import type {
60
+ EntryPointListResponse,
61
+ EntryPointSearchParams,
62
+ ContactServiceQueuesResponse,
63
+ ContactServiceQueueSearchParams,
64
+ } from './types';
61
65
 
62
66
  /**
63
67
  * The main Contact Center plugin class that enables integration with Webex Contact Center.
@@ -163,6 +167,7 @@ import {Failure} from './services/core/GlobalTypes';
163
167
  *
164
168
  * @public
165
169
  */
170
+
166
171
  export default class ContactCenter extends WebexPlugin implements IContactCenter {
167
172
  /**
168
173
  * The plugin's unique namespace identifier in the Webex SDK.
@@ -243,6 +248,71 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
243
248
  */
244
249
  private metricsManager: MetricsManager;
245
250
 
251
+ /**
252
+ * API instance for managing Webex Contact Center entry points
253
+ * Provides functionality to fetch entry points with caching support
254
+ * @type {EntryPoint}
255
+ * @public
256
+ * @example
257
+ * ```typescript
258
+ * const cc = webex.cc;
259
+ * await cc.register();
260
+ * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
261
+ *
262
+ * // Access EntryPointRecord
263
+ * const response = await cc.entryPoint.getEntryPoints({
264
+ * page: 0,
265
+ * pageSize: 50
266
+ * });
267
+ * ```
268
+ */
269
+ private entryPoint: EntryPoint;
270
+
271
+ /**
272
+ * API instance for managing Webex Contact Center address book contacts
273
+ * Provides functionality to fetch address book entries with caching support
274
+ * @type {AddressBook}
275
+ * @public
276
+ * @example
277
+ * ```typescript
278
+ * const cc = webex.cc;
279
+ * await cc.register();
280
+ * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
281
+ *
282
+ * // Access AddressBook API
283
+ * const response = await cc.addressBook.getEntries({
284
+ * page: 0,
285
+ * pageSize: 25
286
+ * });
287
+ * ```
288
+ */
289
+ public addressBook: AddressBook;
290
+
291
+ /**
292
+ * API instance for managing Webex Contact Center queues
293
+ * Provides functionality to fetch queues with caching support
294
+ * @type {Queue}
295
+ * @public
296
+ * @example
297
+ * ```typescript
298
+ * const cc = webex.cc;
299
+ * await cc.register();
300
+ * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
301
+ *
302
+ * // Access Queue API
303
+ * const response = await cc.queue.getQueues({
304
+ * page: 0,
305
+ * pageSize: 50
306
+ * });
307
+ *
308
+ * // Filter queues by specific criteria
309
+ * const filteredQueues = await cc.queue.getQueues({
310
+ * filter: 'id=="queue-id-123"'
311
+ * });
312
+ * ```
313
+ */
314
+ private queue: Queue;
315
+
246
316
  /**
247
317
  * Logger utility for Contact Center plugin
248
318
  * Provides consistent logging across the plugin
@@ -289,6 +359,13 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
289
359
  );
290
360
  this.incomingTaskListener();
291
361
 
362
+ // Initialize API instances
363
+ // will have future function for indivdual fetch etc so better be in an object
364
+ this.entryPoint = new EntryPoint(this.$webex);
365
+ this.addressBook = new AddressBook(this.$webex, () => this.agentConfig?.addressBookId);
366
+ this.queue = new Queue(this.$webex);
367
+
368
+ // Initialize logger
292
369
  LoggerProxy.initialize(this.$webex.logger);
293
370
  });
294
371
  }
@@ -979,11 +1056,25 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
979
1056
  return;
980
1057
  }
981
1058
 
982
- LoggerProxy.log(`Received event: ${eventData.type}`, {
1059
+ LoggerProxy.log(`Received event: ${eventData?.data?.type ?? eventData.type}`, {
983
1060
  module: CC_FILE,
984
1061
  method: METHODS.HANDLE_WEBSOCKET_MESSAGE,
985
1062
  });
986
1063
 
1064
+ // Emit metrics for all websocket events except keepalive and welcome
1065
+ const topLevelType = eventData.type;
1066
+ const nestedType = eventData?.data?.type;
1067
+ if (topLevelType !== CC_EVENTS.WELCOME && eventData.keepalive !== 'true') {
1068
+ const metricsPayload: Record<string, any> = {
1069
+ ws_event_type: nestedType || topLevelType,
1070
+ top_level_type: topLevelType,
1071
+ has_data: Boolean(eventData.data),
1072
+ };
1073
+ this.metricsManager.trackEvent(METRIC_EVENT_NAMES.WEBSOCKET_EVENT_RECEIVED, metricsPayload, [
1074
+ 'operational',
1075
+ ]);
1076
+ }
1077
+
987
1078
  switch (eventData.type) {
988
1079
  case CC_EVENTS.AGENT_MULTI_LOGIN:
989
1080
  // @ts-ignore
@@ -1398,79 +1489,6 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
1398
1489
  }
1399
1490
  }
1400
1491
 
1401
- /**
1402
- * This is used for getting the list of queues to which a task can be consulted or transferred.
1403
- * @param {string} [search] - Optional search string to filter queues by name
1404
- * @param {string} [filter] - Optional OData filter expression (e.g., 'teamId eq "team123"')
1405
- * @param {number} [page=0] - Page number for paginated results, starting at 0
1406
- * @param {number} [pageSize=100] - Number of queues to return per page
1407
- * @returns Promise<ContactServiceQueue[]> Resolves with the list of queues
1408
- * @throws Error If the operation fails
1409
- * @public
1410
- * @example
1411
- * ```typescript
1412
- * const cc = webex.cc;
1413
- * await cc.register();
1414
- * await cc.stationLogin({ teamId: 'team123', loginOption: 'BROWSER' });
1415
- *
1416
- * // Basic usage - get all queues
1417
- * const allQueues = await cc.getQueues();
1418
- *
1419
- * // Search for specific queues
1420
- * const salesQueues = await cc.getQueues('sales'); // Search for 'sales' in queue names
1421
- *
1422
- * // Use filtering and pagination
1423
- * const filteredQueues = await cc.getQueues(
1424
- * '', // No search term
1425
- * 'teamId eq "team123"', // Filter by team
1426
- * 0, // First page
1427
- * 50 // 50 items per page
1428
- * );
1429
- *
1430
- * // Process queue results
1431
- * queues.forEach(queue => {
1432
- * console.log('Queue:', {
1433
- * id: queue.queueId,
1434
- * name: queue.queueName,
1435
- * channelType: queue.channelType,
1436
- * isActive: queue.isActive,
1437
- * description: queue.description
1438
- * });
1439
- * });
1440
- * ```
1441
- */
1442
- public async getQueues(
1443
- search?: string,
1444
- filter?: string,
1445
- page = DEFAULT_PAGE,
1446
- pageSize = DEFAULT_PAGE_SIZE
1447
- ): Promise<ContactServiceQueue[]> {
1448
- LoggerProxy.info('Fetching queues', {
1449
- module: CC_FILE,
1450
- method: METHODS.GET_QUEUES,
1451
- });
1452
-
1453
- const orgId = this.$webex.credentials.getOrgId();
1454
-
1455
- if (!orgId) {
1456
- LoggerProxy.error('Org ID not found.', {
1457
- module: CC_FILE,
1458
- method: METHODS.GET_QUEUES,
1459
- });
1460
-
1461
- throw new Error('Org ID not found.');
1462
- }
1463
-
1464
- const result = await this.services.config.getQueues(orgId, page, pageSize, search, filter);
1465
-
1466
- LoggerProxy.log(`Successfully retrieved ${result?.length} queues`, {
1467
- module: CC_FILE,
1468
- method: METHODS.GET_QUEUES,
1469
- });
1470
-
1471
- return result;
1472
- }
1473
-
1474
1492
  /**
1475
1493
  * Uploads logs to help troubleshoot SDK issues.
1476
1494
  *
@@ -1615,4 +1633,26 @@ export default class ContactCenter extends WebexPlugin implements IContactCenter
1615
1633
  throw error;
1616
1634
  }
1617
1635
  }
1636
+
1637
+ /**
1638
+ * Returns paginated entry points for the organization.
1639
+ * Thin wrapper around internal EntryPoint instance.
1640
+ * @public
1641
+ */
1642
+ public async getEntryPoints(
1643
+ params: EntryPointSearchParams = {}
1644
+ ): Promise<EntryPointListResponse> {
1645
+ return this.entryPoint.getEntryPoints(params);
1646
+ }
1647
+
1648
+ /**
1649
+ * Returns paginated contact service queues for the organization.
1650
+ * Thin wrapper around internal Queue instance.
1651
+ * @public
1652
+ */
1653
+ public async getQueues(
1654
+ params: ContactServiceQueueSearchParams = {}
1655
+ ): Promise<ContactServiceQueuesResponse> {
1656
+ return this.queue.getQueues(params);
1657
+ }
1618
1658
  }
package/src/index.ts CHANGED
@@ -2,7 +2,9 @@ import {registerPlugin} from '@webex/webex-core';
2
2
  import config from './config';
3
3
  import ContactCenter from './cc';
4
4
 
5
- /** @module ContactCenterModule */
5
+ /**
6
+ * @module ContactCenterModule
7
+ * /
6
8
 
7
9
  // Core exports
8
10
  /**
@@ -24,6 +26,22 @@ export {default as Task} from './services/task';
24
26
  */
25
27
  export {default as routingAgent} from './services/agent';
26
28
 
29
+ // API exports (AddressBook is public, EntryPoint and Queue are accessed via cc wrappers)
30
+ export {default as AddressBook} from './services/AddressBook';
31
+
32
+ /** EntryPoint API types */
33
+ export type {
34
+ EntryPointRecord,
35
+ EntryPointListResponse,
36
+ EntryPointSearchParams,
37
+ AddressBookEntry,
38
+ AddressBookEntriesResponse,
39
+ AddressBookEntrySearchParams,
40
+ ContactServiceQueuesResponse,
41
+ ContactServiceQueueSearchParams,
42
+ ContactServiceQueue,
43
+ } from './types';
44
+
27
45
  // Enums
28
46
  /**
29
47
  * Task Events for Contact Center operations
@@ -155,8 +173,6 @@ export type {
155
173
  export type {
156
174
  /** Profile interface */
157
175
  Profile,
158
- /** Contact service queue interface */
159
- ContactServiceQueue,
160
176
  /** Response type from getUserUsingCI method */
161
177
  AgentResponse,
162
178
  /** Response from getDesktopProfileById */
@@ -105,6 +105,29 @@ export default class LoggerProxy {
105
105
  const interactionId = context.interactionId ? ` - interactionId:${context.interactionId}` : '';
106
106
  const trackingId = context.trackingId ? ` - trackingId:${context.trackingId}` : '';
107
107
 
108
- return `${timestamp} ${LOG_PREFIX} - [${level}]: module:${moduleName} - method:${methodName}${interactionId}${trackingId} - ${message}`;
108
+ // Format additional data if provided
109
+ let dataString = '';
110
+ if (context.data) {
111
+ try {
112
+ dataString = ` - data:${JSON.stringify(context.data)}`;
113
+ } catch (e) {
114
+ dataString = ` - data:[object]`;
115
+ }
116
+ }
117
+
118
+ // Format error if provided
119
+ let errorString = '';
120
+ if (context.error) {
121
+ if (context.error instanceof Error) {
122
+ errorString = ` - error:${context.error.name}:${context.error.message}`;
123
+ if (context.error.stack && level === LOGGING_LEVEL.error) {
124
+ errorString += ` - stack:${context.error.stack}`;
125
+ }
126
+ } else {
127
+ errorString = ` - error:${String(context.error)}`;
128
+ }
129
+ }
130
+
131
+ return `${timestamp} ${LOG_PREFIX} - [${level}]: module:${moduleName} - method:${methodName}${interactionId}${trackingId}${dataString}${errorString} - ${message}`;
109
132
  }
110
133
  }
@@ -6,8 +6,8 @@ import {
6
6
  } from '@webex/internal-plugin-metrics/src/metrics.types';
7
7
 
8
8
  import {WebexSDK} from '../types';
9
- import {BehavioralEventTaxonomy, getEventTaxonomy} from './behavioral-events';
10
9
  import LoggerProxy from '../logger-proxy';
10
+ import {BehavioralEventTaxonomy, getEventTaxonomy} from './behavioral-events';
11
11
  import {METRIC_EVENT_NAMES} from './constants';
12
12
  import {Failure} from '../services/core/GlobalTypes';
13
13
  import {PRODUCT_NAME} from '../constants';
@@ -129,6 +129,18 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
129
129
  target: 'agent_rona',
130
130
  verb: 'set',
131
131
  },
132
+ [METRIC_EVENT_NAMES.AGENT_CONTACT_ASSIGN_FAILED]: {
133
+ product,
134
+ agent: 'service',
135
+ target: 'agent_contact_assign',
136
+ verb: 'fail',
137
+ },
138
+ [METRIC_EVENT_NAMES.AGENT_INVITE_FAILED]: {
139
+ product,
140
+ agent: 'service',
141
+ target: 'agent_invite',
142
+ verb: 'fail',
143
+ },
132
144
 
133
145
  // Added Task events
134
146
  [METRIC_EVENT_NAMES.TASK_ACCEPT_SUCCESS]: {
@@ -317,6 +329,48 @@ const eventTaxonomyMap: Record<string, BehavioralEventTaxonomy> = {
317
329
  target: 'agent_device_type_update',
318
330
  verb: 'fail',
319
331
  },
332
+
333
+ // EntryPoint API Events
334
+ [METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_SUCCESS]: {
335
+ product,
336
+ agent: 'user',
337
+ target: 'entrypoint_fetch',
338
+ verb: 'complete',
339
+ },
340
+ [METRIC_EVENT_NAMES.ENTRYPOINT_FETCH_FAILED]: {
341
+ product,
342
+ agent: 'user',
343
+ target: 'entrypoint_fetch',
344
+ verb: 'fail',
345
+ },
346
+
347
+ // AddressBook API Events
348
+ [METRIC_EVENT_NAMES.ADDRESSBOOK_FETCH_SUCCESS]: {
349
+ product,
350
+ agent: 'user',
351
+ target: 'addressbook_fetch',
352
+ verb: 'complete',
353
+ },
354
+ [METRIC_EVENT_NAMES.ADDRESSBOOK_FETCH_FAILED]: {
355
+ product,
356
+ agent: 'user',
357
+ target: 'addressbook_fetch',
358
+ verb: 'fail',
359
+ },
360
+
361
+ // Queue API Events
362
+ [METRIC_EVENT_NAMES.QUEUE_FETCH_SUCCESS]: {
363
+ product,
364
+ agent: 'user',
365
+ target: 'queue_fetch',
366
+ verb: 'complete',
367
+ },
368
+ [METRIC_EVENT_NAMES.QUEUE_FETCH_FAILED]: {
369
+ product,
370
+ agent: 'user',
371
+ target: 'queue_fetch',
372
+ verb: 'fail',
373
+ },
320
374
  };
321
375
 
322
376
  /**
@@ -117,8 +117,23 @@ export const METRIC_EVENT_NAMES = {
117
117
  WEBSOCKET_DEREGISTER_SUCCESS: 'Websocket Deregister Success',
118
118
  WEBSOCKET_DEREGISTER_FAIL: 'Websocket Deregister Failed',
119
119
 
120
+ // WebSocket message events
121
+ WEBSOCKET_EVENT_RECEIVED: 'Websocket Event Received',
122
+
120
123
  AGENT_DEVICE_TYPE_UPDATE_SUCCESS: 'Agent Device Type Update Success',
121
124
  AGENT_DEVICE_TYPE_UPDATE_FAILED: 'Agent Device Type Update Failed',
125
+
126
+ // EntryPoint API Events
127
+ ENTRYPOINT_FETCH_SUCCESS: 'Entrypoint Fetch Success',
128
+ ENTRYPOINT_FETCH_FAILED: 'Entrypoint Fetch Failed',
129
+
130
+ // AddressBook API Events
131
+ ADDRESSBOOK_FETCH_SUCCESS: 'AddressBook Fetch Success',
132
+ ADDRESSBOOK_FETCH_FAILED: 'AddressBook Fetch Failed',
133
+
134
+ // Queue API Events
135
+ QUEUE_FETCH_SUCCESS: 'Queue Fetch Success',
136
+ QUEUE_FETCH_FAILED: 'Queue Fetch Failed',
122
137
  } as const;
123
138
 
124
139
  /**