@webex/calling 3.4.0 → 3.5.0

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 (101) hide show
  1. package/dist/CallHistory/CallHistory.js +103 -4
  2. package/dist/CallHistory/CallHistory.js.map +1 -1
  3. package/dist/CallHistory/CallHistory.test.js +143 -0
  4. package/dist/CallHistory/CallHistory.test.js.map +1 -1
  5. package/dist/CallHistory/callHistoryFixtures.js +224 -1
  6. package/dist/CallHistory/callHistoryFixtures.js.map +1 -1
  7. package/dist/CallHistory/constants.js +8 -2
  8. package/dist/CallHistory/constants.js.map +1 -1
  9. package/dist/CallHistory/types.js.map +1 -1
  10. package/dist/CallSettings/UcmBackendConnector.js +1 -1
  11. package/dist/CallSettings/UcmBackendConnector.js.map +1 -1
  12. package/dist/CallSettings/UcmBackendConnector.test.js +1 -1
  13. package/dist/CallSettings/UcmBackendConnector.test.js.map +1 -1
  14. package/dist/CallSettings/constants.js +1 -3
  15. package/dist/CallSettings/constants.js.map +1 -1
  16. package/dist/CallingClient/CallingClient.js +11 -2
  17. package/dist/CallingClient/CallingClient.js.map +1 -1
  18. package/dist/CallingClient/CallingClient.test.js +249 -193
  19. package/dist/CallingClient/CallingClient.test.js.map +1 -1
  20. package/dist/CallingClient/calling/call.js +81 -0
  21. package/dist/CallingClient/calling/call.js.map +1 -1
  22. package/dist/CallingClient/calling/call.test.js +332 -217
  23. package/dist/CallingClient/calling/call.test.js.map +1 -1
  24. package/dist/CallingClient/constants.js +2 -1
  25. package/dist/CallingClient/constants.js.map +1 -1
  26. package/dist/CallingClient/registration/register.js +18 -13
  27. package/dist/CallingClient/registration/register.js.map +1 -1
  28. package/dist/CallingClient/registration/register.test.js +242 -125
  29. package/dist/CallingClient/registration/register.test.js.map +1 -1
  30. package/dist/Contacts/ContactsClient.js +39 -27
  31. package/dist/Contacts/ContactsClient.js.map +1 -1
  32. package/dist/Contacts/ContactsClient.test.js +64 -1
  33. package/dist/Contacts/ContactsClient.test.js.map +1 -1
  34. package/dist/Contacts/contactFixtures.js +26 -3
  35. package/dist/Contacts/contactFixtures.js.map +1 -1
  36. package/dist/Contacts/types.js.map +1 -1
  37. package/dist/Events/types.js.map +1 -1
  38. package/dist/Metrics/index.js +2 -2
  39. package/dist/Metrics/index.js.map +1 -1
  40. package/dist/common/Utils.js +10 -8
  41. package/dist/common/Utils.js.map +1 -1
  42. package/dist/common/Utils.test.js +25 -1
  43. package/dist/common/Utils.test.js.map +1 -1
  44. package/dist/common/constants.js +5 -1
  45. package/dist/common/constants.js.map +1 -1
  46. package/dist/common/testUtil.js +23 -1
  47. package/dist/common/testUtil.js.map +1 -1
  48. package/dist/common/types.js.map +1 -1
  49. package/dist/module/CallHistory/CallHistory.js +57 -3
  50. package/dist/module/CallHistory/callHistoryFixtures.js +215 -0
  51. package/dist/module/CallHistory/constants.js +7 -1
  52. package/dist/module/CallSettings/UcmBackendConnector.js +5 -3
  53. package/dist/module/CallSettings/constants.js +0 -2
  54. package/dist/module/CallingClient/CallingClient.js +13 -2
  55. package/dist/module/CallingClient/calling/call.js +50 -0
  56. package/dist/module/CallingClient/constants.js +1 -0
  57. package/dist/module/CallingClient/registration/register.js +12 -6
  58. package/dist/module/Contacts/ContactsClient.js +28 -17
  59. package/dist/module/Contacts/contactFixtures.js +25 -2
  60. package/dist/module/Metrics/index.js +6 -2
  61. package/dist/module/common/Utils.js +7 -5
  62. package/dist/module/common/constants.js +4 -0
  63. package/dist/module/common/testUtil.js +24 -0
  64. package/dist/types/CallHistory/CallHistory.d.ts +1 -0
  65. package/dist/types/CallHistory/CallHistory.d.ts.map +1 -1
  66. package/dist/types/CallHistory/callHistoryFixtures.d.ts +98 -1
  67. package/dist/types/CallHistory/callHistoryFixtures.d.ts.map +1 -1
  68. package/dist/types/CallHistory/constants.d.ts +7 -1
  69. package/dist/types/CallHistory/constants.d.ts.map +1 -1
  70. package/dist/types/CallHistory/types.d.ts +9 -1
  71. package/dist/types/CallHistory/types.d.ts.map +1 -1
  72. package/dist/types/CallSettings/UcmBackendConnector.d.ts.map +1 -1
  73. package/dist/types/CallSettings/constants.d.ts +0 -2
  74. package/dist/types/CallSettings/constants.d.ts.map +1 -1
  75. package/dist/types/CallingClient/CallingClient.d.ts.map +1 -1
  76. package/dist/types/CallingClient/calling/call.d.ts +1 -0
  77. package/dist/types/CallingClient/calling/call.d.ts.map +1 -1
  78. package/dist/types/CallingClient/constants.d.ts +1 -0
  79. package/dist/types/CallingClient/constants.d.ts.map +1 -1
  80. package/dist/types/CallingClient/registration/register.d.ts +1 -0
  81. package/dist/types/CallingClient/registration/register.d.ts.map +1 -1
  82. package/dist/types/Contacts/ContactsClient.d.ts +1 -1
  83. package/dist/types/Contacts/ContactsClient.d.ts.map +1 -1
  84. package/dist/types/Contacts/contactFixtures.d.ts +28 -0
  85. package/dist/types/Contacts/contactFixtures.d.ts.map +1 -1
  86. package/dist/types/Contacts/types.d.ts +3 -3
  87. package/dist/types/Contacts/types.d.ts.map +1 -1
  88. package/dist/types/Events/types.d.ts +15 -0
  89. package/dist/types/Events/types.d.ts.map +1 -1
  90. package/dist/types/Metrics/index.d.ts.map +1 -1
  91. package/dist/types/Voicemail/UcmBackendConnector.d.ts +1 -1
  92. package/dist/types/Voicemail/WxCallBackendConnector.d.ts +1 -1
  93. package/dist/types/common/Utils.d.ts +2 -2
  94. package/dist/types/common/Utils.d.ts.map +1 -1
  95. package/dist/types/common/constants.d.ts +4 -0
  96. package/dist/types/common/constants.d.ts.map +1 -1
  97. package/dist/types/common/testUtil.d.ts +20 -0
  98. package/dist/types/common/testUtil.d.ts.map +1 -1
  99. package/dist/types/common/types.d.ts +12 -12
  100. package/dist/types/common/types.d.ts.map +1 -1
  101. package/package.json +3 -3
