@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
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import 'webrtc-adapter';
|
|
2
2
|
import { UserAgentState } from 'sip.js/lib/api/user-agent-state';
|
|
3
|
-
import 'sip.js/lib/api/message';
|
|
4
3
|
import { Parser } from 'sip.js/lib/core/messages/parser';
|
|
5
4
|
import { C } from 'sip.js/lib/core/messages/methods/constants';
|
|
6
5
|
import { URI } from 'sip.js/lib/grammar/uri';
|
|
7
6
|
import { UserAgent } from 'sip.js/lib/api/user-agent';
|
|
8
|
-
import { holdModifier } from 'sip.js/lib/platform/web/modifiers/modifiers';
|
|
7
|
+
import { stripVideo, holdModifier } from 'sip.js/lib/platform/web/modifiers/modifiers';
|
|
9
8
|
import { Registerer } from 'sip.js/lib/api/registerer';
|
|
10
9
|
import { Inviter } from 'sip.js/lib/api/inviter';
|
|
11
10
|
import { Messager } from 'sip.js/lib/api/messager';
|
|
@@ -136,6 +135,7 @@ class ApiRequester {
|
|
|
136
135
|
|
|
137
136
|
|
|
138
137
|
|
|
138
|
+
|
|
139
139
|
|
|
140
140
|
|
|
141
141
|
|
|
@@ -175,6 +175,8 @@ class ApiRequester {
|
|
|
175
175
|
this.token = token;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
+
this.shouldLogErrors = true;
|
|
179
|
+
|
|
178
180
|
methods.forEach(method => {
|
|
179
181
|
// $FlowFixMe
|
|
180
182
|
ApiRequester.prototype[method] = function sugar(...args) {
|
|
@@ -198,6 +200,14 @@ class ApiRequester {
|
|
|
198
200
|
this.fetchOptions = options;
|
|
199
201
|
}
|
|
200
202
|
|
|
203
|
+
disableErrorLogging() {
|
|
204
|
+
this.shouldLogErrors = false;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
enableErrorLogging() {
|
|
208
|
+
this.shouldLogErrors = true;
|
|
209
|
+
}
|
|
210
|
+
|
|
201
211
|
async call(
|
|
202
212
|
path ,
|
|
203
213
|
method = 'get',
|
|
@@ -258,7 +268,9 @@ class ApiRequester {
|
|
|
258
268
|
? exceptionClass.fromText(err, response.status)
|
|
259
269
|
: exceptionClass.fromResponse(err, response.status);
|
|
260
270
|
|
|
261
|
-
|
|
271
|
+
if (this.shouldLogErrors) {
|
|
272
|
+
logger$2.error('API error', error);
|
|
273
|
+
}
|
|
262
274
|
|
|
263
275
|
throw error;
|
|
264
276
|
});
|
|
@@ -266,7 +278,9 @@ class ApiRequester {
|
|
|
266
278
|
|
|
267
279
|
return newParse(response, isJson);
|
|
268
280
|
}).catch(error => {
|
|
269
|
-
|
|
281
|
+
if (this.shouldLogErrors) {
|
|
282
|
+
logger$2.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
|
|
283
|
+
}
|
|
270
284
|
|
|
271
285
|
throw error;
|
|
272
286
|
});
|
|
@@ -577,7 +591,13 @@ class IssueReporter {
|
|
|
577
591
|
}
|
|
578
592
|
|
|
579
593
|
_isLevelAbove(level1 , level2 ) {
|
|
580
|
-
|
|
594
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
595
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
596
|
+
if (index1 === -1 || index2 === -1) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
return index1 > index2;
|
|
581
601
|
}
|
|
582
602
|
|
|
583
603
|
_makeCategory(category ) {
|
|
@@ -606,23 +626,6 @@ const areCandidateValid = (candidates ) =>
|
|
|
606
626
|
getSrflxOrRelay(candidates)
|
|
607
627
|
.length > 0;
|
|
608
628
|
|
|
609
|
-
const toggleVideoDirection = (sdp , direction ) => {
|
|
610
|
-
const parsedSdp = sdpParser.parse(sdp);
|
|
611
|
-
parsedSdp.media = parsedSdp.media.map(media => ({
|
|
612
|
-
...media,
|
|
613
|
-
...(media.type === 'video' ? { direction } : {}),
|
|
614
|
-
}));
|
|
615
|
-
|
|
616
|
-
return sdpParser.write(parsedSdp);
|
|
617
|
-
};
|
|
618
|
-
|
|
619
|
-
const deactivateVideoModifier = (rawDescription ) => {
|
|
620
|
-
const description = rawDescription;
|
|
621
|
-
description.sdp = toggleVideoDirection(description.sdp, 'inactive');
|
|
622
|
-
|
|
623
|
-
return Promise.resolve(description);
|
|
624
|
-
};
|
|
625
|
-
|
|
626
629
|
const hasAnActiveVideo = (sdp ) => {
|
|
627
630
|
if (!sdp) {
|
|
628
631
|
return false;
|
|
@@ -734,6 +737,7 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
734
737
|
const iceRestart = options.offerOptions ? options.offerOptions.iceRestart : false;
|
|
735
738
|
|
|
736
739
|
const isConference = options ? !!options.conference : false;
|
|
740
|
+
const audioOnly = options ? !!options.audioOnly : false;
|
|
737
741
|
|
|
738
742
|
// We should wait for ice when iceRestart (reinvite) or for the first invite
|
|
739
743
|
// We shouldn't wait for ice when holding or resuming the call
|
|
@@ -760,16 +764,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
760
764
|
};
|
|
761
765
|
|
|
762
766
|
return this.getLocalMediaStream(options)
|
|
763
|
-
.then(() => this.updateDirection(options, isConference))
|
|
767
|
+
.then(() => this.updateDirection(options, isConference, audioOnly))
|
|
764
768
|
.then(() => this.createDataChannel(options))
|
|
765
769
|
.then(() => {
|
|
766
|
-
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options)) {
|
|
770
|
+
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
|
|
767
771
|
// Add a video an empty bundle to be able to replaceTrack when joining a conference without video
|
|
768
772
|
this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
|
|
769
773
|
}
|
|
770
774
|
})
|
|
771
775
|
.then(() => this.createLocalOfferOrAnswer(options))
|
|
772
|
-
.then(
|
|
776
|
+
.then(sessionDescription => this.setLocalSessionDescription(sessionDescription))
|
|
773
777
|
.then(() => this.waitForIceGatheringComplete(iceRestart, iceTimeout))
|
|
774
778
|
.then(() => this.getLocalSessionDescription())
|
|
775
779
|
.then(description => {
|
|
@@ -892,7 +896,8 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
892
896
|
}
|
|
893
897
|
|
|
894
898
|
// Overridden to send `inactive` in conference
|
|
895
|
-
updateDirection(options , isConference = false
|
|
899
|
+
updateDirection(options , isConference = false,
|
|
900
|
+
audioOnly = false) {
|
|
896
901
|
if (this._peerConnection === undefined) {
|
|
897
902
|
return Promise.reject(new Error('Peer connection closed.'));
|
|
898
903
|
}
|
|
@@ -907,14 +912,17 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
907
912
|
// if we are stable, assume we are creating a local offer
|
|
908
913
|
this.logger.debug('SessionDescriptionHandler.updateDirection - setting offer direction');
|
|
909
914
|
// determine the direction to offer given the current direction and hold state
|
|
910
|
-
const directionToOffer = (currentDirection ) => {
|
|
915
|
+
const directionToOffer = (currentDirection , transceiver /* RTCRtpTransceiver */) => {
|
|
911
916
|
if (isConference) {
|
|
917
|
+
if (audioOnly && transceiver.receiver.track && transceiver.receiver.track.kind === 'video') {
|
|
918
|
+
return 'sendonly';
|
|
919
|
+
}
|
|
912
920
|
return options && options.hold ? 'sendonly' : 'sendrecv';
|
|
913
921
|
}
|
|
914
922
|
|
|
915
923
|
switch (currentDirection) {
|
|
916
924
|
case 'inactive':
|
|
917
|
-
return options && options.hold ? 'inactive' : 'recvonly';
|
|
925
|
+
return options && options.hold ? 'inactive' : (isConference && !audioOnly ? 'sendrecv' : 'recvonly');
|
|
918
926
|
case 'recvonly':
|
|
919
927
|
return options && options.hold ? 'inactive' : 'recvonly';
|
|
920
928
|
case 'sendonly':
|
|
@@ -930,7 +938,7 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
930
938
|
// set the transceiver direction to the offer direction
|
|
931
939
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
932
940
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
933
|
-
const offerDirection = directionToOffer(transceiver.direction);
|
|
941
|
+
const offerDirection = directionToOffer(transceiver.direction, transceiver);
|
|
934
942
|
if (transceiver.direction !== offerDirection) {
|
|
935
943
|
// eslint-disable-next-line no-param-reassign
|
|
936
944
|
transceiver.direction = offerDirection;
|
|
@@ -989,6 +997,13 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
989
997
|
// set the transceiver direction to the answer direction
|
|
990
998
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
991
999
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
1000
|
+
const { receiver } = transceiver;
|
|
1001
|
+
if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
|
|
1002
|
+
// eslint-disable-next-line no-param-reassign
|
|
1003
|
+
transceiver.direction = 'inactive';
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
|
|
992
1007
|
if (transceiver.direction !== 'stopped' && transceiver.direction !== answerDirection) {
|
|
993
1008
|
// eslint-disable-next-line no-param-reassign
|
|
994
1009
|
transceiver.direction = answerDirection;
|
|
@@ -1027,8 +1042,8 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
1027
1042
|
}
|
|
1028
1043
|
const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
|
|
1029
1044
|
|
|
1030
|
-
// Do not reuse sender tracks in SFU
|
|
1031
|
-
if (sender && !sfu) {
|
|
1045
|
+
// Do not reuse sender video tracks in SFU
|
|
1046
|
+
if (sender && (!sfu || newTrack.kind === 'audio')) {
|
|
1032
1047
|
trackUpdates.push(
|
|
1033
1048
|
new Promise((resolve) => {
|
|
1034
1049
|
this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
|
|
@@ -2094,7 +2109,7 @@ class Contact {
|
|
|
2094
2109
|
|
|
2095
2110
|
return new Contact({
|
|
2096
2111
|
sourceId: single.id || '',
|
|
2097
|
-
name: single.displayName,
|
|
2112
|
+
name: single.displayName || '',
|
|
2098
2113
|
number: numbers.length ? numbers[0].number : '',
|
|
2099
2114
|
numbers,
|
|
2100
2115
|
emails,
|
|
@@ -2125,7 +2140,7 @@ class Contact {
|
|
|
2125
2140
|
|
|
2126
2141
|
return new Contact({
|
|
2127
2142
|
sourceId: single.id || '',
|
|
2128
|
-
name: single.name,
|
|
2143
|
+
name: single.name || '',
|
|
2129
2144
|
number: numbers.length ? numbers[0].number : '',
|
|
2130
2145
|
numbers,
|
|
2131
2146
|
emails,
|
|
@@ -2226,7 +2241,7 @@ class Contact {
|
|
|
2226
2241
|
} = {}) {
|
|
2227
2242
|
this.id = id;
|
|
2228
2243
|
this.uuid = uuid;
|
|
2229
|
-
this.name = name;
|
|
2244
|
+
this.name = name || '';
|
|
2230
2245
|
this.number = number;
|
|
2231
2246
|
this.numbers = numbers;
|
|
2232
2247
|
this.email = email;
|
|
@@ -3535,17 +3550,66 @@ var updateFrom = (instance , from ) => {
|
|
|
3535
3550
|
|
|
3536
3551
|
//
|
|
3537
3552
|
|
|
3553
|
+
|
|
3554
|
+
|
|
3555
|
+
|
|
3556
|
+
|
|
3557
|
+
|
|
3558
|
+
|
|
3559
|
+
|
|
3560
|
+
|
|
3561
|
+
|
|
3562
|
+
|
|
3563
|
+
|
|
3564
|
+
|
|
3565
|
+
|
|
3566
|
+
|
|
3567
|
+
|
|
3568
|
+
|
|
3569
|
+
class Recording {
|
|
3570
|
+
|
|
3571
|
+
|
|
3572
|
+
|
|
3573
|
+
|
|
3574
|
+
|
|
3575
|
+
|
|
3576
|
+
static parseMany(recordings ) {
|
|
3577
|
+
return recordings.map(item => Recording.parse(item));
|
|
3578
|
+
}
|
|
3579
|
+
|
|
3580
|
+
static parse(plain ) {
|
|
3581
|
+
return new Recording({
|
|
3582
|
+
deleted: plain.deleted,
|
|
3583
|
+
fileName: plain.filename,
|
|
3584
|
+
end: plain.end_time ? moment(plain.end_time).toDate() : null,
|
|
3585
|
+
start: moment(plain.start_time).toDate(),
|
|
3586
|
+
uuid: plain.uuid,
|
|
3587
|
+
});
|
|
3588
|
+
}
|
|
3589
|
+
|
|
3590
|
+
constructor({ deleted, end, fileName, start, uuid } ) {
|
|
3591
|
+
this.deleted = deleted;
|
|
3592
|
+
this.end = end;
|
|
3593
|
+
this.fileName = fileName;
|
|
3594
|
+
this.start = start;
|
|
3595
|
+
this.uuid = uuid;
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
|
|
3599
|
+
//
|
|
3600
|
+
|
|
3538
3601
|
|
|
3539
|
-
|
|
3602
|
+
|
|
3540
3603
|
|
|
3541
3604
|
|
|
3542
3605
|
|
|
3543
3606
|
|
|
3544
3607
|
|
|
3545
|
-
|
|
3608
|
+
|
|
3546
3609
|
|
|
3547
3610
|
|
|
3548
3611
|
|
|
3612
|
+
|
|
3549
3613
|
|
|
3550
3614
|
|
|
3551
3615
|
|
|
@@ -3558,7 +3622,7 @@ var updateFrom = (instance , from ) => {
|
|
|
3558
3622
|
|
|
3559
3623
|
|
|
3560
3624
|
|
|
3561
|
-
|
|
3625
|
+
|
|
3562
3626
|
|
|
3563
3627
|
|
|
3564
3628
|
|
|
@@ -3573,13 +3637,14 @@ var updateFrom = (instance , from ) => {
|
|
|
3573
3637
|
|
|
3574
3638
|
|
|
3575
3639
|
|
|
3576
|
-
|
|
3640
|
+
|
|
3641
|
+
|
|
3577
3642
|
|
|
3578
3643
|
|
|
3579
3644
|
class CallLog {
|
|
3580
3645
|
|
|
3581
3646
|
|
|
3582
|
-
|
|
3647
|
+
|
|
3583
3648
|
|
|
3584
3649
|
|
|
3585
3650
|
|
|
@@ -3596,7 +3661,7 @@ class CallLog {
|
|
|
3596
3661
|
|
|
3597
3662
|
|
|
3598
3663
|
|
|
3599
|
-
|
|
3664
|
+
|
|
3600
3665
|
|
|
3601
3666
|
static merge(current , toMerge ) {
|
|
3602
3667
|
const onlyUnique = (value, index, self) => self.indexOf(value) === index;
|
|
@@ -3613,7 +3678,7 @@ class CallLog {
|
|
|
3613
3678
|
|
|
3614
3679
|
static parse(plain ) {
|
|
3615
3680
|
return new CallLog({
|
|
3616
|
-
answer: moment(plain.answer).toDate(),
|
|
3681
|
+
answer: plain.answer ? moment(plain.answer).toDate() : null,
|
|
3617
3682
|
answered: plain.answered,
|
|
3618
3683
|
callDirection: plain.call_direction,
|
|
3619
3684
|
destination: {
|
|
@@ -3627,13 +3692,14 @@ class CallLog {
|
|
|
3627
3692
|
id: plain.id,
|
|
3628
3693
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3629
3694
|
start: moment(plain.start).toDate(),
|
|
3630
|
-
end: moment(plain.end).toDate(),
|
|
3695
|
+
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3696
|
+
recordings: Recording.parseMany(plain.recordings),
|
|
3631
3697
|
});
|
|
3632
3698
|
}
|
|
3633
3699
|
|
|
3634
3700
|
static parseNew(plain , session ) {
|
|
3635
3701
|
return new CallLog({
|
|
3636
|
-
answer: moment(plain.answer).toDate(),
|
|
3702
|
+
answer: plain.answer ? moment(plain.answer).toDate() : null,
|
|
3637
3703
|
answered: plain.answered,
|
|
3638
3704
|
callDirection: plain.call_direction,
|
|
3639
3705
|
destination: {
|
|
@@ -3647,7 +3713,8 @@ class CallLog {
|
|
|
3647
3713
|
id: plain.id,
|
|
3648
3714
|
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3649
3715
|
start: moment(plain.start).toDate(),
|
|
3650
|
-
end: moment(plain.end).toDate(),
|
|
3716
|
+
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3717
|
+
recordings: Recording.parseMany(plain.recordings),
|
|
3651
3718
|
// @TODO: FIXME add verification declined vs missed call
|
|
3652
3719
|
newMissedCall: session
|
|
3653
3720
|
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
@@ -4883,6 +4950,10 @@ class ApiClient {
|
|
|
4883
4950
|
this.fetchOptions = fetchOptions;
|
|
4884
4951
|
this.client.setFetchOptions(fetchOptions);
|
|
4885
4952
|
}
|
|
4953
|
+
|
|
4954
|
+
disableErrorLogging() {
|
|
4955
|
+
this.client.disableErrorLogging();
|
|
4956
|
+
}
|
|
4886
4957
|
}
|
|
4887
4958
|
|
|
4888
4959
|
//
|
|
@@ -5372,9 +5443,15 @@ class WebRTCClient extends Emitter {
|
|
|
5372
5443
|
|
|
5373
5444
|
call(number , enableVideo , audioOnly = false, conference = false) {
|
|
5374
5445
|
logger.info('sdk webrtc creating call', { number, enableVideo, audioOnly });
|
|
5375
|
-
const inviterOptions
|
|
5446
|
+
const inviterOptions = {
|
|
5447
|
+
sessionDescriptionHandlerOptionsReInvite: {
|
|
5448
|
+
conference,
|
|
5449
|
+
audioOnly,
|
|
5450
|
+
},
|
|
5451
|
+
};
|
|
5452
|
+
|
|
5376
5453
|
if (audioOnly) {
|
|
5377
|
-
inviterOptions.sessionDescriptionHandlerModifiersReInvite = [
|
|
5454
|
+
inviterOptions.sessionDescriptionHandlerModifiersReInvite = [stripVideo];
|
|
5378
5455
|
}
|
|
5379
5456
|
|
|
5380
5457
|
const session = new Inviter(this.userAgent, this._makeURI(number), inviterOptions);
|
|
@@ -5403,10 +5480,11 @@ class WebRTCClient extends Emitter {
|
|
|
5403
5480
|
sessionDescriptionHandlerOptions: this.getMediaConfiguration(enableVideo || false, conference),
|
|
5404
5481
|
};
|
|
5405
5482
|
|
|
5406
|
-
inviteOptions.
|
|
5483
|
+
inviteOptions.sessionDescriptionHandlerOptions.audioOnly = audioOnly;
|
|
5407
5484
|
|
|
5485
|
+
inviteOptions.sessionDescriptionHandlerModifiers = [replaceLocalIpModifier];
|
|
5408
5486
|
if (audioOnly) {
|
|
5409
|
-
inviteOptions.sessionDescriptionHandlerModifiers.push(
|
|
5487
|
+
inviteOptions.sessionDescriptionHandlerModifiers.push(stripVideo);
|
|
5410
5488
|
}
|
|
5411
5489
|
|
|
5412
5490
|
// Do not await invite here or we'll miss the Establishing state transition
|
|
@@ -5620,6 +5698,9 @@ class WebRTCClient extends Emitter {
|
|
|
5620
5698
|
if (!this._isWeb()) {
|
|
5621
5699
|
options.sessionDescriptionHandlerModifiers = [holdModifier];
|
|
5622
5700
|
}
|
|
5701
|
+
options.sessionDescriptionHandlerOptions = {
|
|
5702
|
+
constraints: options.constraints,
|
|
5703
|
+
};
|
|
5623
5704
|
|
|
5624
5705
|
// Send re-INVITE
|
|
5625
5706
|
return session.invite(options);
|
|
@@ -5659,6 +5740,9 @@ class WebRTCClient extends Emitter {
|
|
|
5659
5740
|
// (eg: holdModifier)
|
|
5660
5741
|
options.sessionDescriptionHandlerModifiers = [];
|
|
5661
5742
|
}
|
|
5743
|
+
options.sessionDescriptionHandlerOptions = {
|
|
5744
|
+
constraints: options.constraints,
|
|
5745
|
+
};
|
|
5662
5746
|
|
|
5663
5747
|
// Send re-INVITE
|
|
5664
5748
|
return session.invite(options);
|
|
@@ -5888,7 +5972,8 @@ class WebRTCClient extends Emitter {
|
|
|
5888
5972
|
? this.video.deviceId.exact : undefined;
|
|
5889
5973
|
}
|
|
5890
5974
|
|
|
5891
|
-
reinvite(sipSession , newConstraints = null, conference = false
|
|
5975
|
+
reinvite(sipSession , newConstraints = null, conference = false,
|
|
5976
|
+
audioOnly = false) {
|
|
5892
5977
|
if (!sipSession) {
|
|
5893
5978
|
return false;
|
|
5894
5979
|
}
|
|
@@ -5898,16 +5983,17 @@ class WebRTCClient extends Emitter {
|
|
|
5898
5983
|
}
|
|
5899
5984
|
|
|
5900
5985
|
const wasMuted = this.isAudioMuted(sipSession);
|
|
5901
|
-
// When upgrading to video, remove the `
|
|
5986
|
+
// When upgrading to video, remove the `stripVideo` modifiers
|
|
5902
5987
|
if (newConstraints && newConstraints.video) {
|
|
5903
5988
|
const modifiers = sipSession.sessionDescriptionHandlerModifiersReInvite;
|
|
5904
5989
|
sipSession.sessionDescriptionHandlerModifiersReInvite = modifiers.filter(modifier =>
|
|
5905
|
-
modifier !==
|
|
5990
|
+
modifier !== stripVideo);
|
|
5906
5991
|
}
|
|
5907
5992
|
|
|
5908
5993
|
sipSession.sessionDescriptionHandlerOptionsReInvite = {
|
|
5909
5994
|
...sipSession.sessionDescriptionHandlerOptionsReInvite,
|
|
5910
5995
|
conference,
|
|
5996
|
+
audioOnly,
|
|
5911
5997
|
};
|
|
5912
5998
|
|
|
5913
5999
|
const shouldDoVideo = newConstraints ? newConstraints.video : this.sessionWantsToDoVideo(sipSession);
|
|
@@ -5947,6 +6033,8 @@ class WebRTCClient extends Emitter {
|
|
|
5947
6033
|
},
|
|
5948
6034
|
sessionDescriptionHandlerOptions: {
|
|
5949
6035
|
constraints,
|
|
6036
|
+
conference,
|
|
6037
|
+
audioOnly,
|
|
5950
6038
|
offerOptions: {
|
|
5951
6039
|
iceRestart: false,
|
|
5952
6040
|
},
|
|
@@ -6406,6 +6494,8 @@ class WebRTCClient extends Emitter {
|
|
|
6406
6494
|
|
|
6407
6495
|
// Invitation and Inviter extends Session
|
|
6408
6496
|
_setupSession(session ) {
|
|
6497
|
+
const sipSessionId = this.getSipSessionId(session);
|
|
6498
|
+
|
|
6409
6499
|
// When receiving an Invitation, the delegate is not defined.
|
|
6410
6500
|
if (!session.delegate) {
|
|
6411
6501
|
session.delegate = {};
|
|
@@ -6429,8 +6519,18 @@ class WebRTCClient extends Emitter {
|
|
|
6429
6519
|
};
|
|
6430
6520
|
};
|
|
6431
6521
|
|
|
6522
|
+
const oldInviteRequest = session.onInviteRequest.bind(session);
|
|
6523
|
+
let hadRemoteVideo = false;
|
|
6524
|
+
|
|
6525
|
+
// Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
|
|
6526
|
+
// Becase when `onInvite` is called we already got the video track
|
|
6527
|
+
session.onInviteRequest = (request) => {
|
|
6528
|
+
hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
6529
|
+
|
|
6530
|
+
oldInviteRequest(request);
|
|
6531
|
+
};
|
|
6532
|
+
|
|
6432
6533
|
session.delegate.onInvite = (request ) => {
|
|
6433
|
-
const sipSessionId = this.getSipSessionId(session);
|
|
6434
6534
|
let updatedCalleeName = null;
|
|
6435
6535
|
let updatedNumber = null;
|
|
6436
6536
|
if (session.assertedIdentity) {
|
|
@@ -6440,7 +6540,6 @@ class WebRTCClient extends Emitter {
|
|
|
6440
6540
|
logger.info('re-invite received', { updatedCalleeName, updatedNumber });
|
|
6441
6541
|
|
|
6442
6542
|
// Useful to know if it's a video upgrade or an unhold from a remote peer with a video stream
|
|
6443
|
-
const hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
6444
6543
|
|
|
6445
6544
|
// Update SDP
|
|
6446
6545
|
// Remote video is handled by the `track` event. Here we're dealing with video stream removal.
|
|
@@ -6490,7 +6589,7 @@ class WebRTCClient extends Emitter {
|
|
|
6490
6589
|
}
|
|
6491
6590
|
|
|
6492
6591
|
_isAudioOnly(session ) {
|
|
6493
|
-
return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier ===
|
|
6592
|
+
return session.sessionDescriptionHandlerModifiersReInvite.find(modifier => modifier === stripVideo);
|
|
6494
6593
|
}
|
|
6495
6594
|
|
|
6496
6595
|
_setupMedias(session , newStream ) {
|
package/esm/api/agentd.js
CHANGED
|
@@ -305,7 +305,13 @@ class IssueReporter {
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
_isLevelAbove(level1 , level2 ) {
|
|
308
|
-
|
|
308
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
309
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
310
|
+
if (index1 === -1 || index2 === -1) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return index1 > index2;
|
|
309
315
|
}
|
|
310
316
|
|
|
311
317
|
_makeCategory(category ) {
|
|
@@ -363,6 +369,7 @@ class ApiRequester {
|
|
|
363
369
|
|
|
364
370
|
|
|
365
371
|
|
|
372
|
+
|
|
366
373
|
|
|
367
374
|
|
|
368
375
|
|
|
@@ -402,6 +409,8 @@ class ApiRequester {
|
|
|
402
409
|
this.token = token;
|
|
403
410
|
}
|
|
404
411
|
|
|
412
|
+
this.shouldLogErrors = true;
|
|
413
|
+
|
|
405
414
|
methods.forEach(method => {
|
|
406
415
|
// $FlowFixMe
|
|
407
416
|
ApiRequester.prototype[method] = function sugar(...args) {
|
|
@@ -425,6 +434,14 @@ class ApiRequester {
|
|
|
425
434
|
this.fetchOptions = options;
|
|
426
435
|
}
|
|
427
436
|
|
|
437
|
+
disableErrorLogging() {
|
|
438
|
+
this.shouldLogErrors = false;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
enableErrorLogging() {
|
|
442
|
+
this.shouldLogErrors = true;
|
|
443
|
+
}
|
|
444
|
+
|
|
428
445
|
async call(
|
|
429
446
|
path ,
|
|
430
447
|
method = 'get',
|
|
@@ -485,7 +502,9 @@ class ApiRequester {
|
|
|
485
502
|
? exceptionClass.fromText(err, response.status)
|
|
486
503
|
: exceptionClass.fromResponse(err, response.status);
|
|
487
504
|
|
|
488
|
-
|
|
505
|
+
if (this.shouldLogErrors) {
|
|
506
|
+
logger.error('API error', error);
|
|
507
|
+
}
|
|
489
508
|
|
|
490
509
|
throw error;
|
|
491
510
|
});
|
|
@@ -493,7 +512,9 @@ class ApiRequester {
|
|
|
493
512
|
|
|
494
513
|
return newParse(response, isJson);
|
|
495
514
|
}).catch(error => {
|
|
496
|
-
|
|
515
|
+
if (this.shouldLogErrors) {
|
|
516
|
+
logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
|
|
517
|
+
}
|
|
497
518
|
|
|
498
519
|
throw error;
|
|
499
520
|
});
|
package/esm/api/amid.js
CHANGED
|
@@ -244,7 +244,13 @@ class IssueReporter {
|
|
|
244
244
|
}
|
|
245
245
|
|
|
246
246
|
_isLevelAbove(level1 , level2 ) {
|
|
247
|
-
|
|
247
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
248
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
249
|
+
if (index1 === -1 || index2 === -1) {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return index1 > index2;
|
|
248
254
|
}
|
|
249
255
|
|
|
250
256
|
_makeCategory(category ) {
|
package/esm/api/application.js
CHANGED
|
@@ -305,7 +305,13 @@ class IssueReporter {
|
|
|
305
305
|
}
|
|
306
306
|
|
|
307
307
|
_isLevelAbove(level1 , level2 ) {
|
|
308
|
-
|
|
308
|
+
const index1 = LOG_LEVELS.indexOf(level1);
|
|
309
|
+
const index2 = LOG_LEVELS.indexOf(level2);
|
|
310
|
+
if (index1 === -1 || index2 === -1) {
|
|
311
|
+
return false;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return index1 > index2;
|
|
309
315
|
}
|
|
310
316
|
|
|
311
317
|
_makeCategory(category ) {
|
|
@@ -363,6 +369,7 @@ class ApiRequester {
|
|
|
363
369
|
|
|
364
370
|
|
|
365
371
|
|
|
372
|
+
|
|
366
373
|
|
|
367
374
|
|
|
368
375
|
|
|
@@ -402,6 +409,8 @@ class ApiRequester {
|
|
|
402
409
|
this.token = token;
|
|
403
410
|
}
|
|
404
411
|
|
|
412
|
+
this.shouldLogErrors = true;
|
|
413
|
+
|
|
405
414
|
methods.forEach(method => {
|
|
406
415
|
// $FlowFixMe
|
|
407
416
|
ApiRequester.prototype[method] = function sugar(...args) {
|
|
@@ -425,6 +434,14 @@ class ApiRequester {
|
|
|
425
434
|
this.fetchOptions = options;
|
|
426
435
|
}
|
|
427
436
|
|
|
437
|
+
disableErrorLogging() {
|
|
438
|
+
this.shouldLogErrors = false;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
enableErrorLogging() {
|
|
442
|
+
this.shouldLogErrors = true;
|
|
443
|
+
}
|
|
444
|
+
|
|
428
445
|
async call(
|
|
429
446
|
path ,
|
|
430
447
|
method = 'get',
|
|
@@ -485,7 +502,9 @@ class ApiRequester {
|
|
|
485
502
|
? exceptionClass.fromText(err, response.status)
|
|
486
503
|
: exceptionClass.fromResponse(err, response.status);
|
|
487
504
|
|
|
488
|
-
|
|
505
|
+
if (this.shouldLogErrors) {
|
|
506
|
+
logger.error('API error', error);
|
|
507
|
+
}
|
|
489
508
|
|
|
490
509
|
throw error;
|
|
491
510
|
});
|
|
@@ -493,7 +512,9 @@ class ApiRequester {
|
|
|
493
512
|
|
|
494
513
|
return newParse(response, isJson);
|
|
495
514
|
}).catch(error => {
|
|
496
|
-
|
|
515
|
+
if (this.shouldLogErrors) {
|
|
516
|
+
logger.error('Fetch failed', { url, options, message: error.message, stack: error.stack });
|
|
517
|
+
}
|
|
497
518
|
|
|
498
519
|
throw error;
|
|
499
520
|
});
|