@wazo/sdk 0.37.23 → 0.37.27

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/README.md +95 -57
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +12 -7
  4. package/esm/__tests__/web-rtc-client.test.js +47 -20
  5. package/esm/api/agentd.js +1 -1
  6. package/esm/api/amid.js +1 -1
  7. package/esm/api/application.js +1 -1
  8. package/esm/api/auth.js +1 -1
  9. package/esm/api/call-logd.js +1 -1
  10. package/esm/api/calld.js +1 -1
  11. package/esm/api/chatd.js +1 -1
  12. package/esm/api/confd.js +11 -6
  13. package/esm/api/ctid-ng.js +1 -1
  14. package/esm/api/dird.js +2 -2
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +12 -7
  17. package/esm/checker/Checker.js +47 -20
  18. package/esm/checker/checks/aor.js +12 -7
  19. package/esm/checker/checks/api.js +12 -7
  20. package/esm/checker/checks/index.js +47 -20
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +47 -20
  23. package/esm/checker/checks/webrtc.js +47 -20
  24. package/esm/domain/AdHocAPIConference.js +12 -7
  25. package/esm/domain/Contact.js +1 -1
  26. package/esm/domain/Features.js +12 -7
  27. package/esm/domain/Meeting.js +12 -5
  28. package/esm/domain/Phone/CTIPhone.js +12 -7
  29. package/esm/domain/Phone/WebRTCPhone.js +34 -6
  30. package/esm/domain/__tests__/Contact.test.js +1 -1
  31. package/esm/domain/__tests__/Meeting.test.js +144 -0
  32. package/esm/index.js +80 -25
  33. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  34. package/esm/service/CallApi.js +12 -7
  35. package/esm/service/IssueReporter.js +1 -1
  36. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  37. package/esm/service/getApiClient.js +12 -7
  38. package/esm/simple/Auth.js +80 -25
  39. package/esm/simple/Configuration.js +80 -25
  40. package/esm/simple/Directory.js +12 -7
  41. package/esm/simple/Phone.js +80 -25
  42. package/esm/simple/Websocket.js +1 -1
  43. package/esm/simple/index.js +80 -25
  44. package/esm/simple/room/LocalParticipant.js +80 -25
  45. package/esm/simple/room/Participant.js +80 -25
  46. package/esm/simple/room/RemoteParticipant.js +80 -25
  47. package/esm/simple/room/Room.js +80 -25
  48. package/esm/simple/room/SipRoom.js +80 -25
  49. package/esm/simple/room/Stream.js +80 -25
  50. package/esm/simple/room/__tests__/RemoteParticipant.test.js +80 -25
  51. package/esm/simple/utils.js +80 -25
  52. package/esm/types/WebSocketMessage.js +1 -1
  53. package/esm/utils/__tests__/api-requester.test.js +1 -1
  54. package/esm/utils/api-requester.js +1 -1
  55. package/esm/web-rtc-client.js +47 -20
  56. package/esm/websocket-client.js +1 -1
  57. package/lib/__tests__/api-client.test.js +12 -7
  58. package/lib/__tests__/web-rtc-client.test.js +47 -20
  59. package/lib/api/agentd.js +1 -1
  60. package/lib/api/amid.js +1 -1
  61. package/lib/api/application.js +1 -1
  62. package/lib/api/auth.js +1 -1
  63. package/lib/api/call-logd.js +1 -1
  64. package/lib/api/calld.js +1 -1
  65. package/lib/api/chatd.js +1 -1
  66. package/lib/api/confd.js +11 -6
  67. package/lib/api/ctid-ng.js +1 -1
  68. package/lib/api/dird.js +2 -2
  69. package/lib/api/webhookd.js +1 -1
  70. package/lib/api-client.js +12 -7
  71. package/lib/checker/Checker.js +47 -20
  72. package/lib/checker/checks/aor.js +12 -7
  73. package/lib/checker/checks/api.js +12 -7
  74. package/lib/checker/checks/index.js +47 -20
  75. package/lib/checker/checks/wazo-websocket.js +1 -1
  76. package/lib/checker/checks/webrtc-transport.js +47 -20
  77. package/lib/checker/checks/webrtc.js +47 -20
  78. package/lib/domain/AdHocAPIConference.js +12 -7
  79. package/lib/domain/Contact.js +1 -1
  80. package/lib/domain/Features.js +12 -7
  81. package/lib/domain/Meeting.js +16 -5
  82. package/lib/domain/Phone/CTIPhone.js +12 -7
  83. package/lib/domain/Phone/WebRTCPhone.js +34 -6
  84. package/lib/domain/__tests__/Contact.test.js +1 -1
  85. package/lib/domain/__tests__/Meeting.test.js +150 -0
  86. package/lib/index.js +80 -25
  87. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  88. package/lib/service/CallApi.js +12 -7
  89. package/lib/service/IssueReporter.js +1 -1
  90. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  91. package/lib/service/getApiClient.js +12 -7
  92. package/lib/simple/Auth.js +80 -25
  93. package/lib/simple/Configuration.js +80 -25
  94. package/lib/simple/Directory.js +12 -7
  95. package/lib/simple/Phone.js +80 -25
  96. package/lib/simple/Websocket.js +1 -1
  97. package/lib/simple/index.js +80 -25
  98. package/lib/simple/room/LocalParticipant.js +80 -25
  99. package/lib/simple/room/Participant.js +80 -25
  100. package/lib/simple/room/RemoteParticipant.js +80 -25
  101. package/lib/simple/room/Room.js +80 -25
  102. package/lib/simple/room/SipRoom.js +80 -25
  103. package/lib/simple/room/Stream.js +80 -25
  104. package/lib/simple/room/__tests__/RemoteParticipant.test.js +80 -25
  105. package/lib/simple/utils.js +80 -25
  106. package/lib/types/WebSocketMessage.js +2 -0
  107. package/lib/utils/__tests__/api-requester.test.js +1 -1
  108. package/lib/utils/api-requester.js +1 -1
  109. package/lib/web-rtc-client.js +47 -20
  110. package/lib/websocket-client.js +1 -1
  111. package/package.json +1 -1
  112. package/src/domain/Contact.js +1 -1
  113. package/src/domain/Meeting.js +12 -5
  114. package/src/domain/Phone/WebRTCPhone.js +33 -5
  115. package/src/domain/__tests__/Meeting.test.js +50 -0
  116. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  117. package/src/utils/api-requester.js +1 -1
  118. package/src/web-rtc-client.js +27 -10