@@ -259,6 +259,190 @@ export const mockCallHistoryBody = {
259
259
  ],
260
260
  },
261
261
  };
262
+ export const MOCK_CALL_HISTORY_WITH_UCM_LINE_NUMBER = {
263
+ body: {
264
+ statusCode: 200,
265
+ userSessions: [
266
+ {
267
+ id: '123456',
268
+ durationSecs: 438,
269
+ self: {
270
+ id: 'fd2e1234',
271
+ name: 'Mark',
272
+ cucmDN: '1001',
273
+ ucmLineNumber: 1,
274
+ incomingCallProtocols: [],
275
+ callbackInfo: {
276
+ callbackAddress: 'test@cisco.com',
277
+ callbackType: 'EMAIL',
278
+ },
279
+ lookUpInfo: {
280
+ lookupLink: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/98765',
281
+ type: 'CONVERSATION',
282
+ },
283
+ },
284
+ url: 'https://janus-a.wbx2.com/janus/api/v1/history/userSessions/654321',
285
+ sessionId: '123456',
286
+ sessionType: 'SPARK',
287
+ startTime: '2022-08-22T10:45:21.565Z',
288
+ endTime: '2022-08-22T10:53:01.624Z',
289
+ direction: 'OUTGOING',
290
+ disposition: 'INITIATED',
291
+ other: {
292
+ id: '100001',
293
+ name: 'test',
294
+ isPrivate: false,
295
+ callbackAddress: '89998888',
296
+ },
297
+ durationSeconds: 438,
298
+ joinedDurationSeconds: 457,
299
+ participantCount: 2,
300
+ links: {
301
+ locusUrl: 'https://locus-a.wbx2.com/locus/api/v1/loci/786765',
302
+ conversationUrl: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/55443322',
303
+ callbackAddress: '01010101',
304
+ },
305
+ isDeleted: false,
306
+ isPMR: false,
307
+ correlationIds: ['008899'],
308
+ },
309
+ {
310
+ id: '20191817',
311
+ durationSecs: 438,
312
+ self: {
313
+ id: '12131415',
314
+ name: 'Mark',
315
+ cucmDN: '1002',
316
+ ucmLineNumber: 2,
317
+ incomingCallProtocols: [],
318
+ callbackInfo: {
319
+ callbackAddress: 'test@cisco.com',
320
+ callbackType: 'EMAIL',
321
+ },
322
+ lookUpInfo: {
323
+ lookupLink: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/21314151',
324
+ type: 'CONVERSATION',
325
+ },
326
+ },
327
+ url: 'https://janus-a.wbx2.com/janus/api/v1/history/userSessions/100101102',
328
+ sessionId: '20191817',
329
+ sessionType: 'SPARK',
330
+ startTime: '2022-08-30T10:45:21.565Z',
331
+ endTime: '2022-08-30T10:53:01.624Z',
332
+ direction: 'OUTGOING',
333
+ disposition: 'INITIATED',
334
+ other: {
335
+ id: '301302303',
336
+ name: 'test',
337
+ isPrivate: false,
338
+ callbackAddress: '401402403',
339
+ },
340
+ durationSeconds: 438,
341
+ joinedDurationSeconds: 457,
342
+ participantCount: 2,
343
+ links: {
344
+ locusUrl: 'https://locus-a.wbx2.com/locus/api/v1/loci/501502503',
345
+ conversationUrl: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/601602603',
346
+ callbackAddress: '801802803',
347
+ },
348
+ isDeleted: false,
349
+ isPMR: false,
350
+ correlationIds: ['901902903'],
351
+ },
352
+ ],
353
+ },
354
+ };
355
+ export const MOCK_CALL_HISTORY_WITHOUT_UCM_LINE_NUMBER = {
356
+ body: {
357
+ statusCode: 200,
358
+ userSessions: [
359
+ {
360
+ id: '123456',
361
+ durationSecs: 438,
362
+ self: {
363
+ id: 'fd2e1234',
364
+ name: 'Mark',
365
+ cucmDN: '1001',
366
+ incomingCallProtocols: [],
367
+ callbackInfo: {
368
+ callbackAddress: 'test@cisco.com',
369
+ callbackType: 'EMAIL',
370
+ },
371
+ lookUpInfo: {
372
+ lookupLink: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/98765',
373
+ type: 'CONVERSATION',
374
+ },
375
+ },
376
+ url: 'https://janus-a.wbx2.com/janus/api/v1/history/userSessions/654321',
377
+ sessionId: '123456',
378
+ sessionType: 'SPARK',
379
+ startTime: '2022-08-22T10:45:21.565Z',
380
+ endTime: '2022-08-22T10:53:01.624Z',
381
+ direction: 'OUTGOING',
382
+ disposition: 'INITIATED',
383
+ other: {
384
+ id: '100001',
385
+ name: 'test',
386
+ isPrivate: false,
387
+ callbackAddress: '89998888',
388
+ },
389
+ durationSeconds: 438,
390
+ joinedDurationSeconds: 457,
391
+ participantCount: 2,
392
+ links: {
393
+ locusUrl: 'https://locus-a.wbx2.com/locus/api/v1/loci/786765',
394
+ conversationUrl: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/55443322',
395
+ callbackAddress: '01010101',
396
+ },
397
+ isDeleted: false,
398
+ isPMR: false,
399
+ correlationIds: ['008899'],
400
+ },
401
+ {
402
+ id: '20191817',
403
+ durationSecs: 438,
404
+ self: {
405
+ id: '12131415',
406
+ name: 'Mark',
407
+ cucmDN: '1002',
408
+ incomingCallProtocols: [],
409
+ callbackInfo: {
410
+ callbackAddress: 'test@cisco.com',
411
+ callbackType: 'EMAIL',
412
+ },
413
+ lookUpInfo: {
414
+ lookupLink: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/21314151',
415
+ type: 'CONVERSATION',
416
+ },
417
+ },
418
+ url: 'https://janus-a.wbx2.com/janus/api/v1/history/userSessions/100101102',
419
+ sessionId: '20191817',
420
+ sessionType: 'SPARK',
421
+ startTime: '2022-08-30T10:45:21.565Z',
422
+ endTime: '2022-08-30T10:53:01.624Z',
423
+ direction: 'OUTGOING',
424
+ disposition: 'INITIATED',
425
+ other: {
426
+ id: '301302303',
427
+ name: 'test',
428
+ isPrivate: false,
429
+ callbackAddress: '401402403',
430
+ },
431
+ durationSeconds: 438,
432
+ joinedDurationSeconds: 457,
433
+ participantCount: 2,
434
+ links: {
435
+ locusUrl: 'https://locus-a.wbx2.com/locus/api/v1/loci/501502503',
436
+ conversationUrl: 'https://conv-a.wbx2.com/conversation/api/v1/conversations/601602603',
437
+ callbackAddress: '801802803',
438
+ },
439
+ isDeleted: false,
440
+ isPMR: false,
441
+ correlationIds: ['901902903'],
442
+ },
443
+ ],
444
+ },
445
+ };
262
446
  const WEBEX_CALL_SESSION = {
263
447
  id: 'd74d19cc-6aa7-f341-6012-aec433cc6f8d',
264
448
  durationSecs: 438,
@@ -401,3 +585,34 @@ export const ERROR_DETAILS_400 = {
401
585
  },
402
586
  message: 'FAILURE',
403
587
  };
