@wazo/sdk 0.37.22 → 0.37.26

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 (118) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +37 -6
  3. package/esm/__tests__/web-rtc-client.test.js +78 -68
  4. package/esm/api/call-logd.js +7 -0
  5. package/esm/api/calld.js +10 -0
  6. package/esm/api/chatd.js +7 -0
  7. package/esm/api/confd.js +13 -5
  8. package/esm/api/ctid-ng.js +10 -0
  9. package/esm/api/dird.js +4 -1
  10. package/esm/api-client.js +37 -6
  11. package/esm/checker/Checker.js +78 -68
  12. package/esm/checker/checks/aor.js +37 -6
  13. package/esm/checker/checks/api.js +37 -6
  14. package/esm/checker/checks/index.js +78 -68
  15. package/esm/checker/checks/webrtc-transport.js +78 -68
  16. package/esm/checker/checks/webrtc.js +78 -68
  17. package/esm/domain/AdHocAPIConference.js +37 -6
  18. package/esm/domain/Call.js +3 -0
  19. package/esm/domain/CallLog.js +7 -0
  20. package/esm/domain/ChatMessage.js +4 -0
  21. package/esm/domain/ChatRoom.js +3 -0
  22. package/esm/domain/Contact.js +4 -1
  23. package/esm/domain/Features.js +37 -6
  24. package/esm/domain/Meeting.js +15 -5
  25. package/esm/domain/Phone/CTIPhone.js +41 -6
  26. package/esm/domain/Phone/WebRTCPhone.js +41 -15
  27. package/esm/domain/Recording.js +3 -0
  28. package/esm/domain/Voicemail.js +3 -0
  29. package/esm/domain/__tests__/Call.test.js +3 -0
  30. package/esm/domain/__tests__/CallLog.test.js +7 -0
  31. package/esm/domain/__tests__/Contact.test.js +4 -1
  32. package/esm/domain/__tests__/Meeting.test.js +144 -0
  33. package/esm/domain/__tests__/Voicemail.test.js +3 -0
  34. package/esm/index.js +122 -82
  35. package/esm/lib/WazoSessionDescriptionHandler.js +0 -38
  36. package/esm/service/CallApi.js +37 -6
  37. package/esm/service/getApiClient.js +37 -6
  38. package/esm/simple/Auth.js +122 -82
  39. package/esm/simple/Configuration.js +122 -82
  40. package/esm/simple/Directory.js +37 -6
  41. package/esm/simple/Phone.js +122 -82
  42. package/esm/simple/index.js +122 -82
  43. package/esm/simple/room/LocalParticipant.js +122 -82
  44. package/esm/simple/room/Participant.js +122 -82
  45. package/esm/simple/room/RemoteParticipant.js +122 -82
  46. package/esm/simple/room/Room.js +122 -82
  47. package/esm/simple/room/SipRoom.js +122 -82
  48. package/esm/simple/room/Stream.js +122 -82
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +122 -82
  50. package/esm/simple/utils.js +122 -82
  51. package/esm/types/WebSocketMessage.js +1 -1
  52. package/esm/web-rtc-client.js +78 -68
  53. package/lib/__tests__/api-client.test.js +37 -6
  54. package/lib/__tests__/web-rtc-client.test.js +78 -68
  55. package/lib/api/call-logd.js +7 -0
  56. package/lib/api/calld.js +10 -0
  57. package/lib/api/chatd.js +7 -0
  58. package/lib/api/confd.js +13 -5
  59. package/lib/api/ctid-ng.js +10 -0
  60. package/lib/api/dird.js +4 -1
  61. package/lib/api-client.js +37 -6
  62. package/lib/checker/Checker.js +78 -68
  63. package/lib/checker/checks/aor.js +37 -6
  64. package/lib/checker/checks/api.js +37 -6
  65. package/lib/checker/checks/index.js +78 -68
  66. package/lib/checker/checks/webrtc-transport.js +78 -68
  67. package/lib/checker/checks/webrtc.js +78 -68
  68. package/lib/domain/AdHocAPIConference.js +37 -6
  69. package/lib/domain/Call.js +3 -0
  70. package/lib/domain/CallLog.js +7 -0
  71. package/lib/domain/ChatMessage.js +4 -0
  72. package/lib/domain/ChatRoom.js +3 -0
  73. package/lib/domain/Contact.js +4 -1
  74. package/lib/domain/Features.js +37 -6
  75. package/lib/domain/Meeting.js +19 -5
  76. package/lib/domain/Phone/CTIPhone.js +41 -6
  77. package/lib/domain/Phone/WebRTCPhone.js +41 -15
  78. package/lib/domain/Recording.js +3 -0
  79. package/lib/domain/Voicemail.js +3 -0
  80. package/lib/domain/__tests__/Call.test.js +3 -0
  81. package/lib/domain/__tests__/CallLog.test.js +7 -0
  82. package/lib/domain/__tests__/Contact.test.js +4 -1
  83. package/lib/domain/__tests__/Meeting.test.js +150 -0
  84. package/lib/domain/__tests__/Voicemail.test.js +3 -0
  85. package/lib/index.js +122 -82
  86. package/lib/lib/WazoSessionDescriptionHandler.js +0 -38
  87. package/lib/service/CallApi.js +37 -6
  88. package/lib/service/getApiClient.js +37 -6
  89. package/lib/simple/Auth.js +122 -82
  90. package/lib/simple/Configuration.js +122 -82
  91. package/lib/simple/Directory.js +37 -6
  92. package/lib/simple/Phone.js +122 -82
  93. package/lib/simple/index.js +122 -82
  94. package/lib/simple/room/LocalParticipant.js +122 -82
  95. package/lib/simple/room/Participant.js +122 -82
  96. package/lib/simple/room/RemoteParticipant.js +122 -82
  97. package/lib/simple/room/Room.js +122 -82
  98. package/lib/simple/room/SipRoom.js +122 -82
  99. package/lib/simple/room/Stream.js +122 -82
  100. package/lib/simple/room/__tests__/RemoteParticipant.test.js +122 -82
  101. package/lib/simple/utils.js +122 -82
  102. package/lib/types/WebSocketMessage.js +2 -0
  103. package/lib/web-rtc-client.js +78 -68
  104. package/package.json +1 -1
  105. package/src/domain/Call.js +3 -0
  106. package/src/domain/CallLog.js +4 -0
  107. package/src/domain/ChatMessage.js +4 -0
  108. package/src/domain/ChatRoom.js +3 -0
  109. package/src/domain/Contact.js +4 -1
  110. package/src/domain/Meeting.js +15 -5
  111. package/src/domain/Phone/CTIPhone.js +4 -0
  112. package/src/domain/Phone/Phone.js +2 -0
  113. package/src/domain/Phone/WebRTCPhone.js +41 -15
  114. package/src/domain/Recording.js +3 -0
  115. package/src/domain/Voicemail.js +3 -0
  116. package/src/domain/__tests__/Meeting.test.js +50 -0
  117. package/src/lib/WazoSessionDescriptionHandler.js +1 -35
  118. package/src/web-rtc-client.js +41 -24
