@wazo/sdk 0.37.31 → 0.37.35

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 (90) hide show
  1. package/dist/wazo-sdk.js +2 -2
  2. package/esm/__tests__/api-client.test.js +41 -0
  3. package/esm/__tests__/web-rtc-client.test.js +68 -6
  4. package/esm/api/auth.js +5 -0
  5. package/esm/api/call-logd.js +6 -0
  6. package/esm/api/calld.js +30 -0
  7. package/esm/api-client.js +41 -0
  8. package/esm/checker/Checker.js +68 -6
  9. package/esm/checker/checks/aor.js +41 -0
  10. package/esm/checker/checks/api.js +41 -0
  11. package/esm/checker/checks/index.js +68 -6
  12. package/esm/checker/checks/webrtc-transport.js +68 -6
  13. package/esm/checker/checks/webrtc.js +68 -6
  14. package/esm/domain/AdHocAPIConference.js +41 -0
  15. package/esm/domain/CallLog.js +6 -0
  16. package/esm/domain/CallSession.js +8 -0
  17. package/esm/domain/Features.js +41 -0
  18. package/esm/domain/MeetingStatus.js +29 -0
  19. package/esm/domain/Phone/CTIPhone.js +49 -0
  20. package/esm/domain/Phone/WebRTCPhone.js +33 -6
  21. package/esm/domain/__tests__/CallLog.test.js +6 -0
  22. package/esm/domain/__tests__/CallSession.test.js +40 -4
  23. package/esm/domain/__tests__/IndirectTransfer.test.js +8 -0
  24. package/esm/domain/__tests__/Room.test.js +8 -0
  25. package/esm/index.js +101 -12
  26. package/esm/service/CallApi.js +41 -0
  27. package/esm/service/getApiClient.js +41 -0
  28. package/esm/simple/Auth.js +101 -12
  29. package/esm/simple/Configuration.js +101 -12
  30. package/esm/simple/Directory.js +41 -0
  31. package/esm/simple/Phone.js +101 -12
  32. package/esm/simple/index.js +101 -12
  33. package/esm/simple/room/LocalParticipant.js +101 -12
  34. package/esm/simple/room/Participant.js +101 -12
  35. package/esm/simple/room/RemoteParticipant.js +101 -12
  36. package/esm/simple/room/Room.js +101 -12
  37. package/esm/simple/room/SipRoom.js +101 -12
  38. package/esm/simple/room/Stream.js +101 -12
  39. package/esm/simple/room/__tests__/RemoteParticipant.test.js +101 -12
  40. package/esm/simple/utils.js +101 -12
  41. package/esm/web-rtc-client.js +68 -6
  42. package/lib/__tests__/api-client.test.js +41 -0
  43. package/lib/__tests__/web-rtc-client.test.js +68 -6
  44. package/lib/api/auth.js +5 -0
  45. package/lib/api/call-logd.js +6 -0
  46. package/lib/api/calld.js +30 -0
  47. package/lib/api-client.js +41 -0
  48. package/lib/checker/Checker.js +68 -6
  49. package/lib/checker/checks/aor.js +41 -0
  50. package/lib/checker/checks/api.js +41 -0
  51. package/lib/checker/checks/index.js +68 -6
  52. package/lib/checker/checks/webrtc-transport.js +68 -6
  53. package/lib/checker/checks/webrtc.js +68 -6
  54. package/lib/domain/AdHocAPIConference.js +41 -0
  55. package/lib/domain/CallLog.js +6 -0
  56. package/lib/domain/CallSession.js +8 -0
  57. package/lib/domain/Features.js +41 -0
  58. package/lib/domain/MeetingStatus.js +31 -0
  59. package/lib/domain/Phone/CTIPhone.js +49 -0
  60. package/lib/domain/Phone/WebRTCPhone.js +33 -6
  61. package/lib/domain/__tests__/CallLog.test.js +6 -0
  62. package/lib/domain/__tests__/CallSession.test.js +40 -4
  63. package/lib/domain/__tests__/IndirectTransfer.test.js +8 -0
  64. package/lib/domain/__tests__/Room.test.js +8 -0
  65. package/lib/index.js +101 -12
  66. package/lib/service/CallApi.js +41 -0
  67. package/lib/service/getApiClient.js +41 -0
  68. package/lib/simple/Auth.js +101 -12
  69. package/lib/simple/Configuration.js +101 -12
  70. package/lib/simple/Directory.js +41 -0
  71. package/lib/simple/Phone.js +101 -12
  72. package/lib/simple/index.js +101 -12
  73. package/lib/simple/room/LocalParticipant.js +101 -12
  74. package/lib/simple/room/Participant.js +101 -12
  75. package/lib/simple/room/RemoteParticipant.js +101 -12
  76. package/lib/simple/room/Room.js +101 -12
  77. package/lib/simple/room/SipRoom.js +101 -12
  78. package/lib/simple/room/Stream.js +101 -12
  79. package/lib/simple/room/__tests__/RemoteParticipant.test.js +101 -12
  80. package/lib/simple/utils.js +101 -12
  81. package/lib/web-rtc-client.js +68 -6
  82. package/package.json +1 -1
  83. package/src/api/auth.js +5 -0
  84. package/src/api/calld.js +3 -0
  85. package/src/domain/CallLog.js +6 -0
  86. package/src/domain/CallSession.js +8 -0
  87. package/src/domain/MeetingStatus.js +27 -0
  88. package/src/domain/Phone/WebRTCPhone.js +25 -6
  89. package/src/domain/__tests__/CallSession.test.js +32 -4
  90. package/src/web-rtc-client.js +27 -6