588
+ export const MOCK_LINES_API_CALL_RESPONSE = {
589
+ statusCode: 200,
590
+ data: {
591
+ lines: {
592
+ devices: [
593
+ {
594
+ name: 'CSFheliosucm01',
595
+ model: 503,
596
+ lines: [
597
+ {
598
+ dnorpattern: '+14928000001',
599
+ index: 1,
600
+ label: '',
601
+ },
602
+ {
603
+ dnorpattern: '+14928000003',
604
+ index: 2,
605
+ label: '',
606
+ },
607
+ ],
608
+ },
609
+ ],
610
+ },
611
+ },
612
+ message: 'SUCCESS',
613
+ };
614
+ export const MOCK_LINES_API_CALL_RESPONSE_WITH_NO_LINEDATA = {
615
+ statusCode: 200,
616
+ data: {},
617
+ message: 'SUCCESS',
618
+ };
@@ -1,13 +1,19 @@
1
1
  export const APPLICATION_JSON = 'application/json';
2
2
  export const CALL_HISTORY_FILE = 'CallHistory';
3
3
  export const CONTENT_TYPE = 'Content-Type';
4
+ export const CONFIG = 'config';
4
5
  export const FROM_DATE = '?from';
5
6
  export const HISTORY = 'history';
6
7
  export const LIMIT = 50;