package/esm/api-client.js CHANGED
@@ -1531,6 +1531,9 @@ class Contact {
1531
1531
  }
1532
1532
 
1533
1533
  static parseMany(response ) {
1534
+ if (!response || !response.results) {
1535
+ return [];
1536
+ }
1534
1537
  return response.results.map(r => Contact.parse(r, response.column_types));
1535
1538
  }
1536
1539
 
@@ -1901,7 +1904,7 @@ class Contact {
1901
1904
  this[key] = old[key] || this[key];
1902
1905
  });
1903
1906
 
1904
- if (old.lineState && !this.lineState) {
1907
+ if (old.lineState) {
1905
1908
  this.lineState = old.lineState;
1906
1909
  }
1907
1910
 
@@ -2608,8 +2611,9 @@ class ExternalApp {
2608
2611
 
2609
2612
 
2610
2613
 
2611
-
2614
+
2612
2615
 
2616
+
2613
2617
 
2614
2618
 
2615
2619
  class Meeting {
@@ -2620,9 +2624,10 @@ class Meeting {
2620
2624
 
2621
2625
 
2622
2626
 
2623
-
2627
+
2624
2628
 
2625
2629
 
2630
+
2626
2631
 
2627
2632
  static parse(plain ) {
2628
2633
  return new Meeting({
@@ -2632,12 +2637,16 @@ class Meeting {
2632
2637
  ownerUuids: plain.owner_uuids,
2633
2638
  port: plain.port,
2634
2639
  uuid: plain.uuid,
2635
- number: plain.number,
2640
+ extension: plain.exten,
2636
2641
  persistent: plain.persistent,
2642
+ creationTime: moment(plain.creation_time).toDate(),
2637
2643
  });
2638
2644
  }
2639
2645
 
2640
2646
  static parseMany(items ) {
2647
+ if (!items) {
2648
+ return [];
2649
+ }
2641
2650
  return items.map(plain => Meeting.parse(plain));
2642
2651
  }
2643
2652
 
@@ -2652,8 +2661,9 @@ class Meeting {
2652
2661
  ownerUuids,
2653
2662
  port,
2654
2663
  uri,
2655
- number,
2664
+ extension,
2656
2665
  persistent,
2666
+ creationTime,
2657
2667
  } = {}) {
2658
2668
  this.guestSipAuthorization = guestSipAuthorization;
2659
2669
  this.uri = uri;
@@ -2661,8 +2671,9 @@ class Meeting {
2661
2671
  this.ownerUuids = ownerUuids;
2662
2672
  this.port = port;
2663
2673
  this.uuid = uuid;
2664
- this.number = number;
2674
+ this.extension = extension;
2665
2675
  this.persistent = persistent;
2676
+ this.creationTime = creationTime;
2666
2677
 
2667
2678
  // Useful to compare instead of instanceof with minified code
2668
2679
  this.type = 'Meeting';
@@ -2840,6 +2851,10 @@ class ChatMessage {
2840
2851
 
2841
2852
 
2842
2853
  static parseMany(plain ) {
2854
+ if (!plain || !plain.items) {
2855
+ return [];
2856
+ }
2857
+
2843
2858
  return plain.items.map(item => ChatMessage.parse(item));
2844
2859
  }
2845
2860
 
@@ -2949,6 +2964,9 @@ class Voicemail {
2949
2964
  }
2950
2965
 
2951
2966
  static parseMany(plain ) {
2967
+ if (!plain) {
2968
+ return [];
2969
+ }
2952
2970
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2953
2971
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2954
2972
 
@@ -3058,6 +3076,9 @@ class Call {
3058
3076
 
3059
3077
 
3060
3078
  static parseMany(plain ) {
3079
+ if (!plain) {
3080
+ return [];
3081
+ }
3061
3082
  return plain.map((plainCall ) => Call.parse(plainCall));
3062
3083
  }
3063
3084
 
@@ -3230,6 +3251,9 @@ class Recording {
3230
3251
 
3231
3252
 
3232
3253
  static parseMany(recordings = []) {
3254
+ if (!recordings) {
3255
+ return [];
3256
+ }
3233
3257
  return recordings.map(item => Recording.parse(item));
3234
3258
  }
3235
3259
 
@@ -3331,6 +3355,10 @@ class CallLog {
3331
3355
  }
3332
3356
 
3333
3357
  static parseMany(plain ) {
3358
+ if (!plain || !plain.items) {
3359
+ return [];
3360
+ }
3361
+
3334
3362
  return plain.items.map(item => CallLog.parse(item));
3335
3363
  }
3336
3364
 
@@ -3903,6 +3931,9 @@ class ChatRoom {
3903
3931
 
3904
3932
 
3905
3933
  static parseMany(plain ) {
3934
+ if (!plain || !plain.items) {
3935
+ return [];
3936
+ }
3906
3937
  return plain.items.map(item => ChatRoom.parse(item));
3907
3938
  }
3908
3939
 
@@ -1549,6 +1549,9 @@ class Contact {
1549
1549
  }
1550
1550
 
1551
1551
  static parseMany(response ) {
1552
+ if (!response || !response.results) {
1553
+ return [];
1554
+ }
1552
1555
  return response.results.map(r => Contact.parse(r, response.column_types));
1553
1556
  }
1554
1557
 
@@ -1919,7 +1922,7 @@ class Contact {
1919
1922
  this[key] = old[key] || this[key];
1920
1923
  });
1921
1924
 
1922
- if (old.lineState && !this.lineState) {
1925
+ if (old.lineState) {
1923
1926
  this.lineState = old.lineState;
1924
1927
  }
1925
1928
 
@@ -2626,8 +2629,9 @@ class ExternalApp {
2626
2629
 
2627
2630
 
2628
2631
 
2629
-
2632
+
2630
2633
 
2634
+
2631
2635
 
2632
2636
 
2633
2637
  class Meeting {
@@ -2638,9 +2642,10 @@ class Meeting {
2638
2642
 
2639
2643
 
2640
2644
 
2641
-
2645
+
2642
2646
 
2643
2647
 
2648
+
2644
2649
 
2645
2650
  static parse(plain ) {
2646
2651
  return new Meeting({
@@ -2650,12 +2655,16 @@ class Meeting {
2650
2655
  ownerUuids: plain.owner_uuids,
2651
2656
  port: plain.port,
2652
2657
  uuid: plain.uuid,
2653
- number: plain.number,
2658
+ extension: plain.exten,
2654
2659
  persistent: plain.persistent,
2660
+ creationTime: moment(plain.creation_time).toDate(),
2655
2661
  });
2656
2662
  }
2657
2663
 
2658
2664
  static parseMany(items ) {
2665
+ if (!items) {
2666
+ return [];
2667
+ }
2659
2668
  return items.map(plain => Meeting.parse(plain));
2660
2669
  }
2661
2670
 
@@ -2670,8 +2679,9 @@ class Meeting {
2670
2679
  ownerUuids,
2671
2680
  port,
2672
2681
  uri,
2673
- number,
2682
+ extension,
2674
2683
  persistent,
2684
+ creationTime,
2675
2685
  } = {}) {
2676
2686
  this.guestSipAuthorization = guestSipAuthorization;
2677
2687
  this.uri = uri;
@@ -2679,8 +2689,9 @@ class Meeting {
2679
2689
  this.ownerUuids = ownerUuids;
2680
2690
  this.port = port;
2681
2691
  this.uuid = uuid;
2682
- this.number = number;
2692
+ this.extension = extension;
2683
2693
  this.persistent = persistent;
2694
+ this.creationTime = creationTime;
2684
2695
 
2685
2696
  // Useful to compare instead of instanceof with minified code
2686
2697
  this.type = 'Meeting';
@@ -2858,6 +2869,10 @@ class ChatMessage {
2858
2869
 
2859
2870
 
2860
2871
  static parseMany(plain ) {
2872
+ if (!plain || !plain.items) {
2873
+ return [];
2874
+ }
2875
+
2861
2876
  return plain.items.map(item => ChatMessage.parse(item));
2862
2877
  }
2863
2878
 
@@ -2967,6 +2982,9 @@ class Voicemail {
2967
2982
  }
2968
2983
 
2969
2984
  static parseMany(plain ) {
2985
+ if (!plain) {
2986
+ return [];
2987
+ }
2970
2988
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2971
2989
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2972
2990
 
@@ -3076,6 +3094,9 @@ class Call {
3076
3094
 
3077
3095
 
3078
3096
  static parseMany(plain ) {
3097
+ if (!plain) {
3098
+ return [];
3099
+ }
3079
3100
  return plain.map((plainCall ) => Call.parse(plainCall));
3080
3101
  }
3081
3102
 
@@ -3274,6 +3295,9 @@ class Recording {
3274
3295
 
3275
3296
 
3276
3297
  static parseMany(recordings = []) {
3298
+ if (!recordings) {
3299
+ return [];
3300
+ }
3277
3301
  return recordings.map(item => Recording.parse(item));
3278
3302
  }
3279
3303
 
@@ -3375,6 +3399,10 @@ class CallLog {
3375
3399
  }
3376
3400
 
3377
3401
  static parseMany(plain ) {
3402
+ if (!plain || !plain.items) {
3403
+ return [];
3404
+ }
3405
+
3378
3406
  return plain.items.map(item => CallLog.parse(item));
3379
3407
  }
3380
3408
 
@@ -3947,6 +3975,9 @@ class ChatRoom {
3947
3975
 
3948
3976
 
3949
3977
  static parseMany(plain ) {
3978
+ if (!plain || !plain.items) {
3979
+ return [];
3980
+ }
3950
3981
  return plain.items.map(item => ChatRoom.parse(item));
3951
3982
  }
3952
3983
 
@@ -5349,10 +5380,6 @@ const getSrflxOrRelay = (candidates ) =>
5349
5380
  candidates
5350
5381
  .filter(candidate => candidate && (candidate.type === 'srflx' || candidate.type === 'relay'));
5351
5382
 
5352
- const areCandidateValid = (candidates ) =>
5353
- getSrflxOrRelay(candidates)
5354
- .length > 0;
5355
-
5356
5383
  const getVideoDirection = (sdp ) => {
5357
5384
  const parsedSdp = sdpParser.parse(sdp);
5358
5385
  const videoMedia = parsedSdp.media.find(media => media.type === 'video');
@@ -5405,8 +5432,6 @@ const fixSdp = (sdp , candidates , forcePort = true)
5405
5432
  /* global RTCSessionDescriptionInit, navigator */
5406
5433
 
5407
5434
  const wazoLogger = IssueReporter$1 ? IssueReporter$1.loggerFor('webrtc-sdh') : console;
5408
- const MAX_WAIT_FOR_ICE_TRIES = 20;
5409
- const WAIT_FOR_ICE_TIMEOUT = 500;
5410
5435
 
5411
5436
  // Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
5412
5437
  const wazoMediaStreamFactory = (constraints ) => {
@@ -5596,38 +5621,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
5596
5621
  this._peerConnection = undefined;
5597
5622
  }
5598
5623
 
5599
- async _waitForValidGatheredIce() {
5600
- let tries = 0;
5601
-
5602
- while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
5603
- wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
5604
- tries,
5605
- max: MAX_WAIT_FOR_ICE_TRIES,
5606
- });
5607
-
5608
- tries++;
5609
-
5610
- // eslint-disable-next-line no-await-in-loop
5611
- await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
5612
- }
5613
-
5614
- if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
5615
- const errorMsg = 'No valid candidates found, can\'t answer the call';
5616
- const error = new Error(errorMsg);
5617
- wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
5618
-
5619
- // Emit an error, because sip.js catches the exception and switch to status Terminated.
5620
- this.eventEmitter.emit('error', error);
5621
-
5622
- wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5623
- }
5624
-
5625
- // eslint-disable-next-line
5626
- wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
5627
-
5628
- return this.getLocalSessionDescription();
5629
- }
5630
-
5631
5624
  // Overridden to send `inactive` in conference
5632
5625
  updateDirection(options , isConference = false,
5633
5626
  audioOnly = false) {
@@ -6297,7 +6290,7 @@ class WebRTCClient extends Emitter {
6297
6290
  }
6298
6291
 
6299
6292
  call(number , enableVideo , audioOnly = false, conference = false) {
6300
- logger$1.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6293
+ logger$1.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6301
6294
  const inviterOptions = {
6302
6295
  sessionDescriptionHandlerOptionsReInvite: {
6303
6296
  conference,
@@ -7373,6 +7366,7 @@ class WebRTCClient extends Emitter {
7373
7366
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
7374
7367
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
7375
7368
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
7369
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
7376
7370
 
7377
7371
  logger$1.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
7378
7372
 
@@ -7380,7 +7374,8 @@ class WebRTCClient extends Emitter {
7380
7374
  constraints: {
7381
7375
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
7382
7376
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
7383
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
7377
+ video: screenSharing ? (isDesktop
7378
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
7384
7379
  : this._getVideoConstraints(enableVideo),
7385
7380
  screen: screenSharing,
7386
7381
  desktop: isDesktop,
@@ -7715,12 +7710,14 @@ class WebRTCClient extends Emitter {
7715
7710
 
7716
7711
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7717
7712
 
7718
- pc.oniceconnectionstatechange = () => {
7719
- logger$1.info('on ice connection state changed', { state: pc.iceConnectionState });
7720
- if (pc.iceConnectionState === 'disconnected') {
7721
- this.eventEmitter.emit(ON_DISCONNECTED);
7722
- }
7723
- };
7713
+ if (pc) {
7714
+ pc.oniceconnectionstatechange = () => {
7715
+ logger$1.info('on ice connection state changed', { state: pc.iceConnectionState });
7716
+ if (pc.iceConnectionState === 'disconnected') {
7717
+ this.eventEmitter.emit(ON_DISCONNECTED);
7718
+ }
7719
+ };
7720
+ }
7724
7721
 
7725
7722
  if (withEvent) {
7726
7723
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -7930,13 +7927,17 @@ class WebRTCClient extends Emitter {
7930
7927
  const nbStats = this.sessionNetworkStats[sessionId].length;
7931
7928
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
7932
7929
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
7930
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
7933
7931
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
7934
7932
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
7933
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
7935
7934
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
7936
7935
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
7937
7936
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
7938
- let audioBytesSent = 0;
7939
- let audioBytesReceived = 0;
7937
+ let audioBytesSent = 0; // content + header
7938
+ let audioBytesReceived = 0; // content + header
7939
+ let audioContentSent = 0; // useful to detect blank call
7940
+ let audioContentReceived = 0;
7940
7941
  let videoBytesSent = 0;
7941
7942
  let videoBytesReceived = 0;
7942
7943
  let transportSent = 0;
@@ -7945,25 +7946,27 @@ class WebRTCClient extends Emitter {
7945
7946
 
7946
7947
  stats.forEach(report => {
7947
7948
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
7948
- audioBytesSent += report.bytesSent + report.headerBytesSent;
7949
+ audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
7950
+ audioContentSent += Number(report.bytesSent);
7949
7951
  }
7950
7952
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
7951
- audioBytesSent += report.bytesSent;
7953
+ audioBytesSent += Number(report.bytesSent);
7952
7954
  }
7953
7955
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7954
- videoBytesSent += report.bytesSent + report.headerBytesSent;
7956
+ videoBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
7955
7957
  }
7956
7958
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7957
- packetsLost += report.packetsLost;
7958
- networkStats.packetsReceived = report.packetsReceived;
7959
- audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7959
+ packetsLost += Number(report.packetsLost);
7960
+ networkStats.packetsReceived = Number(report.packetsReceived);
7961
+ audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
7962
+ audioContentReceived += Number(report.bytesReceived);
7960
7963
  }
7961
7964
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
7962
- videoBytesReceived += report.bytesReceived + report.headerBytesReceived;
7965
+ videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
7963
7966
  }
7964
7967
  if (report.type === 'outbound-rtp' && report.kind === 'video') {
7965
7968
  if ('framesPerSecond' in report) {
7966
- networkStats.framesPerSecond = report.framesPerSecond;
7969
+ networkStats.framesPerSecond = Number(report.framesPerSecond);
7967
7970
  }
7968
7971
  if ('framerateMean' in report) {
7969
7972
  // framerateMean is only available in FF
@@ -7971,24 +7974,31 @@ class WebRTCClient extends Emitter {
7971
7974
  }
7972
7975
  }
7973
7976
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7974
- packetsLost += report.packetsLost;
7975
- networkStats.roundTripTime = report.roundTripTime;
7976
- networkStats.jitter = report.jitter;
7977
+ packetsLost += Number(report.packetsLost);
7978
+ networkStats.roundTripTime = Number(report.roundTripTime);
7979
+ networkStats.jitter = Number(report.jitter);
7977
7980
  }
7978
7981
  if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7979
- packetsLost += report.packetsLost;
7982
+ packetsLost += Number(report.packetsLost);
7980
7983
  }
7981
7984
  if (report.type === 'transport') {
7982
- transportSent += report.bytesSent;
7983
- transportReceived += report.bytesReceived;
7985
+ transportSent += Number(report.bytesSent);
7986
+ transportReceived += Number(report.bytesReceived);
7984
7987
  }
7985
7988
  });
7986
7989
 
7987
7990
  networkStats.packetsLost = packetsLost;
7991
+
7988
7992
  networkStats.totalAudioBytesSent = audioBytesSent;
7989
7993
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
7990
7994
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
7991
7995
  networkStats.audioBytesReceived = audioBytesReceived;
7996
+
7997
+ networkStats.totalAudioContentSent = audioContentSent;
7998
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
7999
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8000
+ networkStats.audioContentReceived = audioContentReceived;
8001
+
7992
8002
  networkStats.totalVideoBytesSent = videoBytesSent;
7993
8003
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
7994
8004
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -1531,6 +1531,9 @@ class Contact {
1531
1531
  }
1532
1532
 
1533
1533
  static parseMany(response ) {
1534
+ if (!response || !response.results) {
1535
+ return [];
1536
+ }
1534
1537
  return response.results.map(r => Contact.parse(r, response.column_types));
1535
1538
  }
1536
1539
 
@@ -1901,7 +1904,7 @@ class Contact {
1901
1904
  this[key] = old[key] || this[key];
1902
1905
  });
1903
1906
 
1904
- if (old.lineState && !this.lineState) {
1907
+ if (old.lineState) {
1905
1908
  this.lineState = old.lineState;
1906
1909
  }
1907
1910
 
@@ -2608,8 +2611,9 @@ class ExternalApp {
2608
2611
 
2609
2612
 
2610
2613
 
2611
-
2614
+
2612
2615
 
2616
+
2613
2617
 
2614
2618
 
2615
2619
  class Meeting {
@@ -2620,9 +2624,10 @@ class Meeting {
2620
2624
 
2621
2625
 
2622
2626
 
2623
-
2627
+
2624
2628
 
2625
2629
 
2630
+
2626
2631
 
2627
2632
  static parse(plain ) {
2628
2633
  return new Meeting({
@@ -2632,12 +2637,16 @@ class Meeting {
2632
2637
  ownerUuids: plain.owner_uuids,
2633
2638
  port: plain.port,
2634
2639
  uuid: plain.uuid,
2635
- number: plain.number,
2640
+ extension: plain.exten,
2636
2641
  persistent: plain.persistent,
2642
+ creationTime: moment(plain.creation_time).toDate(),
2637
2643
  });
2638
2644
  }
2639
2645
 
2640
2646
  static parseMany(items ) {
2647
+ if (!items) {
2648
+ return [];
2649
+ }
2641
2650
  return items.map(plain => Meeting.parse(plain));
2642
2651
  }
2643
2652
 
@@ -2652,8 +2661,9 @@ class Meeting {
2652
2661
  ownerUuids,
2653
2662
  port,
2654
2663
  uri,
2655
- number,
2664
+ extension,
2656
2665
  persistent,
2666
+ creationTime,
2657
2667
  } = {}) {
2658
2668
  this.guestSipAuthorization = guestSipAuthorization;
2659
2669
  this.uri = uri;
@@ -2661,8 +2671,9 @@ class Meeting {
2661
2671
  this.ownerUuids = ownerUuids;
2662
2672
  this.port = port;
2663
2673
  this.uuid = uuid;
2664
- this.number = number;
2674
+ this.extension = extension;
2665
2675
  this.persistent = persistent;
2676
+ this.creationTime = creationTime;
2666
2677
 
2667
2678
  // Useful to compare instead of instanceof with minified code
2668
2679
  this.type = 'Meeting';
@@ -2840,6 +2851,10 @@ class ChatMessage {
2840
2851
 
2841
2852
 
2842
2853
  static parseMany(plain ) {
2854
+ if (!plain || !plain.items) {
2855
+ return [];
2856
+ }
2857
+
2843
2858
  return plain.items.map(item => ChatMessage.parse(item));
2844
2859
  }
2845
2860
 
@@ -2949,6 +2964,9 @@ class Voicemail {
2949
2964
  }
2950
2965
 
2951
2966
  static parseMany(plain ) {
2967
+ if (!plain) {
2968
+ return [];
2969
+ }
2952
2970
  const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
2953
2971
  const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
2954
2972
 
@@ -3058,6 +3076,9 @@ class Call {
3058
3076
 
3059
3077
 
3060
3078
  static parseMany(plain ) {
3079
+ if (!plain) {
3080
+ return [];
3081
+ }
3061
3082
  return plain.map((plainCall ) => Call.parse(plainCall));
3062
3083
  }
3063
3084
 
@@ -3230,6 +3251,9 @@ class Recording {
3230
3251
 
3231
3252
 
3232
3253
  static parseMany(recordings = []) {
3254
+ if (!recordings) {
3255
+ return [];
3256
+ }
3233
3257
  return recordings.map(item => Recording.parse(item));
3234
3258
  }
3235
3259
 
@@ -3331,6 +3355,10 @@ class CallLog {
3331
3355
  }
3332
3356
 
3333
3357
  static parseMany(plain ) {
3358
+ if (!plain || !plain.items) {
3359
+ return [];
3360
+ }
3361
+
3334
3362
  return plain.items.map(item => CallLog.parse(item));
3335
3363
  }
3336
3364
 
@@ -3903,6 +3931,9 @@ class ChatRoom {
3903
3931
 
3904
3932
 
3905
3933
  static parseMany(plain ) {
3934
+ if (!plain || !plain.items) {
3935
+ return [];
3936
+ }
3906
3937
  return plain.items.map(item => ChatRoom.parse(item));
3907
3938
  }
3908
3939