@wazo/sdk 0.37.28 → 0.37.32

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 (81) hide show
  1. package/README.md +2 -1
  2. package/dist/wazo-sdk.js +4 -4
  3. package/esm/__tests__/api-client.test.js +30 -0
  4. package/esm/__tests__/web-rtc-client.test.js +65 -6
  5. package/esm/api/calld.js +30 -0
  6. package/esm/api-client.js +30 -0
  7. package/esm/checker/Checker.js +65 -6
  8. package/esm/checker/checks/aor.js +30 -0
  9. package/esm/checker/checks/api.js +30 -0
  10. package/esm/checker/checks/index.js +65 -6
  11. package/esm/checker/checks/webrtc-transport.js +65 -6
  12. package/esm/checker/checks/webrtc.js +65 -6
  13. package/esm/domain/AdHocAPIConference.js +30 -0
  14. package/esm/domain/CallSession.js +15 -3
  15. package/esm/domain/Features.js +30 -0
  16. package/esm/domain/MeetingStatus.js +29 -0
  17. package/esm/domain/Phone/CTIPhone.js +45 -3
  18. package/esm/domain/Phone/WebRTCPhone.js +28 -6
  19. package/esm/domain/__tests__/CallSession.test.js +32 -3
  20. package/esm/domain/__tests__/IndirectTransfer.test.js +15 -3
  21. package/esm/domain/__tests__/Room.test.js +15 -3
  22. package/esm/index.js +93 -12
  23. package/esm/service/CallApi.js +30 -0
  24. package/esm/service/getApiClient.js +30 -0
  25. package/esm/simple/Auth.js +93 -12
  26. package/esm/simple/Configuration.js +93 -12
  27. package/esm/simple/Directory.js +30 -0
  28. package/esm/simple/Phone.js +93 -12
  29. package/esm/simple/index.js +93 -12
  30. package/esm/simple/room/LocalParticipant.js +93 -12
  31. package/esm/simple/room/Participant.js +93 -12
  32. package/esm/simple/room/RemoteParticipant.js +93 -12
  33. package/esm/simple/room/Room.js +93 -12
  34. package/esm/simple/room/SipRoom.js +93 -12
  35. package/esm/simple/room/Stream.js +93 -12
  36. package/esm/simple/room/__tests__/RemoteParticipant.test.js +93 -12
  37. package/esm/simple/utils.js +93 -12
  38. package/esm/web-rtc-client.js +65 -6
  39. package/lib/__tests__/api-client.test.js +30 -0
  40. package/lib/__tests__/web-rtc-client.test.js +65 -6
  41. package/lib/api/calld.js +30 -0
  42. package/lib/api-client.js +30 -0
  43. package/lib/checker/Checker.js +65 -6
  44. package/lib/checker/checks/aor.js +30 -0
  45. package/lib/checker/checks/api.js +30 -0
  46. package/lib/checker/checks/index.js +65 -6
  47. package/lib/checker/checks/webrtc-transport.js +65 -6
  48. package/lib/checker/checks/webrtc.js +65 -6
  49. package/lib/domain/AdHocAPIConference.js +30 -0
  50. package/lib/domain/CallSession.js +15 -3
  51. package/lib/domain/Features.js +30 -0
  52. package/lib/domain/MeetingStatus.js +31 -0
  53. package/lib/domain/Phone/CTIPhone.js +45 -3
  54. package/lib/domain/Phone/WebRTCPhone.js +28 -6
  55. package/lib/domain/__tests__/CallSession.test.js +32 -3
  56. package/lib/domain/__tests__/IndirectTransfer.test.js +15 -3
  57. package/lib/domain/__tests__/Room.test.js +15 -3
  58. package/lib/index.js +93 -12
  59. package/lib/service/CallApi.js +30 -0
  60. package/lib/service/getApiClient.js +30 -0
  61. package/lib/simple/Auth.js +93 -12
  62. package/lib/simple/Configuration.js +93 -12
  63. package/lib/simple/Directory.js +30 -0
  64. package/lib/simple/Phone.js +93 -12
  65. package/lib/simple/index.js +93 -12
  66. package/lib/simple/room/LocalParticipant.js +93 -12
  67. package/lib/simple/room/Participant.js +93 -12
  68. package/lib/simple/room/RemoteParticipant.js +93 -12
  69. package/lib/simple/room/Room.js +93 -12
  70. package/lib/simple/room/SipRoom.js +93 -12
  71. package/lib/simple/room/Stream.js +93 -12
  72. package/lib/simple/room/__tests__/RemoteParticipant.test.js +93 -12
  73. package/lib/simple/utils.js +93 -12
  74. package/lib/web-rtc-client.js +65 -6
  75. package/package.json +1 -1
  76. package/src/api/calld.js +3 -0
  77. package/src/domain/CallSession.js +16 -4
  78. package/src/domain/MeetingStatus.js +27 -0
  79. package/src/domain/Phone/WebRTCPhone.js +13 -3
  80. package/src/domain/__tests__/CallSession.test.js +17 -0
  81. package/src/web-rtc-client.js +35 -6