@@ -2745,6 +2745,7 @@ var authMethods = (client , baseUrl ) => ({
2745
2745
 
2746
2746
 
2747
2747
 
2748
+
2748
2749
  ) {
2749
2750
  const body = {
2750
2751
  backend: params.backend || DEFAULT_BACKEND_USER,
@@ -2764,6 +2765,10 @@ var authMethods = (client , baseUrl ) => ({
2764
2765
  headers['Wazo-Session-Type'] = 'mobile';
2765
2766
  }
2766
2767
 
2768
+ if (params.tenantId) {
2769
+ body.tenant_id = params.tenantId;
2770
+ }
2771
+
2767
2772
  return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
2768
2773
  },
2769
2774
 
@@ -3832,11 +3837,13 @@ class Recording {
3832
3837
 
3833
3838
 
3834
3839
 
3840
+
3835
3841
 
3836
3842
 
3837
3843
 
3838
3844
 
3839
3845
 
3846
+
3840
3847
 
3841
3848
 
3842
3849
 
@@ -3857,10 +3864,12 @@ class Recording {
3857
3864
 
3858
3865
 
3859
3866
 
3867
+
3860
3868
 
3861
3869
 
3862
3870
 
3863
3871
 
3872
+
3864
3873
 
3865
3874
 
3866
3875
 
@@ -3922,10 +3931,12 @@ class CallLog {
3922
3931
  || plain.destination_extension
3923
3932
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3924
3933
  name: plain.requested_name || plain.destination_name || '',
3934
+ uuid: plain.destination_user_uuid,
3925
3935
  },
3926
3936
  source: {
3927
3937
  extension: plain.source_extension,
3928
3938
  name: plain.source_name,
3939
+ uuid: plain.source_user_uuid,
3929
3940
  },
3930
3941
  id: plain.id,
3931
3942
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -4579,6 +4590,34 @@ var chatdMethods = (client , baseUrl ) => ({
4579
4590
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4580
4591
  });
4581
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
+
4582
4621
  /* */
4583
4622
 
4584
4623
 
@@ -4773,6 +4812,8 @@ var calldMethods = (client , baseUrl ) => ({
4773
4812
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4774
4813
  ApiRequester.successResponseParser),
4775
4814
 
4815
+ guestGetMeetingStatus: (meetingUuid ) =>
4816
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4776
4817
  });
4777
4818
 
4778
4819
  //
@@ -5332,7 +5373,7 @@ const ON_NETWORK_STATS = 'onNetworkStats';
5332
5373
  const ON_DISCONNECTED = 'onDisconnected';
5333
5374
  class CanceledCallError extends Error {}
5334
5375
 
5335
- const MAX_REGISTER_TRIES = 10;
5376
+ const MAX_REGISTER_TRIES = 5;
5336
5377
 
5337
5378
 
5338
5379
 
@@ -5386,6 +5427,7 @@ class WebRTCClient extends Emitter {
5386
5427
 
5387
5428
 
5388
5429
 
5430
+
5389
5431
 
5390
5432
  // sugar
5391
5433
 
@@ -5448,6 +5490,7 @@ class WebRTCClient extends Emitter {
5448
5490
  this.conferences = {};
5449
5491
  this.networkMonitoringInterval = {};
5450
5492
  this.sessionNetworkStats = {};
5493
+ this.forceClosed = false;
5451
5494
 
5452
5495
  this._boundOnHeartbeat = this._onHeartbeat.bind(this);
5453
5496
  this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
@@ -5569,6 +5612,8 @@ class WebRTCClient extends Emitter {
5569
5612
  skipRegister: this.skipRegister,
5570
5613
  };
5571
5614
 
5615
+ this.forceClosed = false;
5616
+
5572
5617
  if (this.skipRegister) {
5573
5618
  logger.info('sdk webrtc skip register...', logInfo);
5574
5619
  return Promise.resolve();
@@ -5593,7 +5638,15 @@ class WebRTCClient extends Emitter {
5593
5638
  const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
5594
5639
 
5595
5640
  const onRegisterFailed = () => {
5596
- logger.info('sdk webrtc registering failed', { tries, registerer: !!this.registerer });
5641
+ logger.info('sdk webrtc registering failed', {
5642
+ tries,
5643
+ registerer: !!this.registerer,
5644
+ forceClosed: this.forceClosed,
5645
+ });
5646
+ if (this.forceClosed) {
5647
+ return;
5648
+ }
5649
+
5597
5650
  this.connectionPromise = null;
5598
5651
  if (this.registerer && this.registerer.waiting) {
5599
5652
  this.registerer.waitingToggle(false);
@@ -5871,8 +5924,9 @@ class WebRTCClient extends Emitter {
5871
5924
  }
5872
5925
  }
5873
5926
 
5874
- async close() {
5875
- logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
5927
+ async close(force = false) {
5928
+ logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
5929
+ this.forceClosed = force;
5876
5930
  this._cleanupMedia();
5877
5931
  this.connectionPromise = null;
5878
5932
 
@@ -5891,7 +5945,7 @@ class WebRTCClient extends Emitter {
5891
5945
  this.userAgent.delegate = null;
5892
5946
  this.userAgent.stateChange.removeAllListeners();
5893
5947
 
5894
- await this._disconnectTransport();
5948
+ await this._disconnectTransport(force);
5895
5949
 
5896
5950
  this._cleanupRegister();
5897
5951
 
@@ -7327,7 +7381,15 @@ class WebRTCClient extends Emitter {
7327
7381
  return UserAgent.makeURI(`sip:${target}@${this.config.host}`);
7328
7382
  }
7329
7383
 
7330
- async _disconnectTransport() {
7384
+ async _disconnectTransport(force = false) {
7385
+ if (force) {
7386
+ // Bypass sip.js state machine that prevent to close WS with the state `Connecting`
7387
+ this.userAgent.transport.disconnectResolve = () => {};
7388
+ // eslint-disable-next-line
7389
+ this.userAgent.transport._ws.close(1000);
7390
+ return;
7391
+ }
7392
+
7331
7393
  // Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
7332
7394
  if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
7333
7395
  try {
@@ -2406,6 +2406,7 @@ var authMethods = (client , baseUrl ) => ({
2406
2406
 
2407
2407
 
2408
2408
 
2409
+
2409
2410
  ) {
2410
2411
  const body = {
2411
2412
  backend: params.backend || DEFAULT_BACKEND_USER,
@@ -2425,6 +2426,10 @@ var authMethods = (client , baseUrl ) => ({
2425
2426
  headers['Wazo-Session-Type'] = 'mobile';
2426
2427
  }
2427
2428
 
2429
+ if (params.tenantId) {
2430
+ body.tenant_id = params.tenantId;
2431
+ }
2432
+
2428
2433
  return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
2429
2434
  },
2430
2435
 
@@ -3284,11 +3289,13 @@ class Recording {
3284
3289
 
3285
3290
 
3286
3291
 
3292
+
3287
3293
 
3288
3294
 
3289
3295
 
3290
3296
 
3291
3297
 
3298
+
3292
3299
 
3293
3300
 
3294
3301
 
@@ -3309,10 +3316,12 @@ class Recording {
3309
3316
 
3310
3317
 
3311
3318
 
3319
+
3312
3320
 
3313
3321
 
3314
3322
 
3315
3323
 
3324
+
3316
3325
 
3317
3326
 
3318
3327
 
@@ -3374,10 +3383,12 @@ class CallLog {
3374
3383
  || plain.destination_extension
3375
3384
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3376
3385
  name: plain.requested_name || plain.destination_name || '',
3386
+ uuid: plain.destination_user_uuid,
3377
3387
  },
3378
3388
  source: {
3379
3389
  extension: plain.source_extension,
3380
3390
  name: plain.source_name,
3391
+ uuid: plain.source_user_uuid,
3381
3392
  },
3382
3393
  id: plain.id,
3383
3394
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -4016,6 +4027,34 @@ var chatdMethods = (client , baseUrl ) => ({
4016
4027
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4017
4028
  });
4018
4029
 
4030
+ //
4031
+
4032
+
4033
+
4034
+
4035
+
4036
+ class MeetingStatus {
4037
+
4038
+
4039
+
4040
+
4041
+ constructor({
4042
+ full,
4043
+ } = {}) {
4044
+ this.full = full;
4045
+
4046
+ // Useful to compare instead of instanceof with minified code
4047
+ this.type = 'MeetingStatus';
4048
+ }
4049
+
4050
+ static parse(plain ) {
4051
+ return new MeetingStatus({
4052
+ full: plain.full,
4053
+ });
4054
+ }
4055
+
4056
+ }
4057
+
4019
4058
  /* */
4020
4059
 
4021
4060
 
@@ -4210,6 +4249,8 @@ var calldMethods = (client , baseUrl ) => ({
4210
4249
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4211
4250
  ApiRequester.successResponseParser),
4212
4251
 
4252
+ guestGetMeetingStatus: (meetingUuid ) =>
4253
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4213
4254
  });
4214
4255
 
4215
4256
  //
@@ -87,11 +87,13 @@ class Recording {
87
87
 
88
88
 
89
89
 
90
+
90
91
 
91
92
 
92
93
 
93
94
 
94
95
 
96
+
95
97
 
96
98
 
97
99
 
@@ -112,10 +114,12 @@ class Recording {
112
114
 
113
115
 
114
116
 
117
+
115
118
 
116
119
 
117
120
 
118
121
 
122
+
119
123
 
120
124
 
121
125
 
@@ -177,10 +181,12 @@ class CallLog {
177
181
  || plain.destination_extension
178
182
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
179
183
  name: plain.requested_name || plain.destination_name || '',
184
+ uuid: plain.destination_user_uuid,
180
185
  },
181
186
  source: {
182
187
  extension: plain.source_extension,
183
188
  name: plain.source_name,
189
+ uuid: plain.source_user_uuid,
184
190
  },
185
191
  id: plain.id,
186
192
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -375,6 +375,14 @@ class CallSession {
375
375
  return !!this.answerTime;
376
376
  }
377
377
 
378
+ toJSON() {
379
+ const jsonObj = { ...this };
380
+ // $FlowFixMe
381
+ jsonObj.answered = this.answered;
382
+
383
+ return jsonObj;
384
+ }
385
+
378
386
  static parseCall(call ) {
379
387
  return new CallSession({
380
388
  callId: call.id,
@@ -2197,6 +2197,7 @@ var authMethods = (client , baseUrl ) => ({
2197
2197
 
2198
2198
 
2199
2199
 
2200
+
2200
2201
  ) {
2201
2202
  const body = {
2202
2203
  backend: params.backend || DEFAULT_BACKEND_USER,
@@ -2216,6 +2217,10 @@ var authMethods = (client , baseUrl ) => ({
2216
2217
  headers['Wazo-Session-Type'] = 'mobile';
2217
2218
  }
2218
2219
 
2220
+ if (params.tenantId) {
2221
+ body.tenant_id = params.tenantId;
2222
+ }
2223
+
2219
2224
  return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
2220
2225
  },
2221
2226
 
@@ -3284,11 +3289,13 @@ class Recording {
3284
3289
 
3285
3290
 
3286
3291
 
3292
+
3287
3293
 
3288
3294
 
3289
3295
 
3290
3296
 
3291
3297
 
3298
+
3292
3299
 
3293
3300
 
3294
3301
 
@@ -3309,10 +3316,12 @@ class Recording {
3309
3316
 
3310
3317
 
3311
3318
 
3319
+
3312
3320
 
3313
3321
 
3314
3322
 
3315
3323
 
3324
+
3316
3325
 
3317
3326
 
3318
3327
 
@@ -3374,10 +3383,12 @@ class CallLog {
3374
3383
  || plain.destination_extension
3375
3384
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3376
3385
  name: plain.requested_name || plain.destination_name || '',
3386
+ uuid: plain.destination_user_uuid,
3377
3387
  },
3378
3388
  source: {
3379
3389
  extension: plain.source_extension,
3380
3390
  name: plain.source_name,
3391
+ uuid: plain.source_user_uuid,
3381
3392
  },
3382
3393
  id: plain.id,
3383
3394
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -4016,6 +4027,34 @@ var chatdMethods = (client , baseUrl ) => ({
4016
4027
  client.get(`${baseUrl}/users/me/rooms/messages`, options),
4017
4028
  });
4018
4029
 
4030
+ //
4031
+
4032
+
4033
+
4034
+
4035
+
4036
+ class MeetingStatus {
4037
+
4038
+
4039
+
4040
+
4041
+ constructor({
4042
+ full,
4043
+ } = {}) {
4044
+ this.full = full;
4045
+
4046
+ // Useful to compare instead of instanceof with minified code
4047
+ this.type = 'MeetingStatus';
4048
+ }
4049
+
4050
+ static parse(plain ) {
4051
+ return new MeetingStatus({
4052
+ full: plain.full,
4053
+ });
4054
+ }
4055
+
4056
+ }
4057
+
4019
4058
  /* */
4020
4059
 
4021
4060
 
@@ -4210,6 +4249,8 @@ var calldMethods = (client , baseUrl ) => ({
4210
4249
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4211
4250
  ApiRequester.successResponseParser),
4212
4251
 
4252
+ guestGetMeetingStatus: (meetingUuid ) =>
4253
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4213
4254
  });
4214
4255
 
4215
4256
  //
@@ -0,0 +1,29 @@
1
+ //
2
+
3
+
4
+
5
+
6
+
7
+ class MeetingStatus {
8
+
9
+
10
+
11
+
12
+ constructor({
13
+ full,
14
+ } = {}) {
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 ) {
22
+ return new MeetingStatus({
23
+ full: plain.full,
24
+ });
25
+ }
26
+
27
+ }
28
+
29
+ export default MeetingStatus;
@@ -2049,6 +2049,14 @@ class CallSession {
2049
2049
  return !!this.answerTime;
2050
2050
  }
2051
2051
 
2052
+ toJSON() {
2053
+ const jsonObj = { ...this };
2054
+ // $FlowFixMe
2055
+ jsonObj.answered = this.answered;
2056
+
2057
+ return jsonObj;
2058
+ }
2059
+
2052
2060
  static parseCall(call ) {
2053
2061
  return new CallSession({
2054
2062
  callId: call.id,
@@ -2159,11 +2167,13 @@ class Recording {
2159
2167
 
2160
2168
 
2161
2169
 
2170
+
2162
2171
 
2163
2172
 
2164
2173
 
2165
2174
 
2166
2175
 
2176
+
2167
2177
 
2168
2178
 
2169
2179
 
@@ -2184,10 +2194,12 @@ class Recording {
2184
2194
 
2185
2195
 
2186
2196
 
2197
+
2187
2198
 
2188
2199
 
2189
2200
 
2190
2201
 
2202
+
2191
2203
 
2192
2204
 
2193
2205
 
@@ -2249,10 +2261,12 @@ class CallLog {
2249
2261
  || plain.destination_extension
2250
2262
  || `meeting-${plain.requested_name || plain.destination_name || ''}`,
2251
2263
  name: plain.requested_name || plain.destination_name || '',
2264
+ uuid: plain.destination_user_uuid,
2252
2265
  },
2253
2266
  source: {
2254
2267
  extension: plain.source_extension,
2255
2268
  name: plain.source_name,
2269
+ uuid: plain.source_user_uuid,
2256
2270
  },
2257
2271
  id: plain.id,
2258
2272
  duration: (plain.duration || 0) * 1000, // duration is in seconds
@@ -3129,6 +3143,7 @@ var authMethods = (client , baseUrl ) => ({
3129
3143
 
3130
3144
 
3131
3145
 
3146
+
3132
3147
  ) {
3133
3148
  const body = {
3134
3149
  backend: params.backend || DEFAULT_BACKEND_USER,
@@ -3148,6 +3163,10 @@ var authMethods = (client , baseUrl ) => ({
3148
3163
  headers['Wazo-Session-Type'] = 'mobile';
3149
3164
  }
3150
3165
 
3166
+ if (params.tenantId) {
3167
+ body.tenant_id = params.tenantId;
3168
+ }
3169
+
3151
3170
  return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
3152
3171
  },
3153
3172
 
@@ -4407,6 +4426,34 @@ class IndirectTransfer {
4407
4426
  }
4408
4427
  }
4409
4428
 
4429
+ //
4430
+
4431
+
4432
+
4433
+
4434
+
4435
+ class MeetingStatus {
4436
+
4437
+
4438
+
4439
+
4440
+ constructor({
4441
+ full,
4442
+ } = {}) {
4443
+ this.full = full;
4444
+
4445
+ // Useful to compare instead of instanceof with minified code
4446
+ this.type = 'MeetingStatus';
4447
+ }
4448
+
4449
+ static parse(plain ) {
4450
+ return new MeetingStatus({
4451
+ full: plain.full,
4452
+ });
4453
+ }
4454
+
4455
+ }
4456
+
4410
4457
  /* */
4411
4458
 
4412
4459
 
@@ -4601,6 +4648,8 @@ var calldMethods = (client , baseUrl ) => ({
4601
4648
  client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
4602
4649
  ApiRequester.successResponseParser),
4603
4650
 
4651
+ guestGetMeetingStatus: (meetingUuid ) =>
4652
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
4604
4653
  });
4605
4654
 
4606
4655
  //
@@ -397,6 +397,14 @@ class CallSession {
397
397
  return !!this.answerTime;
398
398
  }
399
399
 
400
+ toJSON() {
401
+ const jsonObj = { ...this };
402
+ // $FlowFixMe
403
+ jsonObj.answered = this.answered;
404
+
405
+ return jsonObj;
406
+ }
407
+
400
408
  static parseCall(call ) {
401
409
  return new CallSession({
402
410
  callId: call.id,
@@ -1714,6 +1722,12 @@ class WebRTCPhone extends Emitter {
1714
1722
  return Promise.resolve(null);
1715
1723
  }
1716
1724
 
1725
+ const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
1726
+ if (sipSessionId && !(sipSessionId in this.callSessions)) {
1727
+ logger.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
1728
+ return Promise.resolve(null);
1729
+ }
1730
+
1717
1731
  if (callSession.getId() in this.acceptedSessions) {
1718
1732
  logger.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
1719
1733
  return Promise.resolve(callSession.sipCallId);
@@ -2174,7 +2188,7 @@ class WebRTCPhone extends Emitter {
2174
2188
  return this.client && this.client.isConference(callSession.sipCallId);
2175
2189
  }
2176
2190
 
2177
- async close() {
2191
+ async close(force = false) {
2178
2192
  logger.info('WebRTC close');
2179
2193
 
2180
2194
  try {
@@ -2186,7 +2200,7 @@ class WebRTCPhone extends Emitter {
2186
2200
  logger.error('WebRTC close, unregister error', e);
2187
2201
  }
2188
2202
 
2189
- this.client.close();
2203
+ this.client.close(force);
2190
2204
  this.unbind();
2191
2205
 
2192
2206
  this.incomingSessions = [];
@@ -2338,9 +2352,17 @@ class WebRTCPhone extends Emitter {
2338
2352
  });
2339
2353
 
2340
2354
  this.client.on(this.client.ACCEPTED, (sipSession ) => {
2341
- logger.info('WebRTC call accepted', { sipId: sipSession.id });
2355
+ const sessionId = this.getSipSessionId(sipSession);
2356
+ const hasSession = sessionId in this.callSessions;
2342
2357
 
2343
- this._onCallAccepted(sipSession, this.client.hasVideo(this.getSipSessionId(sipSession)));
2358
+ logger.info('WebRTC call accepted', { sipId: sessionId, hasSession });
2359
+
2360
+ if (!hasSession) {
2361
+ logger.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
2362
+ return;
2363
+ }
2364
+
2365
+ this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
2344
2366
 
2345
2367
  if (this.audioOutputDeviceId) {
2346
2368
  this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
@@ -2476,9 +2498,14 @@ class WebRTCPhone extends Emitter {
2476
2498
  return this.client.getSipSessionId(sipSession);
2477
2499
  }
2478
2500
 
2479
- _updateCallSession(callSession ) {
2501
+ getSipSessionIdFromCallSession(callSession ) {
2480
2502
  const sipSession = this.findSipSession(callSession);
2481
- const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
2503
+
2504
+ return sipSession ? this.getSipSessionId(sipSession) : null;
2505
+ }
2506
+
2507
+ _updateCallSession(callSession ) {
2508
+ const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
2482
2509
 
2483
2510
  if (sipSessionId) {
2484
2511
  this.callSessions[sipSessionId] = callSession;