8
+ export const LINES = 'lines';
7
9
  export const NUMBER_OF_DAYS = 10;
10
+ export const ORG_ID = 'orgId';
11
+ export const PEOPLE = 'people';
8
12
  export const RESPONSE_MESSAGE = 'responseMessage';
9
- export const UPDATE_MISSED_CALLS_ENDPOINT = 'setReadState';
10
13
  export const SET_READ_STATE_SUCCESS_MESSAGE = 'Missed calls are read by the user.';
11
14
  export const SUCCESS_MESSAGE = 'SUCCESS';
12
15
  export const STATUS_CODE = 'statusCode';
13
16
  export const USER_SESSIONS = 'userSessions';
17
+ export const UPDATE_MISSED_CALLS_ENDPOINT = 'setReadState';
18
+ export const UNIFIED_COMMUNICATIONS = 'uc';
19
+ export const VERSION_1 = 'v1';
@@ -1,9 +1,9 @@
1
1
  import log from '../Logger';
2
2
  import SDKConnector from '../SDKConnector';
3
3
  import { serviceErrorCodeHandler } from '../common/Utils';
4
- import { FAILURE_MESSAGE, STATUS_CODE, SUCCESS_MESSAGE, UCM_CONNECTOR_FILE, VOICEMAIL, } from '../common/constants';
4
+ import { FAILURE_MESSAGE, STATUS_CODE, SUCCESS_MESSAGE, UCM_CONNECTOR_FILE, VOICEMAIL, WEBEX_API_CONFIG_INT_URL, WEBEX_API_CONFIG_PROD_URL, } from '../common/constants';
5
5
  import { HTTP_METHODS } from '../common/types';
