@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.
- package/dist/wazo-sdk.js +2 -2
- package/esm/__tests__/api-client.test.js +41 -0
- package/esm/__tests__/web-rtc-client.test.js +68 -6
- package/esm/api/auth.js +5 -0
- package/esm/api/call-logd.js +6 -0
- package/esm/api/calld.js +30 -0
- package/esm/api-client.js +41 -0
- package/esm/checker/Checker.js +68 -6
- package/esm/checker/checks/aor.js +41 -0
- package/esm/checker/checks/api.js +41 -0
- package/esm/checker/checks/index.js +68 -6
- package/esm/checker/checks/webrtc-transport.js +68 -6
- package/esm/checker/checks/webrtc.js +68 -6
- package/esm/domain/AdHocAPIConference.js +41 -0
- package/esm/domain/CallLog.js +6 -0
- package/esm/domain/CallSession.js +8 -0
- package/esm/domain/Features.js +41 -0
- package/esm/domain/MeetingStatus.js +29 -0
- package/esm/domain/Phone/CTIPhone.js +49 -0
- package/esm/domain/Phone/WebRTCPhone.js +33 -6
- package/esm/domain/__tests__/CallLog.test.js +6 -0
- package/esm/domain/__tests__/CallSession.test.js +40 -4
- package/esm/domain/__tests__/IndirectTransfer.test.js +8 -0
- package/esm/domain/__tests__/Room.test.js +8 -0
- package/esm/index.js +101 -12
- package/esm/service/CallApi.js +41 -0
- package/esm/service/getApiClient.js +41 -0
- package/esm/simple/Auth.js +101 -12
- package/esm/simple/Configuration.js +101 -12
- package/esm/simple/Directory.js +41 -0
- package/esm/simple/Phone.js +101 -12
- package/esm/simple/index.js +101 -12
- package/esm/simple/room/LocalParticipant.js +101 -12
- package/esm/simple/room/Participant.js +101 -12
- package/esm/simple/room/RemoteParticipant.js +101 -12
- package/esm/simple/room/Room.js +101 -12
- package/esm/simple/room/SipRoom.js +101 -12
- package/esm/simple/room/Stream.js +101 -12
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +101 -12
- package/esm/simple/utils.js +101 -12
- package/esm/web-rtc-client.js +68 -6
- package/lib/__tests__/api-client.test.js +41 -0
- package/lib/__tests__/web-rtc-client.test.js +68 -6
- package/lib/api/auth.js +5 -0
- package/lib/api/call-logd.js +6 -0
- package/lib/api/calld.js +30 -0
- package/lib/api-client.js +41 -0
- package/lib/checker/Checker.js +68 -6
- package/lib/checker/checks/aor.js +41 -0
- package/lib/checker/checks/api.js +41 -0
- package/lib/checker/checks/index.js +68 -6
- package/lib/checker/checks/webrtc-transport.js +68 -6
- package/lib/checker/checks/webrtc.js +68 -6
- package/lib/domain/AdHocAPIConference.js +41 -0
- package/lib/domain/CallLog.js +6 -0
- package/lib/domain/CallSession.js +8 -0
- package/lib/domain/Features.js +41 -0
- package/lib/domain/MeetingStatus.js +31 -0
- package/lib/domain/Phone/CTIPhone.js +49 -0
- package/lib/domain/Phone/WebRTCPhone.js +33 -6
- package/lib/domain/__tests__/CallLog.test.js +6 -0
- package/lib/domain/__tests__/CallSession.test.js +40 -4
- package/lib/domain/__tests__/IndirectTransfer.test.js +8 -0
- package/lib/domain/__tests__/Room.test.js +8 -0
- package/lib/index.js +101 -12
- package/lib/service/CallApi.js +41 -0
- package/lib/service/getApiClient.js +41 -0
- package/lib/simple/Auth.js +101 -12
- package/lib/simple/Configuration.js +101 -12
- package/lib/simple/Directory.js +41 -0
- package/lib/simple/Phone.js +101 -12
- package/lib/simple/index.js +101 -12
- package/lib/simple/room/LocalParticipant.js +101 -12
- package/lib/simple/room/Participant.js +101 -12
- package/lib/simple/room/RemoteParticipant.js +101 -12
- package/lib/simple/room/Room.js +101 -12
- package/lib/simple/room/SipRoom.js +101 -12
- package/lib/simple/room/Stream.js +101 -12
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +101 -12
- package/lib/simple/utils.js +101 -12
- package/lib/web-rtc-client.js +68 -6
- package/package.json +1 -1
- package/src/api/auth.js +5 -0
- package/src/api/calld.js +3 -0
- package/src/domain/CallLog.js +6 -0
- package/src/domain/CallSession.js +8 -0
- package/src/domain/MeetingStatus.js +27 -0
- package/src/domain/Phone/WebRTCPhone.js +25 -6
- package/src/domain/__tests__/CallSession.test.js +32 -4
- package/src/web-rtc-client.js +27 -6
package/lib/simple/utils.js
CHANGED
|
@@ -2228,6 +2228,7 @@ var authMethods = (client , baseUrl ) => ({
|
|
|
2228
2228
|
|
|
2229
2229
|
|
|
2230
2230
|
|
|
2231
|
+
|
|
2231
2232
|
) {
|
|
2232
2233
|
const body = {
|
|
2233
2234
|
backend: params.backend || DEFAULT_BACKEND_USER,
|
|
@@ -2247,6 +2248,10 @@ var authMethods = (client , baseUrl ) => ({
|
|
|
2247
2248
|
headers['Wazo-Session-Type'] = 'mobile';
|
|
2248
2249
|
}
|
|
2249
2250
|
|
|
2251
|
+
if (params.tenantId) {
|
|
2252
|
+
body.tenant_id = params.tenantId;
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2250
2255
|
return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
|
|
2251
2256
|
},
|
|
2252
2257
|
|
|
@@ -3603,6 +3608,14 @@ class CallSession {
|
|
|
3603
3608
|
return !!this.answerTime;
|
|
3604
3609
|
}
|
|
3605
3610
|
|
|
3611
|
+
toJSON() {
|
|
3612
|
+
const jsonObj = { ...this };
|
|
3613
|
+
// $FlowFixMe
|
|
3614
|
+
jsonObj.answered = this.answered;
|
|
3615
|
+
|
|
3616
|
+
return jsonObj;
|
|
3617
|
+
}
|
|
3618
|
+
|
|
3606
3619
|
static parseCall(call ) {
|
|
3607
3620
|
return new CallSession({
|
|
3608
3621
|
callId: call.id,
|
|
@@ -3713,11 +3726,13 @@ class Recording {
|
|
|
3713
3726
|
|
|
3714
3727
|
|
|
3715
3728
|
|
|
3729
|
+
|
|
3716
3730
|
|
|
3717
3731
|
|
|
3718
3732
|
|
|
3719
3733
|
|
|
3720
3734
|
|
|
3735
|
+
|
|
3721
3736
|
|
|
3722
3737
|
|
|
3723
3738
|
|
|
@@ -3738,10 +3753,12 @@ class Recording {
|
|
|
3738
3753
|
|
|
3739
3754
|
|
|
3740
3755
|
|
|
3756
|
+
|
|
3741
3757
|
|
|
3742
3758
|
|
|
3743
3759
|
|
|
3744
3760
|
|
|
3761
|
+
|
|
3745
3762
|
|
|
3746
3763
|
|
|
3747
3764
|
|
|
@@ -3803,10 +3820,12 @@ class CallLog {
|
|
|
3803
3820
|
|| plain.destination_extension
|
|
3804
3821
|
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3805
3822
|
name: plain.requested_name || plain.destination_name || '',
|
|
3823
|
+
uuid: plain.destination_user_uuid,
|
|
3806
3824
|
},
|
|
3807
3825
|
source: {
|
|
3808
3826
|
extension: plain.source_extension,
|
|
3809
3827
|
name: plain.source_name,
|
|
3828
|
+
uuid: plain.source_user_uuid,
|
|
3810
3829
|
},
|
|
3811
3830
|
id: plain.id,
|
|
3812
3831
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
@@ -4854,6 +4873,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4854
4873
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4855
4874
|
});
|
|
4856
4875
|
|
|
4876
|
+
//
|
|
4877
|
+
|
|
4878
|
+
|
|
4879
|
+
|
|
4880
|
+
|
|
4881
|
+
|
|
4882
|
+
class MeetingStatus {
|
|
4883
|
+
|
|
4884
|
+
|
|
4885
|
+
|
|
4886
|
+
|
|
4887
|
+
constructor({
|
|
4888
|
+
full,
|
|
4889
|
+
} = {}) {
|
|
4890
|
+
this.full = full;
|
|
4891
|
+
|
|
4892
|
+
// Useful to compare instead of instanceof with minified code
|
|
4893
|
+
this.type = 'MeetingStatus';
|
|
4894
|
+
}
|
|
4895
|
+
|
|
4896
|
+
static parse(plain ) {
|
|
4897
|
+
return new MeetingStatus({
|
|
4898
|
+
full: plain.full,
|
|
4899
|
+
});
|
|
4900
|
+
}
|
|
4901
|
+
|
|
4902
|
+
}
|
|
4903
|
+
|
|
4857
4904
|
/* */
|
|
4858
4905
|
|
|
4859
4906
|
|
|
@@ -5048,6 +5095,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5048
5095
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
5049
5096
|
ApiRequester.successResponseParser),
|
|
5050
5097
|
|
|
5098
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
5099
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
5051
5100
|
});
|
|
5052
5101
|
|
|
5053
5102
|
//
|
|
@@ -6637,7 +6686,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6637
6686
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6638
6687
|
class CanceledCallError extends Error {}
|
|
6639
6688
|
|
|
6640
|
-
const MAX_REGISTER_TRIES =
|
|
6689
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6641
6690
|
|
|
6642
6691
|
|
|
6643
6692
|
|
|
@@ -6691,6 +6740,7 @@ class WebRTCClient extends Emitter {
|
|
|
6691
6740
|
|
|
6692
6741
|
|
|
6693
6742
|
|
|
6743
|
+
|
|
6694
6744
|
|
|
6695
6745
|
// sugar
|
|
6696
6746
|
|
|
@@ -6753,6 +6803,7 @@ class WebRTCClient extends Emitter {
|
|
|
6753
6803
|
this.conferences = {};
|
|
6754
6804
|
this.networkMonitoringInterval = {};
|
|
6755
6805
|
this.sessionNetworkStats = {};
|
|
6806
|
+
this.forceClosed = false;
|
|
6756
6807
|
|
|
6757
6808
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6758
6809
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6874,6 +6925,8 @@ class WebRTCClient extends Emitter {
|
|
|
6874
6925
|
skipRegister: this.skipRegister,
|
|
6875
6926
|
};
|
|
6876
6927
|
|
|
6928
|
+
this.forceClosed = false;
|
|
6929
|
+
|
|
6877
6930
|
if (this.skipRegister) {
|
|
6878
6931
|
logger$8.info('sdk webrtc skip register...', logInfo);
|
|
6879
6932
|
return Promise.resolve();
|
|
@@ -6898,7 +6951,15 @@ class WebRTCClient extends Emitter {
|
|
|
6898
6951
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6899
6952
|
|
|
6900
6953
|
const onRegisterFailed = () => {
|
|
6901
|
-
logger$8.info('sdk webrtc registering failed', {
|
|
6954
|
+
logger$8.info('sdk webrtc registering failed', {
|
|
6955
|
+
tries,
|
|
6956
|
+
registerer: !!this.registerer,
|
|
6957
|
+
forceClosed: this.forceClosed,
|
|
6958
|
+
});
|
|
6959
|
+
if (this.forceClosed) {
|
|
6960
|
+
return;
|
|
6961
|
+
}
|
|
6962
|
+
|
|
6902
6963
|
this.connectionPromise = null;
|
|
6903
6964
|
if (this.registerer && this.registerer.waiting) {
|
|
6904
6965
|
this.registerer.waitingToggle(false);
|
|
@@ -7176,8 +7237,9 @@ class WebRTCClient extends Emitter {
|
|
|
7176
7237
|
}
|
|
7177
7238
|
}
|
|
7178
7239
|
|
|
7179
|
-
async close() {
|
|
7180
|
-
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
7240
|
+
async close(force = false) {
|
|
7241
|
+
logger$8.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
7242
|
+
this.forceClosed = force;
|
|
7181
7243
|
this._cleanupMedia();
|
|
7182
7244
|
this.connectionPromise = null;
|
|
7183
7245
|
|
|
@@ -7196,7 +7258,7 @@ class WebRTCClient extends Emitter {
|
|
|
7196
7258
|
this.userAgent.delegate = null;
|
|
7197
7259
|
this.userAgent.stateChange.removeAllListeners();
|
|
7198
7260
|
|
|
7199
|
-
await this._disconnectTransport();
|
|
7261
|
+
await this._disconnectTransport(force);
|
|
7200
7262
|
|
|
7201
7263
|
this._cleanupRegister();
|
|
7202
7264
|
|
|
@@ -8632,7 +8694,15 @@ class WebRTCClient extends Emitter {
|
|
|
8632
8694
|
return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8633
8695
|
}
|
|
8634
8696
|
|
|
8635
|
-
async _disconnectTransport() {
|
|
8697
|
+
async _disconnectTransport(force = false) {
|
|
8698
|
+
if (force) {
|
|
8699
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
8700
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
8701
|
+
// eslint-disable-next-line
|
|
8702
|
+
this.userAgent.transport._ws.close(1000);
|
|
8703
|
+
return;
|
|
8704
|
+
}
|
|
8705
|
+
|
|
8636
8706
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8637
8707
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8638
8708
|
try {
|
|
@@ -9579,6 +9649,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9579
9649
|
return Promise.resolve(null);
|
|
9580
9650
|
}
|
|
9581
9651
|
|
|
9652
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9653
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9654
|
+
logger$7.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9655
|
+
return Promise.resolve(null);
|
|
9656
|
+
}
|
|
9657
|
+
|
|
9582
9658
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9583
9659
|
logger$7.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9584
9660
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -10039,7 +10115,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10039
10115
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
10040
10116
|
}
|
|
10041
10117
|
|
|
10042
|
-
async close() {
|
|
10118
|
+
async close(force = false) {
|
|
10043
10119
|
logger$7.info('WebRTC close');
|
|
10044
10120
|
|
|
10045
10121
|
try {
|
|
@@ -10051,7 +10127,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10051
10127
|
logger$7.error('WebRTC close, unregister error', e);
|
|
10052
10128
|
}
|
|
10053
10129
|
|
|
10054
|
-
this.client.close();
|
|
10130
|
+
this.client.close(force);
|
|
10055
10131
|
this.unbind();
|
|
10056
10132
|
|
|
10057
10133
|
this.incomingSessions = [];
|
|
@@ -10203,9 +10279,17 @@ class WebRTCPhone extends Emitter {
|
|
|
10203
10279
|
});
|
|
10204
10280
|
|
|
10205
10281
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
10206
|
-
|
|
10282
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10283
|
+
const hasSession = sessionId in this.callSessions;
|
|
10284
|
+
|
|
10285
|
+
logger$7.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10286
|
+
|
|
10287
|
+
if (!hasSession) {
|
|
10288
|
+
logger$7.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10289
|
+
return;
|
|
10290
|
+
}
|
|
10207
10291
|
|
|
10208
|
-
this._onCallAccepted(sipSession, this.client.hasVideo(
|
|
10292
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
10209
10293
|
|
|
10210
10294
|
if (this.audioOutputDeviceId) {
|
|
10211
10295
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -10341,9 +10425,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10341
10425
|
return this.client.getSipSessionId(sipSession);
|
|
10342
10426
|
}
|
|
10343
10427
|
|
|
10344
|
-
|
|
10428
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10345
10429
|
const sipSession = this.findSipSession(callSession);
|
|
10346
|
-
|
|
10430
|
+
|
|
10431
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10432
|
+
}
|
|
10433
|
+
|
|
10434
|
+
_updateCallSession(callSession ) {
|
|
10435
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10347
10436
|
|
|
10348
10437
|
if (sipSessionId) {
|
|
10349
10438
|
this.callSessions[sipSessionId] = callSession;
|
package/lib/web-rtc-client.js
CHANGED
|
@@ -2756,6 +2756,7 @@ var authMethods = (client , baseUrl ) => ({
|
|
|
2756
2756
|
|
|
2757
2757
|
|
|
2758
2758
|
|
|
2759
|
+
|
|
2759
2760
|
) {
|
|
2760
2761
|
const body = {
|
|
2761
2762
|
backend: params.backend || DEFAULT_BACKEND_USER,
|
|
@@ -2775,6 +2776,10 @@ var authMethods = (client , baseUrl ) => ({
|
|
|
2775
2776
|
headers['Wazo-Session-Type'] = 'mobile';
|
|
2776
2777
|
}
|
|
2777
2778
|
|
|
2779
|
+
if (params.tenantId) {
|
|
2780
|
+
body.tenant_id = params.tenantId;
|
|
2781
|
+
}
|
|
2782
|
+
|
|
2778
2783
|
return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
|
|
2779
2784
|
},
|
|
2780
2785
|
|
|
@@ -3843,11 +3848,13 @@ class Recording {
|
|
|
3843
3848
|
|
|
3844
3849
|
|
|
3845
3850
|
|
|
3851
|
+
|
|
3846
3852
|
|
|
3847
3853
|
|
|
3848
3854
|
|
|
3849
3855
|
|
|
3850
3856
|
|
|
3857
|
+
|
|
3851
3858
|
|
|
3852
3859
|
|
|
3853
3860
|
|
|
@@ -3868,10 +3875,12 @@ class Recording {
|
|
|
3868
3875
|
|
|
3869
3876
|
|
|
3870
3877
|
|
|
3878
|
+
|
|
3871
3879
|
|
|
3872
3880
|
|
|
3873
3881
|
|
|
3874
3882
|
|
|
3883
|
+
|
|
3875
3884
|
|
|
3876
3885
|
|
|
3877
3886
|
|
|
@@ -3933,10 +3942,12 @@ class CallLog {
|
|
|
3933
3942
|
|| plain.destination_extension
|
|
3934
3943
|
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3935
3944
|
name: plain.requested_name || plain.destination_name || '',
|
|
3945
|
+
uuid: plain.destination_user_uuid,
|
|
3936
3946
|
},
|
|
3937
3947
|
source: {
|
|
3938
3948
|
extension: plain.source_extension,
|
|
3939
3949
|
name: plain.source_name,
|
|
3950
|
+
uuid: plain.source_user_uuid,
|
|
3940
3951
|
},
|
|
3941
3952
|
id: plain.id,
|
|
3942
3953
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
@@ -4590,6 +4601,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4590
4601
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4591
4602
|
});
|
|
4592
4603
|
|
|
4604
|
+
//
|
|
4605
|
+
|
|
4606
|
+
|
|
4607
|
+
|
|
4608
|
+
|
|
4609
|
+
|
|
4610
|
+
class MeetingStatus {
|
|
4611
|
+
|
|
4612
|
+
|
|
4613
|
+
|
|
4614
|
+
|
|
4615
|
+
constructor({
|
|
4616
|
+
full,
|
|
4617
|
+
} = {}) {
|
|
4618
|
+
this.full = full;
|
|
4619
|
+
|
|
4620
|
+
// Useful to compare instead of instanceof with minified code
|
|
4621
|
+
this.type = 'MeetingStatus';
|
|
4622
|
+
}
|
|
4623
|
+
|
|
4624
|
+
static parse(plain ) {
|
|
4625
|
+
return new MeetingStatus({
|
|
4626
|
+
full: plain.full,
|
|
4627
|
+
});
|
|
4628
|
+
}
|
|
4629
|
+
|
|
4630
|
+
}
|
|
4631
|
+
|
|
4593
4632
|
/* */
|
|
4594
4633
|
|
|
4595
4634
|
|
|
@@ -4784,6 +4823,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4784
4823
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
4785
4824
|
ApiRequester.successResponseParser),
|
|
4786
4825
|
|
|
4826
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
4827
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
4787
4828
|
});
|
|
4788
4829
|
|
|
4789
4830
|
//
|
|
@@ -5346,7 +5387,7 @@ const events = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
5346
5387
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
5347
5388
|
class CanceledCallError extends Error {}
|
|
5348
5389
|
|
|
5349
|
-
const MAX_REGISTER_TRIES =
|
|
5390
|
+
const MAX_REGISTER_TRIES = 5;
|
|
5350
5391
|
|
|
5351
5392
|
|
|
5352
5393
|
|
|
@@ -5400,6 +5441,7 @@ class WebRTCClient extends Emitter {
|
|
|
5400
5441
|
|
|
5401
5442
|
|
|
5402
5443
|
|
|
5444
|
+
|
|
5403
5445
|
|
|
5404
5446
|
// sugar
|
|
5405
5447
|
|
|
@@ -5462,6 +5504,7 @@ class WebRTCClient extends Emitter {
|
|
|
5462
5504
|
this.conferences = {};
|
|
5463
5505
|
this.networkMonitoringInterval = {};
|
|
5464
5506
|
this.sessionNetworkStats = {};
|
|
5507
|
+
this.forceClosed = false;
|
|
5465
5508
|
|
|
5466
5509
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
5467
5510
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -5583,6 +5626,8 @@ class WebRTCClient extends Emitter {
|
|
|
5583
5626
|
skipRegister: this.skipRegister,
|
|
5584
5627
|
};
|
|
5585
5628
|
|
|
5629
|
+
this.forceClosed = false;
|
|
5630
|
+
|
|
5586
5631
|
if (this.skipRegister) {
|
|
5587
5632
|
logger.info('sdk webrtc skip register...', logInfo);
|
|
5588
5633
|
return Promise.resolve();
|
|
@@ -5607,7 +5652,15 @@ class WebRTCClient extends Emitter {
|
|
|
5607
5652
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
5608
5653
|
|
|
5609
5654
|
const onRegisterFailed = () => {
|
|
5610
|
-
logger.info('sdk webrtc registering failed', {
|
|
5655
|
+
logger.info('sdk webrtc registering failed', {
|
|
5656
|
+
tries,
|
|
5657
|
+
registerer: !!this.registerer,
|
|
5658
|
+
forceClosed: this.forceClosed,
|
|
5659
|
+
});
|
|
5660
|
+
if (this.forceClosed) {
|
|
5661
|
+
return;
|
|
5662
|
+
}
|
|
5663
|
+
|
|
5611
5664
|
this.connectionPromise = null;
|
|
5612
5665
|
if (this.registerer && this.registerer.waiting) {
|
|
5613
5666
|
this.registerer.waitingToggle(false);
|
|
@@ -5885,8 +5938,9 @@ class WebRTCClient extends Emitter {
|
|
|
5885
5938
|
}
|
|
5886
5939
|
}
|
|
5887
5940
|
|
|
5888
|
-
async close() {
|
|
5889
|
-
logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
5941
|
+
async close(force = false) {
|
|
5942
|
+
logger.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
5943
|
+
this.forceClosed = force;
|
|
5890
5944
|
this._cleanupMedia();
|
|
5891
5945
|
this.connectionPromise = null;
|
|
5892
5946
|
|
|
@@ -5905,7 +5959,7 @@ class WebRTCClient extends Emitter {
|
|
|
5905
5959
|
this.userAgent.delegate = null;
|
|
5906
5960
|
this.userAgent.stateChange.removeAllListeners();
|
|
5907
5961
|
|
|
5908
|
-
await this._disconnectTransport();
|
|
5962
|
+
await this._disconnectTransport(force);
|
|
5909
5963
|
|
|
5910
5964
|
this._cleanupRegister();
|
|
5911
5965
|
|
|
@@ -7341,7 +7395,15 @@ class WebRTCClient extends Emitter {
|
|
|
7341
7395
|
return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
7342
7396
|
}
|
|
7343
7397
|
|
|
7344
|
-
async _disconnectTransport() {
|
|
7398
|
+
async _disconnectTransport(force = false) {
|
|
7399
|
+
if (force) {
|
|
7400
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
7401
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
7402
|
+
// eslint-disable-next-line
|
|
7403
|
+
this.userAgent.transport._ws.close(1000);
|
|
7404
|
+
return;
|
|
7405
|
+
}
|
|
7406
|
+
|
|
7345
7407
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
7346
7408
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
7347
7409
|
try {
|
package/package.json
CHANGED
package/src/api/auth.js
CHANGED
|
@@ -31,6 +31,7 @@ export default (client: ApiRequester, baseUrl: string) => ({
|
|
|
31
31
|
backend: string,
|
|
32
32
|
expiration: number,
|
|
33
33
|
mobile?: boolean,
|
|
34
|
+
tenantId?: string,
|
|
34
35
|
}): Promise<?Session> {
|
|
35
36
|
const body: Object = {
|
|
36
37
|
backend: params.backend || DEFAULT_BACKEND_USER,
|
|
@@ -50,6 +51,10 @@ export default (client: ApiRequester, baseUrl: string) => ({
|
|
|
50
51
|
headers['Wazo-Session-Type'] = 'mobile';
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
if (params.tenantId) {
|
|
55
|
+
body.tenant_id = params.tenantId;
|
|
56
|
+
}
|
|
57
|
+
|
|
53
58
|
return client.post(`${baseUrl}/token`, body, headers).then(response => Session.parse(response));
|
|
54
59
|
},
|
|
55
60
|
|
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
|
});
|
package/src/domain/CallLog.js
CHANGED
|
@@ -13,11 +13,13 @@ type CallLogResponse = {
|
|
|
13
13
|
call_direction: string,
|
|
14
14
|
destination_extension: string,
|
|
15
15
|
destination_name: ?string,
|
|
16
|
+
destination_user_uuid: ?string,
|
|
16
17
|
duration: number,
|
|
17
18
|
end: ?string,
|
|
18
19
|
id: number,
|
|
19
20
|
source_extension: string,
|
|
20
21
|
source_name: string,
|
|
22
|
+
source_user_uuid: string,
|
|
21
23
|
recordings: RecordingResponse[],
|
|
22
24
|
requested_extension: string,
|
|
23
25
|
requested_name: string,
|
|
@@ -38,10 +40,12 @@ type CallLogArguments = {
|
|
|
38
40
|
destination: {
|
|
39
41
|
extension: string,
|
|
40
42
|
name: string,
|
|
43
|
+
uuid: ?string,
|
|
41
44
|
},
|
|
42
45
|
source: {
|
|
43
46
|
extension: string,
|
|
44
47
|
name: string,
|
|
48
|
+
uuid: ?string,
|
|
45
49
|
},
|
|
46
50
|
id: number,
|
|
47
51
|
duration: number,
|
|
@@ -103,10 +107,12 @@ export default class CallLog {
|
|
|
103
107
|
|| plain.destination_extension
|
|
104
108
|
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
105
109
|
name: plain.requested_name || plain.destination_name || '',
|
|
110
|
+
uuid: plain.destination_user_uuid,
|
|
106
111
|
},
|
|
107
112
|
source: {
|
|
108
113
|
extension: plain.source_extension,
|
|
109
114
|
name: plain.source_name,
|
|
115
|
+
uuid: plain.source_user_uuid,
|
|
110
116
|
},
|
|
111
117
|
id: plain.id,
|
|
112
118
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
@@ -351,6 +351,14 @@ export default class CallSession {
|
|
|
351
351
|
return !!this.answerTime;
|
|
352
352
|
}
|
|
353
353
|
|
|
354
|
+
toJSON() {
|
|
355
|
+
const jsonObj = { ...this };
|
|
356
|
+
// $FlowFixMe
|
|
357
|
+
jsonObj.answered = this.answered;
|
|
358
|
+
|
|
359
|
+
return jsonObj;
|
|
360
|
+
}
|
|
361
|
+
|
|
354
362
|
static parseCall(call: Call): CallSession {
|
|
355
363
|
return new CallSession({
|
|
356
364
|
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
|
+
}
|
|
@@ -841,6 +841,12 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
841
841
|
return Promise.resolve(null);
|
|
842
842
|
}
|
|
843
843
|
|
|
844
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
845
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
846
|
+
logger.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
847
|
+
return Promise.resolve(null);
|
|
848
|
+
}
|
|
849
|
+
|
|
844
850
|
if (callSession.getId() in this.acceptedSessions) {
|
|
845
851
|
logger.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
846
852
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -1301,7 +1307,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1301
1307
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
1302
1308
|
}
|
|
1303
1309
|
|
|
1304
|
-
async close(): Promise<void> {
|
|
1310
|
+
async close(force: boolean = false): Promise<void> {
|
|
1305
1311
|
logger.info('WebRTC close');
|
|
1306
1312
|
|
|
1307
1313
|
try {
|
|
@@ -1313,7 +1319,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1313
1319
|
logger.error('WebRTC close, unregister error', e);
|
|
1314
1320
|
}
|
|
1315
1321
|
|
|
1316
|
-
this.client.close();
|
|
1322
|
+
this.client.close(force);
|
|
1317
1323
|
this.unbind();
|
|
1318
1324
|
|
|
1319
1325
|
this.incomingSessions = [];
|
|
@@ -1465,9 +1471,17 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1465
1471
|
});
|
|
1466
1472
|
|
|
1467
1473
|
this.client.on(this.client.ACCEPTED, (sipSession: Session) => {
|
|
1468
|
-
|
|
1474
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
1475
|
+
const hasSession = sessionId in this.callSessions;
|
|
1476
|
+
|
|
1477
|
+
logger.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
1478
|
+
|
|
1479
|
+
if (!hasSession) {
|
|
1480
|
+
logger.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1469
1483
|
|
|
1470
|
-
this._onCallAccepted(sipSession, this.client.hasVideo(
|
|
1484
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
1471
1485
|
|
|
1472
1486
|
if (this.audioOutputDeviceId) {
|
|
1473
1487
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -1603,9 +1617,14 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1603
1617
|
return this.client.getSipSessionId(sipSession);
|
|
1604
1618
|
}
|
|
1605
1619
|
|
|
1606
|
-
|
|
1620
|
+
getSipSessionIdFromCallSession(callSession: CallSession) {
|
|
1607
1621
|
const sipSession = this.findSipSession(callSession);
|
|
1608
|
-
|
|
1622
|
+
|
|
1623
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
1624
|
+
}
|
|
1625
|
+
|
|
1626
|
+
_updateCallSession(callSession: CallSession) {
|
|
1627
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
1609
1628
|
|
|
1610
1629
|
if (sipSessionId) {
|
|
1611
1630
|
this.callSessions[sipSessionId] = callSession;
|