@wazo/sdk 0.37.27 → 0.37.31
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/README.md +3 -2
- package/dist/wazo-sdk.js +4 -4
- package/esm/__tests__/web-rtc-client.test.js +9 -1
- package/esm/checker/Checker.js +9 -1
- package/esm/checker/checks/index.js +9 -1
- package/esm/checker/checks/webrtc-transport.js +9 -1
- package/esm/checker/checks/webrtc.js +9 -1
- package/esm/domain/CallSession.js +29 -2
- package/esm/domain/Phone/CTIPhone.js +29 -2
- package/esm/domain/Phone/WebRTCPhone.js +57 -4
- package/esm/domain/SFUNotAvailableError.js +9 -0
- package/esm/domain/__tests__/CallSession.test.js +46 -2
- package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
- package/esm/domain/__tests__/Room.test.js +29 -2
- package/esm/index.js +77 -5
- package/esm/simple/Auth.js +76 -5
- package/esm/simple/Configuration.js +76 -5
- package/esm/simple/Phone.js +76 -5
- package/esm/simple/index.js +76 -5
- package/esm/simple/room/LocalParticipant.js +76 -5
- package/esm/simple/room/Participant.js +76 -5
- package/esm/simple/room/RemoteParticipant.js +76 -5
- package/esm/simple/room/Room.js +76 -5
- package/esm/simple/room/SipRoom.js +76 -5
- package/esm/simple/room/Stream.js +76 -5
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +76 -5
- package/esm/simple/utils.js +76 -5
- package/esm/web-rtc-client.js +9 -1
- package/lib/__tests__/web-rtc-client.test.js +9 -1
- package/lib/checker/Checker.js +9 -1
- package/lib/checker/checks/index.js +9 -1
- package/lib/checker/checks/webrtc-transport.js +9 -1
- package/lib/checker/checks/webrtc.js +9 -1
- package/lib/domain/CallSession.js +29 -2
- package/lib/domain/Phone/CTIPhone.js +29 -2
- package/lib/domain/Phone/WebRTCPhone.js +57 -3
- package/lib/domain/SFUNotAvailableError.js +11 -0
- package/lib/domain/__tests__/CallSession.test.js +46 -2
- package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
- package/lib/domain/__tests__/Room.test.js +29 -2
- package/lib/index.js +77 -5
- package/lib/simple/Auth.js +76 -5
- package/lib/simple/Configuration.js +76 -5
- package/lib/simple/Phone.js +76 -5
- package/lib/simple/index.js +76 -5
- package/lib/simple/room/LocalParticipant.js +76 -5
- package/lib/simple/room/Participant.js +76 -5
- package/lib/simple/room/RemoteParticipant.js +76 -5
- package/lib/simple/room/Room.js +76 -5
- package/lib/simple/room/SipRoom.js +76 -5
- package/lib/simple/room/Stream.js +76 -5
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +76 -5
- package/lib/simple/utils.js +76 -5
- package/lib/web-rtc-client.js +9 -1
- package/package.json +1 -1
- package/src/domain/CallSession.js +32 -4
- package/src/domain/Phone/WebRTCPhone.js +27 -1
- package/src/domain/SFUNotAvailableError.js +7 -0
- package/src/domain/__tests__/CallSession.test.js +17 -0
- package/src/index.js +2 -0
- package/src/simple/Phone.js +2 -1
- package/src/simple/index.js +2 -0
- package/src/web-rtc-client.js +9 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
2
|
import { SessionState } from 'sip.js/lib/api/session-state';
|
|
3
|
+
import type { Session } from 'sip.js/lib/api/session';
|
|
3
4
|
|
|
4
5
|
import Call from './Call';
|
|
5
6
|
import newFrom from '../utils/new-from';
|
|
@@ -7,13 +8,16 @@ import updateFrom from '../utils/update-from';
|
|
|
7
8
|
|
|
8
9
|
type CallSessionArguments = {
|
|
9
10
|
answered: boolean,
|
|
11
|
+
answerTime?: ?Date,
|
|
10
12
|
answeredBySystem: boolean,
|
|
11
13
|
call: ?Call,
|
|
12
14
|
callId: string,
|
|
13
15
|
callerNumber: string,
|
|
14
16
|
cameraEnabled: boolean,
|
|
17
|
+
creationTime?: ?Date,
|
|
15
18
|
dialedExtension?: string | null,
|
|
16
19
|
displayName: string,
|
|
20
|
+
endTime?: ?Date,
|
|
17
21
|
isCaller: boolean,
|
|
18
22
|
muted: boolean,
|
|
19
23
|
videoMuted: boolean,
|
|
@@ -30,6 +34,7 @@ type CallSessionArguments = {
|
|
|
30
34
|
screensharing: boolean,
|
|
31
35
|
recording: boolean,
|
|
32
36
|
recordingPaused: boolean,
|
|
37
|
+
sipSession?: Session,
|
|
33
38
|
};
|
|
34
39
|
|
|
35
40
|
export default class CallSession {
|
|
@@ -49,11 +54,15 @@ export default class CallSession {
|
|
|
49
54
|
|
|
50
55
|
callerNumber: string;
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
creationTime: ?Date;
|
|
53
58
|
|
|
54
|
-
|
|
59
|
+
startTime: number; // = creationTime
|
|
60
|
+
|
|
61
|
+
answerTime: ?Date;
|
|
55
62
|
|
|
56
|
-
|
|
63
|
+
endTime: ?Date;
|
|
64
|
+
|
|
65
|
+
isCaller: boolean;
|
|
57
66
|
|
|
58
67
|
answeredBySystem: boolean;
|
|
59
68
|
|
|
@@ -89,6 +98,8 @@ export default class CallSession {
|
|
|
89
98
|
|
|
90
99
|
recordingPaused: boolean;
|
|
91
100
|
|
|
101
|
+
sipSession: Session;
|
|
102
|
+
|
|
92
103
|
constructor({
|
|
93
104
|
answered,
|
|
94
105
|
answeredBySystem,
|
|
@@ -101,6 +112,8 @@ export default class CallSession {
|
|
|
101
112
|
paused,
|
|
102
113
|
ringing,
|
|
103
114
|
startTime,
|
|
115
|
+
creationTime,
|
|
116
|
+
endTime,
|
|
104
117
|
cameraEnabled,
|
|
105
118
|
dialedExtension,
|
|
106
119
|
sipCallId,
|
|
@@ -113,12 +126,16 @@ export default class CallSession {
|
|
|
113
126
|
recording,
|
|
114
127
|
recordingPaused,
|
|
115
128
|
videoRemotelyDowngraded,
|
|
129
|
+
sipSession,
|
|
130
|
+
answerTime,
|
|
116
131
|
}: CallSessionArguments) {
|
|
117
132
|
this.callId = callId;
|
|
118
133
|
this.sipCallId = sipCallId;
|
|
119
134
|
this.displayName = displayName;
|
|
120
135
|
this.number = number;
|
|
136
|
+
this.creationTime = creationTime;
|
|
121
137
|
this.startTime = startTime;
|
|
138
|
+
this.endTime = endTime;
|
|
122
139
|
this.isCaller = isCaller;
|
|
123
140
|
this.answered = answered;
|
|
124
141
|
this.answeredBySystem = answeredBySystem;
|
|
@@ -137,6 +154,8 @@ export default class CallSession {
|
|
|
137
154
|
this.recording = recording || false;
|
|
138
155
|
this.recordingPaused = recordingPaused || false;
|
|
139
156
|
this.videoRemotelyDowngraded = videoRemotelyDowngraded;
|
|
157
|
+
this.sipSession = sipSession;
|
|
158
|
+
this.answerTime = answerTime || this.answerTime;
|
|
140
159
|
|
|
141
160
|
// Useful to compare instead of instanceof with minified code
|
|
142
161
|
this.type = 'CallSession';
|
|
@@ -167,7 +186,7 @@ export default class CallSession {
|
|
|
167
186
|
}
|
|
168
187
|
|
|
169
188
|
answer() {
|
|
170
|
-
this.
|
|
189
|
+
this.answerTime = new Date();
|
|
171
190
|
}
|
|
172
191
|
|
|
173
192
|
systemAnswer() {
|
|
@@ -323,6 +342,15 @@ export default class CallSession {
|
|
|
323
342
|
return newFrom(callSession, CallSession);
|
|
324
343
|
}
|
|
325
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
|
+
|
|
326
354
|
static parseCall(call: Call): CallSession {
|
|
327
355
|
return new CallSession({
|
|
328
356
|
callId: call.id,
|
|
@@ -30,6 +30,7 @@ export const ON_CAMERA_DISABLED = 'onCameraDisabled';
|
|
|
30
30
|
export const ON_CAMERA_RESUMED = 'onCameraResumed';
|
|
31
31
|
export const ON_CALL_CANCELED = 'onCallCanceled';
|
|
32
32
|
export const ON_CALL_FAILED = 'onCallFailed';
|
|
33
|
+
export const ON_CALL_REJECTED = 'onCallRejected';
|
|
33
34
|
export const ON_CALL_ENDED = 'onCallEnded';
|
|
34
35
|
export const ON_CALL_ENDING = 'onCallEnding';
|
|
35
36
|
export const ON_MESSAGE = 'onMessage';
|
|
@@ -74,6 +75,7 @@ export const events = [
|
|
|
74
75
|
ON_CAMERA_DISABLED,
|
|
75
76
|
ON_CALL_FAILED,
|
|
76
77
|
ON_CALL_ENDED,
|
|
78
|
+
ON_CALL_REJECTED,
|
|
77
79
|
ON_MESSAGE,
|
|
78
80
|
ON_REINVITE,
|
|
79
81
|
ON_TRACK,
|
|
@@ -430,6 +432,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
430
432
|
|
|
431
433
|
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
432
434
|
const callSession = this._createCallSession(sipSession);
|
|
435
|
+
callSession.endTime = new Date();
|
|
433
436
|
const wasCurrentSession = this._onCallTerminated(sipSession);
|
|
434
437
|
|
|
435
438
|
return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
|
|
@@ -627,6 +630,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
627
630
|
this.removeIncomingSessions(sipSessionId);
|
|
628
631
|
}
|
|
629
632
|
|
|
633
|
+
callSession.answerTime = new Date();
|
|
634
|
+
this._updateCallSession(callSession);
|
|
630
635
|
this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
|
|
631
636
|
|
|
632
637
|
return callSession;
|
|
@@ -842,6 +847,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
842
847
|
}
|
|
843
848
|
|
|
844
849
|
this.shouldSendReinvite = false;
|
|
850
|
+
callSession.answerTime = new Date();
|
|
851
|
+
this._updateCallSession(callSession);
|
|
845
852
|
this.acceptedSessions[callSession.getId()] = true;
|
|
846
853
|
|
|
847
854
|
this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
|
|
@@ -941,7 +948,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
941
948
|
// Hold current session if different from the current one (we don't want 2 sessions active at the same time).
|
|
942
949
|
if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
|
|
943
950
|
logger.info('WebRTC hold call after resume', { id: this.currentSipSession.id });
|
|
944
|
-
this.holdSipSession(this.currentSipSession,
|
|
951
|
+
this.holdSipSession(this.currentSipSession, this.currentCallSession);
|
|
945
952
|
}
|
|
946
953
|
|
|
947
954
|
const promise = this.unholdSipSession(sipSession, callSession, withEvent, isConference);
|
|
@@ -1151,6 +1158,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1151
1158
|
return Promise.resolve(null);
|
|
1152
1159
|
}
|
|
1153
1160
|
const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
|
|
1161
|
+
callSession.creationTime = new Date();
|
|
1162
|
+
this._updateCallSession(callSession);
|
|
1154
1163
|
|
|
1155
1164
|
this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
|
|
1156
1165
|
|
|
@@ -1429,6 +1438,9 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1429
1438
|
callSession);
|
|
1430
1439
|
}
|
|
1431
1440
|
|
|
1441
|
+
callSession.creationTime = new Date();
|
|
1442
|
+
this._updateCallSession(callSession);
|
|
1443
|
+
|
|
1432
1444
|
this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
|
|
1433
1445
|
});
|
|
1434
1446
|
|
|
@@ -1468,6 +1480,15 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1468
1480
|
this.eventEmitter.emit(ON_CALL_ERROR, e);
|
|
1469
1481
|
});
|
|
1470
1482
|
|
|
1483
|
+
this.client.on(this.client.REJECTED, session => {
|
|
1484
|
+
logger.info('WebRTC call rejected', session.id);
|
|
1485
|
+
const callSession = this._createCallSession(session);
|
|
1486
|
+
callSession.endTime = new Date();
|
|
1487
|
+
this._updateCallSession(callSession);
|
|
1488
|
+
|
|
1489
|
+
this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
|
|
1490
|
+
});
|
|
1491
|
+
|
|
1471
1492
|
this.client.on(this.client.UNREGISTERED, () => {
|
|
1472
1493
|
logger.info('WebRTC unregistered');
|
|
1473
1494
|
this.eventEmitter.emit(ON_UNREGISTERED);
|
|
@@ -1682,6 +1703,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1682
1703
|
const number = identity ? identity.uri._normal.user : null;
|
|
1683
1704
|
const { state } = sipSession || {};
|
|
1684
1705
|
const sessionId = this.getSipSessionId(sipSession);
|
|
1706
|
+
fromSession = fromSession || this.callSessions[sessionId];
|
|
1685
1707
|
|
|
1686
1708
|
const callSession = new CallSession({
|
|
1687
1709
|
callId: fromSession && fromSession.callId,
|
|
@@ -1689,6 +1711,9 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1689
1711
|
sipStatus: state,
|
|
1690
1712
|
displayName: identity ? identity.displayName || number : number,
|
|
1691
1713
|
startTime: fromSession ? fromSession.startTime : new Date(),
|
|
1714
|
+
creationTime: fromSession ? fromSession.creationTime : null,
|
|
1715
|
+
answerTime: fromSession ? fromSession.answerTime : null,
|
|
1716
|
+
endTime: fromSession ? fromSession.endTime : null,
|
|
1692
1717
|
answered: state === SessionState.Established,
|
|
1693
1718
|
paused: this.client.isCallHeld(sipSession),
|
|
1694
1719
|
isCaller: 'incoming' in extra ? !extra.incoming : false,
|
|
@@ -1699,6 +1724,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1699
1724
|
videoMuted: fromSession ? fromSession.isVideoMuted() : false,
|
|
1700
1725
|
recording: fromSession ? fromSession.isRecording() : false,
|
|
1701
1726
|
recordingPaused: false, // @TODO
|
|
1727
|
+
sipSession,
|
|
1702
1728
|
...extra,
|
|
1703
1729
|
});
|
|
1704
1730
|
|
|
@@ -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
|
});
|
package/src/index.js
CHANGED
|
@@ -9,6 +9,7 @@ import IssueReporter from './service/IssueReporter';
|
|
|
9
9
|
// Domain
|
|
10
10
|
import BadResponse from './domain/BadResponse';
|
|
11
11
|
import ServerError from './domain/ServerError';
|
|
12
|
+
import SFUNotAvailableError from './domain/SFUNotAvailableError';
|
|
12
13
|
import Call from './domain/Call';
|
|
13
14
|
import CallLog from './domain/CallLog';
|
|
14
15
|
import Recording from './domain/Recording';
|
|
@@ -95,6 +96,7 @@ export default {
|
|
|
95
96
|
WazoWebSocketClient: WebSocketClient,
|
|
96
97
|
BadResponse,
|
|
97
98
|
ServerError,
|
|
99
|
+
SFUNotAvailableError,
|
|
98
100
|
Call,
|
|
99
101
|
CallSession,
|
|
100
102
|
CTIPhone,
|
package/src/simple/Phone.js
CHANGED
|
@@ -14,6 +14,7 @@ import IssueReporter from '../service/IssueReporter';
|
|
|
14
14
|
import Emitter from '../utils/Emitter';
|
|
15
15
|
|
|
16
16
|
import Wazo from './index';
|
|
17
|
+
import SFUNotAvailableError from '../domain/SFUNotAvailableError';
|
|
17
18
|
|
|
18
19
|
const logger = IssueReporter.loggerFor('simple-phone');
|
|
19
20
|
const sipLogger = IssueReporter.loggerFor('sip.js');
|
|
@@ -397,7 +398,7 @@ class Phone extends Emitter {
|
|
|
397
398
|
|
|
398
399
|
checkSfu() {
|
|
399
400
|
if (!this.hasSfu()) {
|
|
400
|
-
throw new
|
|
401
|
+
throw new SFUNotAvailableError();
|
|
401
402
|
}
|
|
402
403
|
}
|
|
403
404
|
|
package/src/simple/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { CanceledCallError } from '../web-rtc-client';
|
|
|
15
15
|
|
|
16
16
|
import BadResponse from '../domain/BadResponse';
|
|
17
17
|
import ServerError from '../domain/ServerError';
|
|
18
|
+
import SFUNotAvailableError from '../domain/SFUNotAvailableError';
|
|
18
19
|
import Call from '../domain/Call';
|
|
19
20
|
import CallLog from '../domain/CallLog';
|
|
20
21
|
import Recording from '../domain/Recording';
|
|
@@ -101,6 +102,7 @@ const Wazo = {
|
|
|
101
102
|
InvalidSubscription,
|
|
102
103
|
InvalidAuthorization,
|
|
103
104
|
CanceledCallError,
|
|
105
|
+
SFUNotAvailableError,
|
|
104
106
|
};
|
|
105
107
|
|
|
106
108
|
if (window) {
|
package/src/web-rtc-client.js
CHANGED
|
@@ -87,6 +87,7 @@ type WebRtcConfig = {
|
|
|
87
87
|
displayName: string,
|
|
88
88
|
host: string,
|
|
89
89
|
port?: number,
|
|
90
|
+
websocketSip?: ?string,
|
|
90
91
|
authorizationUser: ?string,
|
|
91
92
|
password: ?string,
|
|
92
93
|
uri: string,
|
|
@@ -1703,6 +1704,13 @@ export default class WebRTCClient extends Emitter {
|
|
|
1703
1704
|
}
|
|
1704
1705
|
|
|
1705
1706
|
_createWebRTCConfiguration(configOverrides: Object = {}) {
|
|
1707
|
+
let { host } = this.config;
|
|
1708
|
+
let port = this.config.port || 443;
|
|
1709
|
+
|
|
1710
|
+
if (this.config.websocketSip) {
|
|
1711
|
+
[host, port = 443] = this.config.websocketSip.split(':');
|
|
1712
|
+
}
|
|
1713
|
+
|
|
1706
1714
|
const config: Object = {
|
|
1707
1715
|
authorizationUsername: this.config.authorizationUser,
|
|
1708
1716
|
authorizationPassword: this.config.password,
|
|
@@ -1738,7 +1746,7 @@ export default class WebRTCClient extends Emitter {
|
|
|
1738
1746
|
},
|
|
1739
1747
|
transportOptions: {
|
|
1740
1748
|
traceSip: configOverrides.traceSip || false,
|
|
1741
|
-
wsServers: `wss://${
|
|
1749
|
+
wsServers: `wss://${host}:${port}/api/asterisk/ws`,
|
|
1742
1750
|
},
|
|
1743
1751
|
sessionDescriptionHandlerFactoryOptions: {
|
|
1744
1752
|
modifiers: [replaceLocalIpModifier],
|