6
- import { CF_ENDPOINT, ORG_ENDPOINT, PEOPLE_ENDPOINT, WEBEX_APIS_INT_URL, WEBEX_APIS_PROD_URL, } from './constants';
6
+ import { CF_ENDPOINT, ORG_ENDPOINT, PEOPLE_ENDPOINT } from './constants';
7
7
  export class UcmBackendConnector {
8
8
  sdkConnector;
9
9
  webex;
@@ -51,7 +51,9 @@ export class UcmBackendConnector {
51
51
  file: UCM_CONNECTOR_FILE,
52
52
  method: this.getCallForwardAlwaysSetting.name,
53
53
  };
54
- const webexApisUrl = this.useProdWebexApis ? WEBEX_APIS_PROD_URL : WEBEX_APIS_INT_URL;
54
+ const webexApisUrl = this.useProdWebexApis
55
+ ? WEBEX_API_CONFIG_PROD_URL
56
+ : WEBEX_API_CONFIG_INT_URL;
55
57
  try {
56
58
  if (directoryNumber) {
57
59
  const resp = await this.webex.request({
@@ -7,5 +7,3 @@ export const CF_ENDPOINT = 'features/callForwarding';
7
7
  export const VM_ENDPOINT = 'features/voicemail';
8
8
  export const CALL_WAITING_ENDPOINT = 'CallWaiting';
9
9
  export const XSI_VERSION = 'v2.0';
10
- export const WEBEX_APIS_INT_URL = 'https://integration.webexapis.com/v1/uc/config';
11
- export const WEBEX_APIS_PROD_URL = 'https://webexapis.com/v1/uc/config';
@@ -38,20 +38,31 @@ export class CallingClient extends Eventing {
38
38
  ? this.sdkConfig.serviceData
39
39
  : { indicator: ServiceIndicator.CALLING, domain: '' };
40
40
  const logLevel = this.sdkConfig?.logger?.level ? this.sdkConfig.logger.level : LOGGER.ERROR;
41
+ log.setLogger(logLevel, CALLING_CLIENT_FILE);
41
42
  validateServiceData(serviceData);
42
43
  this.callManager = getCallManager(this.webex, serviceData.indicator);
43
44
  this.metricManager = getMetricManager(this.webex, serviceData.indicator);
44
45
  this.mediaEngine = Media;
45
46
  this.primaryMobiusUris = [];
46
47
  this.backupMobiusUris = [];
48
+ let mobiusServiceHost = '';
49
+ try {
50
+ mobiusServiceHost = new URL(this.webex.internal.services._serviceUrls.mobius).host;
51
+ }
52
+ catch (error) {
53
+ log.warn(`Failed to parse mobius service URL`, {
54
+ file: CALLING_CLIENT_FILE,
55
+ method: this.constructor.name,
56
+ });
57
+ }
47
58
  this.mobiusClusters =
48
- this.webex.internal.services._hostCatalog[MOBIUS_US_PROD] ||
59
+ (mobiusServiceHost && this.webex.internal.services._hostCatalog[mobiusServiceHost]) ||
60
+ this.webex.internal.services._hostCatalog[MOBIUS_US_PROD] ||
49
61
  this.webex.internal.services._hostCatalog[MOBIUS_EU_PROD] ||
50
62
  this.webex.internal.services._hostCatalog[MOBIUS_US_INT] ||
51
63
  this.webex.internal.services._hostCatalog[MOBIUS_EU_INT];
52
64
  this.mobiusHost = '';
53
65
  this.registerSessionsListener();
54
- log.setLogger(logLevel, CALLING_CLIENT_FILE);
55
66
  this.registerCallsClearedListener();
56
67
  }
57
68
  async init() {
@@ -132,6 +132,12 @@ export class Call extends Eventing {
132
132
  },
133
133
  },
134
134
  S_RECV_CALL_SETUP: {
135
+ after: {
136
+ 10000: {
137
+ target: 'S_CALL_CLEARED',
138
+ actions: ['triggerTimeout'],
139
+ },
140
+ },
135
141
  on: {
136
142
  E_SEND_CALL_ALERTING: {
137
143
  target: 'S_SEND_CALL_PROGRESS',
@@ -152,6 +158,12 @@ export class Call extends Eventing {
152
158
  },
153
159
  },
154
160
  S_SEND_CALL_SETUP: {
161
+ after: {
162
+ 10000: {
163
+ target: 'S_CALL_CLEARED',
164
+ actions: ['triggerTimeout'],
165
+ },
166
+ },
155
167
  on: {
156
168
  E_RECV_CALL_PROGRESS: {
157
169
  target: 'S_RECV_CALL_PROGRESS',
@@ -176,6 +188,12 @@ export class Call extends Eventing {
176
188
  },
177
189
  },
178
190
  S_RECV_CALL_PROGRESS: {
191
+ after: {
192
+ 60000: {
193
+ target: 'S_CALL_CLEARED',
194
+ actions: ['triggerTimeout'],
195
+ },
196
+ },
179
197
  on: {
180
198
  E_RECV_CALL_CONNECT: {
181
199
  target: 'S_RECV_CALL_CONNECT',
@@ -200,6 +218,12 @@ export class Call extends Eventing {
200
218
  },
201
219
  },
202
220
  S_SEND_CALL_PROGRESS: {
221
+ after: {
222
+ 60000: {
223
+ target: 'S_CALL_CLEARED',
224
+ actions: ['triggerTimeout'],
225
+ },
226
+ },
203
227
  on: {
204
228
  E_SEND_CALL_CONNECT: {
205
229
  target: 'S_SEND_CALL_CONNECT',
@@ -220,6 +244,12 @@ export class Call extends Eventing {
220
244
  },
221
245
  },
222
246
  S_RECV_CALL_CONNECT: {
247
+ after: {
248
+ 10000: {
249
+ target: 'S_CALL_CLEARED',
250
+ actions: ['triggerTimeout'],
251
+ },
252
+ },
223
253
  on: {
224
254
  E_CALL_ESTABLISHED: {
225
255
  target: 'S_CALL_ESTABLISHED',
@@ -240,6 +270,12 @@ export class Call extends Eventing {
240
270
  },
241
271
  },
242
272
  S_SEND_CALL_CONNECT: {
273
+ after: {
274
+ 10000: {
275
+ target: 'S_CALL_CLEARED',
276
+ actions: ['triggerTimeout'],
277
+ },
278
+ },
243
279
  on: {
244
280
  E_CALL_ESTABLISHED: {
245
281
  target: 'S_CALL_ESTABLISHED',
@@ -365,6 +401,7 @@ export class Call extends Eventing {
365
401
  incomingCallDisconnect: (context, event) => this.handleIncomingCallDisconnect(event),
366
402
  outgoingCallDisconnect: (context, event) => this.handleOutgoingCallDisconnect(event),
367
403
  unknownState: (context, event) => this.handleUnknownState(event),
404
+ triggerTimeout: () => this.handleTimeout(),
368
405
  },
369
406
  });
370
407
  const mediaMachine = createMachine({
@@ -1753,5 +1790,18 @@ export class Call extends Eventing {
1753
1790
  getCallRtpStats() {
1754
1791
  return this.getCallStats();
1755
1792
  }
1793
+ async handleTimeout() {
1794
+ log.warn(`Call timed out`, {
1795
+ file: CALL_FILE,
1796
+ method: 'handleTimeout',
1797
+ });
1798
+ this.deleteCb(this.getCorrelationId());
1799
+ this.emit(CALL_EVENT_KEYS.DISCONNECT, this.getCorrelationId());
1800
+ const response = await this.delete();
1801
+ log.log(`handleTimeout: Response code: ${response.statusCode}`, {
1802
+ file: CALL_FILE,
1803
+ method: this.handleTimeout.name,
1804
+ });
1805
+ }
1756
1806
  }
1757
1807
  export const createCall = (activeUrl, webex, dest, dir, deviceId, lineId, deleteCb, indicator) => new Call(activeUrl, webex, dest, dir, deviceId, lineId, deleteCb, indicator);
@@ -107,6 +107,7 @@ export const SEC_TO_MSEC_MFACTOR = 1000;
107
107
  export const MINUTES_TO_SEC_MFACTOR = 60;
108
108
  export const REG_RANDOM_T_FACTOR_UPPER_LIMIT = 10000;
109
109
  export const REG_TRY_BACKUP_TIMER_VAL_IN_SEC = 1200;
110
+ export const REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC = 114;
110
111
  export const REG_FAILBACK_429_MAX_RETRIES = 5;
111
112
  export const REGISTER_UTIL = 'registerDevice';
112
113
  export const GET_MOBIUS_SERVERS_UTIL = 'getMobiusServers';
@@ -6,8 +6,8 @@ import { getMetricManager } from '../../Metrics';
6
6
  import { getCallManager } from '../calling';
7
7
  import log from '../../Logger';
8
8
  import SDKConnector from '../../SDKConnector';
9
- import { ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, } from '../../common/types';
10
- import { CALLING_USER_AGENT, CISCO_DEVICE_URL, DEVICES_ENDPOINT_RESOURCE, SPARK_USER_AGENT, WEBEX_WEB_CLIENT, BASE_REG_RETRY_TIMER_VAL_IN_SEC, BASE_REG_TIMER_MFACTOR, SEC_TO_MSEC_MFACTOR, REG_RANDOM_T_FACTOR_UPPER_LIMIT, REG_TRY_BACKUP_TIMER_VAL_IN_SEC, MINUTES_TO_SEC_MFACTOR, FAILBACK_429_RETRY_UTIL, REG_FAILBACK_429_MAX_RETRIES, FAILBACK_UTIL, REGISTRATION_FILE, DEFAULT_REHOMING_INTERVAL_MIN, DEFAULT_REHOMING_INTERVAL_MAX, DEFAULT_KEEPALIVE_INTERVAL, } from '../constants';
9
+ import { ALLOWED_SERVICES, HTTP_METHODS, RegistrationStatus, ServiceIndicator, } from '../../common/types';
10
+ import { CALLING_USER_AGENT, CISCO_DEVICE_URL, DEVICES_ENDPOINT_RESOURCE, SPARK_USER_AGENT, WEBEX_WEB_CLIENT, BASE_REG_RETRY_TIMER_VAL_IN_SEC, BASE_REG_TIMER_MFACTOR, SEC_TO_MSEC_MFACTOR, REG_RANDOM_T_FACTOR_UPPER_LIMIT, REG_TRY_BACKUP_TIMER_VAL_IN_SEC, MINUTES_TO_SEC_MFACTOR, FAILBACK_429_RETRY_UTIL, REG_FAILBACK_429_MAX_RETRIES, FAILBACK_UTIL, REGISTRATION_FILE, DEFAULT_REHOMING_INTERVAL_MIN, DEFAULT_REHOMING_INTERVAL_MAX, DEFAULT_KEEPALIVE_INTERVAL, REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC, } from '../constants';
11
11
  import { LINE_EVENTS } from '../line/types';
12
12
  export class Registration {
13
13
  sdkConnector;
@@ -30,9 +30,11 @@ export class Registration {
30
30
  backupMobiusUris;
31
31
  registerRetry = false;
32
32
  reconnectPending = false;
33
+ isCCFlow = false;
33
34
  constructor(webex, serviceData, mutex, lineEmitter, logLevel) {
34
35
  this.sdkConnector = SDKConnector;
35
36
  this.serviceData = serviceData;
37
+ this.isCCFlow = serviceData.indicator === ServiceIndicator.CONTACT_CENTER;
36
38
  if (!this.sdkConnector.getWebex()) {
37
39
  SDKConnector.setWebex(webex);
38
40
  }
@@ -147,8 +149,11 @@ export class Registration {
147
149
  method: this.startFailoverTimer.name,
148
150
  };
149
151
  let interval = this.getRegRetryInterval(attempt);
150
- if (timeElapsed + interval > REG_TRY_BACKUP_TIMER_VAL_IN_SEC) {
151
- const excessVal = timeElapsed + interval - REG_TRY_BACKUP_TIMER_VAL_IN_SEC;
152
+ const TIMER_THRESHOLD = this.isCCFlow
153
+ ? REG_TRY_BACKUP_TIMER_VAL_FOR_CC_IN_SEC
154
+ : REG_TRY_BACKUP_TIMER_VAL_IN_SEC;
155
+ if (timeElapsed + interval > TIMER_THRESHOLD) {
156
+ const excessVal = timeElapsed + interval - TIMER_THRESHOLD;
152
157
  interval -= excessVal;
153
158
  }
154
159
  let abort;
@@ -409,13 +414,14 @@ export class Registration {
409
414
  startKeepaliveTimer(url, interval) {
410
415
  let keepAliveRetryCount = 0;
411
416
  this.clearKeepaliveTimer();
417
+ const RETRY_COUNT_THRESHOLD = this.isCCFlow ? 4 : 5;
412
418
  this.keepaliveTimer = setInterval(async () => {
413
419
  const logContext = {
414
420
  file: REGISTRATION_FILE,
415
421
  method: this.startKeepaliveTimer.name,
416
422
  };
417
423
  await this.mutex.runExclusive(async () => {
418
- if (this.isDeviceRegistered() && keepAliveRetryCount < 5) {
424
+ if (this.isDeviceRegistered() && keepAliveRetryCount < RETRY_COUNT_THRESHOLD) {
419
425
  try {
420
426
  const res = await this.postKeepAlive(url);
421
427
  log.info(`Sent Keepalive, status: ${res.statusCode}`, logContext);
@@ -434,7 +440,7 @@ export class Registration {
434
440
  }
435
441
  this.metricManager.submitRegistrationMetric(METRIC_EVENT.REGISTRATION, REG_ACTION.KEEPALIVE_FAILURE, METRIC_TYPE.BEHAVIORAL, clientError);
436
442
  }, { method: this.startKeepaliveTimer.name, file: REGISTRATION_FILE });
437
- if (abort || keepAliveRetryCount >= 5) {
443
+ if (abort || keepAliveRetryCount >= RETRY_COUNT_THRESHOLD) {
438
444
  this.setStatus(RegistrationStatus.INACTIVE);
439
445
  this.clearKeepaliveTimer();
440
446
  this.clearFailbackTimer();
@@ -5,9 +5,6 @@ import log from '../Logger';
5
5
  import { CONTACTS_FILE, CONTACTS_SCHEMA, CONTACT_FILTER, DEFAULT_GROUP_NAME, ENCRYPT_FILTER, GROUP_FILTER, OR, SCIM_ID_FILTER, USERS, encryptedFields, } from './constants';
6
6
  import { ContactType, GroupType, } from './types';
7
7
  import { scimQuery, serviceErrorCodeHandler } from '../common/Utils';
8
- import Logger from '../Logger';
9
- import ExtendedError from '../Errors/catalog/ExtendedError';
10
- import { ERROR_TYPE } from '../Errors/types';
11
8
  export class ContactsClient {
12
9
  sdkConnector;
13
10
  encryptionKeyUrl;
@@ -132,26 +129,39 @@ export class ContactsClient {
132
129
  return decryptedContact;
133
130
  }
134
131
  resolveCloudContacts(contactsDataMap, inputList) {
132
+ const loggerContext = {
133
+ file: CONTACTS_FILE,
134
+ method: 'resolveCloudContacts',
135
+ };
135
136
  const finalContactList = [];
137
+ const resolvedList = [];
136
138
  try {
137
- const contactList = Object.keys(contactsDataMap);
138
- for (let n = 0; n < contactList.length; n += 1) {
139
- const filteredContact = inputList.Resources.filter((item) => item.id === contactList[n])[0];
139
+ inputList.Resources.forEach((item) => {
140
+ resolvedList.push(item.id);
141
+ });
142
+ Object.values(contactsDataMap).forEach((item) => {
143
+ const isResolved = resolvedList.some((listItem) => listItem === item.contactId);
144
+ if (!isResolved) {
145
+ finalContactList.push({ ...item, resolved: false });
146
+ }
147
+ });
148
+ for (let n = 0; n < inputList.Resources.length; n += 1) {
149
+ const filteredContact = inputList.Resources[n];
140
150
  const { displayName, emails, phoneNumbers, photos } = filteredContact;
141
- const { sipAddresses } = filteredContact[SCIM_WEBEXIDENTITY_USER];
142
- const firstName = filteredContact.name.givenName;
143
- const lastName = filteredContact.name.familyName;
144
- const manager = filteredContact[SCIM_ENTERPRISE_USER].manager.displayName;
145
- const department = filteredContact[SCIM_ENTERPRISE_USER].department;
146
- let avatarURL = '';
147
- if (photos?.length) {
148
- avatarURL = photos[0].value;
151
+ let sipAddresses;
152
+ if (filteredContact[SCIM_WEBEXIDENTITY_USER]) {
153
+ sipAddresses = filteredContact[SCIM_WEBEXIDENTITY_USER].sipAddresses;
149
154
  }
150
- const { contactType, avatarUrlDomain, encryptionKeyUrl, ownerId, groups } = contactsDataMap[contactList[n]];
155
+ const firstName = filteredContact.name?.givenName;
156
+ const lastName = filteredContact.name?.familyName;
157
+ const manager = filteredContact[SCIM_ENTERPRISE_USER]?.manager?.displayName;
158
+ const department = filteredContact[SCIM_ENTERPRISE_USER]?.department;
159
+ const avatarURL = photos?.length ? photos[0].value : '';
160
+ const { contactType, avatarUrlDomain, encryptionKeyUrl, ownerId, groups } = contactsDataMap[inputList.Resources[n].id];
151
161
  const cloudContact = {
152
162
  avatarUrlDomain,
153
163
  avatarURL,
154
- contactId: contactList[n],
164
+ contactId: inputList.Resources[n].id,
155
165
  contactType,
156
166
  department,
157
167
  displayName,
@@ -164,12 +174,13 @@ export class ContactsClient {
164
174
  ownerId,
165
175
  phoneNumbers,
166
176
  sipAddresses,
177
+ resolved: true,
167
178
  };
168
179
  finalContactList.push(cloudContact);
169
180
  }
170
181
  }
171
182
  catch (error) {
172
- Logger.error(new ExtendedError(error.message, {}, ERROR_TYPE.DEFAULT), {});
183
+ log.warn('Error occurred while parsing resolved contacts', loggerContext);
173
184
  return null;
174
185
  }
175
186
  return finalContactList;
@@ -243,6 +243,19 @@ export const mockContactGroupListTwo = [
243
243
  isMigration: false,
244
244
  },
245
245
  ];
246
+ export const mockContactMinimum = {
247
+ contactId: 'userId',
248
+ contactType: 'CLOUD',
249
+ encryptionKeyUrl: 'kms://cisco.com/keys/dcf18f9d-155e-44ff-ad61-c8a69b7103ab',
250
+ groups: ['1561977e-3443-4ccf-a591-69686275d7d2'],
251
+ ownerId: 'ownerId',
252
+ };
253
+ export const scimUserMinimum = {
254
+ schemas: ['urn:ietf:params:scim:schemas:core:2.0:User'],
255
+ id: 'userId',
256
+ userName: 'userName',
257
+ userType: 'user',
258
+ };
246
259
  const scimUser1 = {
247
260
  schemas: [
248
261
  'urn:ietf:params:scim:schemas:core:2.0:User',
@@ -417,12 +430,22 @@ export const mockSCIMListResponse = {
417
430
  statusCode: 200,
418
431
  body: {
419
432
  schemas: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],
420
- totalResults: 11,
421
- itemsPerPage: 11,
433
+ totalResults: 2,
434
+ itemsPerPage: 2,
422
435
  startIndex: 1,
423
436
  Resources: [scimUser1, scimUser2NoPhoto],
424
437
  },
425
438
  };
439
+ export const mockSCIMMinListResponse = {
440
+ statusCode: 200,
441
+ body: {
442
+ schemas: ['urn:ietf:params:scim:api:messages:2.0:ListResponse'],
443
+ totalResults: 1,
444
+ itemsPerPage: 1,
445
+ startIndex: 1,
446
+ Resources: [scimUserMinimum],
447
+ },
448
+ };
426
449
  export const mockKmsKey = {
427
450
  uri: 'kms://kms-cisco.wbx2.com/keys/16095024-612d-4424-ba51-57cad2402e14',
428
451
  };
@@ -188,7 +188,9 @@ class MetricManager {
188
188
  },
189
189
  fields: {
190
190
  device_url: this.deviceInfo?.device?.clientDeviceUri,
191
- calling_sdk_version: process.env.CALLING_SDK_VERSION || VERSION,
191
+ calling_sdk_version: typeof process !== 'undefined' && process.env.CALLING_SDK_VERSION
192
+ ? process.env.CALLING_SDK_VERSION
193
+ : VERSION,
192
194
  },
193
195
  type,
194
196
  };
@@ -205,7 +207,9 @@ class MetricManager {
205
207
  },
206
208
  fields: {
207
209
  device_url: this.deviceInfo?.device?.clientDeviceUri,
208
- calling_sdk_version: process.env.CALLING_SDK_VERSION || VERSION,
210
+ calling_sdk_version: typeof process !== 'undefined' && process.env.CALLING_SDK_VERSION
211
+ ? process.env.CALLING_SDK_VERSION
212
+ : VERSION,
209
213
  },
210
214
  type,
211
215
  };