@wazo/sdk 0.37.30 → 0.37.34
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 +4 -4
- package/esm/__tests__/api-client.test.js +30 -0
- package/esm/__tests__/web-rtc-client.test.js +57 -6
- package/esm/api/calld.js +30 -0
- package/esm/api-client.js +30 -0
- package/esm/checker/Checker.js +57 -6
- package/esm/checker/checks/aor.js +30 -0
- package/esm/checker/checks/api.js +30 -0
- package/esm/checker/checks/index.js +57 -6
- package/esm/checker/checks/webrtc-transport.js +57 -6
- package/esm/checker/checks/webrtc.js +57 -6
- package/esm/domain/AdHocAPIConference.js +30 -0
- package/esm/domain/CallSession.js +9 -1
- package/esm/domain/Features.js +30 -0
- package/esm/domain/MeetingStatus.js +29 -0
- package/esm/domain/Phone/CTIPhone.js +39 -1
- package/esm/domain/Phone/WebRTCPhone.js +43 -8
- package/esm/domain/__tests__/CallSession.test.js +41 -5
- package/esm/domain/__tests__/IndirectTransfer.test.js +9 -1
- package/esm/domain/__tests__/Room.test.js +9 -1
- package/esm/index.js +100 -14
- package/esm/service/CallApi.js +30 -0
- package/esm/service/getApiClient.js +30 -0
- package/esm/simple/Auth.js +100 -14
- package/esm/simple/Configuration.js +100 -14
- package/esm/simple/Directory.js +30 -0
- package/esm/simple/Phone.js +100 -14
- package/esm/simple/index.js +100 -14
- package/esm/simple/room/LocalParticipant.js +100 -14
- package/esm/simple/room/Participant.js +100 -14
- package/esm/simple/room/RemoteParticipant.js +100 -14
- package/esm/simple/room/Room.js +100 -14
- package/esm/simple/room/SipRoom.js +100 -14
- package/esm/simple/room/Stream.js +100 -14
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +100 -14
- package/esm/simple/utils.js +100 -14
- package/esm/web-rtc-client.js +57 -6
- package/lib/__tests__/api-client.test.js +30 -0
- package/lib/__tests__/web-rtc-client.test.js +57 -6
- package/lib/api/calld.js +30 -0
- package/lib/api-client.js +30 -0
- package/lib/checker/Checker.js +57 -6
- package/lib/checker/checks/aor.js +30 -0
- package/lib/checker/checks/api.js +30 -0
- package/lib/checker/checks/index.js +57 -6
- package/lib/checker/checks/webrtc-transport.js +57 -6
- package/lib/checker/checks/webrtc.js +57 -6
- package/lib/domain/AdHocAPIConference.js +30 -0
- package/lib/domain/CallSession.js +9 -1
- package/lib/domain/Features.js +30 -0
- package/lib/domain/MeetingStatus.js +31 -0
- package/lib/domain/Phone/CTIPhone.js +39 -1
- package/lib/domain/Phone/WebRTCPhone.js +43 -8
- package/lib/domain/__tests__/CallSession.test.js +41 -5
- package/lib/domain/__tests__/IndirectTransfer.test.js +9 -1
- package/lib/domain/__tests__/Room.test.js +9 -1
- package/lib/index.js +100 -14
- package/lib/service/CallApi.js +30 -0
- package/lib/service/getApiClient.js +30 -0
- package/lib/simple/Auth.js +100 -14
- package/lib/simple/Configuration.js +100 -14
- package/lib/simple/Directory.js +30 -0
- package/lib/simple/Phone.js +100 -14
- package/lib/simple/index.js +100 -14
- package/lib/simple/room/LocalParticipant.js +100 -14
- package/lib/simple/room/Participant.js +100 -14
- package/lib/simple/room/RemoteParticipant.js +100 -14
- package/lib/simple/room/Room.js +100 -14
- package/lib/simple/room/SipRoom.js +100 -14
- package/lib/simple/room/Stream.js +100 -14
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +100 -14
- package/lib/simple/utils.js +100 -14
- package/lib/web-rtc-client.js +57 -6
- package/package.json +1 -1
- package/src/api/calld.js +3 -0
- package/src/domain/CallSession.js +9 -1
- package/src/domain/MeetingStatus.js +27 -0
- package/src/domain/Phone/WebRTCPhone.js +34 -7
- package/src/domain/__tests__/CallSession.test.js +32 -4
- package/src/web-rtc-client.js +27 -6
package/lib/service/CallApi.js
CHANGED
|
@@ -4022,6 +4022,34 @@ class IndirectTransfer {
|
|
|
4022
4022
|
}
|
|
4023
4023
|
}
|
|
4024
4024
|
|
|
4025
|
+
//
|
|
4026
|
+
|
|
4027
|
+
|
|
4028
|
+
|
|
4029
|
+
|
|
4030
|
+
|
|
4031
|
+
class MeetingStatus {
|
|
4032
|
+
|
|
4033
|
+
|
|
4034
|
+
|
|
4035
|
+
|
|
4036
|
+
constructor({
|
|
4037
|
+
full,
|
|
4038
|
+
} = {}) {
|
|
4039
|
+
this.full = full;
|
|
4040
|
+
|
|
4041
|
+
// Useful to compare instead of instanceof with minified code
|
|
4042
|
+
this.type = 'MeetingStatus';
|
|
4043
|
+
}
|
|
4044
|
+
|
|
4045
|
+
static parse(plain ) {
|
|
4046
|
+
return new MeetingStatus({
|
|
4047
|
+
full: plain.full,
|
|
4048
|
+
});
|
|
4049
|
+
}
|
|
4050
|
+
|
|
4051
|
+
}
|
|
4052
|
+
|
|
4025
4053
|
/* */
|
|
4026
4054
|
|
|
4027
4055
|
|
|
@@ -4216,6 +4244,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4216
4244
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
4217
4245
|
ApiRequester.successResponseParser),
|
|
4218
4246
|
|
|
4247
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
4248
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
4219
4249
|
});
|
|
4220
4250
|
|
|
4221
4251
|
//
|
|
@@ -4024,6 +4024,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4024
4024
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4025
4025
|
});
|
|
4026
4026
|
|
|
4027
|
+
//
|
|
4028
|
+
|
|
4029
|
+
|
|
4030
|
+
|
|
4031
|
+
|
|
4032
|
+
|
|
4033
|
+
class MeetingStatus {
|
|
4034
|
+
|
|
4035
|
+
|
|
4036
|
+
|
|
4037
|
+
|
|
4038
|
+
constructor({
|
|
4039
|
+
full,
|
|
4040
|
+
} = {}) {
|
|
4041
|
+
this.full = full;
|
|
4042
|
+
|
|
4043
|
+
// Useful to compare instead of instanceof with minified code
|
|
4044
|
+
this.type = 'MeetingStatus';
|
|
4045
|
+
}
|
|
4046
|
+
|
|
4047
|
+
static parse(plain ) {
|
|
4048
|
+
return new MeetingStatus({
|
|
4049
|
+
full: plain.full,
|
|
4050
|
+
});
|
|
4051
|
+
}
|
|
4052
|
+
|
|
4053
|
+
}
|
|
4054
|
+
|
|
4027
4055
|
/* */
|
|
4028
4056
|
|
|
4029
4057
|
|
|
@@ -4218,6 +4246,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4218
4246
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
4219
4247
|
ApiRequester.successResponseParser),
|
|
4220
4248
|
|
|
4249
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
4250
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
4221
4251
|
});
|
|
4222
4252
|
|
|
4223
4253
|
//
|
package/lib/simple/Auth.js
CHANGED
|
@@ -3596,13 +3596,21 @@ class CallSession {
|
|
|
3596
3596
|
|
|
3597
3597
|
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
3598
3598
|
set answered(value ) {
|
|
3599
|
-
this.answerTime = value ? new Date() : null;
|
|
3599
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
3600
3600
|
}
|
|
3601
3601
|
|
|
3602
3602
|
get answered() {
|
|
3603
3603
|
return !!this.answerTime;
|
|
3604
3604
|
}
|
|
3605
3605
|
|
|
3606
|
+
toJSON() {
|
|
3607
|
+
const jsonObj = { ...this };
|
|
3608
|
+
// $FlowFixMe
|
|
3609
|
+
jsonObj.answered = this.answered;
|
|
3610
|
+
|
|
3611
|
+
return jsonObj;
|
|
3612
|
+
}
|
|
3613
|
+
|
|
3606
3614
|
static parseCall(call ) {
|
|
3607
3615
|
return new CallSession({
|
|
3608
3616
|
callId: call.id,
|
|
@@ -4854,6 +4862,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4854
4862
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4855
4863
|
});
|
|
4856
4864
|
|
|
4865
|
+
//
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
|
|
4869
|
+
|
|
4870
|
+
|
|
4871
|
+
class MeetingStatus {
|
|
4872
|
+
|
|
4873
|
+
|
|
4874
|
+
|
|
4875
|
+
|
|
4876
|
+
constructor({
|
|
4877
|
+
full,
|
|
4878
|
+
} = {}) {
|
|
4879
|
+
this.full = full;
|
|
4880
|
+
|
|
4881
|
+
// Useful to compare instead of instanceof with minified code
|
|
4882
|
+
this.type = 'MeetingStatus';
|
|
4883
|
+
}
|
|
4884
|
+
|
|
4885
|
+
static parse(plain ) {
|
|
4886
|
+
return new MeetingStatus({
|
|
4887
|
+
full: plain.full,
|
|
4888
|
+
});
|
|
4889
|
+
}
|
|
4890
|
+
|
|
4891
|
+
}
|
|
4892
|
+
|
|
4857
4893
|
/* */
|
|
4858
4894
|
|
|
4859
4895
|
|
|
@@ -5048,6 +5084,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5048
5084
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
5049
5085
|
ApiRequester.successResponseParser),
|
|
5050
5086
|
|
|
5087
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
5088
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
5051
5089
|
});
|
|
5052
5090
|
|
|
5053
5091
|
//
|
|
@@ -6373,7 +6411,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6373
6411
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6374
6412
|
class CanceledCallError extends Error {}
|
|
6375
6413
|
|
|
6376
|
-
const MAX_REGISTER_TRIES =
|
|
6414
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6377
6415
|
|
|
6378
6416
|
|
|
6379
6417
|
|
|
@@ -6427,6 +6465,7 @@ class WebRTCClient extends Emitter {
|
|
|
6427
6465
|
|
|
6428
6466
|
|
|
6429
6467
|
|
|
6468
|
+
|
|
6430
6469
|
|
|
6431
6470
|
// sugar
|
|
6432
6471
|
|
|
@@ -6489,6 +6528,7 @@ class WebRTCClient extends Emitter {
|
|
|
6489
6528
|
this.conferences = {};
|
|
6490
6529
|
this.networkMonitoringInterval = {};
|
|
6491
6530
|
this.sessionNetworkStats = {};
|
|
6531
|
+
this.forceClosed = false;
|
|
6492
6532
|
|
|
6493
6533
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6494
6534
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6610,6 +6650,8 @@ class WebRTCClient extends Emitter {
|
|
|
6610
6650
|
skipRegister: this.skipRegister,
|
|
6611
6651
|
};
|
|
6612
6652
|
|
|
6653
|
+
this.forceClosed = false;
|
|
6654
|
+
|
|
6613
6655
|
if (this.skipRegister) {
|
|
6614
6656
|
logger$9.info('sdk webrtc skip register...', logInfo);
|
|
6615
6657
|
return Promise.resolve();
|
|
@@ -6634,7 +6676,15 @@ class WebRTCClient extends Emitter {
|
|
|
6634
6676
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6635
6677
|
|
|
6636
6678
|
const onRegisterFailed = () => {
|
|
6637
|
-
logger$9.info('sdk webrtc registering failed', {
|
|
6679
|
+
logger$9.info('sdk webrtc registering failed', {
|
|
6680
|
+
tries,
|
|
6681
|
+
registerer: !!this.registerer,
|
|
6682
|
+
forceClosed: this.forceClosed,
|
|
6683
|
+
});
|
|
6684
|
+
if (this.forceClosed) {
|
|
6685
|
+
return;
|
|
6686
|
+
}
|
|
6687
|
+
|
|
6638
6688
|
this.connectionPromise = null;
|
|
6639
6689
|
if (this.registerer && this.registerer.waiting) {
|
|
6640
6690
|
this.registerer.waitingToggle(false);
|
|
@@ -6912,8 +6962,9 @@ class WebRTCClient extends Emitter {
|
|
|
6912
6962
|
}
|
|
6913
6963
|
}
|
|
6914
6964
|
|
|
6915
|
-
async close() {
|
|
6916
|
-
logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
6965
|
+
async close(force = false) {
|
|
6966
|
+
logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
6967
|
+
this.forceClosed = force;
|
|
6917
6968
|
this._cleanupMedia();
|
|
6918
6969
|
this.connectionPromise = null;
|
|
6919
6970
|
|
|
@@ -6932,7 +6983,7 @@ class WebRTCClient extends Emitter {
|
|
|
6932
6983
|
this.userAgent.delegate = null;
|
|
6933
6984
|
this.userAgent.stateChange.removeAllListeners();
|
|
6934
6985
|
|
|
6935
|
-
await this._disconnectTransport();
|
|
6986
|
+
await this._disconnectTransport(force);
|
|
6936
6987
|
|
|
6937
6988
|
this._cleanupRegister();
|
|
6938
6989
|
|
|
@@ -8368,7 +8419,15 @@ class WebRTCClient extends Emitter {
|
|
|
8368
8419
|
return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8369
8420
|
}
|
|
8370
8421
|
|
|
8371
|
-
async _disconnectTransport() {
|
|
8422
|
+
async _disconnectTransport(force = false) {
|
|
8423
|
+
if (force) {
|
|
8424
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
8425
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
8426
|
+
// eslint-disable-next-line
|
|
8427
|
+
this.userAgent.transport._ws.close(1000);
|
|
8428
|
+
return;
|
|
8429
|
+
}
|
|
8430
|
+
|
|
8372
8431
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8373
8432
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8374
8433
|
try {
|
|
@@ -9105,6 +9164,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9105
9164
|
}
|
|
9106
9165
|
|
|
9107
9166
|
callSession.answerTime = new Date();
|
|
9167
|
+
this._updateCallSession(callSession);
|
|
9108
9168
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
9109
9169
|
|
|
9110
9170
|
return callSession;
|
|
@@ -9314,6 +9374,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9314
9374
|
return Promise.resolve(null);
|
|
9315
9375
|
}
|
|
9316
9376
|
|
|
9377
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9378
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9379
|
+
logger$8.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9380
|
+
return Promise.resolve(null);
|
|
9381
|
+
}
|
|
9382
|
+
|
|
9317
9383
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9318
9384
|
logger$8.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9319
9385
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -9321,6 +9387,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9321
9387
|
|
|
9322
9388
|
this.shouldSendReinvite = false;
|
|
9323
9389
|
callSession.answerTime = new Date();
|
|
9390
|
+
this._updateCallSession(callSession);
|
|
9324
9391
|
this.acceptedSessions[callSession.getId()] = true;
|
|
9325
9392
|
|
|
9326
9393
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -9420,7 +9487,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9420
9487
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
9421
9488
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
9422
9489
|
logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
9423
|
-
this.holdSipSession(this.currentSipSession,
|
|
9490
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
9424
9491
|
}
|
|
9425
9492
|
|
|
9426
9493
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -9631,6 +9698,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9631
9698
|
}
|
|
9632
9699
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
9633
9700
|
callSession.creationTime = new Date();
|
|
9701
|
+
this._updateCallSession(callSession);
|
|
9634
9702
|
|
|
9635
9703
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
9636
9704
|
|
|
@@ -9772,7 +9840,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9772
9840
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
9773
9841
|
}
|
|
9774
9842
|
|
|
9775
|
-
async close() {
|
|
9843
|
+
async close(force = false) {
|
|
9776
9844
|
logger$8.info('WebRTC close');
|
|
9777
9845
|
|
|
9778
9846
|
try {
|
|
@@ -9784,7 +9852,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9784
9852
|
logger$8.error('WebRTC close, unregister error', e);
|
|
9785
9853
|
}
|
|
9786
9854
|
|
|
9787
|
-
this.client.close();
|
|
9855
|
+
this.client.close(force);
|
|
9788
9856
|
this.unbind();
|
|
9789
9857
|
|
|
9790
9858
|
this.incomingSessions = [];
|
|
@@ -9910,6 +9978,8 @@ class WebRTCPhone extends Emitter {
|
|
|
9910
9978
|
}
|
|
9911
9979
|
|
|
9912
9980
|
callSession.creationTime = new Date();
|
|
9981
|
+
this._updateCallSession(callSession);
|
|
9982
|
+
|
|
9913
9983
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
9914
9984
|
});
|
|
9915
9985
|
|
|
@@ -9934,9 +10004,17 @@ class WebRTCPhone extends Emitter {
|
|
|
9934
10004
|
});
|
|
9935
10005
|
|
|
9936
10006
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
9937
|
-
|
|
10007
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10008
|
+
const hasSession = sessionId in this.callSessions;
|
|
9938
10009
|
|
|
9939
|
-
|
|
10010
|
+
logger$8.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10011
|
+
|
|
10012
|
+
if (!hasSession) {
|
|
10013
|
+
logger$8.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10014
|
+
return;
|
|
10015
|
+
}
|
|
10016
|
+
|
|
10017
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
9940
10018
|
|
|
9941
10019
|
if (this.audioOutputDeviceId) {
|
|
9942
10020
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -9953,6 +10031,8 @@ class WebRTCPhone extends Emitter {
|
|
|
9953
10031
|
logger$8.info('WebRTC call rejected', session.id);
|
|
9954
10032
|
const callSession = this._createCallSession(session);
|
|
9955
10033
|
callSession.endTime = new Date();
|
|
10034
|
+
this._updateCallSession(callSession);
|
|
10035
|
+
|
|
9956
10036
|
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
9957
10037
|
});
|
|
9958
10038
|
|
|
@@ -10070,9 +10150,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10070
10150
|
return this.client.getSipSessionId(sipSession);
|
|
10071
10151
|
}
|
|
10072
10152
|
|
|
10073
|
-
|
|
10153
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10074
10154
|
const sipSession = this.findSipSession(callSession);
|
|
10075
|
-
|
|
10155
|
+
|
|
10156
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10157
|
+
}
|
|
10158
|
+
|
|
10159
|
+
_updateCallSession(callSession ) {
|
|
10160
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10076
10161
|
|
|
10077
10162
|
if (sipSessionId) {
|
|
10078
10163
|
this.callSessions[sipSessionId] = callSession;
|
|
@@ -10177,6 +10262,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10177
10262
|
displayName: identity ? identity.displayName || number : number,
|
|
10178
10263
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
10179
10264
|
creationTime: fromSession ? fromSession.creationTime : null,
|
|
10265
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
10180
10266
|
endTime: fromSession ? fromSession.endTime : null,
|
|
10181
10267
|
answered: state === sessionState.SessionState.Established,
|
|
10182
10268
|
paused: this.client.isCallHeld(sipSession),
|
|
@@ -3594,13 +3594,21 @@ class CallSession {
|
|
|
3594
3594
|
|
|
3595
3595
|
// Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
|
|
3596
3596
|
set answered(value ) {
|
|
3597
|
-
this.answerTime = value ? new Date() : null;
|
|
3597
|
+
this.answerTime = value ? this.answerTime || new Date() : null;
|
|
3598
3598
|
}
|
|
3599
3599
|
|
|
3600
3600
|
get answered() {
|
|
3601
3601
|
return !!this.answerTime;
|
|
3602
3602
|
}
|
|
3603
3603
|
|
|
3604
|
+
toJSON() {
|
|
3605
|
+
const jsonObj = { ...this };
|
|
3606
|
+
// $FlowFixMe
|
|
3607
|
+
jsonObj.answered = this.answered;
|
|
3608
|
+
|
|
3609
|
+
return jsonObj;
|
|
3610
|
+
}
|
|
3611
|
+
|
|
3604
3612
|
static parseCall(call ) {
|
|
3605
3613
|
return new CallSession({
|
|
3606
3614
|
callId: call.id,
|
|
@@ -4852,6 +4860,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4852
4860
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4853
4861
|
});
|
|
4854
4862
|
|
|
4863
|
+
//
|
|
4864
|
+
|
|
4865
|
+
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
|
|
4869
|
+
class MeetingStatus {
|
|
4870
|
+
|
|
4871
|
+
|
|
4872
|
+
|
|
4873
|
+
|
|
4874
|
+
constructor({
|
|
4875
|
+
full,
|
|
4876
|
+
} = {}) {
|
|
4877
|
+
this.full = full;
|
|
4878
|
+
|
|
4879
|
+
// Useful to compare instead of instanceof with minified code
|
|
4880
|
+
this.type = 'MeetingStatus';
|
|
4881
|
+
}
|
|
4882
|
+
|
|
4883
|
+
static parse(plain ) {
|
|
4884
|
+
return new MeetingStatus({
|
|
4885
|
+
full: plain.full,
|
|
4886
|
+
});
|
|
4887
|
+
}
|
|
4888
|
+
|
|
4889
|
+
}
|
|
4890
|
+
|
|
4855
4891
|
/* */
|
|
4856
4892
|
|
|
4857
4893
|
|
|
@@ -5046,6 +5082,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
5046
5082
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
5047
5083
|
ApiRequester.successResponseParser),
|
|
5048
5084
|
|
|
5085
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
5086
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
5049
5087
|
});
|
|
5050
5088
|
|
|
5051
5089
|
//
|
|
@@ -6371,7 +6409,7 @@ const events$1 = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
|
|
|
6371
6409
|
const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
|
|
6372
6410
|
class CanceledCallError extends Error {}
|
|
6373
6411
|
|
|
6374
|
-
const MAX_REGISTER_TRIES =
|
|
6412
|
+
const MAX_REGISTER_TRIES = 5;
|
|
6375
6413
|
|
|
6376
6414
|
|
|
6377
6415
|
|
|
@@ -6425,6 +6463,7 @@ class WebRTCClient extends Emitter {
|
|
|
6425
6463
|
|
|
6426
6464
|
|
|
6427
6465
|
|
|
6466
|
+
|
|
6428
6467
|
|
|
6429
6468
|
// sugar
|
|
6430
6469
|
|
|
@@ -6487,6 +6526,7 @@ class WebRTCClient extends Emitter {
|
|
|
6487
6526
|
this.conferences = {};
|
|
6488
6527
|
this.networkMonitoringInterval = {};
|
|
6489
6528
|
this.sessionNetworkStats = {};
|
|
6529
|
+
this.forceClosed = false;
|
|
6490
6530
|
|
|
6491
6531
|
this._boundOnHeartbeat = this._onHeartbeat.bind(this);
|
|
6492
6532
|
this.heartbeat = new Heartbeat(config.heartbeatDelay, config.heartbeatTimeout, config.maxHeartbeats);
|
|
@@ -6608,6 +6648,8 @@ class WebRTCClient extends Emitter {
|
|
|
6608
6648
|
skipRegister: this.skipRegister,
|
|
6609
6649
|
};
|
|
6610
6650
|
|
|
6651
|
+
this.forceClosed = false;
|
|
6652
|
+
|
|
6611
6653
|
if (this.skipRegister) {
|
|
6612
6654
|
logger$9.info('sdk webrtc skip register...', logInfo);
|
|
6613
6655
|
return Promise.resolve();
|
|
@@ -6632,7 +6674,15 @@ class WebRTCClient extends Emitter {
|
|
|
6632
6674
|
const registerOptions = this._isWeb() ? {} : { extraContactHeaderParams: ['mobility=mobile'] };
|
|
6633
6675
|
|
|
6634
6676
|
const onRegisterFailed = () => {
|
|
6635
|
-
logger$9.info('sdk webrtc registering failed', {
|
|
6677
|
+
logger$9.info('sdk webrtc registering failed', {
|
|
6678
|
+
tries,
|
|
6679
|
+
registerer: !!this.registerer,
|
|
6680
|
+
forceClosed: this.forceClosed,
|
|
6681
|
+
});
|
|
6682
|
+
if (this.forceClosed) {
|
|
6683
|
+
return;
|
|
6684
|
+
}
|
|
6685
|
+
|
|
6636
6686
|
this.connectionPromise = null;
|
|
6637
6687
|
if (this.registerer && this.registerer.waiting) {
|
|
6638
6688
|
this.registerer.waitingToggle(false);
|
|
@@ -6910,8 +6960,9 @@ class WebRTCClient extends Emitter {
|
|
|
6910
6960
|
}
|
|
6911
6961
|
}
|
|
6912
6962
|
|
|
6913
|
-
async close() {
|
|
6914
|
-
logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent });
|
|
6963
|
+
async close(force = false) {
|
|
6964
|
+
logger$9.info('sdk webrtc closing client', { userAgent: !!this.userAgent, force });
|
|
6965
|
+
this.forceClosed = force;
|
|
6915
6966
|
this._cleanupMedia();
|
|
6916
6967
|
this.connectionPromise = null;
|
|
6917
6968
|
|
|
@@ -6930,7 +6981,7 @@ class WebRTCClient extends Emitter {
|
|
|
6930
6981
|
this.userAgent.delegate = null;
|
|
6931
6982
|
this.userAgent.stateChange.removeAllListeners();
|
|
6932
6983
|
|
|
6933
|
-
await this._disconnectTransport();
|
|
6984
|
+
await this._disconnectTransport(force);
|
|
6934
6985
|
|
|
6935
6986
|
this._cleanupRegister();
|
|
6936
6987
|
|
|
@@ -8366,7 +8417,15 @@ class WebRTCClient extends Emitter {
|
|
|
8366
8417
|
return userAgent.UserAgent.makeURI(`sip:${target}@${this.config.host}`);
|
|
8367
8418
|
}
|
|
8368
8419
|
|
|
8369
|
-
async _disconnectTransport() {
|
|
8420
|
+
async _disconnectTransport(force = false) {
|
|
8421
|
+
if (force) {
|
|
8422
|
+
// Bypass sip.js state machine that prevent to close WS with the state `Connecting`
|
|
8423
|
+
this.userAgent.transport.disconnectResolve = () => {};
|
|
8424
|
+
// eslint-disable-next-line
|
|
8425
|
+
this.userAgent.transport._ws.close(1000);
|
|
8426
|
+
return;
|
|
8427
|
+
}
|
|
8428
|
+
|
|
8370
8429
|
// Check if `disconnectPromise` is not present to avoid `Disconnect promise must not be defined` errors.
|
|
8371
8430
|
if (this.userAgent && this.userAgent.transport && !this.userAgent.transport.disconnectPromise) {
|
|
8372
8431
|
try {
|
|
@@ -9103,6 +9162,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9103
9162
|
}
|
|
9104
9163
|
|
|
9105
9164
|
callSession.answerTime = new Date();
|
|
9165
|
+
this._updateCallSession(callSession);
|
|
9106
9166
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
9107
9167
|
|
|
9108
9168
|
return callSession;
|
|
@@ -9312,6 +9372,12 @@ class WebRTCPhone extends Emitter {
|
|
|
9312
9372
|
return Promise.resolve(null);
|
|
9313
9373
|
}
|
|
9314
9374
|
|
|
9375
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
9376
|
+
if (sipSessionId && !(sipSessionId in this.callSessions)) {
|
|
9377
|
+
logger$8.warn('Call session already ended or not found, can\'t accept it.', { sipSessionId });
|
|
9378
|
+
return Promise.resolve(null);
|
|
9379
|
+
}
|
|
9380
|
+
|
|
9315
9381
|
if (callSession.getId() in this.acceptedSessions) {
|
|
9316
9382
|
logger$8.warn('CallSession already accepted.', { id: callSession ? callSession.getId() : 'n/a' });
|
|
9317
9383
|
return Promise.resolve(callSession.sipCallId);
|
|
@@ -9319,6 +9385,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9319
9385
|
|
|
9320
9386
|
this.shouldSendReinvite = false;
|
|
9321
9387
|
callSession.answerTime = new Date();
|
|
9388
|
+
this._updateCallSession(callSession);
|
|
9322
9389
|
this.acceptedSessions[callSession.getId()] = true;
|
|
9323
9390
|
|
|
9324
9391
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -9418,7 +9485,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9418
9485
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
9419
9486
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
9420
9487
|
logger$8.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
9421
|
-
this.holdSipSession(this.currentSipSession,
|
|
9488
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
9422
9489
|
}
|
|
9423
9490
|
|
|
9424
9491
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -9629,6 +9696,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9629
9696
|
}
|
|
9630
9697
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
9631
9698
|
callSession.creationTime = new Date();
|
|
9699
|
+
this._updateCallSession(callSession);
|
|
9632
9700
|
|
|
9633
9701
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
9634
9702
|
|
|
@@ -9770,7 +9838,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9770
9838
|
return this.client && this.client.isConference(callSession.sipCallId);
|
|
9771
9839
|
}
|
|
9772
9840
|
|
|
9773
|
-
async close() {
|
|
9841
|
+
async close(force = false) {
|
|
9774
9842
|
logger$8.info('WebRTC close');
|
|
9775
9843
|
|
|
9776
9844
|
try {
|
|
@@ -9782,7 +9850,7 @@ class WebRTCPhone extends Emitter {
|
|
|
9782
9850
|
logger$8.error('WebRTC close, unregister error', e);
|
|
9783
9851
|
}
|
|
9784
9852
|
|
|
9785
|
-
this.client.close();
|
|
9853
|
+
this.client.close(force);
|
|
9786
9854
|
this.unbind();
|
|
9787
9855
|
|
|
9788
9856
|
this.incomingSessions = [];
|
|
@@ -9908,6 +9976,8 @@ class WebRTCPhone extends Emitter {
|
|
|
9908
9976
|
}
|
|
9909
9977
|
|
|
9910
9978
|
callSession.creationTime = new Date();
|
|
9979
|
+
this._updateCallSession(callSession);
|
|
9980
|
+
|
|
9911
9981
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
9912
9982
|
});
|
|
9913
9983
|
|
|
@@ -9932,9 +10002,17 @@ class WebRTCPhone extends Emitter {
|
|
|
9932
10002
|
});
|
|
9933
10003
|
|
|
9934
10004
|
this.client.on(this.client.ACCEPTED, (sipSession ) => {
|
|
9935
|
-
|
|
10005
|
+
const sessionId = this.getSipSessionId(sipSession);
|
|
10006
|
+
const hasSession = sessionId in this.callSessions;
|
|
9936
10007
|
|
|
9937
|
-
|
|
10008
|
+
logger$8.info('WebRTC call accepted', { sipId: sessionId, hasSession });
|
|
10009
|
+
|
|
10010
|
+
if (!hasSession) {
|
|
10011
|
+
logger$8.warn('Call accepted ignored, session is no longer present in the WebRtcPhone', { sessionId });
|
|
10012
|
+
return;
|
|
10013
|
+
}
|
|
10014
|
+
|
|
10015
|
+
this._onCallAccepted(sipSession, this.client.hasVideo(sessionId));
|
|
9938
10016
|
|
|
9939
10017
|
if (this.audioOutputDeviceId) {
|
|
9940
10018
|
this.client.changeAudioOutputDevice(this.audioOutputDeviceId);
|
|
@@ -9951,6 +10029,8 @@ class WebRTCPhone extends Emitter {
|
|
|
9951
10029
|
logger$8.info('WebRTC call rejected', session.id);
|
|
9952
10030
|
const callSession = this._createCallSession(session);
|
|
9953
10031
|
callSession.endTime = new Date();
|
|
10032
|
+
this._updateCallSession(callSession);
|
|
10033
|
+
|
|
9954
10034
|
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
9955
10035
|
});
|
|
9956
10036
|
|
|
@@ -10068,9 +10148,14 @@ class WebRTCPhone extends Emitter {
|
|
|
10068
10148
|
return this.client.getSipSessionId(sipSession);
|
|
10069
10149
|
}
|
|
10070
10150
|
|
|
10071
|
-
|
|
10151
|
+
getSipSessionIdFromCallSession(callSession ) {
|
|
10072
10152
|
const sipSession = this.findSipSession(callSession);
|
|
10073
|
-
|
|
10153
|
+
|
|
10154
|
+
return sipSession ? this.getSipSessionId(sipSession) : null;
|
|
10155
|
+
}
|
|
10156
|
+
|
|
10157
|
+
_updateCallSession(callSession ) {
|
|
10158
|
+
const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
|
|
10074
10159
|
|
|
10075
10160
|
if (sipSessionId) {
|
|
10076
10161
|
this.callSessions[sipSessionId] = callSession;
|
|
@@ -10175,6 +10260,7 @@ class WebRTCPhone extends Emitter {
|
|
|
10175
10260
|
displayName: identity ? identity.displayName || number : number,
|
|
10176
10261
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
10177
10262
|
creationTime: fromSession ? fromSession.creationTime : null,
|
|
10263
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
10178
10264
|
endTime: fromSession ? fromSession.endTime : null,
|
|
10179
10265
|
answered: state === sessionState.SessionState.Established,
|
|
10180
10266
|
paused: this.client.isCallHeld(sipSession),
|
package/lib/simple/Directory.js
CHANGED
|
@@ -4022,6 +4022,34 @@ var chatdMethods = (client , baseUrl ) => ({
|
|
|
4022
4022
|
client.get(`${baseUrl}/users/me/rooms/messages`, options),
|
|
4023
4023
|
});
|
|
4024
4024
|
|
|
4025
|
+
//
|
|
4026
|
+
|
|
4027
|
+
|
|
4028
|
+
|
|
4029
|
+
|
|
4030
|
+
|
|
4031
|
+
class MeetingStatus {
|
|
4032
|
+
|
|
4033
|
+
|
|
4034
|
+
|
|
4035
|
+
|
|
4036
|
+
constructor({
|
|
4037
|
+
full,
|
|
4038
|
+
} = {}) {
|
|
4039
|
+
this.full = full;
|
|
4040
|
+
|
|
4041
|
+
// Useful to compare instead of instanceof with minified code
|
|
4042
|
+
this.type = 'MeetingStatus';
|
|
4043
|
+
}
|
|
4044
|
+
|
|
4045
|
+
static parse(plain ) {
|
|
4046
|
+
return new MeetingStatus({
|
|
4047
|
+
full: plain.full,
|
|
4048
|
+
});
|
|
4049
|
+
}
|
|
4050
|
+
|
|
4051
|
+
}
|
|
4052
|
+
|
|
4025
4053
|
/* */
|
|
4026
4054
|
|
|
4027
4055
|
|
|
@@ -4216,6 +4244,8 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4216
4244
|
client.put(`${baseUrl}/users/me/calls/${callId}/record/resume`, null, null,
|
|
4217
4245
|
ApiRequester.successResponseParser),
|
|
4218
4246
|
|
|
4247
|
+
guestGetMeetingStatus: (meetingUuid ) =>
|
|
4248
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}/status`).then(MeetingStatus.parse),
|
|
4219
4249
|
});
|
|
4220
4250
|
|
|
4221
4251
|
//
|