@@ -1236,7 +1236,7 @@ class Contact {
1236
1236
  this[key] = old[key] || this[key];
1237
1237
  });
1238
1238
 
1239
- if (old.lineState && !this.lineState) {
1239
+ if (old.lineState) {
1240
1240
  this.lineState = old.lineState;
1241
1241
  }
1242
1242
 
@@ -1951,7 +1951,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1951
1951
 
1952
1952
  // Use a function here to be able to mock it in tests
1953
1953
  const realFetch = () => {
1954
- if (typeof document !== 'undefined') {
1954
+ if (typeof document !== 'undefined' && window.fetch) {
1955
1955
  // Browser
1956
1956
  return window.fetch;
1957
1957
  }
@@ -2630,8 +2630,9 @@ class ExternalApp {
2630
2630
 
2631
2631
 
2632
2632
 
2633
-
2633
+
2634
2634
 
2635
+
2635
2636
 
2636
2637
 
2637
2638
  class Meeting {
@@ -2642,9 +2643,10 @@ class Meeting {
2642
2643
 
2643
2644
 
2644
2645
 
2645
-
2646
+
2646
2647
 
2647
2648
 
2649
+
2648
2650
 
2649
2651
  static parse(plain ) {
2650
2652
  return new Meeting({
@@ -2654,8 +2656,9 @@ class Meeting {
2654
2656
  ownerUuids: plain.owner_uuids,
2655
2657
  port: plain.port,
2656
2658
  uuid: plain.uuid,
2657
- number: plain.number,
2659
+ extension: plain.exten,
2658
2660
  persistent: plain.persistent,
2661
+ creationTime: moment(plain.creation_time).toDate(),
2659
2662
  });
2660
2663
  }
2661
2664
 
@@ -2677,8 +2680,9 @@ class Meeting {
2677
2680
  ownerUuids,
2678
2681
  port,
2679
2682
  uri,
2680
- number,
2683
+ extension,
2681
2684
  persistent,
2685
+ creationTime,
2682
2686
  } = {}) {
2683
2687
  this.guestSipAuthorization = guestSipAuthorization;
2684
2688
  this.uri = uri;
@@ -2686,8 +2690,9 @@ class Meeting {
2686
2690
  this.ownerUuids = ownerUuids;
2687
2691
  this.port = port;
2688
2692
  this.uuid = uuid;
2689
- this.number = number;
2693
+ this.extension = extension;
2690
2694
  this.persistent = persistent;
2695
+ this.creationTime = creationTime;
2691
2696
 
2692
2697
  // Useful to compare instead of instanceof with minified code
2693
2698
  this.type = 'Meeting';
@@ -6057,11 +6062,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6057
6062
 
6058
6063
  // $FlowFixMe
6059
6064
  setRemoteSessionDescription(sessionDescription ) {
6060
- const result = super.setRemoteSessionDescription(sessionDescription);
6065
+ try {
6066
+ const result = super.setRemoteSessionDescription(sessionDescription);
6061
6067
 
6062
- this.eventEmitter.emit('setDescription', sessionDescription);
6068
+ this.eventEmitter.emit('setDescription', sessionDescription);
6063
6069
 
6064
- return result;
6070
+ return result;
6071
+ } catch (error) {
6072
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6073
+ throw error;
6074
+ }
6065
6075
  }
6066
6076
 
6067
6077
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6966,7 +6976,7 @@ class WebRTCClient extends Emitter {
6966
6976
  }
6967
6977
 
6968
6978
  call(number , enableVideo , audioOnly = false, conference = false) {
6969
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6979
+ logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6970
6980
  const inviterOptions = {
6971
6981
  sessionDescriptionHandlerOptionsReInvite: {
6972
6982
  conference,
@@ -8042,6 +8052,7 @@ class WebRTCClient extends Emitter {
8042
8052
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
8043
8053
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
8044
8054
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
8055
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
8045
8056
 
8046
8057
  logger$8.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
8047
8058
 
@@ -8049,7 +8060,8 @@ class WebRTCClient extends Emitter {
8049
8060
  constraints: {
8050
8061
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
8051
8062
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
8052
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
8063
+ video: screenSharing ? (isDesktop
8064
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
8053
8065
  : this._getVideoConstraints(enableVideo),
8054
8066
  screen: screenSharing,
8055
8067
  desktop: isDesktop,
@@ -8384,12 +8396,14 @@ class WebRTCClient extends Emitter {
8384
8396
 
8385
8397
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8386
8398
 
8387
- pc.oniceconnectionstatechange = () => {
8388
- logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8389
- if (pc.iceConnectionState === 'disconnected') {
8390
- this.eventEmitter.emit(ON_DISCONNECTED$1);
8391
- }
8392
- };
8399
+ if (pc) {
8400
+ pc.oniceconnectionstatechange = () => {
8401
+ logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8402
+ if (pc.iceConnectionState === 'disconnected') {
8403
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8404
+ }
8405
+ };
8406
+ }
8393
8407
 
8394
8408
  if (withEvent) {
8395
8409
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8599,13 +8613,17 @@ class WebRTCClient extends Emitter {
8599
8613
  const nbStats = this.sessionNetworkStats[sessionId].length;
8600
8614
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8601
8615
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8616
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8602
8617
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8603
8618
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8619
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8604
8620
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8605
8621
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8606
8622
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8607
- let audioBytesSent = 0;
8608
- let audioBytesReceived = 0;
8623
+ let audioBytesSent = 0; // content + header
8624
+ let audioBytesReceived = 0; // content + header
8625
+ let audioContentSent = 0; // useful to detect blank call
8626
+ let audioContentReceived = 0;
8609
8627
  let videoBytesSent = 0;
8610
8628
  let videoBytesReceived = 0;
8611
8629
  let transportSent = 0;
@@ -8615,6 +8633,7 @@ class WebRTCClient extends Emitter {
8615
8633
  stats.forEach(report => {
8616
8634
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8617
8635
  audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8636
+ audioContentSent += Number(report.bytesSent);
8618
8637
  }
8619
8638
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8620
8639
  audioBytesSent += Number(report.bytesSent);
@@ -8626,6 +8645,7 @@ class WebRTCClient extends Emitter {
8626
8645
  packetsLost += Number(report.packetsLost);
8627
8646
  networkStats.packetsReceived = Number(report.packetsReceived);
8628
8647
  audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8648
+ audioContentReceived += Number(report.bytesReceived);
8629
8649
  }
8630
8650
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8631
8651
  videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
@@ -8654,10 +8674,17 @@ class WebRTCClient extends Emitter {
8654
8674
  });
8655
8675
 
8656
8676
  networkStats.packetsLost = packetsLost;
8677
+
8657
8678
  networkStats.totalAudioBytesSent = audioBytesSent;
8658
8679
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8659
8680
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8660
8681
  networkStats.audioBytesReceived = audioBytesReceived;
8682
+
8683
+ networkStats.totalAudioContentSent = audioContentSent;
8684
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8685
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8686
+ networkStats.audioContentReceived = audioContentReceived;
8687
+
8661
8688
  networkStats.totalVideoBytesSent = videoBytesSent;
8662
8689
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8663
8690
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -8869,6 +8896,7 @@ class WebRTCPhone extends Emitter {
8869
8896
  constraints,
8870
8897
  audioOnly,
8871
8898
  conference,
8899
+ iceRestart,
8872
8900
  });
8873
8901
 
8874
8902
  if (!sipSession) {
@@ -8972,6 +9000,11 @@ class WebRTCPhone extends Emitter {
8972
9000
 
8973
9001
  this.client.downgradeToAudio(sipSession);
8974
9002
 
9003
+ if (callSession) {
9004
+ callSession.cameraEnabled = false;
9005
+ this._updateCallSession(callSession);
9006
+ }
9007
+
8975
9008
  if (withMessage) {
8976
9009
  this._sendReinviteMessage(callSession, false);
8977
9010
  }
@@ -8999,6 +9032,11 @@ class WebRTCPhone extends Emitter {
8999
9032
 
9000
9033
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
9001
9034
 
9035
+ if (callSession) {
9036
+ callSession.cameraEnabled = true;
9037
+ this._updateCallSession(callSession);
9038
+ }
9039
+
9002
9040
  // If no stream is returned, it means we have to reinvite
9003
9041
  if (!newStream) {
9004
9042
  return true;
@@ -9268,7 +9306,7 @@ class WebRTCPhone extends Emitter {
9268
9306
  }
9269
9307
 
9270
9308
  _onCallAccepted(sipSession , cameraEnabled ) {
9271
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9309
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9272
9310
 
9273
9311
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9274
9312
  this.currentSipSession = sipSession;
@@ -9337,6 +9375,7 @@ class WebRTCPhone extends Emitter {
9337
9375
  _onCallTerminated(sipSession ) {
9338
9376
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9339
9377
 
9378
+ const sipSessionId = this.getSipSessionId(sipSession);
9340
9379
  const callSession = this._createCallSession(sipSession);
9341
9380
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9342
9381
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9354,7 +9393,6 @@ class WebRTCPhone extends Emitter {
9354
9393
  }, 5);
9355
9394
  }
9356
9395
 
9357
- const sipSessionId = this.getSipSessionId(sipSession);
9358
9396
  if (sipSessionId) {
9359
9397
  this.removeIncomingSessions(sipSessionId);
9360
9398
  }
@@ -9780,7 +9818,7 @@ class WebRTCPhone extends Emitter {
9780
9818
  // @TODO: line is not used here
9781
9819
  async makeCall(number , line , cameraEnabled ,
9782
9820
  audioOnly = false, conference = false) {
9783
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9821
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
9784
9822
  if (!number) {
9785
9823
  return Promise.resolve(null);
9786
9824
  }
@@ -9999,8 +10037,12 @@ class WebRTCPhone extends Emitter {
9999
10037
  }
10000
10038
 
10001
10039
  const sessionId = this.incomingSessions[0];
10040
+ const sipSession = this.client.getSipSession(sessionId);
10041
+ if (!sipSession) {
10042
+ return null;
10043
+ }
10002
10044
 
10003
- return this._createCallSession(this.client.getSipSession(sessionId));
10045
+ return this._createCallSession(sipSession);
10004
10046
  }
10005
10047
 
10006
10048
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10141,9 +10183,13 @@ class WebRTCPhone extends Emitter {
10141
10183
  if (this.shouldSendReinvite && this.currentSipSession
10142
10184
  && this.currentSipSession.state === SessionState.Established) {
10143
10185
  this.shouldSendReinvite = false;
10186
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
10187
+ const isConference = pc ? pc.sfu : false;
10188
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
10189
+
10144
10190
  try {
10145
10191
  // Send reinvite with iceRestart
10146
- this.sendReinvite(this.currentCallSession, null, false, false, true);
10192
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
10147
10193
  } catch (e) {
10148
10194
  logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
10149
10195
  }
@@ -10227,6 +10273,15 @@ class WebRTCPhone extends Emitter {
10227
10273
  return this.client.getSipSessionId(sipSession);
10228
10274
  }
10229
10275
 
10276
+ _updateCallSession(callSession ) {
10277
+ const sipSession = this.findSipSession(callSession);
10278
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10279
+
10280
+ if (sipSessionId) {
10281
+ this.callSessions[sipSessionId] = callSession;
10282
+ }
10283
+ }
10284
+
10230
10285
  _onMessage(message ) {
10231
10286
  if (!message || message.method !== 'MESSAGE') {
10232
10287
  return;
@@ -1236,7 +1236,7 @@ class Contact {
1236
1236
  this[key] = old[key] || this[key];
1237
1237
  });
1238
1238
 
1239
- if (old.lineState && !this.lineState) {
1239
+ if (old.lineState) {
1240
1240
  this.lineState = old.lineState;
1241
1241
  }
1242
1242
 
@@ -1951,7 +1951,7 @@ const logger$c = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
1951
1951
 
1952
1952
  // Use a function here to be able to mock it in tests
1953
1953
  const realFetch = () => {
1954
- if (typeof document !== 'undefined') {
1954
+ if (typeof document !== 'undefined' && window.fetch) {
1955
1955
  // Browser
1956
1956
  return window.fetch;
1957
1957
  }
@@ -2630,8 +2630,9 @@ class ExternalApp {
2630
2630
 
2631
2631
 
2632
2632
 
2633
-
2633
+
2634
2634
 
2635
+
2635
2636
 
2636
2637
 
2637
2638
  class Meeting {
@@ -2642,9 +2643,10 @@ class Meeting {
2642
2643
 
2643
2644
 
2644
2645
 
2645
-
2646
+
2646
2647
 
2647
2648
 
2649
+
2648
2650
 
2649
2651
  static parse(plain ) {
2650
2652
  return new Meeting({
@@ -2654,8 +2656,9 @@ class Meeting {
2654
2656
  ownerUuids: plain.owner_uuids,
2655
2657
  port: plain.port,
2656
2658
  uuid: plain.uuid,
2657
- number: plain.number,
2659
+ extension: plain.exten,
2658
2660
  persistent: plain.persistent,
2661
+ creationTime: moment(plain.creation_time).toDate(),
2659
2662
  });
2660
2663
  }
2661
2664
 
@@ -2677,8 +2680,9 @@ class Meeting {
2677
2680
  ownerUuids,
2678
2681
  port,
2679
2682
  uri,
2680
- number,
2683
+ extension,
2681
2684
  persistent,
2685
+ creationTime,
2682
2686
  } = {}) {
2683
2687
  this.guestSipAuthorization = guestSipAuthorization;
2684
2688
  this.uri = uri;
@@ -2686,8 +2690,9 @@ class Meeting {
2686
2690
  this.ownerUuids = ownerUuids;
2687
2691
  this.port = port;
2688
2692
  this.uuid = uuid;
2689
- this.number = number;
2693
+ this.extension = extension;
2690
2694
  this.persistent = persistent;
2695
+ this.creationTime = creationTime;
2691
2696
 
2692
2697
  // Useful to compare instead of instanceof with minified code
2693
2698
  this.type = 'Meeting';
@@ -6057,11 +6062,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
6057
6062
 
6058
6063
  // $FlowFixMe
6059
6064
  setRemoteSessionDescription(sessionDescription ) {
6060
- const result = super.setRemoteSessionDescription(sessionDescription);
6065
+ try {
6066
+ const result = super.setRemoteSessionDescription(sessionDescription);
6061
6067
 
6062
- this.eventEmitter.emit('setDescription', sessionDescription);
6068
+ this.eventEmitter.emit('setDescription', sessionDescription);
6063
6069
 
6064
- return result;
6070
+ return result;
6071
+ } catch (error) {
6072
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
6073
+ throw error;
6074
+ }
6065
6075
  }
6066
6076
 
6067
6077
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -6966,7 +6976,7 @@ class WebRTCClient extends Emitter {
6966
6976
  }
6967
6977
 
6968
6978
  call(number , enableVideo , audioOnly = false, conference = false) {
6969
- logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
6979
+ logger$8.info('sdk webrtc creating call', { number, enableVideo, audioOnly, conference });
6970
6980
  const inviterOptions = {
6971
6981
  sessionDescriptionHandlerOptionsReInvite: {
6972
6982
  conference,
@@ -8042,6 +8052,7 @@ class WebRTCClient extends Emitter {
8042
8052
  const screenSharing = constraints && 'screen' in constraints ? constraints.screen : false;
8043
8053
  const isDesktop = constraints && 'desktop' in constraints ? constraints.desktop : false;
8044
8054
  const withAudio = constraints && 'audio' in constraints ? constraints.audio : true;
8055
+ const mandatoryVideo = constraints && typeof constraints.video === 'object' ? constraints.video.mandatory : {};
8045
8056
 
8046
8057
  logger$8.info('Retrieving media a configuration', { enableVideo, screenSharing, isDesktop, withAudio, constraints });
8047
8058
 
@@ -8049,7 +8060,8 @@ class WebRTCClient extends Emitter {
8049
8060
  constraints: {
8050
8061
  // Exact constraint are not supported with `getDisplayMedia` and we must have a video=false in desktop screenshare
8051
8062
  audio: screenSharing ? !isDesktop : (withAudio ? this._getAudioConstraints() : false),
8052
- video: screenSharing ? (isDesktop ? ({ mandatory: { chromeMediaSource: 'desktop' } }) : { cursor: 'always' })
8063
+ video: screenSharing ? (isDesktop
8064
+ ? ({ mandatory: { chromeMediaSource: 'desktop', ...(mandatoryVideo || {}) } }) : { cursor: 'always' })
8053
8065
  : this._getVideoConstraints(enableVideo),
8054
8066
  screen: screenSharing,
8055
8067
  desktop: isDesktop,
@@ -8384,12 +8396,14 @@ class WebRTCClient extends Emitter {
8384
8396
 
8385
8397
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
8386
8398
 
8387
- pc.oniceconnectionstatechange = () => {
8388
- logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8389
- if (pc.iceConnectionState === 'disconnected') {
8390
- this.eventEmitter.emit(ON_DISCONNECTED$1);
8391
- }
8392
- };
8399
+ if (pc) {
8400
+ pc.oniceconnectionstatechange = () => {
8401
+ logger$8.info('on ice connection state changed', { state: pc.iceConnectionState });
8402
+ if (pc.iceConnectionState === 'disconnected') {
8403
+ this.eventEmitter.emit(ON_DISCONNECTED$1);
8404
+ }
8405
+ };
8406
+ }
8393
8407
 
8394
8408
  if (withEvent) {
8395
8409
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
@@ -8599,13 +8613,17 @@ class WebRTCClient extends Emitter {
8599
8613
  const nbStats = this.sessionNetworkStats[sessionId].length;
8600
8614
  const lastNetworkStats = this.sessionNetworkStats[sessionId][nbStats - 1];
8601
8615
  const lastAudioSent = lastNetworkStats ? lastNetworkStats.audioBytesSent : 0;
8616
+ const lastAudioContentSent = lastNetworkStats ? lastNetworkStats.audioContentSent : 0;
8602
8617
  const lastVideoSent = lastNetworkStats ? lastNetworkStats.videoBytesSent : 0;
8603
8618
  const lastAudioReceived = lastNetworkStats ? lastNetworkStats.audioBytesReceived : 0;
8619
+ const lastAudioContentReceived = lastNetworkStats ? lastNetworkStats.audioContentReceived : 0;
8604
8620
  const lastVideoReceived = lastNetworkStats ? lastNetworkStats.videoBytesReceived : 0;
8605
8621
  const lastTransportSent = lastNetworkStats ? lastNetworkStats.transportSent : 0;
8606
8622
  const lastTransportReceived = lastNetworkStats ? lastNetworkStats.transportReceived : 0;
8607
- let audioBytesSent = 0;
8608
- let audioBytesReceived = 0;
8623
+ let audioBytesSent = 0; // content + header
8624
+ let audioBytesReceived = 0; // content + header
8625
+ let audioContentSent = 0; // useful to detect blank call
8626
+ let audioContentReceived = 0;
8609
8627
  let videoBytesSent = 0;
8610
8628
  let videoBytesReceived = 0;
8611
8629
  let transportSent = 0;
@@ -8615,6 +8633,7 @@ class WebRTCClient extends Emitter {
8615
8633
  stats.forEach(report => {
8616
8634
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
8617
8635
  audioBytesSent += Number(report.bytesSent) + Number(report.headerBytesSent);
8636
+ audioContentSent += Number(report.bytesSent);
8618
8637
  }
8619
8638
  if (report.type === 'remote-outbound-rtp' && report.kind === 'audio') {
8620
8639
  audioBytesSent += Number(report.bytesSent);
@@ -8626,6 +8645,7 @@ class WebRTCClient extends Emitter {
8626
8645
  packetsLost += Number(report.packetsLost);
8627
8646
  networkStats.packetsReceived = Number(report.packetsReceived);
8628
8647
  audioBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
8648
+ audioContentReceived += Number(report.bytesReceived);
8629
8649
  }
8630
8650
  if (report.type === 'inbound-rtp' && report.kind === 'video') {
8631
8651
  videoBytesReceived += Number(report.bytesReceived) + Number(report.headerBytesReceived);
@@ -8654,10 +8674,17 @@ class WebRTCClient extends Emitter {
8654
8674
  });
8655
8675
 
8656
8676
  networkStats.packetsLost = packetsLost;
8677
+
8657
8678
  networkStats.totalAudioBytesSent = audioBytesSent;
8658
8679
  networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
8659
8680
  networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
8660
8681
  networkStats.audioBytesReceived = audioBytesReceived;
8682
+
8683
+ networkStats.totalAudioContentSent = audioContentSent;
8684
+ networkStats.audioContentSent = audioContentSent - lastAudioContentSent;
8685
+ networkStats.totalAudioBytesReceived = audioContentReceived - lastAudioContentReceived;
8686
+ networkStats.audioContentReceived = audioContentReceived;
8687
+
8661
8688
  networkStats.totalVideoBytesSent = videoBytesSent;
8662
8689
  networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
8663
8690
  networkStats.totalVideoBytesReceived = videoBytesReceived;
@@ -8869,6 +8896,7 @@ class WebRTCPhone extends Emitter {
8869
8896
  constraints,
8870
8897
  audioOnly,
8871
8898
  conference,
8899
+ iceRestart,
8872
8900
  });
8873
8901
 
8874
8902
  if (!sipSession) {
@@ -8972,6 +9000,11 @@ class WebRTCPhone extends Emitter {
8972
9000
 
8973
9001
  this.client.downgradeToAudio(sipSession);
8974
9002
 
9003
+ if (callSession) {
9004
+ callSession.cameraEnabled = false;
9005
+ this._updateCallSession(callSession);
9006
+ }
9007
+
8975
9008
  if (withMessage) {
8976
9009
  this._sendReinviteMessage(callSession, false);
8977
9010
  }
@@ -8999,6 +9032,11 @@ class WebRTCPhone extends Emitter {
8999
9032
 
9000
9033
  const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
9001
9034
 
9035
+ if (callSession) {
9036
+ callSession.cameraEnabled = true;
9037
+ this._updateCallSession(callSession);
9038
+ }
9039
+
9002
9040
  // If no stream is returned, it means we have to reinvite
9003
9041
  if (!newStream) {
9004
9042
  return true;
@@ -9268,7 +9306,7 @@ class WebRTCPhone extends Emitter {
9268
9306
  }
9269
9307
 
9270
9308
  _onCallAccepted(sipSession , cameraEnabled ) {
9271
- logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9309
+ logger$7.info('WebRTC phone - on call accepted', { sipId: sipSession.id, cameraEnabled });
9272
9310
 
9273
9311
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
9274
9312
  this.currentSipSession = sipSession;
@@ -9337,6 +9375,7 @@ class WebRTCPhone extends Emitter {
9337
9375
  _onCallTerminated(sipSession ) {
9338
9376
  logger$7.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
9339
9377
 
9378
+ const sipSessionId = this.getSipSessionId(sipSession);
9340
9379
  const callSession = this._createCallSession(sipSession);
9341
9380
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
9342
9381
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -9354,7 +9393,6 @@ class WebRTCPhone extends Emitter {
9354
9393
  }, 5);
9355
9394
  }
9356
9395
 
9357
- const sipSessionId = this.getSipSessionId(sipSession);
9358
9396
  if (sipSessionId) {
9359
9397
  this.removeIncomingSessions(sipSessionId);
9360
9398
  }
@@ -9780,7 +9818,7 @@ class WebRTCPhone extends Emitter {
9780
9818
  // @TODO: line is not used here
9781
9819
  async makeCall(number , line , cameraEnabled ,
9782
9820
  audioOnly = false, conference = false) {
9783
- logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled });
9821
+ logger$7.info('make WebRTC call', { number, lineId: line ? line.id : null, cameraEnabled, audioOnly, conference });
9784
9822
  if (!number) {
9785
9823
  return Promise.resolve(null);
9786
9824
  }
@@ -9999,8 +10037,12 @@ class WebRTCPhone extends Emitter {
9999
10037
  }
10000
10038
 
10001
10039
  const sessionId = this.incomingSessions[0];
10040
+ const sipSession = this.client.getSipSession(sessionId);
10041
+ if (!sipSession) {
10042
+ return null;
10043
+ }
10002
10044
 
10003
- return this._createCallSession(this.client.getSipSession(sessionId));
10045
+ return this._createCallSession(sipSession);
10004
10046
  }
10005
10047
 
10006
10048
  sendMessage(sipSession = null, body , contentType = 'text/plain') {
@@ -10141,9 +10183,13 @@ class WebRTCPhone extends Emitter {
10141
10183
  if (this.shouldSendReinvite && this.currentSipSession
10142
10184
  && this.currentSipSession.state === SessionState.Established) {
10143
10185
  this.shouldSendReinvite = false;
10186
+ const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
10187
+ const isConference = pc ? pc.sfu : false;
10188
+ const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
10189
+
10144
10190
  try {
10145
10191
  // Send reinvite with iceRestart
10146
- this.sendReinvite(this.currentCallSession, null, false, false, true);
10192
+ this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
10147
10193
  } catch (e) {
10148
10194
  logger$7.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
10149
10195
  }
@@ -10227,6 +10273,15 @@ class WebRTCPhone extends Emitter {
10227
10273
  return this.client.getSipSessionId(sipSession);
10228
10274
  }
10229
10275
 
10276
+ _updateCallSession(callSession ) {
10277
+ const sipSession = this.findSipSession(callSession);
10278
+ const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
10279
+
10280
+ if (sipSessionId) {
10281
+ this.callSessions[sipSessionId] = callSession;
10282
+ }
10283
+ }
10284
+
10230
10285
  _onMessage(message ) {
10231
10286
  if (!message || message.method !== 'MESSAGE') {
10232
10287
  return;
@@ -1 +1 @@
1
-
1
+ import 'moment';
@@ -440,7 +440,7 @@ const logger = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
440
440
 
441
441
  // Use a function here to be able to mock it in tests
442
442
  const realFetch = () => {
443
- if (typeof document !== 'undefined') {
443
+ if (typeof document !== 'undefined' && window.fetch) {
444
444
  // Browser
445
445
  return window.fetch;
446
446
  }
@@ -440,7 +440,7 @@ const logger = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
440
440
 
441
441
  // Use a function here to be able to mock it in tests
442
442
  const realFetch = () => {
443
- if (typeof document !== 'undefined') {
443
+ if (typeof document !== 'undefined' && window.fetch) {
444
444
  // Browser
445
445
  return window.fetch;
446
446
  }