@@ -3260,6 +3260,7 @@ var updateFrom = (instance , from ) => {
3260
3260
 
3261
3261
 
3262
3262
 
3263
+
3263
3264
 
3264
3265
 
3265
3266
 
@@ -3307,14 +3308,14 @@ class CallSession {
3307
3308
 
3308
3309
 
3309
3310
 
3311
+ // = creationTime
3312
+
3310
3313
 
3311
3314
 
3312
3315
 
3313
3316
 
3314
3317
 
3315
3318
 
3316
-
3317
-
3318
3319
 
3319
3320
 
3320
3321
 
@@ -3378,6 +3379,7 @@ class CallSession {
3378
3379
  recordingPaused,
3379
3380
  videoRemotelyDowngraded,
3380
3381
  sipSession,
3382
+ answerTime,
3381
3383
  } ) {
3382
3384
  this.callId = callId;
3383
3385
  this.sipCallId = sipCallId;
@@ -3405,6 +3407,7 @@ class CallSession {
3405
3407
  this.recordingPaused = recordingPaused || false;
3406
3408
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
3407
3409
  this.sipSession = sipSession;
3410
+ this.answerTime = answerTime || this.answerTime;
3408
3411
 
3409
3412
  // Useful to compare instead of instanceof with minified code
3410
3413
  this.type = 'CallSession';
@@ -3435,7 +3438,7 @@ class CallSession {
3435
3438
  }
3436
3439
 
3437
3440
  answer() {
3438
- this.answered = true;
3441
+ this.answerTime = new Date();
3439
3442
  }
3440
3443
 
3441
3444
  systemAnswer() {
@@ -3591,6 +3594,15 @@ class CallSession {
3591
3594
  return newFrom(callSession, CallSession);
3592
3595
  }
3593
3596
 
3597
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
3598
+ set answered(value ) {
3599
+ this.answerTime = value ? this.answerTime || new Date() : null;
3600
+ }
3601
+
3602
+ get answered() {
3603
+ return !!this.answerTime;
3604
+ }
3605
+
3594
3606
  static parseCall(call ) {
3595
3607
  return new CallSession({
3596
3608
  callId: call.id,
@@ -4842,6 +4854,34 @@ var chatdMethods = (client , baseUrl ) => ({
4842
4854
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4843
4855
  });
4844
4856
 
4857
+ //
4858
+
4859
+
4860
+
4861
+
4862
+
4863
+ class MeetingStatus {
4864
+
4865
+
4866
+
4867
+
4868
+ constructor({
4869
+ full,
4870
+ } = {}) {
4871
+ this.full = full;
4872
+
4873
+ // Useful to compare instead of instanceof with minified code
4874
+ this.type = 'MeetingStatus';
4875
+ }
4876
+
4877
+ static parse(plain ) {
4878
+ return new MeetingStatus({
4879
+ full: plain.full,
4880
+ });
4881
+ }
4882
+
4883
+ }
4884
+
4845
4885
  /* */
4846
4886
 
4847
4887
 
@@ -5036,6 +5076,8 @@ var calldMethods = (client , baseUrl ) => ({
5036
5076
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
5037
5077
  ApiRequester.successResponseParser),
5038
5078
 
5079
+ guestGetMeetingStatus: (meetingUuid ) =>
5080
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
5039
5081
  });
5040
5082
 
5041
5083
  //
@@ -6637,6 +6679,7 @@ const MAX_REGISTER_TRIES = 10;
6637
6679
 
6638
6680
 
6639
6681
 
6682
+
6640
6683
 
6641
6684
 
6642
6685
 
@@ -6678,6 +6721,7 @@ class WebRTCClient extends Emitter {
6678
6721
 
6679
6722
 
6680
6723
 
6724
+
6681
6725
 
6682
6726
  // sugar
6683
6727
 
@@ -6740,6 +6784,7 @@ class WebRTCClient extends Emitter {
6740
6784
  this.conferences = {};
6741
6785
  this.networkMonitoringInterval = {};
6742
6786
  this.sessionNetworkStats = {};
6787
+ this.forceClosed = false;
6743
6788
 
6744
6789
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
6745
6790
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -6861,6 +6906,8 @@ class WebRTCClient extends Emitter {
6861
6906
  skipRegister: this.skipRegister,
6862
6907
  };
6863
6908
 
6909
+ this.forceClosed = false;
6910
+
6864
6911
  if (this.skipRegister) {
6865
6912
  logger$8.info('sdk webrtc skip register...', logInfo);
6866
6913
  return Promise.resolve();
@@ -6885,7 +6932,15 @@ class WebRTCClient extends Emitter {
6885
6932
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
6886
6933
 
6887
6934
  const onRegisterFailed = () => {
6888
- logger$8.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
6935
+ logger$8.info('sdk webrtc registering failed', {
6936
+ tries,
6937
+ registerer: !!this.registerer,
6938
+ forceClosed: this.forceClosed,
6939
+ });
6940
+ if (this.forceClosed) {
6941
+ return;
6942
+ }
6943
+
6889
6944
  this.connectionPromise = null;
6890
6945
  if (this.registerer && this.registerer.waiting) {
6891
6946
  this.registerer.waitingToggle(false);
@@ -7163,8 +7218,9 @@ class WebRTCClient extends Emitter {
7163
7218
  }
7164
7219
  }
7165
7220
 
7166
- async close() {
7167
- logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
7221
+ async close(force = false) {
7222
+ logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
7223
+ this.forceClosed = force;
7168
7224
  this._cleanupMedia();
7169
7225
  this.connectionPromise = null;
7170
7226
 
@@ -7183,7 +7239,7 @@ class WebRTCClient extends Emitter {
7183
7239
  this.userAgent.delegate = null;
7184
7240
  this.userAgent.stateChange.removeAllListeners();
7185
7241
 
7186
- await this._disconnectTransport();
7242
+ await this._disconnectTransport(force);
7187
7243
 
7188
7244
  this._cleanupRegister();
7189
7245
 
@@ -8253,6 +8309,13 @@ class WebRTCClient extends Emitter {
8253
8309
  }
8254
8310
 
8255
8311
  _createWebRTCConfiguration(configOverrides = {}) {
8312
+ let { host } = this.config;
8313
+ let port = this.config.port || 443;
8314
+
8315
+ if (this.config.websocketSip) {
8316
+ [host, port = 443] = this.config.websocketSip.split(':');
8317
+ }
8318
+
8256
8319
  const config = {
8257
8320
  authorizationUsername: this.config.authorizationUser,
8258
8321
  authorizationPassword: this.config.password,
@@ -8288,7 +8351,7 @@ class WebRTCClient extends Emitter {
8288
8351
  },
8289
8352
  transportOptions: {
8290
8353
  traceSip: configOverrides.traceSip || false,
8291
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
8354
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
8292
8355
  },
8293
8356
  sessionDescriptionHandlerFactoryOptions: {
8294
8357
  modifiers: [replaceLocalIpModifier],
@@ -8612,7 +8675,15 @@ class WebRTCClient extends Emitter {
8612
8675
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
8613
8676
  }
8614
8677
 
8615
- async _disconnectTransport() {
8678
+ async _disconnectTransport(force = false) {
8679
+ if (force) {
8680
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
8681
+ this.userAgent.transport.disconnectResolve = () => {};
8682
+ // eslint-disable-next-line
8683
+ this.userAgent.transport._ws.close(1000);
8684
+ return;
8685
+ }
8686
+
8616
8687
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
8617
8688
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
8618
8689
  try {
@@ -9348,6 +9419,8 @@ class WebRTCPhone extends Emitter {
9348
9419
  this.removeIncomingSessions(sipSessionId);
9349
9420
  }
9350
9421
 
9422
+ callSession.answerTime = new Date();
9423
+ this._updateCallSession(callSession);
9351
9424
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
9352
9425
 
9353
9426
  return callSession;
@@ -9563,6 +9636,8 @@ class WebRTCPhone extends Emitter {
9563
9636
  }
9564
9637
 
9565
9638
  this.shouldSendReinvite = false;
9639
+ callSession.answerTime = new Date();
9640
+ this._updateCallSession(callSession);
9566
9641
  this.acceptedSessions[callSession.getId()] = true;
9567
9642
 
9568
9643
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -9662,7 +9737,7 @@ class WebRTCPhone extends Emitter {
9662
9737
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
9663
9738
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
9664
9739
  logger$7.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
9665
- this.holdSipSession(this.currentSipSession, callSession);
9740
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
9666
9741
  }
9667
9742
 
9668
9743
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -9873,6 +9948,7 @@ class WebRTCPhone extends Emitter {
9873
9948
  }
9874
9949
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
9875
9950
  callSession.creationTime = new Date();
9951
+ this._updateCallSession(callSession);
9876
9952
 
9877
9953
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
9878
9954
 
@@ -10014,7 +10090,7 @@ class WebRTCPhone extends Emitter {
10014
10090
  return this.client && this.client.isConference(callSession.sipCallId);
10015
10091
  }
10016
10092
 
10017
- async close() {
10093
+ async close(force = false) {
10018
10094
  logger$7.info('WebRTC close');
10019
10095
 
10020
10096
  try {
@@ -10026,7 +10102,7 @@ class WebRTCPhone extends Emitter {
10026
10102
  logger$7.error('WebRTC close, unregister error', e);
10027
10103
  }
10028
10104
 
10029
- this.client.close();
10105
+ this.client.close(force);
10030
10106
  this.unbind();
10031
10107
 
10032
10108
  this.incomingSessions = [];
@@ -10152,6 +10228,8 @@ class WebRTCPhone extends Emitter {
10152
10228
  }
10153
10229
 
10154
10230
  callSession.creationTime = new Date();
10231
+ this._updateCallSession(callSession);
10232
+
10155
10233
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
10156
10234
  });
10157
10235
 
@@ -10195,6 +10273,8 @@ class WebRTCPhone extends Emitter {
10195
10273
  logger$7.info('WebRTC call rejected', session.id);
10196
10274
  const callSession = this._createCallSession(session);
10197
10275
  callSession.endTime = new Date();
10276
+ this._updateCallSession(callSession);
10277
+
10198
10278
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
10199
10279
  });
10200
10280
 
@@ -10419,6 +10499,7 @@ class WebRTCPhone extends Emitter {
10419
10499
  displayName: identity ? identity.displayName || number : number,
10420
10500
  startTime: fromSession ? fromSession.startTime : new Date(),
10421
10501
  creationTime: fromSession ? fromSession.creationTime : null,
10502
+ answerTime: fromSession ? fromSession.answerTime : null,
10422
10503
  endTime: fromSession ? fromSession.endTime : null,
10423
10504
  answered: state === sessionState.SessionState.Established,
10424
10505
  paused: this.client.isCallHeld(sipSession),
@@ -4590,6 +4590,34 @@ var chatdMethods = (client , baseUrl ) => ({
4590
4590
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4591
4591
  });
4592
4592
 
4593
+ //
4594
+
4595
+
4596
+
4597
+
4598
+
4599
+ class MeetingStatus {
4600
+
4601
+
4602
+
4603
+
4604
+ constructor({
4605
+ full,
4606
+ } = {}) {
4607
+ this.full = full;
4608
+
4609
+ // Useful to compare instead of instanceof with minified code
4610
+ this.type = 'MeetingStatus';
4611
+ }
4612
+
4613
+ static parse(plain ) {
4614
+ return new MeetingStatus({
4615
+ full: plain.full,
4616
+ });
4617
+ }
4618
+
4619
+ }
4620
+
4593
4621
  /* */
4594
4622
 
4595
4623
 
@@ -4784,6 +4812,8 @@ var calldMethods = (client , baseUrl ) => ({
4784
4812
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4785
4813
  ApiRequester.successResponseParser),
4786
4814
 
4815
+ guestGetMeetingStatus: (meetingUuid ) =>
4816
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4787
4817
  });
4788
4818
 
4789
4819
  //
@@ -5358,6 +5388,7 @@ const MAX_REGISTER_TRIES = 10;
5358
5388
 
5359
5389
 
5360
5390
 
5391
+
5361
5392
 
5362
5393
 
5363
5394
 
@@ -5399,6 +5430,7 @@ class WebRTCClient extends Emitter {
5399
5430
 
5400
5431
 
5401
5432
 
5433
+
5402
5434
 
5403
5435
  // sugar
5404
5436
 
@@ -5461,6 +5493,7 @@ class WebRTCClient extends Emitter {
5461
5493
  this.conferences = {};
5462
5494
  this.networkMonitoringInterval = {};
5463
5495
  this.sessionNetworkStats = {};
5496
+ this.forceClosed = false;
5464
5497
 
5465
5498
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
5466
5499
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -5582,6 +5615,8 @@ class WebRTCClient extends Emitter {
5582
5615
  skipRegister: this.skipRegister,
5583
5616
  };
5584
5617
 
5618
+ this.forceClosed = false;
5619
+
5585
5620
  if (this.skipRegister) {
5586
5621
  logger.info('sdk webrtc skip register...', logInfo);
5587
5622
  return Promise.resolve();
@@ -5606,7 +5641,15 @@ class WebRTCClient extends Emitter {
5606
5641
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
5607
5642
 
5608
5643
  const onRegisterFailed = () => {
5609
- logger.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
5644
+ logger.info('sdk webrtc registering failed', {
5645
+ tries,
5646
+ registerer: !!this.registerer,
5647
+ forceClosed: this.forceClosed,
5648
+ });
5649
+ if (this.forceClosed) {
5650
+ return;
5651
+ }
5652
+
5610
5653
  this.connectionPromise = null;
5611
5654
  if (this.registerer && this.registerer.waiting) {
5612
5655
  this.registerer.waitingToggle(false);
@@ -5884,8 +5927,9 @@ class WebRTCClient extends Emitter {
5884
5927
  }
5885
5928
  }
5886
5929
 
5887
- async close() {
5888
- logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
5930
+ async close(force = false) {
5931
+ logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
5932
+ this.forceClosed = force;
5889
5933
  this._cleanupMedia();
5890
5934
  this.connectionPromise = null;
5891
5935
 
@@ -5904,7 +5948,7 @@ class WebRTCClient extends Emitter {
5904
5948
  this.userAgent.delegate = null;
5905
5949
  this.userAgent.stateChange.removeAllListeners();
5906
5950
 
5907
- await this._disconnectTransport();
5951
+ await this._disconnectTransport(force);
5908
5952
 
5909
5953
  this._cleanupRegister();
5910
5954
 
@@ -6974,6 +7018,13 @@ class WebRTCClient extends Emitter {
6974
7018
  }
6975
7019
 
6976
7020
  _createWebRTCConfiguration(configOverrides = {}) {
7021
+ let { host } = this.config;
7022
+ let port = this.config.port || 443;
7023
+
7024
+ if (this.config.websocketSip) {
7025
+ [host, port = 443] = this.config.websocketSip.split(':');
7026
+ }
7027
+
6977
7028
  const config = {
6978
7029
  authorizationUsername: this.config.authorizationUser,
6979
7030
  authorizationPassword: this.config.password,
@@ -7009,7 +7060,7 @@ class WebRTCClient extends Emitter {
7009
7060
  },
7010
7061
  transportOptions: {
7011
7062
  traceSip: configOverrides.traceSip || false,
7012
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
7063
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
7013
7064
  },
7014
7065
  sessionDescriptionHandlerFactoryOptions: {
7015
7066
  modifiers: [replaceLocalIpModifier],
@@ -7333,7 +7384,15 @@ class WebRTCClient extends Emitter {
7333
7384
  return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
7334
7385
  }
7335
7386
 
7336
- async _disconnectTransport() {
7387
+ async _disconnectTransport(force = false) {
7388
+ if (force) {
7389
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
7390
+ this.userAgent.transport.disconnectResolve = () => {};
7391
+ // eslint-disable-next-line
7392
+ this.userAgent.transport._ws.close(1000);
7393
+ return;
7394
+ }
7395
+
7337
7396
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
7338
7397
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
7339
7398
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "0.37.28",
3
+ "version": "0.37.32",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "dist/wazo-sdk.js",
6
6
  "author": "Wazo (http://wazo.io)",
package/src/api/calld.js CHANGED
@@ -7,6 +7,7 @@ import ChatMessage from '../domain/ChatMessage';
7
7
  import Voicemail from '../domain/Voicemail';
8
8
  import Call from '../domain/Call';
9
9
  import IndirectTransfer from '../domain/IndirectTransfer';
10
+ import MeetingStatus from '../domain/MeetingStatus';
10
11
 
11
12
  type CallQuery = {
12
13
  from_mobile: boolean,
@@ -200,4 +201,6 @@ export default (client: ApiRequester, baseUrl: string) => ({
200
201
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
201
202
  ApiRequester.successResponseParser),
202
203
 
204
+ guestGetMeetingStatus: (meetingUuid: string): Promise<MeetingStatus> =>
205
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
203
206
  });
@@ -8,6 +8,7 @@ import updateFrom from '../utils/update-from';
8
8
 
9
9
  type CallSessionArguments = {
10
10
  answered: boolean,
11
+ answerTime?: ?Date,
11
12
  answeredBySystem: boolean,
12
13
  call: ?Call,
13
14
  callId: string,
@@ -55,14 +56,14 @@ export default class CallSession {
55
56
 
56
57
  creationTime: ?Date;
57
58
 
58
- startTime: number;
59
+ startTime: number; // = creationTime
60
+
61
+ answerTime: ?Date;
59
62
 
60
63
  endTime: ?Date;
61
64
 
62
65
  isCaller: boolean;
63
66
 
64
- answered: boolean;
65
-
66
67
  answeredBySystem: boolean;
67
68
 
68
69
  dialedExtension: string;
@@ -126,6 +127,7 @@ export default class CallSession {
126
127
  recordingPaused,
127
128
  videoRemotelyDowngraded,
128
129
  sipSession,
130
+ answerTime,
129
131
  }: CallSessionArguments) {
130
132
  this.callId = callId;
131
133
  this.sipCallId = sipCallId;
@@ -153,6 +155,7 @@ export default class CallSession {
153
155
  this.recordingPaused = recordingPaused || false;
154
156
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
155
157
  this.sipSession = sipSession;
158
+ this.answerTime = answerTime || this.answerTime;
156
159
 
157
160
  // Useful to compare instead of instanceof with minified code
158
161
  this.type = 'CallSession';
@@ -183,7 +186,7 @@ export default class CallSession {
183
186
  }
184
187
 
185
188
  answer() {
186
- this.answered = true;
189
+ this.answerTime = new Date();
187
190
  }
188
191
 
189
192
  systemAnswer() {
@@ -339,6 +342,15 @@ export default class CallSession {
339
342
  return newFrom(callSession, CallSession);
340
343
  }
341
344
 
345
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
346
+ set answered(value: boolean) {
347
+ this.answerTime = value ? this.answerTime || new Date() : null;
348
+ }
349
+
350
+ get answered(): boolean {
351
+ return !!this.answerTime;
352
+ }
353
+
342
354
  static parseCall(call: Call): CallSession {
343
355
  return new CallSession({
344
356
  callId: call.id,
@@ -0,0 +1,27 @@
1
+ // @flow
2
+
3
+ export type MeetingStatusResponse = {
4
+ full: boolean
5
+ };
6
+
7
+ export default class MeetingStatus {
8
+ type: string;
9
+
10
+ full: boolean;
11
+
12
+ constructor({
13
+ full,
14
+ }: Object = {}) {
15
+ this.full = full;
16
+
17
+ // Useful to compare instead of instanceof with minified code
18
+ this.type = 'MeetingStatus';
19
+ }
20
+
21
+ static parse(plain: MeetingStatusResponse): MeetingStatus {
22
+ return new MeetingStatus({
23
+ full: plain.full,
24
+ });
25
+ }
26
+
27
+ }
@@ -630,6 +630,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
630
630
  this.removeIncomingSessions(sipSessionId);
631
631
  }
632
632
 
633
+ callSession.answerTime = new Date();
634
+ this._updateCallSession(callSession);
633
635
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
634
636
 
635
637
  return callSession;
@@ -845,6 +847,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
845
847
  }
846
848
 
847
849
  this.shouldSendReinvite = false;
850
+ callSession.answerTime = new Date();
851
+ this._updateCallSession(callSession);
848
852
  this.acceptedSessions[callSession.getId()] = true;
849
853
 
850
854
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -944,7 +948,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
944
948
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
945
949
  if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
946
950
  logger.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
947
- this.holdSipSession(this.currentSipSession, callSession);
951
+ this.holdSipSession(this.currentSipSession, this.currentCallSession);
948
952
  }
949
953
 
950
954
  const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
@@ -1155,6 +1159,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1155
1159
  }
1156
1160
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
1157
1161
  callSession.creationTime = new Date();
1162
+ this._updateCallSession(callSession);
1158
1163
 
1159
1164
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
1160
1165
 
@@ -1296,7 +1301,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1296
1301
  return this.client && this.client.isConference(callSession.sipCallId);
1297
1302
  }
1298
1303
 
1299
- async close(): Promise<void> {
1304
+ async close(force: boolean = false): Promise<void> {
1300
1305
  logger.info('WebRTC close');
1301
1306
 
1302
1307
  try {
@@ -1308,7 +1313,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1308
1313
  logger.error('WebRTC close, unregister error', e);
1309
1314
  }
1310
1315
 
1311
- this.client.close();
1316
+ this.client.close(force);
1312
1317
  this.unbind();
1313
1318
 
1314
1319
  this.incomingSessions = [];
@@ -1434,6 +1439,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
1434
1439
  }
1435
1440
 
1436
1441
  callSession.creationTime = new Date();
1442
+ this._updateCallSession(callSession);
1443
+
1437
1444
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
1438
1445
  });
1439
1446
 
@@ -1477,6 +1484,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
1477
1484
  logger.info('WebRTC call rejected', session.id);
1478
1485
  const callSession = this._createCallSession(session);
1479
1486
  callSession.endTime = new Date();
1487
+ this._updateCallSession(callSession);
1488
+
1480
1489
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
1481
1490
  });
1482
1491
 
@@ -1703,6 +1712,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1703
1712
  displayName: identity ? identity.displayName || number : number,
1704
1713
  startTime: fromSession ? fromSession.startTime : new Date(),
1705
1714
  creationTime: fromSession ? fromSession.creationTime : null,
1715
+ answerTime: fromSession ? fromSession.answerTime : null,
1706
1716
  endTime: fromSession ? fromSession.endTime : null,
1707
1717
  answered: state === SessionState.Established,
1708
1718
  paused: this.client.isCallHeld(sipSession),
@@ -37,4 +37,21 @@ describe('CallSession domain', () => {
37
37
  expect(cs1.is(cs2)).toBeTruthy();
38
38
  expect(cs2.is(cs1)).toBeTruthy();
39
39
  });
40
+
41
+ it('should set answerTime when setting answered', () => {
42
+ const cs1 = new CallSession({});
43
+ cs1.answered = true;
44
+
45
+ const cs2 = new CallSession({});
46
+ cs2.answer();
47
+
48
+ const cs3 = new CallSession({ answered: true });
49
+
50
+ expect(cs1.answered).toBeTruthy();
51
+ expect(cs1.answerTime).not.toBeNull();
52
+ expect(cs2.answered).toBeTruthy();
53
+ expect(cs2.answerTime).not.toBeNull();
54
+ expect(cs3.answered).toBeTruthy();
55
+ expect(cs3.answerTime).not.toBeNull();
56
+ });
40
57
  });