@wazo/sdk 0.37.0-rc.5 → 0.37.2
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 +5 -5
- package/esm/__tests__/api-client.test.js +93 -16
- package/esm/__tests__/web-rtc-client.test.js +153 -54
- package/esm/api/agentd.js +24 -3
- package/esm/api/amid.js +7 -1
- package/esm/api/application.js +24 -3
- package/esm/api/auth.js +24 -3
- package/esm/api/call-logd.js +78 -20
- package/esm/api/calld.js +24 -20
- package/esm/api/chatd.js +24 -3
- package/esm/api/confd.js +24 -3
- package/esm/api/ctid-ng.js +24 -3
- package/esm/api/dird.js +27 -6
- package/esm/api/webhookd.js +7 -1
- package/esm/api-client.js +93 -16
- package/esm/checker/Checker.js +156 -54
- package/esm/checker/checks/aor.js +95 -16
- package/esm/checker/checks/api.js +94 -16
- package/esm/checker/checks/index.js +156 -54
- package/esm/checker/checks/wazo-websocket.js +7 -1
- package/esm/checker/checks/webrtc-transport.js +153 -54
- package/esm/checker/checks/webrtc.js +153 -54
- package/esm/domain/AdHocAPIConference.js +1717 -1640
- package/esm/domain/CallLog.js +71 -19
- package/esm/domain/CallSession.js +1 -18
- package/esm/domain/Contact.js +3 -3
- package/esm/domain/Features.js +93 -16
- package/esm/domain/IndirectTransfer.js +0 -17
- package/esm/domain/Phone/CTIPhone.js +100 -19
- package/esm/domain/Phone/Phone.js +0 -17
- package/esm/domain/Phone/WebRTCPhone.js +51 -36
- package/esm/domain/Recording.js +51 -0
- package/esm/domain/Room.js +0 -17
- package/esm/domain/SwitchboardCall.js +0 -17
- package/esm/domain/__tests__/CallLog.test.js +89 -19
- package/esm/domain/__tests__/CallSession.test.js +1 -18
- package/esm/domain/__tests__/Contact.test.js +3 -3
- package/esm/domain/__tests__/IndirectTransfer.test.js +1 -18
- package/esm/domain/__tests__/Room.test.js +1 -18
- package/esm/domain/__tests__/Session.test.js +7 -0
- package/esm/index.js +3436 -2911
- package/esm/lib/WazoSessionDescriptionHandler.js +28 -10
- package/esm/service/CallApi.js +93 -16
- package/esm/service/IssueReporter.js +7 -1
- package/esm/service/__tests__/IssueReporter.test.js +26 -2
- package/esm/service/getApiClient.js +93 -16
- package/esm/simple/Auth.js +619 -97
- package/esm/simple/Configuration.js +619 -97
- package/esm/simple/Directory.js +93 -16
- package/esm/simple/Phone.js +3261 -2739
- package/esm/simple/Websocket.js +7 -1
- package/esm/simple/index.js +619 -97
- package/esm/simple/room/LocalParticipant.js +619 -97
- package/esm/simple/room/Participant.js +619 -97
- package/esm/simple/room/RemoteParticipant.js +619 -97
- package/esm/simple/room/Room.js +619 -97
- package/esm/simple/room/Stream.js +619 -97
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +619 -97
- package/esm/simple/utils.js +619 -97
- package/esm/utils/__tests__/api-requester.test.js +32 -6
- package/esm/utils/api-requester.js +24 -3
- package/esm/web-rtc-client.js +153 -54
- package/esm/websocket-client.js +7 -1
- package/lib/__tests__/api-client.test.js +93 -16
- package/lib/__tests__/web-rtc-client.test.js +154 -55
- package/lib/api/agentd.js +24 -3
- package/lib/api/amid.js +7 -1
- package/lib/api/application.js +24 -3
- package/lib/api/auth.js +24 -3
- package/lib/api/call-logd.js +78 -20
- package/lib/api/calld.js +24 -20
- package/lib/api/chatd.js +24 -3
- package/lib/api/confd.js +24 -3
- package/lib/api/ctid-ng.js +24 -3
- package/lib/api/dird.js +27 -6
- package/lib/api/webhookd.js +7 -1
- package/lib/api-client.js +93 -16
- package/lib/checker/Checker.js +157 -55
- package/lib/checker/checks/aor.js +95 -16
- package/lib/checker/checks/api.js +94 -16
- package/lib/checker/checks/index.js +157 -55
- package/lib/checker/checks/wazo-websocket.js +7 -1
- package/lib/checker/checks/webrtc-transport.js +154 -55
- package/lib/checker/checks/webrtc.js +154 -55
- package/lib/domain/AdHocAPIConference.js +1717 -1640
- package/lib/domain/CallLog.js +71 -19
- package/lib/domain/CallSession.js +1 -18
- package/lib/domain/Contact.js +3 -3
- package/lib/domain/Features.js +93 -16
- package/lib/domain/IndirectTransfer.js +0 -17
- package/lib/domain/Phone/CTIPhone.js +100 -19
- package/lib/domain/Phone/Phone.js +0 -16
- package/lib/domain/Phone/WebRTCPhone.js +51 -36
- package/lib/domain/Recording.js +57 -0
- package/lib/domain/Room.js +0 -17
- package/lib/domain/SwitchboardCall.js +0 -17
- package/lib/domain/__tests__/CallLog.test.js +89 -19
- package/lib/domain/__tests__/CallSession.test.js +1 -18
- package/lib/domain/__tests__/Contact.test.js +3 -3
- package/lib/domain/__tests__/IndirectTransfer.test.js +1 -18
- package/lib/domain/__tests__/Room.test.js +1 -18
- package/lib/domain/__tests__/Session.test.js +7 -0
- package/lib/index.js +3437 -2912
- package/lib/lib/WazoSessionDescriptionHandler.js +28 -10
- package/lib/service/CallApi.js +93 -16
- package/lib/service/IssueReporter.js +7 -1
- package/lib/service/__tests__/IssueReporter.test.js +26 -2
- package/lib/service/getApiClient.js +93 -16
- package/lib/simple/Auth.js +620 -98
- package/lib/simple/Configuration.js +620 -98
- package/lib/simple/Directory.js +93 -16
- package/lib/simple/Phone.js +3262 -2740
- package/lib/simple/Websocket.js +7 -1
- package/lib/simple/index.js +620 -98
- package/lib/simple/room/LocalParticipant.js +620 -98
- package/lib/simple/room/Participant.js +620 -98
- package/lib/simple/room/RemoteParticipant.js +620 -98
- package/lib/simple/room/Room.js +620 -98
- package/lib/simple/room/Stream.js +620 -98
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +620 -98
- package/lib/simple/utils.js +620 -98
- package/lib/utils/__tests__/api-requester.test.js +32 -6
- package/lib/utils/api-requester.js +24 -3
- package/lib/web-rtc-client.js +154 -55
- package/lib/websocket-client.js +7 -1
- package/package.json +1 -1
- package/src/api-client.js +4 -0
- package/src/checker/checks/aor.js +2 -0
- package/src/checker/checks/api.js +1 -0
- package/src/domain/CallLog.js +18 -11
- package/src/domain/CallSession.js +1 -2
- package/src/domain/Contact.js +3 -3
- package/src/domain/Phone/CTIPhone.js +6 -2
- package/src/domain/Phone/Phone.js +2 -0
- package/src/domain/Phone/WebRTCPhone.js +26 -16
- package/src/domain/Recording.js +48 -0
- package/src/domain/__tests__/CallLog.test.js +19 -0
- package/src/domain/__tests__/Session.test.js +7 -0
- package/src/index.js +6 -0
- package/src/lib/WazoSessionDescriptionHandler.js +21 -9
- package/src/service/IssueReporter.js +7 -1
- package/src/service/__tests__/IssueReporter.test.js +20 -1
- package/src/simple/Phone.js +5 -1
- package/src/simple/index.js +6 -0
- package/src/simple/room/Room.js +18 -15
- package/src/simple/room/Stream.js +1 -4
- package/src/utils/__tests__/api-requester.test.js +9 -4
- package/src/utils/api-requester.js +17 -2
- package/src/web-rtc-client.js +40 -13
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
require('webrtc-adapter');
|
|
4
4
|
var userAgentState = require('sip.js/lib/api/user-agent-state');
|
|
5
|
-
require('sip.js/lib/api/message');
|
|
6
5
|
var parser = require('sip.js/lib/core/messages/parser');
|
|
7
6
|
var constants = require('sip.js/lib/core/messages/methods/constants');
|
|
8
7
|
var uri = require('sip.js/lib/grammar/uri');
|
|
@@ -145,6 +144,7 @@ class ApiRequester {
|
|
|
145
144
|
|
|
146
145
|
|
|
147
146
|
|
|
147
|
+
|
|
148
148
|
|
|
149
149
|
|
|
150
150
|
|
|
@@ -184,6 +184,8 @@ class ApiRequester {
|
|
|
184
184
|
this.token = token;
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
this.shouldLogErrors = true;
|
|
188
|
+
|
|
187
189
|
methods.forEach(method => {
|
|
188
190
|
// $FlowFixMe
|
|
189
191
|
ApiRequester.prototype[method] = function sugar(...args) {
|
|
@@ -207,6 +209,14 @@ class ApiRequester {
|
|
|
207
209
|
this.fetchOptions = options;
|
|
208
210
|
}
|
|
209
211
|
|
|
212
|
+
disableErrorLogging() {
|
|
213
|
+
this.shouldLogErrors = false;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
enableErrorLogging() {
|
|
217
|
+
this.shouldLogErrors = true;
|
|
218
|
+
}
|
|
219
|
+
|
|
210
220
|
async call(
|
|
211
221
|
path ,
|
|
212
222
|
method = 'get',
|
|
@@ -267,7 +277,9 @@ class ApiRequester {
|
|
|
267
277
|
? exceptionClass.fromText(err, response.status)
|
|
268
278
|
: exceptionClass.fromResponse(err, response.status);
|
|
269
279
|
|
|
270
|
-
|
|
280
|
+
if (this.shouldLogErrors) {
|
|
281
|
+
logger$2.error('API error', error);
|
|
282
|
+
}
|
|
271
283
|
|
|
272
284
|
throw error;
|
|
273
285
|
});
|
|
@@ -275,7 +287,9 @@ class ApiRequester {
|
|
|
275
287
|
|
|
276
288
|
return newParse(response, isJson);
|
|
277
289
|
}).catch(error => {
|
|
278
|
-
|
|
290
|
+
if (this.shouldLogErrors) {
|
|
291
|
+
logger$2.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
|
|
292
|
+
}
|
|
279
293
|
|
|
280
294
|
throw error;
|
|
281
295
|
});
|
|
@@ -586,7 +600,13 @@ class IssueReporter {
|
|
|
586
600
|
}
|
|
587
601
|
|
|
588
602
|
_isLevelAbove(level1 , level2 ) {
|
|
589
|
-
|
|
603
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
604
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
605
|
+
if (index1 === -1 || index2 === -1) {
|
|
606
|
+
return false;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
return index1 > index2;
|
|
590
610
|
}
|
|
591
611
|
|
|
592
612
|
_makeCategory(category ) {
|
|
@@ -615,23 +635,6 @@ const areCandidateValid = (candidates ) =>
|
|
|
615
635
|
getSrflxOrRelay(candidates)
|
|
616
636
|
.length > 0;
|
|
617
637
|
|
|
618
|
-
const toggleVideoDirection = (sdp , direction ) => {
|
|
619
|
-
const parsedSdp = sdpParser__default['default'].parse(sdp);
|
|
620
|
-
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
621
|
-
...media,
|
|
622
|
-
...(media.type === 'video' ? { direction } : {}),
|
|
623
|
-
}));
|
|
624
|
-
|
|
625
|
-
return sdpParser__default['default'].write(parsedSdp);
|
|
626
|
-
};
|
|
627
|
-
|
|
628
|
-
const deactivateVideoModifier = (rawDescription ) => {
|
|
629
|
-
const description = rawDescription;
|
|
630
|
-
description.sdp = toggleVideoDirection(description.sdp, 'inactive');
|
|
631
|
-
|
|
632
|
-
return Promise.resolve(description);
|
|
633
|
-
};
|
|
634
|
-
|
|
635
638
|
const hasAnActiveVideo = (sdp ) => {
|
|
636
639
|
if (!sdp) {
|
|
637
640
|
return false;
|
|
@@ -743,6 +746,7 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
743
746
|
const iceRestart = options.offerOptions ? options.offerOptions.iceRestart : false;
|
|
744
747
|
|
|
745
748
|
const isConference = options ? !!options.conference : false;
|
|
749
|
+
const audioOnly = options ? !!options.audioOnly : false;
|
|
746
750
|
|
|
747
751
|
// We should wait for ice when iceRestart (reinvite) or for the first invite
|
|
748
752
|
// We shouldn't wait for ice when holding or resuming the call
|
|
@@ -769,16 +773,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
769
773
|
};
|
|
770
774
|
|
|
771
775
|
return this.getLocalMediaStream(options)
|
|
772
|
-
.then(() => this.updateDirection(options, isConference))
|
|
776
|
+
.then(() => this.updateDirection(options, isConference, audioOnly))
|
|
773
777
|
.then(() => this.createDataChannel(options))
|
|
774
778
|
.then(() => {
|
|
775
|
-
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options)) {
|
|
779
|
+
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
|
|
776
780
|
// Add a video an empty bundle to be able to replaceTrack when joining a conference without video
|
|
777
781
|
this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
|
|
778
782
|
}
|
|
779
783
|
})
|
|
780
784
|
.then(() => this.createLocalOfferOrAnswer(options))
|
|
781
|
-
.then(
|
|
785
|
+
.then(sessionDescription => this.setLocalSessionDescription(sessionDescription))
|
|
782
786
|
.then(() => this.waitForIceGatheringComplete(iceRestart, iceTimeout))
|
|
783
787
|
.then(() => this.getLocalSessionDescription())
|
|
784
788
|
.then(description => {
|
|
@@ -901,7 +905,8 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
901
905
|
}
|
|
902
906
|
|
|
903
907
|
// Overridden to send `inactive` in conference
|
|
904
|
-
updateDirection(options , isConference = false
|
|
908
|
+
updateDirection(options , isConference = false,
|
|
909
|
+
audioOnly = false) {
|
|
905
910
|
if (this._peerConnection === undefined) {
|
|
906
911
|
return Promise.reject(new Error('Peer connection closed.'));
|
|
907
912
|
}
|
|
@@ -916,14 +921,17 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
916
921
|
// if we are stable, assume we are creating a local offer
|
|
917
922
|
this.logger.debug('SessionDescriptionHandler.updateDirection - setting offer direction');
|
|
918
923
|
// determine the direction to offer given the current direction and hold state
|
|
919
|
-
const directionToOffer = (currentDirection ) => {
|
|
924
|
+
const directionToOffer = (currentDirection , transceiver /* RTCRtpTransceiver */) => {
|
|
920
925
|
if (isConference) {
|
|
926
|
+
if (audioOnly && transceiver.receiver.track && transceiver.receiver.track.kind === 'video') {
|
|
927
|
+
return 'sendonly';
|
|
928
|
+
}
|
|
921
929
|
return options && options.hold ? 'sendonly' : 'sendrecv';
|
|
922
930
|
}
|
|
923
931
|
|
|
924
932
|
switch (currentDirection) {
|
|
925
933
|
case 'inactive':
|
|
926
|
-
return options && options.hold ? 'inactive' : 'recvonly';
|
|
934
|
+
return options && options.hold ? 'inactive' : (isConference && !audioOnly ? 'sendrecv' : 'recvonly');
|
|
927
935
|
case 'recvonly':
|
|
928
936
|
return options && options.hold ? 'inactive' : 'recvonly';
|
|
929
937
|
case 'sendonly':
|
|
@@ -939,7 +947,7 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
939
947
|
// set the transceiver direction to the offer direction
|
|
940
948
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
941
949
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
942
|
-
const offerDirection = directionToOffer(transceiver.direction);
|
|
950
|
+
const offerDirection = directionToOffer(transceiver.direction, transceiver);
|
|
943
951
|
if (transceiver.direction !== offerDirection) {
|
|
944
952
|
// eslint-disable-next-line no-param-reassign
|
|
945
953
|
transceiver.direction = offerDirection;
|
|
@@ -998,6 +1006,13 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
998
1006
|
// set the transceiver direction to the answer direction
|
|
999
1007
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
1000
1008
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
1009
|
+
const { receiver } = transceiver;
|
|
1010
|
+
if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
|
|
1011
|
+
// eslint-disable-next-line no-param-reassign
|
|
1012
|
+
transceiver.direction = 'inactive';
|
|
1013
|
+
return;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1001
1016
|
if (transceiver.direction !== 'stopped' && transceiver.direction !== answerDirection) {
|
|
1002
1017
|
// eslint-disable-next-line no-param-reassign
|
|
1003
1018
|
transceiver.direction = answerDirection;
|
|
@@ -1036,8 +1051,8 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
1036
1051
|
}
|
|
1037
1052
|
const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
|
|
1038
1053
|
|
|
1039
|
-
// Do not reuse sender tracks in SFU
|
|
1040
|
-
if (sender && !sfu) {
|
|
1054
|
+
// Do not reuse sender video tracks in SFU
|
|
1055
|
+
if (sender && (!sfu || newTrack.kind === 'audio')) {
|
|
1041
1056
|
trackUpdates.push(
|
|
1042
1057
|
new Promise((resolve) => {
|
|
1043
1058
|
this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
|
|
@@ -2103,7 +2118,7 @@ class Contact {
|
|
|
2103
2118
|
|
|
2104
2119
|
return new Contact({
|
|
2105
2120
|
sourceId: single.id || '',
|
|
2106
|
-
name: single.displayName,
|
|
2121
|
+
name: single.displayName || '',
|
|
2107
2122
|
number: numbers.length ? numbers[0].number : '',
|
|
2108
2123
|
numbers,
|
|
2109
2124
|
emails,
|
|
@@ -2134,7 +2149,7 @@ class Contact {
|
|
|
2134
2149
|
|
|
2135
2150
|
return new Contact({
|
|
2136
2151
|
sourceId: single.id || '',
|
|
2137
|
-
name: single.name,
|
|
2152
|
+
name: single.name || '',
|
|
2138
2153
|
number: numbers.length ? numbers[0].number : '',
|
|
2139
2154
|
numbers,
|
|
2140
2155
|
emails,
|
|
@@ -2235,7 +2250,7 @@ class Contact {
|
|
|
2235
2250
|
} = {}) {
|
|
2236
2251
|
this.id = id;
|
|
2237
2252
|
this.uuid = uuid;
|
|
2238
|
-
this.name = name;
|
|
2253
|
+
this.name = name || '';
|
|
2239
2254
|
this.number = number;
|
|
2240
2255
|
this.numbers = numbers;
|
|
2241
2256
|
this.email = email;
|
|
@@ -3544,17 +3559,66 @@ var updateFrom = (instance , from ) => {
|
|
|
3544
3559
|
|
|
3545
3560
|
//
|
|
3546
3561
|
|
|
3562
|
+
|
|
3563
|
+
|
|
3564
|
+
|
|
3565
|
+
|
|
3566
|
+
|
|
3567
|
+
|
|
3568
|
+
|
|
3569
|
+
|
|
3570
|
+
|
|
3571
|
+
|
|
3572
|
+
|
|
3573
|
+
|
|
3574
|
+
|
|
3575
|
+
|
|
3576
|
+
|
|
3577
|
+
|
|
3578
|
+
class Recording {
|
|
3579
|
+
|
|
3580
|
+
|
|
3581
|
+
|
|
3582
|
+
|
|
3583
|
+
|
|
3584
|
+
|
|
3585
|
+
static parseMany(recordings ) {
|
|
3586
|
+
return recordings.map(item => Recording.parse(item));
|
|
3587
|
+
}
|
|
3588
|
+
|
|
3589
|
+
static parse(plain ) {
|
|
3590
|
+
return new Recording({
|
|
3591
|
+
deleted: plain.deleted,
|
|
3592
|
+
fileName: plain.filename,
|
|
3593
|
+
end: plain.end_time ? moment__default['default'](plain.end_time).toDate() : null,
|
|
3594
|
+
start: moment__default['default'](plain.start_time).toDate(),
|
|
3595
|
+
uuid: plain.uuid,
|
|
3596
|
+
});
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
constructor({ deleted, end, fileName, start, uuid } ) {
|
|
3600
|
+
this.deleted = deleted;
|
|
3601
|
+
this.end = end;
|
|
3602
|
+
this.fileName = fileName;
|
|
3603
|
+
this.start = start;
|
|
3604
|
+
this.uuid = uuid;
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
|
|
3608
|
+
//
|
|
3609
|
+
|
|
3547
3610
|
|
|
3548
|
-
|
|
3611
|
+
|
|
3549
3612
|
|
|
3550
3613
|
|
|
3551
3614
|
|
|
3552
3615
|
|
|
3553
3616
|
|
|
3554
|
-
|
|
3617
|
+
|
|
3555
3618
|
|
|
3556
3619
|
|
|
3557
3620
|
|
|
3621
|
+
|
|
3558
3622
|
|
|
3559
3623
|
|
|
3560
3624
|
|
|
@@ -3567,7 +3631,7 @@ var updateFrom = (instance , from ) => {
|
|
|
3567
3631
|
|
|
3568
3632
|
|
|
3569
3633
|
|
|
3570
|
-
|
|
3634
|
+
|
|
3571
3635
|
|
|
3572
3636
|
|
|
3573
3637
|
|
|
@@ -3582,13 +3646,14 @@ var updateFrom = (instance , from ) => {
|
|
|
3582
3646
|
|
|
3583
3647
|
|
|
3584
3648
|
|
|
3585
|
-
|
|
3649
|
+
|
|
3650
|
+
|
|
3586
3651
|
|
|
3587
3652
|
|
|
3588
3653
|
class CallLog {
|
|
3589
3654
|
|
|
3590
3655
|
|
|
3591
|
-
|
|
3656
|
+
|
|
3592
3657
|
|
|
3593
3658
|
|
|
3594
3659
|
|
|
@@ -3605,7 +3670,7 @@ class CallLog {
|
|
|
3605
3670
|
|
|
3606
3671
|
|
|
3607
3672
|
|
|
3608
|
-
|
|
3673
|
+
|
|
3609
3674
|
|
|
3610
3675
|
static merge(current , toMerge ) {
|
|
3611
3676
|
const onlyUnique = (value, index, self) => self.indexOf(value) === index;
|
|
@@ -3622,7 +3687,7 @@ class CallLog {
|
|
|
3622
3687
|
|
|
3623
3688
|
static parse(plain ) {
|
|
3624
3689
|
return new CallLog({
|
|
3625
|
-
answer: moment__default['default'](plain.answer).toDate(),
|
|
3690
|
+
answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
|
|
3626
3691
|
answered: plain.answered,
|
|
3627
3692
|
callDirection: plain.call_direction,
|
|
3628
3693
|
destination: {
|
|
@@ -3636,13 +3701,14 @@ class CallLog {
|
|
|
3636
3701
|
id: plain.id,
|
|
3637
3702
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3638
3703
|
start: moment__default['default'](plain.start).toDate(),
|
|
3639
|
-
end: moment__default['default'](plain.end).toDate(),
|
|
3704
|
+
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3705
|
+
recordings: Recording.parseMany(plain.recordings),
|
|
3640
3706
|
});
|
|
3641
3707
|
}
|
|
3642
3708
|
|
|
3643
3709
|
static parseNew(plain , session ) {
|
|
3644
3710
|
return new CallLog({
|
|
3645
|
-
answer: moment__default['default'](plain.answer).toDate(),
|
|
3711
|
+
answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
|
|
3646
3712
|
answered: plain.answered,
|
|
3647
3713
|
callDirection: plain.call_direction,
|
|
3648
3714
|
destination: {
|
|
@@ -3656,7 +3722,8 @@ class CallLog {
|
|
|
3656
3722
|
id: plain.id,
|
|
3657
3723
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3658
3724
|
start: moment__default['default'](plain.start).toDate(),
|
|
3659
|
-
end: moment__default['default'](plain.end).toDate(),
|
|
3725
|
+
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3726
|
+
recordings: Recording.parseMany(plain.recordings),
|
|
3660
3727
|
// @TODO: FIXME add verification declined vs missed call
|
|
3661
3728
|
newMissedCall: session
|
|
3662
3729
|
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
@@ -4892,6 +4959,10 @@ class ApiClient {
|
|
|
4892
4959
|
this.fetchOptions = fetchOptions;
|
|
4893
4960
|
this.client.setFetchOptions(fetchOptions);
|
|
4894
4961
|
}
|
|
4962
|
+
|
|
4963
|
+
disableErrorLogging() {
|
|
4964
|
+
this.client.disableErrorLogging();
|
|
4965
|
+
}
|
|
4895
4966
|
}
|
|
4896
4967
|
|
|
4897
4968
|
//
|
|
@@ -5381,9 +5452,15 @@ class WebRTCClient extends Emitter {
|
|
|
5381
5452
|
|
|
5382
5453
|
call(number , enableVideo , audioOnly = false, conference = false) {
|
|
5383
5454
|
logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
|
|
5384
|
-
const inviterOptions
|
|
5455
|
+
const inviterOptions = {
|
|
5456
|
+
sessionDescriptionHandlerOptionsReInvite: {
|
|
5457
|
+
conference,
|
|
5458
|
+
audioOnly,
|
|
5459
|
+
},
|
|
5460
|
+
};
|
|
5461
|
+
|
|
5385
5462
|
if (audioOnly) {
|
|
5386
|
-
inviterOptions.sessionDescriptionHandlerModifiersReInvite = [
|
|
5463
|
+
inviterOptions.sessionDescriptionHandlerModifiersReInvite = [modifiers.stripVideo];
|
|
5387
5464
|
}
|
|
5388
5465
|
|
|
5389
5466
|
const session = new inviter.Inviter(this.userAgent, this._makeURI(number), inviterOptions);
|
|
@@ -5412,10 +5489,11 @@ class WebRTCClient extends Emitter {
|
|
|
5412
5489
|
sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
|
|
5413
5490
|
};
|
|
5414
5491
|
|
|
5415
|
-
inviteOptions.
|
|
5492
|
+
inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
|
|
5416
5493
|
|
|
5494
|
+
inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
|
|
5417
5495
|
if (audioOnly) {
|
|
5418
|
-
inviteOptions.sessionDescriptionHandlerModifiers.push(
|
|
5496
|
+
inviteOptions.sessionDescriptionHandlerModifiers.push(modifiers.stripVideo);
|
|
5419
5497
|
}
|
|
5420
5498
|
|
|
5421
5499
|
// Do not await invite here or we'll miss the Establishing state transition
|
|
@@ -5629,6 +5707,9 @@ class WebRTCClient extends Emitter {
|
|
|
5629
5707
|
if (!this._isWeb()) {
|
|
5630
5708
|
options.sessionDescriptionHandlerModifiers = [modifiers.holdModifier];
|
|
5631
5709
|
}
|
|
5710
|
+
options.sessionDescriptionHandlerOptions = {
|
|
5711
|
+
constraints: options.constraints,
|
|
5712
|
+
};
|
|
5632
5713
|
|
|
5633
5714
|
// Send re-INVITE
|
|
5634
5715
|
return session.invite(options);
|
|
@@ -5668,6 +5749,9 @@ class WebRTCClient extends Emitter {
|
|
|
5668
5749
|
// (eg: holdModifier)
|
|
5669
5750
|
options.sessionDescriptionHandlerModifiers = [];
|
|
5670
5751
|
}
|
|
5752
|
+
options.sessionDescriptionHandlerOptions = {
|
|
5753
|
+
constraints: options.constraints,
|
|
5754
|
+
};
|
|
5671
5755
|
|
|
5672
5756
|
// Send re-INVITE
|
|
5673
5757
|
return session.invite(options);
|
|
@@ -5897,7 +5981,8 @@ class WebRTCClient extends Emitter {
|
|
|
5897
5981
|
? this.video.deviceId.exact : undefined;
|
|
5898
5982
|
}
|
|
5899
5983
|
|
|
5900
|
-
reinvite(sipSession , newConstraints = null, conference = false
|
|
5984
|
+
reinvite(sipSession , newConstraints = null, conference = false,
|
|
5985
|
+
audioOnly = false) {
|
|
5901
5986
|
if (!sipSession) {
|
|
5902
5987
|
return false;
|
|
5903
5988
|
}
|
|
@@ -5907,16 +5992,17 @@ class WebRTCClient extends Emitter {
|
|
|
5907
5992
|
}
|
|
5908
5993
|
|
|
5909
5994
|
const wasMuted = this.isAudioMuted(sipSession);
|
|
5910
|
-
// When upgrading to video, remove the `
|
|
5995
|
+
// When upgrading to video, remove the `stripVideo` modifiers
|
|
5911
5996
|
if (newConstraints && newConstraints.video) {
|
|
5912
|
-
const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
|
|
5913
|
-
sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier =>
|
|
5914
|
-
modifier !==
|
|
5997
|
+
const modifiers$1 = sipSession.sessionDescriptionHandlerModifiersReInvite;
|
|
5998
|
+
sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers$1.filter(modifier =>
|
|
5999
|
+
modifier !== modifiers.stripVideo);
|
|
5915
6000
|
}
|
|
5916
6001
|
|
|
5917
6002
|
sipSession.sessionDescriptionHandlerOptionsReInvite = {
|
|
5918
6003
|
...sipSession.sessionDescriptionHandlerOptionsReInvite,
|
|
5919
6004
|
conference,
|
|
6005
|
+
audioOnly,
|
|
5920
6006
|
};
|
|
5921
6007
|
|
|
5922
6008
|
const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
|
|
@@ -5956,6 +6042,8 @@ class WebRTCClient extends Emitter {
|
|
|
5956
6042
|
},
|
|
5957
6043
|
sessionDescriptionHandlerOptions: {
|
|
5958
6044
|
constraints,
|
|
6045
|
+
conference,
|
|
6046
|
+
audioOnly,
|
|
5959
6047
|
offerOptions: {
|
|
5960
6048
|
iceRestart: false,
|
|
5961
6049
|
},
|
|
@@ -6415,6 +6503,8 @@ class WebRTCClient extends Emitter {
|
|
|
6415
6503
|
|
|
6416
6504
|
// Invitation and Inviter extends Session
|
|
6417
6505
|
_setupSession(session ) {
|
|
6506
|
+
const sipSessionId = this.getSipSessionId(session);
|
|
6507
|
+
|
|
6418
6508
|
// When receiving an Invitation, the delegate is not defined.
|
|
6419
6509
|
if (!session.delegate) {
|
|
6420
6510
|
session.delegate = {};
|
|
@@ -6438,8 +6528,18 @@ class WebRTCClient extends Emitter {
|
|
|
6438
6528
|
};
|
|
6439
6529
|
};
|
|
6440
6530
|
|
|
6531
|
+
const oldInviteRequest = session.onInviteRequest.bind(session);
|
|
6532
|
+
let hadRemoteVideo = false;
|
|
6533
|
+
|
|
6534
|
+
// Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
|
|
6535
|
+
// Becase when `onInvite` is called we already got the video track
|
|
6536
|
+
session.onInviteRequest = (request) => {
|
|
6537
|
+
hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
6538
|
+
|
|
6539
|
+
oldInviteRequest(request);
|
|
6540
|
+
};
|
|
6541
|
+
|
|
6441
6542
|
session.delegate.onInvite = (request ) => {
|
|
6442
|
-
const sipSessionId = this.getSipSessionId(session);
|
|
6443
6543
|
let updatedCalleeName = null;
|
|
6444
6544
|
let updatedNumber = null;
|
|
6445
6545
|
if (session.assertedIdentity) {
|
|
@@ -6449,7 +6549,6 @@ class WebRTCClient extends Emitter {
|
|
|
6449
6549
|
logger.info('re-invite received', { updatedCalleeName, updatedNumber });
|
|
6450
6550
|
|
|
6451
6551
|
// Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
|
|
6452
|
-
const hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
6453
6552
|
|
|
6454
6553
|
// Update SDP
|
|
6455
6554
|
// Remote video is handled by the `track` event. Here we're dealing with video stream removal.
|
|
@@ -6499,7 +6598,7 @@ class WebRTCClient extends Emitter {
|
|
|
6499
6598
|
}
|
|
6500
6599
|
|
|
6501
6600
|
_isAudioOnly(session ) {
|
|
6502
|
-
return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier ===
|
|
6601
|
+
return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === modifiers.stripVideo);
|
|
6503
6602
|
}
|
|
6504
6603
|
|
|
6505
6604
|
_setupMedias(session , newStream ) {
|
package/lib/api/agentd.js
CHANGED
|
@@ -311,7 +311,13 @@ class IssueReporter {
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
_isLevelAbove(level1 , level2 ) {
|
|
314
|
-
|
|
314
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
315
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
316
|
+
if (index1 === -1 || index2 === -1) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return index1 > index2;
|
|
315
321
|
}
|
|
316
322
|
|
|
317
323
|
_makeCategory(category ) {
|
|
@@ -369,6 +375,7 @@ class ApiRequester {
|
|
|
369
375
|
|
|
370
376
|
|
|
371
377
|
|
|
378
|
+
|
|
372
379
|
|
|
373
380
|
|
|
374
381
|
|
|
@@ -408,6 +415,8 @@ class ApiRequester {
|
|
|
408
415
|
this.token = token;
|
|
409
416
|
}
|
|
410
417
|
|
|
418
|
+
this.shouldLogErrors = true;
|
|
419
|
+
|
|
411
420
|
methods.forEach(method => {
|
|
412
421
|
// $FlowFixMe
|
|
413
422
|
ApiRequester.prototype[method] = function sugar(...args) {
|
|
@@ -431,6 +440,14 @@ class ApiRequester {
|
|
|
431
440
|
this.fetchOptions = options;
|
|
432
441
|
}
|
|
433
442
|
|
|
443
|
+
disableErrorLogging() {
|
|
444
|
+
this.shouldLogErrors = false;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
enableErrorLogging() {
|
|
448
|
+
this.shouldLogErrors = true;
|
|
449
|
+
}
|
|
450
|
+
|
|
434
451
|
async call(
|
|
435
452
|
path ,
|
|
436
453
|
method = 'get',
|
|
@@ -491,7 +508,9 @@ class ApiRequester {
|
|
|
491
508
|
? exceptionClass.fromText(err, response.status)
|
|
492
509
|
: exceptionClass.fromResponse(err, response.status);
|
|
493
510
|
|
|
494
|
-
|
|
511
|
+
if (this.shouldLogErrors) {
|
|
512
|
+
logger.error('API error', error);
|
|
513
|
+
}
|
|
495
514
|
|
|
496
515
|
throw error;
|
|
497
516
|
});
|
|
@@ -499,7 +518,9 @@ class ApiRequester {
|
|
|
499
518
|
|
|
500
519
|
return newParse(response, isJson);
|
|
501
520
|
}).catch(error => {
|
|
502
|
-
|
|
521
|
+
if (this.shouldLogErrors) {
|
|
522
|
+
logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
|
|
523
|
+
}
|
|
503
524
|
|
|
504
525
|
throw error;
|
|
505
526
|
});
|
package/lib/api/amid.js
CHANGED
|
@@ -250,7 +250,13 @@ class IssueReporter {
|
|
|
250
250
|
}
|
|
251
251
|
|
|
252
252
|
_isLevelAbove(level1 , level2 ) {
|
|
253
|
-
|
|
253
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
254
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
255
|
+
if (index1 === -1 || index2 === -1) {
|
|
256
|
+
return false;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return index1 > index2;
|
|
254
260
|
}
|
|
255
261
|
|
|
256
262
|
_makeCategory(category ) {
|
package/lib/api/application.js
CHANGED
|
@@ -311,7 +311,13 @@ class IssueReporter {
|
|
|
311
311
|
}
|
|
312
312
|
|
|
313
313
|
_isLevelAbove(level1 , level2 ) {
|
|
314
|
-
|
|
314
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
315
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
316
|
+
if (index1 === -1 || index2 === -1) {
|
|
317
|
+
return false;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return index1 > index2;
|
|
315
321
|
}
|
|
316
322
|
|
|
317
323
|
_makeCategory(category ) {
|
|
@@ -369,6 +375,7 @@ class ApiRequester {
|
|
|
369
375
|
|
|
370
376
|
|
|
371
377
|
|
|
378
|
+
|
|
372
379
|
|
|
373
380
|
|
|
374
381
|
|
|
@@ -408,6 +415,8 @@ class ApiRequester {
|
|
|
408
415
|
this.token = token;
|
|
409
416
|
}
|
|
410
417
|
|
|
418
|
+
this.shouldLogErrors = true;
|
|
419
|
+
|
|
411
420
|
methods.forEach(method => {
|
|
412
421
|
// $FlowFixMe
|
|
413
422
|
ApiRequester.prototype[method] = function sugar(...args) {
|
|
@@ -431,6 +440,14 @@ class ApiRequester {
|
|
|
431
440
|
this.fetchOptions = options;
|
|
432
441
|
}
|
|
433
442
|
|
|
443
|
+
disableErrorLogging() {
|
|
444
|
+
this.shouldLogErrors = false;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
enableErrorLogging() {
|
|
448
|
+
this.shouldLogErrors = true;
|
|
449
|
+
}
|
|
450
|
+
|
|
434
451
|
async call(
|
|
435
452
|
path ,
|
|
436
453
|
method = 'get',
|
|
@@ -491,7 +508,9 @@ class ApiRequester {
|
|
|
491
508
|
? exceptionClass.fromText(err, response.status)
|
|
492
509
|
: exceptionClass.fromResponse(err, response.status);
|
|
493
510
|
|
|
494
|
-
|
|
511
|
+
if (this.shouldLogErrors) {
|
|
512
|
+
logger.error('API error', error);
|
|
513
|
+
}
|
|
495
514
|
|
|
496
515
|
throw error;
|
|
497
516
|
});
|
|
@@ -499,7 +518,9 @@ class ApiRequester {
|
|
|
499
518
|
|
|
500
519
|
return newParse(response, isJson);
|
|
501
520
|
}).catch(error => {
|
|
502
|
-
|
|
521
|
+
if (this.shouldLogErrors) {
|
|
522
|
+
logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
|
|
523
|
+
}
|
|
503
524
|
|
|
504
525
|
throw error;
|
|
505
526
|
});
|