@wazo/sdk 0.37.2 → 0.37.6
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 +84 -22
- package/esm/__tests__/web-rtc-client.test.js +156 -55
- package/esm/api/call-logd.js +10 -22
- package/esm/api/calld.js +3 -0
- package/esm/api/confd.js +71 -0
- package/esm/api-client.js +84 -22
- package/esm/checker/Checker.js +160 -55
- package/esm/checker/checks/aor.js +84 -22
- package/esm/checker/checks/api.js +84 -22
- package/esm/checker/checks/index.js +160 -55
- package/esm/checker/checks/wazo-websocket.js +4 -0
- package/esm/checker/checks/webrtc-transport.js +156 -55
- package/esm/checker/checks/webrtc.js +156 -55
- package/esm/domain/AdHocAPIConference.js +84 -22
- package/esm/domain/CallLog.js +10 -22
- package/esm/domain/Features.js +84 -22
- package/esm/domain/Meeting.js +71 -0
- package/esm/domain/Phone/CTIPhone.js +84 -22
- package/esm/domain/Phone/WebRTCPhone.js +22 -8
- package/esm/domain/__tests__/CallLog.test.js +10 -22
- package/esm/index.js +726 -371
- package/esm/lib/WazoSessionDescriptionHandler.js +17 -9
- package/esm/service/CallApi.js +84 -22
- package/esm/service/getApiClient.js +84 -22
- package/esm/simple/Auth.js +717 -363
- package/esm/simple/Configuration.js +717 -363
- package/esm/simple/Directory.js +84 -22
- package/esm/simple/Phone.js +709 -355
- package/esm/simple/Websocket.js +6 -0
- package/esm/simple/index.js +719 -365
- package/esm/simple/room/LocalParticipant.js +689 -335
- package/esm/simple/room/Participant.js +689 -335
- package/esm/simple/room/RemoteParticipant.js +689 -335
- package/esm/simple/room/Room.js +689 -335
- package/esm/simple/room/SipRoom.js +13001 -0
- package/esm/simple/room/Stream.js +719 -365
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +4130 -3774
- package/esm/simple/utils.js +719 -365
- package/esm/web-rtc-client.js +156 -55
- package/esm/websocket-client.js +5 -1
- package/lib/__tests__/api-client.test.js +84 -22
- package/lib/__tests__/web-rtc-client.test.js +156 -55
- package/lib/api/call-logd.js +10 -22
- package/lib/api/calld.js +3 -0
- package/lib/api/confd.js +71 -0
- package/lib/api-client.js +84 -22
- package/lib/checker/Checker.js +160 -55
- package/lib/checker/checks/aor.js +84 -22
- package/lib/checker/checks/api.js +84 -22
- package/lib/checker/checks/index.js +160 -55
- package/lib/checker/checks/wazo-websocket.js +4 -0
- package/lib/checker/checks/webrtc-transport.js +156 -55
- package/lib/checker/checks/webrtc.js +156 -55
- package/lib/domain/AdHocAPIConference.js +84 -22
- package/lib/domain/CallLog.js +10 -22
- package/lib/domain/Features.js +84 -22
- package/lib/domain/Meeting.js +73 -0
- package/lib/domain/Phone/CTIPhone.js +84 -22
- package/lib/domain/Phone/WebRTCPhone.js +22 -8
- package/lib/domain/__tests__/CallLog.test.js +10 -22
- package/lib/index.js +726 -371
- package/lib/lib/WazoSessionDescriptionHandler.js +17 -9
- package/lib/service/CallApi.js +84 -22
- package/lib/service/getApiClient.js +84 -22
- package/lib/simple/Auth.js +717 -363
- package/lib/simple/Configuration.js +717 -363
- package/lib/simple/Directory.js +84 -22
- package/lib/simple/Phone.js +709 -355
- package/lib/simple/Websocket.js +6 -0
- package/lib/simple/index.js +719 -365
- package/lib/simple/room/LocalParticipant.js +689 -335
- package/lib/simple/room/Participant.js +689 -335
- package/lib/simple/room/RemoteParticipant.js +689 -335
- package/lib/simple/room/Room.js +689 -335
- package/lib/simple/room/SipRoom.js +13011 -0
- package/lib/simple/room/Stream.js +719 -365
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +4131 -3775
- package/lib/simple/utils.js +719 -365
- package/lib/web-rtc-client.js +156 -55
- package/lib/websocket-client.js +6 -0
- package/package.json +1 -1
- package/src/api/calld.js +3 -0
- package/src/api/confd.js +13 -0
- package/src/domain/CallLog.js +10 -22
- package/src/domain/Meeting.js +59 -0
- package/src/domain/Phone/WebRTCPhone.js +22 -8
- package/src/index.js +2 -0
- package/src/lib/WazoSessionDescriptionHandler.js +17 -9
- package/src/simple/Phone.js +13 -4
- package/src/simple/index.js +4 -0
- package/src/simple/room/Participant.js +7 -0
- package/src/simple/room/Room.js +158 -79
- package/src/simple/room/SipRoom.js +147 -0
- package/src/simple/room/Stream.js +1 -3
- package/src/simple/room/__tests__/RemoteParticipant.test.js +3 -2
- package/src/types/WebSocketMessage.js +21 -0
- package/src/web-rtc-client.js +55 -24
- package/src/websocket-client.js +4 -0
|
@@ -769,7 +769,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
769
769
|
.then(() => {
|
|
770
770
|
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
|
|
771
771
|
// Add a video an empty bundle to be able to replaceTrack when joining a conference without video
|
|
772
|
-
this.peerConnection.addTransceiver
|
|
772
|
+
if (this.peerConnection.addTransceiver) {
|
|
773
|
+
this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
|
|
774
|
+
}
|
|
773
775
|
}
|
|
774
776
|
})
|
|
775
777
|
.then(() => this.createLocalOfferOrAnswer(options))
|
|
@@ -796,12 +798,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
796
798
|
};
|
|
797
799
|
})
|
|
798
800
|
.then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
|
|
799
|
-
.then((sessionDescription) => {
|
|
800
|
-
// Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
|
|
801
|
-
this.localMediaStreamConstraints = options.constraints;
|
|
802
|
-
|
|
803
|
-
return sessionDescription;
|
|
804
|
-
})
|
|
805
801
|
.then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
|
|
806
802
|
.catch((error) => {
|
|
807
803
|
wazoLogger.error('error when creating media', error);
|
|
@@ -996,6 +992,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
996
992
|
|
|
997
993
|
// set the transceiver direction to the answer direction
|
|
998
994
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
995
|
+
if (transceiver.stopped) {
|
|
996
|
+
return;
|
|
997
|
+
}
|
|
999
998
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
1000
999
|
const { receiver } = transceiver;
|
|
1001
1000
|
if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
|
|
@@ -1040,10 +1039,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
1040
1039
|
if (kind !== 'audio' && kind !== 'video') {
|
|
1041
1040
|
throw new Error(`Unknown new track kind ${kind}.`);
|
|
1042
1041
|
}
|
|
1043
|
-
const sender = pc.getSenders().find((otherSender) =>
|
|
1042
|
+
const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
|
|
1043
|
+
otherSender.track && otherSender.track.kind === kind);
|
|
1044
1044
|
|
|
1045
1045
|
// Do not reuse sender video tracks in SFU
|
|
1046
1046
|
if (sender && (!sfu || newTrack.kind === 'audio')) {
|
|
1047
|
+
if (sender.track) {
|
|
1048
|
+
// eslint-disable-next-line no-param-reassign
|
|
1049
|
+
newTrack.enabled = sender.track.enabled;
|
|
1050
|
+
}
|
|
1047
1051
|
trackUpdates.push(
|
|
1048
1052
|
new Promise((resolve) => {
|
|
1049
1053
|
this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
|
|
@@ -1077,7 +1081,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
1077
1081
|
// Review: could make streamless tracks a configurable option?
|
|
1078
1082
|
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
|
|
1079
1083
|
try {
|
|
1080
|
-
pc.addTrack
|
|
1084
|
+
if (pc.addTrack) {
|
|
1085
|
+
pc.addTrack(newTrack, localStream);
|
|
1086
|
+
} else {
|
|
1087
|
+
pc.addStream(localStream);
|
|
1088
|
+
}
|
|
1081
1089
|
} catch (error) {
|
|
1082
1090
|
this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
|
|
1083
1091
|
throw error;
|
|
@@ -3034,6 +3042,65 @@ class ExternalApp {
|
|
|
3034
3042
|
}
|
|
3035
3043
|
}
|
|
3036
3044
|
|
|
3045
|
+
//
|
|
3046
|
+
|
|
3047
|
+
|
|
3048
|
+
|
|
3049
|
+
|
|
3050
|
+
|
|
3051
|
+
|
|
3052
|
+
|
|
3053
|
+
|
|
3054
|
+
|
|
3055
|
+
|
|
3056
|
+
|
|
3057
|
+
class Meeting {
|
|
3058
|
+
|
|
3059
|
+
|
|
3060
|
+
|
|
3061
|
+
|
|
3062
|
+
|
|
3063
|
+
|
|
3064
|
+
|
|
3065
|
+
|
|
3066
|
+
|
|
3067
|
+
|
|
3068
|
+
static parse(plain ) {
|
|
3069
|
+
return new Meeting({
|
|
3070
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
3071
|
+
hostname: plain.hostname,
|
|
3072
|
+
name: plain.name,
|
|
3073
|
+
ownerUuids: plain.owner_uuids,
|
|
3074
|
+
port: plain.port,
|
|
3075
|
+
uuid: plain.uuid,
|
|
3076
|
+
number: plain.number,
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
|
|
3080
|
+
static newFrom(meeting ) {
|
|
3081
|
+
return newFrom(meeting, Meeting);
|
|
3082
|
+
}
|
|
3083
|
+
|
|
3084
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
3085
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
3086
|
+
this.hostname = hostname;
|
|
3087
|
+
this.name = name;
|
|
3088
|
+
this.ownerUuids = ownerUuids;
|
|
3089
|
+
this.port = port;
|
|
3090
|
+
this.uuid = uuid;
|
|
3091
|
+
this.number = number;
|
|
3092
|
+
|
|
3093
|
+
// Useful to compare instead of instanceof with minified code
|
|
3094
|
+
this.type = 'Meeting';
|
|
3095
|
+
}
|
|
3096
|
+
|
|
3097
|
+
getGuestSipCredentials() {
|
|
3098
|
+
// eslint-disable-next-line no-undef
|
|
3099
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
3100
|
+
return { username, secret };
|
|
3101
|
+
}
|
|
3102
|
+
}
|
|
3103
|
+
|
|
3037
3104
|
/* */
|
|
3038
3105
|
|
|
3039
3106
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -3098,6 +3165,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
3098
3165
|
return null;
|
|
3099
3166
|
}
|
|
3100
3167
|
},
|
|
3168
|
+
|
|
3169
|
+
createMyMeeting: (name ) =>
|
|
3170
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
3171
|
+
|
|
3172
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
3173
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
3174
|
+
|
|
3175
|
+
getMeeting: (meetingUuid ) =>
|
|
3176
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3177
|
+
|
|
3178
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
3179
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3101
3180
|
});
|
|
3102
3181
|
|
|
3103
3182
|
//
|
|
@@ -3682,7 +3761,11 @@ class CallLog {
|
|
|
3682
3761
|
answered: plain.answered,
|
|
3683
3762
|
callDirection: plain.call_direction,
|
|
3684
3763
|
destination: {
|
|
3685
|
-
|
|
3764
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
3765
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
3766
|
+
extension: plain.requested_extension
|
|
3767
|
+
|| plain.destination_extension
|
|
3768
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3686
3769
|
name: plain.requested_name || plain.destination_name || '',
|
|
3687
3770
|
},
|
|
3688
3771
|
source: {
|
|
@@ -3698,27 +3781,11 @@ class CallLog {
|
|
|
3698
3781
|
}
|
|
3699
3782
|
|
|
3700
3783
|
static parseNew(plain , session ) {
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
3707
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
3708
|
-
},
|
|
3709
|
-
source: {
|
|
3710
|
-
extension: plain.source_extension,
|
|
3711
|
-
name: plain.source_name,
|
|
3712
|
-
},
|
|
3713
|
-
id: plain.id,
|
|
3714
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3715
|
-
start: moment(plain.start).toDate(),
|
|
3716
|
-
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3717
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3718
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
3719
|
-
newMissedCall: session
|
|
3720
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
3721
|
-
});
|
|
3784
|
+
const callLog = CallLog.parse(plain);
|
|
3785
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
3786
|
+
callLog.newMissedCall = session
|
|
3787
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
3788
|
+
return callLog;
|
|
3722
3789
|
}
|
|
3723
3790
|
|
|
3724
3791
|
static newFrom(profile ) {
|
|
@@ -4475,6 +4542,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4475
4542
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
4476
4543
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
4477
4544
|
|
|
4545
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
4546
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
4547
|
+
|
|
4478
4548
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
4479
4549
|
|
|
4480
4550
|
mute: (callId ) =>
|
|
@@ -5107,6 +5177,7 @@ const MAX_REGISTER_TRIES = 10;
|
|
|
5107
5177
|
|
|
5108
5178
|
|
|
5109
5179
|
|
|
5180
|
+
|
|
5110
5181
|
|
|
5111
5182
|
|
|
5112
5183
|
|
|
@@ -5133,6 +5204,7 @@ class WebRTCClient extends Emitter {
|
|
|
5133
5204
|
|
|
5134
5205
|
|
|
5135
5206
|
|
|
5207
|
+
|
|
5136
5208
|
|
|
5137
5209
|
// sugar
|
|
5138
5210
|
|
|
@@ -5171,6 +5243,8 @@ class WebRTCClient extends Emitter {
|
|
|
5171
5243
|
super();
|
|
5172
5244
|
this.uaConfigOverrides = uaConfigOverrides;
|
|
5173
5245
|
this.config = config;
|
|
5246
|
+
this.skipRegister = config.skipRegister;
|
|
5247
|
+
|
|
5174
5248
|
this._buildConfig(config, session).then((newConfig ) => {
|
|
5175
5249
|
this.config = newConfig;
|
|
5176
5250
|
this.userAgent = this.createUserAgent(uaConfigOverrides);
|
|
@@ -5298,14 +5372,22 @@ class WebRTCClient extends Emitter {
|
|
|
5298
5372
|
}
|
|
5299
5373
|
|
|
5300
5374
|
register(tries = 0) {
|
|
5301
|
-
|
|
5375
|
+
const logInfo = {
|
|
5302
5376
|
userAgent: !!this.userAgent,
|
|
5303
5377
|
registered: this.isRegistered(),
|
|
5304
5378
|
connectionPromise: !!this.connectionPromise,
|
|
5305
5379
|
registerer: !!this.registerer,
|
|
5306
5380
|
waiting: this.registerer && this.registerer.waiting,
|
|
5307
5381
|
tries,
|
|
5308
|
-
|
|
5382
|
+
skipRegister: this.skipRegister,
|
|
5383
|
+
};
|
|
5384
|
+
|
|
5385
|
+
if (this.skipRegister) {
|
|
5386
|
+
logger.info('sdk webrtc skip register...', logInfo);
|
|
5387
|
+
return Promise.resolve();
|
|
5388
|
+
}
|
|
5389
|
+
|
|
5390
|
+
logger.info('sdk webrtc registering...', logInfo);
|
|
5309
5391
|
|
|
5310
5392
|
if (!this.userAgent) {
|
|
5311
5393
|
logger.info('sdk webrtc recreating User Agent');
|
|
@@ -5636,12 +5718,18 @@ class WebRTCClient extends Emitter {
|
|
|
5636
5718
|
}
|
|
5637
5719
|
|
|
5638
5720
|
if (pc.getSenders) {
|
|
5721
|
+
if (!pc.getSenders().length) {
|
|
5722
|
+
return false;
|
|
5723
|
+
}
|
|
5639
5724
|
pc.getSenders().forEach(sender => {
|
|
5640
5725
|
if (sender && sender.track && sender.track.kind === 'audio') {
|
|
5641
5726
|
muted = muted && !sender.track.enabled;
|
|
5642
5727
|
}
|
|
5643
5728
|
});
|
|
5644
5729
|
} else {
|
|
5730
|
+
if (!pc.getLocalStreams().length) {
|
|
5731
|
+
return false;
|
|
5732
|
+
}
|
|
5645
5733
|
pc.getLocalStreams().forEach(stream => {
|
|
5646
5734
|
stream.getAudioTracks().forEach(track => {
|
|
5647
5735
|
muted = muted && !track.enabled;
|
|
@@ -5700,6 +5788,8 @@ class WebRTCClient extends Emitter {
|
|
|
5700
5788
|
}
|
|
5701
5789
|
options.sessionDescriptionHandlerOptions = {
|
|
5702
5790
|
constraints: options.constraints,
|
|
5791
|
+
hold: true,
|
|
5792
|
+
conference: isConference,
|
|
5703
5793
|
};
|
|
5704
5794
|
|
|
5705
5795
|
// Send re-INVITE
|
|
@@ -5742,6 +5832,8 @@ class WebRTCClient extends Emitter {
|
|
|
5742
5832
|
}
|
|
5743
5833
|
options.sessionDescriptionHandlerOptions = {
|
|
5744
5834
|
constraints: options.constraints,
|
|
5835
|
+
hold: false,
|
|
5836
|
+
conference: isConference,
|
|
5745
5837
|
};
|
|
5746
5838
|
|
|
5747
5839
|
// Send re-INVITE
|
|
@@ -5925,7 +6017,8 @@ class WebRTCClient extends Emitter {
|
|
|
5925
6017
|
}
|
|
5926
6018
|
const sdh = session.sessionDescriptionHandler;
|
|
5927
6019
|
const pc = sdh.peerConnection;
|
|
5928
|
-
const
|
|
6020
|
+
const sessionId = this.getSipSessionId(session);
|
|
6021
|
+
const localStream = this.getLocalStream(sessionId);
|
|
5929
6022
|
|
|
5930
6023
|
// Release old video stream
|
|
5931
6024
|
if (localStream) {
|
|
@@ -5951,11 +6044,8 @@ class WebRTCClient extends Emitter {
|
|
|
5951
6044
|
|
|
5952
6045
|
// let's update the local stream
|
|
5953
6046
|
this.eventEmitter.emit('onVideoInputChange', stream);
|
|
5954
|
-
|
|
5955
|
-
|
|
5956
|
-
} catch (_) {
|
|
5957
|
-
// Nothing to do
|
|
5958
|
-
}
|
|
6047
|
+
this.setLocalMediaStream(sessionId, stream);
|
|
6048
|
+
|
|
5959
6049
|
return stream;
|
|
5960
6050
|
});
|
|
5961
6051
|
}
|
|
@@ -6257,9 +6347,11 @@ class WebRTCClient extends Emitter {
|
|
|
6257
6347
|
remoteStream.removeTrack(track);
|
|
6258
6348
|
});
|
|
6259
6349
|
|
|
6260
|
-
pc.getReceivers
|
|
6261
|
-
|
|
6262
|
-
|
|
6350
|
+
if (pc.getReceivers) {
|
|
6351
|
+
pc.getReceivers().forEach(receiver => {
|
|
6352
|
+
remoteStream.addTrack(receiver.track);
|
|
6353
|
+
});
|
|
6354
|
+
}
|
|
6263
6355
|
}
|
|
6264
6356
|
|
|
6265
6357
|
getMediaConfiguration(enableVideo , conference = false, constraints = null) {
|
|
@@ -6294,6 +6386,25 @@ class WebRTCClient extends Emitter {
|
|
|
6294
6386
|
return sessionId in this.conferences;
|
|
6295
6387
|
}
|
|
6296
6388
|
|
|
6389
|
+
createAudioElementFor(sessionId ) {
|
|
6390
|
+
const audio = document.createElement('audio');
|
|
6391
|
+
audio.setAttribute('id', `audio-${sessionId}`);
|
|
6392
|
+
|
|
6393
|
+
if (audio.setSinkId && this.audioOutputDeviceId) {
|
|
6394
|
+
audio.setSinkId(this.audioOutputDeviceId);
|
|
6395
|
+
}
|
|
6396
|
+
|
|
6397
|
+
if (document.body) {
|
|
6398
|
+
document.body.appendChild(audio);
|
|
6399
|
+
}
|
|
6400
|
+
this.audioElements[sessionId] = audio;
|
|
6401
|
+
|
|
6402
|
+
audio.volume = this.audioOutputVolume;
|
|
6403
|
+
audio.autoplay = true;
|
|
6404
|
+
|
|
6405
|
+
return audio;
|
|
6406
|
+
}
|
|
6407
|
+
|
|
6297
6408
|
_onTransportError() {
|
|
6298
6409
|
this.eventEmitter.emit(TRANSPORT_ERROR);
|
|
6299
6410
|
this.attemptReconnection();
|
|
@@ -6523,7 +6634,7 @@ class WebRTCClient extends Emitter {
|
|
|
6523
6634
|
let hadRemoteVideo = false;
|
|
6524
6635
|
|
|
6525
6636
|
// Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
|
|
6526
|
-
//
|
|
6637
|
+
// Because when `onInvite` is called we already got the video track
|
|
6527
6638
|
session.onInviteRequest = (request) => {
|
|
6528
6639
|
hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
6529
6640
|
|
|
@@ -6598,20 +6709,10 @@ class WebRTCClient extends Emitter {
|
|
|
6598
6709
|
const isConference = this.isConference(sessionId);
|
|
6599
6710
|
|
|
6600
6711
|
if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
|
|
6601
|
-
|
|
6602
|
-
audio.setAttribute('id', `audio-${sessionId}`);
|
|
6603
|
-
|
|
6604
|
-
if (audio.setSinkId && this.audioOutputDeviceId) {
|
|
6605
|
-
audio.setSinkId(this.audioOutputDeviceId);
|
|
6606
|
-
}
|
|
6607
|
-
|
|
6608
|
-
if (document.body) {
|
|
6609
|
-
document.body.appendChild(audio);
|
|
6610
|
-
}
|
|
6611
|
-
this.audioElements[sessionId] = audio;
|
|
6712
|
+
this.createAudioElementFor(sessionId);
|
|
6612
6713
|
}
|
|
6613
6714
|
|
|
6614
|
-
const audioElement = this.audioElements[
|
|
6715
|
+
const audioElement = this.audioElements[sessionId];
|
|
6615
6716
|
const stream = newStream || this.getRemoteStream(sessionId);
|
|
6616
6717
|
|
|
6617
6718
|
if (!this._isWeb() || !stream) {
|
|
@@ -2699,6 +2699,65 @@ class ExternalApp {
|
|
|
2699
2699
|
}
|
|
2700
2700
|
}
|
|
2701
2701
|
|
|
2702
|
+
//
|
|
2703
|
+
|
|
2704
|
+
|
|
2705
|
+
|
|
2706
|
+
|
|
2707
|
+
|
|
2708
|
+
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
|
|
2712
|
+
|
|
2713
|
+
|
|
2714
|
+
class Meeting {
|
|
2715
|
+
|
|
2716
|
+
|
|
2717
|
+
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
|
|
2721
|
+
|
|
2722
|
+
|
|
2723
|
+
|
|
2724
|
+
|
|
2725
|
+
static parse(plain ) {
|
|
2726
|
+
return new Meeting({
|
|
2727
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
2728
|
+
hostname: plain.hostname,
|
|
2729
|
+
name: plain.name,
|
|
2730
|
+
ownerUuids: plain.owner_uuids,
|
|
2731
|
+
port: plain.port,
|
|
2732
|
+
uuid: plain.uuid,
|
|
2733
|
+
number: plain.number,
|
|
2734
|
+
});
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
static newFrom(meeting ) {
|
|
2738
|
+
return newFrom(meeting, Meeting);
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
2742
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
2743
|
+
this.hostname = hostname;
|
|
2744
|
+
this.name = name;
|
|
2745
|
+
this.ownerUuids = ownerUuids;
|
|
2746
|
+
this.port = port;
|
|
2747
|
+
this.uuid = uuid;
|
|
2748
|
+
this.number = number;
|
|
2749
|
+
|
|
2750
|
+
// Useful to compare instead of instanceof with minified code
|
|
2751
|
+
this.type = 'Meeting';
|
|
2752
|
+
}
|
|
2753
|
+
|
|
2754
|
+
getGuestSipCredentials() {
|
|
2755
|
+
// eslint-disable-next-line no-undef
|
|
2756
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
2757
|
+
return { username, secret };
|
|
2758
|
+
}
|
|
2759
|
+
}
|
|
2760
|
+
|
|
2702
2761
|
/* */
|
|
2703
2762
|
|
|
2704
2763
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -2763,6 +2822,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2763
2822
|
return null;
|
|
2764
2823
|
}
|
|
2765
2824
|
},
|
|
2825
|
+
|
|
2826
|
+
createMyMeeting: (name ) =>
|
|
2827
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
2828
|
+
|
|
2829
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
2830
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
2831
|
+
|
|
2832
|
+
getMeeting: (meetingUuid ) =>
|
|
2833
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2834
|
+
|
|
2835
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
2836
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2766
2837
|
});
|
|
2767
2838
|
|
|
2768
2839
|
//
|
|
@@ -3141,7 +3212,11 @@ class CallLog {
|
|
|
3141
3212
|
answered: plain.answered,
|
|
3142
3213
|
callDirection: plain.call_direction,
|
|
3143
3214
|
destination: {
|
|
3144
|
-
|
|
3215
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
3216
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
3217
|
+
extension: plain.requested_extension
|
|
3218
|
+
|| plain.destination_extension
|
|
3219
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3145
3220
|
name: plain.requested_name || plain.destination_name || '',
|
|
3146
3221
|
},
|
|
3147
3222
|
source: {
|
|
@@ -3157,27 +3232,11 @@ class CallLog {
|
|
|
3157
3232
|
}
|
|
3158
3233
|
|
|
3159
3234
|
static parseNew(plain , session ) {
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
3166
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
3167
|
-
},
|
|
3168
|
-
source: {
|
|
3169
|
-
extension: plain.source_extension,
|
|
3170
|
-
name: plain.source_name,
|
|
3171
|
-
},
|
|
3172
|
-
id: plain.id,
|
|
3173
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3174
|
-
start: moment(plain.start).toDate(),
|
|
3175
|
-
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3176
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3177
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
3178
|
-
newMissedCall: session
|
|
3179
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
3180
|
-
});
|
|
3235
|
+
const callLog = CallLog.parse(plain);
|
|
3236
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
3237
|
+
callLog.newMissedCall = session
|
|
3238
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
3239
|
+
return callLog;
|
|
3181
3240
|
}
|
|
3182
3241
|
|
|
3183
3242
|
static newFrom(profile ) {
|
|
@@ -3919,6 +3978,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
3919
3978
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
3920
3979
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
3921
3980
|
|
|
3981
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
3982
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
3983
|
+
|
|
3922
3984
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
3923
3985
|
|
|
3924
3986
|
mute: (callId ) =>
|
package/esm/domain/CallLog.js
CHANGED
|
@@ -162,7 +162,11 @@ class CallLog {
|
|
|
162
162
|
answered: plain.answered,
|
|
163
163
|
callDirection: plain.call_direction,
|
|
164
164
|
destination: {
|
|
165
|
-
|
|
165
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
166
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
167
|
+
extension: plain.requested_extension
|
|
168
|
+
|| plain.destination_extension
|
|
169
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
166
170
|
name: plain.requested_name || plain.destination_name || '',
|
|
167
171
|
},
|
|
168
172
|
source: {
|
|
@@ -178,27 +182,11 @@ class CallLog {
|
|
|
178
182
|
}
|
|
179
183
|
|
|
180
184
|
static parseNew(plain , session ) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
187
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
188
|
-
},
|
|
189
|
-
source: {
|
|
190
|
-
extension: plain.source_extension,
|
|
191
|
-
name: plain.source_name,
|
|
192
|
-
},
|
|
193
|
-
id: plain.id,
|
|
194
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
195
|
-
start: moment(plain.start).toDate(),
|
|
196
|
-
end: plain.end ? moment(plain.end).toDate() : null,
|
|
197
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
198
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
199
|
-
newMissedCall: session
|
|
200
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
201
|
-
});
|
|
185
|
+
const callLog = CallLog.parse(plain);
|
|
186
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
187
|
+
callLog.newMissedCall = session
|
|
188
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
189
|
+
return callLog;
|
|
202
190
|
}
|
|
203
191
|
|
|
204
192
|
static newFrom(profile ) {
|