@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
|
@@ -778,7 +778,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
778
778
|
.then(() => {
|
|
779
779
|
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
|
|
780
780
|
// Add a video an empty bundle to be able to replaceTrack when joining a conference without video
|
|
781
|
-
this.peerConnection.addTransceiver
|
|
781
|
+
if (this.peerConnection.addTransceiver) {
|
|
782
|
+
this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
|
|
783
|
+
}
|
|
782
784
|
}
|
|
783
785
|
})
|
|
784
786
|
.then(() => this.createLocalOfferOrAnswer(options))
|
|
@@ -805,12 +807,6 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
805
807
|
};
|
|
806
808
|
})
|
|
807
809
|
.then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
|
|
808
|
-
.then((sessionDescription) => {
|
|
809
|
-
// Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
|
|
810
|
-
this.localMediaStreamConstraints = options.constraints;
|
|
811
|
-
|
|
812
|
-
return sessionDescription;
|
|
813
|
-
})
|
|
814
810
|
.then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
|
|
815
811
|
.catch((error) => {
|
|
816
812
|
wazoLogger.error('error when creating media', error);
|
|
@@ -1005,6 +1001,9 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
1005
1001
|
|
|
1006
1002
|
// set the transceiver direction to the answer direction
|
|
1007
1003
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
1004
|
+
if (transceiver.stopped) {
|
|
1005
|
+
return;
|
|
1006
|
+
}
|
|
1008
1007
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
1009
1008
|
const { receiver } = transceiver;
|
|
1010
1009
|
if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
|
|
@@ -1049,10 +1048,15 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
1049
1048
|
if (kind !== 'audio' && kind !== 'video') {
|
|
1050
1049
|
throw new Error(`Unknown new track kind ${kind}.`);
|
|
1051
1050
|
}
|
|
1052
|
-
const sender = pc.getSenders().find((otherSender) =>
|
|
1051
|
+
const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
|
|
1052
|
+
otherSender.track && otherSender.track.kind === kind);
|
|
1053
1053
|
|
|
1054
1054
|
// Do not reuse sender video tracks in SFU
|
|
1055
1055
|
if (sender && (!sfu || newTrack.kind === 'audio')) {
|
|
1056
|
+
if (sender.track) {
|
|
1057
|
+
// eslint-disable-next-line no-param-reassign
|
|
1058
|
+
newTrack.enabled = sender.track.enabled;
|
|
1059
|
+
}
|
|
1056
1060
|
trackUpdates.push(
|
|
1057
1061
|
new Promise((resolve) => {
|
|
1058
1062
|
this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
|
|
@@ -1086,7 +1090,11 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
|
|
|
1086
1090
|
// Review: could make streamless tracks a configurable option?
|
|
1087
1091
|
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
|
|
1088
1092
|
try {
|
|
1089
|
-
pc.addTrack
|
|
1093
|
+
if (pc.addTrack) {
|
|
1094
|
+
pc.addTrack(newTrack, localStream);
|
|
1095
|
+
} else {
|
|
1096
|
+
pc.addStream(localStream);
|
|
1097
|
+
}
|
|
1090
1098
|
} catch (error) {
|
|
1091
1099
|
this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
|
|
1092
1100
|
throw error;
|
|
@@ -3043,6 +3051,65 @@ class ExternalApp {
|
|
|
3043
3051
|
}
|
|
3044
3052
|
}
|
|
3045
3053
|
|
|
3054
|
+
//
|
|
3055
|
+
|
|
3056
|
+
|
|
3057
|
+
|
|
3058
|
+
|
|
3059
|
+
|
|
3060
|
+
|
|
3061
|
+
|
|
3062
|
+
|
|
3063
|
+
|
|
3064
|
+
|
|
3065
|
+
|
|
3066
|
+
class Meeting {
|
|
3067
|
+
|
|
3068
|
+
|
|
3069
|
+
|
|
3070
|
+
|
|
3071
|
+
|
|
3072
|
+
|
|
3073
|
+
|
|
3074
|
+
|
|
3075
|
+
|
|
3076
|
+
|
|
3077
|
+
static parse(plain ) {
|
|
3078
|
+
return new Meeting({
|
|
3079
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
3080
|
+
hostname: plain.hostname,
|
|
3081
|
+
name: plain.name,
|
|
3082
|
+
ownerUuids: plain.owner_uuids,
|
|
3083
|
+
port: plain.port,
|
|
3084
|
+
uuid: plain.uuid,
|
|
3085
|
+
number: plain.number,
|
|
3086
|
+
});
|
|
3087
|
+
}
|
|
3088
|
+
|
|
3089
|
+
static newFrom(meeting ) {
|
|
3090
|
+
return newFrom(meeting, Meeting);
|
|
3091
|
+
}
|
|
3092
|
+
|
|
3093
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
3094
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
3095
|
+
this.hostname = hostname;
|
|
3096
|
+
this.name = name;
|
|
3097
|
+
this.ownerUuids = ownerUuids;
|
|
3098
|
+
this.port = port;
|
|
3099
|
+
this.uuid = uuid;
|
|
3100
|
+
this.number = number;
|
|
3101
|
+
|
|
3102
|
+
// Useful to compare instead of instanceof with minified code
|
|
3103
|
+
this.type = 'Meeting';
|
|
3104
|
+
}
|
|
3105
|
+
|
|
3106
|
+
getGuestSipCredentials() {
|
|
3107
|
+
// eslint-disable-next-line no-undef
|
|
3108
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
3109
|
+
return { username, secret };
|
|
3110
|
+
}
|
|
3111
|
+
}
|
|
3112
|
+
|
|
3046
3113
|
/* */
|
|
3047
3114
|
|
|
3048
3115
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -3107,6 +3174,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
3107
3174
|
return null;
|
|
3108
3175
|
}
|
|
3109
3176
|
},
|
|
3177
|
+
|
|
3178
|
+
createMyMeeting: (name ) =>
|
|
3179
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
3180
|
+
|
|
3181
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
3182
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
3183
|
+
|
|
3184
|
+
getMeeting: (meetingUuid ) =>
|
|
3185
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3186
|
+
|
|
3187
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
3188
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
3110
3189
|
});
|
|
3111
3190
|
|
|
3112
3191
|
//
|
|
@@ -3691,7 +3770,11 @@ class CallLog {
|
|
|
3691
3770
|
answered: plain.answered,
|
|
3692
3771
|
callDirection: plain.call_direction,
|
|
3693
3772
|
destination: {
|
|
3694
|
-
|
|
3773
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
3774
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
3775
|
+
extension: plain.requested_extension
|
|
3776
|
+
|| plain.destination_extension
|
|
3777
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3695
3778
|
name: plain.requested_name || plain.destination_name || '',
|
|
3696
3779
|
},
|
|
3697
3780
|
source: {
|
|
@@ -3707,27 +3790,11 @@ class CallLog {
|
|
|
3707
3790
|
}
|
|
3708
3791
|
|
|
3709
3792
|
static parseNew(plain , session ) {
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
3716
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
3717
|
-
},
|
|
3718
|
-
source: {
|
|
3719
|
-
extension: plain.source_extension,
|
|
3720
|
-
name: plain.source_name,
|
|
3721
|
-
},
|
|
3722
|
-
id: plain.id,
|
|
3723
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3724
|
-
start: moment__default['default'](plain.start).toDate(),
|
|
3725
|
-
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3726
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3727
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
3728
|
-
newMissedCall: session
|
|
3729
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
3730
|
-
});
|
|
3793
|
+
const callLog = CallLog.parse(plain);
|
|
3794
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
3795
|
+
callLog.newMissedCall = session
|
|
3796
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
3797
|
+
return callLog;
|
|
3731
3798
|
}
|
|
3732
3799
|
|
|
3733
3800
|
static newFrom(profile ) {
|
|
@@ -4484,6 +4551,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
4484
4551
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
4485
4552
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
4486
4553
|
|
|
4554
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
4555
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
4556
|
+
|
|
4487
4557
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
4488
4558
|
|
|
4489
4559
|
mute: (callId ) =>
|
|
@@ -5116,6 +5186,7 @@ const MAX_REGISTER_TRIES = 10;
|
|
|
5116
5186
|
|
|
5117
5187
|
|
|
5118
5188
|
|
|
5189
|
+
|
|
5119
5190
|
|
|
5120
5191
|
|
|
5121
5192
|
|
|
@@ -5142,6 +5213,7 @@ class WebRTCClient extends Emitter {
|
|
|
5142
5213
|
|
|
5143
5214
|
|
|
5144
5215
|
|
|
5216
|
+
|
|
5145
5217
|
|
|
5146
5218
|
// sugar
|
|
5147
5219
|
|
|
@@ -5180,6 +5252,8 @@ class WebRTCClient extends Emitter {
|
|
|
5180
5252
|
super();
|
|
5181
5253
|
this.uaConfigOverrides = uaConfigOverrides;
|
|
5182
5254
|
this.config = config;
|
|
5255
|
+
this.skipRegister = config.skipRegister;
|
|
5256
|
+
|
|
5183
5257
|
this._buildConfig(config, session).then((newConfig ) => {
|
|
5184
5258
|
this.config = newConfig;
|
|
5185
5259
|
this.userAgent = this.createUserAgent(uaConfigOverrides);
|
|
@@ -5307,14 +5381,22 @@ class WebRTCClient extends Emitter {
|
|
|
5307
5381
|
}
|
|
5308
5382
|
|
|
5309
5383
|
register(tries = 0) {
|
|
5310
|
-
|
|
5384
|
+
const logInfo = {
|
|
5311
5385
|
userAgent: !!this.userAgent,
|
|
5312
5386
|
registered: this.isRegistered(),
|
|
5313
5387
|
connectionPromise: !!this.connectionPromise,
|
|
5314
5388
|
registerer: !!this.registerer,
|
|
5315
5389
|
waiting: this.registerer && this.registerer.waiting,
|
|
5316
5390
|
tries,
|
|
5317
|
-
|
|
5391
|
+
skipRegister: this.skipRegister,
|
|
5392
|
+
};
|
|
5393
|
+
|
|
5394
|
+
if (this.skipRegister) {
|
|
5395
|
+
logger.info('sdk webrtc skip register...', logInfo);
|
|
5396
|
+
return Promise.resolve();
|
|
5397
|
+
}
|
|
5398
|
+
|
|
5399
|
+
logger.info('sdk webrtc registering...', logInfo);
|
|
5318
5400
|
|
|
5319
5401
|
if (!this.userAgent) {
|
|
5320
5402
|
logger.info('sdk webrtc recreating User Agent');
|
|
@@ -5645,12 +5727,18 @@ class WebRTCClient extends Emitter {
|
|
|
5645
5727
|
}
|
|
5646
5728
|
|
|
5647
5729
|
if (pc.getSenders) {
|
|
5730
|
+
if (!pc.getSenders().length) {
|
|
5731
|
+
return false;
|
|
5732
|
+
}
|
|
5648
5733
|
pc.getSenders().forEach(sender => {
|
|
5649
5734
|
if (sender && sender.track && sender.track.kind === 'audio') {
|
|
5650
5735
|
muted = muted && !sender.track.enabled;
|
|
5651
5736
|
}
|
|
5652
5737
|
});
|
|
5653
5738
|
} else {
|
|
5739
|
+
if (!pc.getLocalStreams().length) {
|
|
5740
|
+
return false;
|
|
5741
|
+
}
|
|
5654
5742
|
pc.getLocalStreams().forEach(stream => {
|
|
5655
5743
|
stream.getAudioTracks().forEach(track => {
|
|
5656
5744
|
muted = muted && !track.enabled;
|
|
@@ -5709,6 +5797,8 @@ class WebRTCClient extends Emitter {
|
|
|
5709
5797
|
}
|
|
5710
5798
|
options.sessionDescriptionHandlerOptions = {
|
|
5711
5799
|
constraints: options.constraints,
|
|
5800
|
+
hold: true,
|
|
5801
|
+
conference: isConference,
|
|
5712
5802
|
};
|
|
5713
5803
|
|
|
5714
5804
|
// Send re-INVITE
|
|
@@ -5751,6 +5841,8 @@ class WebRTCClient extends Emitter {
|
|
|
5751
5841
|
}
|
|
5752
5842
|
options.sessionDescriptionHandlerOptions = {
|
|
5753
5843
|
constraints: options.constraints,
|
|
5844
|
+
hold: false,
|
|
5845
|
+
conference: isConference,
|
|
5754
5846
|
};
|
|
5755
5847
|
|
|
5756
5848
|
// Send re-INVITE
|
|
@@ -5934,7 +6026,8 @@ class WebRTCClient extends Emitter {
|
|
|
5934
6026
|
}
|
|
5935
6027
|
const sdh = session.sessionDescriptionHandler;
|
|
5936
6028
|
const pc = sdh.peerConnection;
|
|
5937
|
-
const
|
|
6029
|
+
const sessionId = this.getSipSessionId(session);
|
|
6030
|
+
const localStream = this.getLocalStream(sessionId);
|
|
5938
6031
|
|
|
5939
6032
|
// Release old video stream
|
|
5940
6033
|
if (localStream) {
|
|
@@ -5960,11 +6053,8 @@ class WebRTCClient extends Emitter {
|
|
|
5960
6053
|
|
|
5961
6054
|
// let's update the local stream
|
|
5962
6055
|
this.eventEmitter.emit('onVideoInputChange', stream);
|
|
5963
|
-
|
|
5964
|
-
|
|
5965
|
-
} catch (_) {
|
|
5966
|
-
// Nothing to do
|
|
5967
|
-
}
|
|
6056
|
+
this.setLocalMediaStream(sessionId, stream);
|
|
6057
|
+
|
|
5968
6058
|
return stream;
|
|
5969
6059
|
});
|
|
5970
6060
|
}
|
|
@@ -6266,9 +6356,11 @@ class WebRTCClient extends Emitter {
|
|
|
6266
6356
|
remoteStream.removeTrack(track);
|
|
6267
6357
|
});
|
|
6268
6358
|
|
|
6269
|
-
pc.getReceivers
|
|
6270
|
-
|
|
6271
|
-
|
|
6359
|
+
if (pc.getReceivers) {
|
|
6360
|
+
pc.getReceivers().forEach(receiver => {
|
|
6361
|
+
remoteStream.addTrack(receiver.track);
|
|
6362
|
+
});
|
|
6363
|
+
}
|
|
6272
6364
|
}
|
|
6273
6365
|
|
|
6274
6366
|
getMediaConfiguration(enableVideo , conference = false, constraints = null) {
|
|
@@ -6303,6 +6395,25 @@ class WebRTCClient extends Emitter {
|
|
|
6303
6395
|
return sessionId in this.conferences;
|
|
6304
6396
|
}
|
|
6305
6397
|
|
|
6398
|
+
createAudioElementFor(sessionId ) {
|
|
6399
|
+
const audio = document.createElement('audio');
|
|
6400
|
+
audio.setAttribute('id', `audio-${sessionId}`);
|
|
6401
|
+
|
|
6402
|
+
if (audio.setSinkId && this.audioOutputDeviceId) {
|
|
6403
|
+
audio.setSinkId(this.audioOutputDeviceId);
|
|
6404
|
+
}
|
|
6405
|
+
|
|
6406
|
+
if (document.body) {
|
|
6407
|
+
document.body.appendChild(audio);
|
|
6408
|
+
}
|
|
6409
|
+
this.audioElements[sessionId] = audio;
|
|
6410
|
+
|
|
6411
|
+
audio.volume = this.audioOutputVolume;
|
|
6412
|
+
audio.autoplay = true;
|
|
6413
|
+
|
|
6414
|
+
return audio;
|
|
6415
|
+
}
|
|
6416
|
+
|
|
6306
6417
|
_onTransportError() {
|
|
6307
6418
|
this.eventEmitter.emit(TRANSPORT_ERROR);
|
|
6308
6419
|
this.attemptReconnection();
|
|
@@ -6532,7 +6643,7 @@ class WebRTCClient extends Emitter {
|
|
|
6532
6643
|
let hadRemoteVideo = false;
|
|
6533
6644
|
|
|
6534
6645
|
// Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
|
|
6535
|
-
//
|
|
6646
|
+
// Because when `onInvite` is called we already got the video track
|
|
6536
6647
|
session.onInviteRequest = (request) => {
|
|
6537
6648
|
hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
6538
6649
|
|
|
@@ -6607,20 +6718,10 @@ class WebRTCClient extends Emitter {
|
|
|
6607
6718
|
const isConference = this.isConference(sessionId);
|
|
6608
6719
|
|
|
6609
6720
|
if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
|
|
6610
|
-
|
|
6611
|
-
audio.setAttribute('id', `audio-${sessionId}`);
|
|
6612
|
-
|
|
6613
|
-
if (audio.setSinkId && this.audioOutputDeviceId) {
|
|
6614
|
-
audio.setSinkId(this.audioOutputDeviceId);
|
|
6615
|
-
}
|
|
6616
|
-
|
|
6617
|
-
if (document.body) {
|
|
6618
|
-
document.body.appendChild(audio);
|
|
6619
|
-
}
|
|
6620
|
-
this.audioElements[sessionId] = audio;
|
|
6721
|
+
this.createAudioElementFor(sessionId);
|
|
6621
6722
|
}
|
|
6622
6723
|
|
|
6623
|
-
const audioElement = this.audioElements[
|
|
6724
|
+
const audioElement = this.audioElements[sessionId];
|
|
6624
6725
|
const stream = newStream || this.getRemoteStream(sessionId);
|
|
6625
6726
|
|
|
6626
6727
|
if (!this._isWeb() || !stream) {
|
|
@@ -2705,6 +2705,65 @@ class ExternalApp {
|
|
|
2705
2705
|
}
|
|
2706
2706
|
}
|
|
2707
2707
|
|
|
2708
|
+
//
|
|
2709
|
+
|
|
2710
|
+
|
|
2711
|
+
|
|
2712
|
+
|
|
2713
|
+
|
|
2714
|
+
|
|
2715
|
+
|
|
2716
|
+
|
|
2717
|
+
|
|
2718
|
+
|
|
2719
|
+
|
|
2720
|
+
class Meeting {
|
|
2721
|
+
|
|
2722
|
+
|
|
2723
|
+
|
|
2724
|
+
|
|
2725
|
+
|
|
2726
|
+
|
|
2727
|
+
|
|
2728
|
+
|
|
2729
|
+
|
|
2730
|
+
|
|
2731
|
+
static parse(plain ) {
|
|
2732
|
+
return new Meeting({
|
|
2733
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
2734
|
+
hostname: plain.hostname,
|
|
2735
|
+
name: plain.name,
|
|
2736
|
+
ownerUuids: plain.owner_uuids,
|
|
2737
|
+
port: plain.port,
|
|
2738
|
+
uuid: plain.uuid,
|
|
2739
|
+
number: plain.number,
|
|
2740
|
+
});
|
|
2741
|
+
}
|
|
2742
|
+
|
|
2743
|
+
static newFrom(meeting ) {
|
|
2744
|
+
return newFrom(meeting, Meeting);
|
|
2745
|
+
}
|
|
2746
|
+
|
|
2747
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
2748
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
2749
|
+
this.hostname = hostname;
|
|
2750
|
+
this.name = name;
|
|
2751
|
+
this.ownerUuids = ownerUuids;
|
|
2752
|
+
this.port = port;
|
|
2753
|
+
this.uuid = uuid;
|
|
2754
|
+
this.number = number;
|
|
2755
|
+
|
|
2756
|
+
// Useful to compare instead of instanceof with minified code
|
|
2757
|
+
this.type = 'Meeting';
|
|
2758
|
+
}
|
|
2759
|
+
|
|
2760
|
+
getGuestSipCredentials() {
|
|
2761
|
+
// eslint-disable-next-line no-undef
|
|
2762
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
2763
|
+
return { username, secret };
|
|
2764
|
+
}
|
|
2765
|
+
}
|
|
2766
|
+
|
|
2708
2767
|
/* */
|
|
2709
2768
|
|
|
2710
2769
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -2769,6 +2828,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2769
2828
|
return null;
|
|
2770
2829
|
}
|
|
2771
2830
|
},
|
|
2831
|
+
|
|
2832
|
+
createMyMeeting: (name ) =>
|
|
2833
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
2834
|
+
|
|
2835
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
2836
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
2837
|
+
|
|
2838
|
+
getMeeting: (meetingUuid ) =>
|
|
2839
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2840
|
+
|
|
2841
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
2842
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2772
2843
|
});
|
|
2773
2844
|
|
|
2774
2845
|
//
|
|
@@ -3147,7 +3218,11 @@ class CallLog {
|
|
|
3147
3218
|
answered: plain.answered,
|
|
3148
3219
|
callDirection: plain.call_direction,
|
|
3149
3220
|
destination: {
|
|
3150
|
-
|
|
3221
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
3222
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
3223
|
+
extension: plain.requested_extension
|
|
3224
|
+
|| plain.destination_extension
|
|
3225
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3151
3226
|
name: plain.requested_name || plain.destination_name || '',
|
|
3152
3227
|
},
|
|
3153
3228
|
source: {
|
|
@@ -3163,27 +3238,11 @@ class CallLog {
|
|
|
3163
3238
|
}
|
|
3164
3239
|
|
|
3165
3240
|
static parseNew(plain , session ) {
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
3172
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
3173
|
-
},
|
|
3174
|
-
source: {
|
|
3175
|
-
extension: plain.source_extension,
|
|
3176
|
-
name: plain.source_name,
|
|
3177
|
-
},
|
|
3178
|
-
id: plain.id,
|
|
3179
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3180
|
-
start: moment__default['default'](plain.start).toDate(),
|
|
3181
|
-
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
3182
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3183
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
3184
|
-
newMissedCall: session
|
|
3185
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
3186
|
-
});
|
|
3241
|
+
const callLog = CallLog.parse(plain);
|
|
3242
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
3243
|
+
callLog.newMissedCall = session
|
|
3244
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
3245
|
+
return callLog;
|
|
3187
3246
|
}
|
|
3188
3247
|
|
|
3189
3248
|
static newFrom(profile ) {
|
|
@@ -3925,6 +3984,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
3925
3984
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
3926
3985
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
3927
3986
|
|
|
3987
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
3988
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
3989
|
+
|
|
3928
3990
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
3929
3991
|
|
|
3930
3992
|
mute: (callId ) =>
|
package/lib/domain/CallLog.js
CHANGED
|
@@ -168,7 +168,11 @@ class CallLog {
|
|
|
168
168
|
answered: plain.answered,
|
|
169
169
|
callDirection: plain.call_direction,
|
|
170
170
|
destination: {
|
|
171
|
-
|
|
171
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
172
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
173
|
+
extension: plain.requested_extension
|
|
174
|
+
|| plain.destination_extension
|
|
175
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
172
176
|
name: plain.requested_name || plain.destination_name || '',
|
|
173
177
|
},
|
|
174
178
|
source: {
|
|
@@ -184,27 +188,11 @@ class CallLog {
|
|
|
184
188
|
}
|
|
185
189
|
|
|
186
190
|
static parseNew(plain , session ) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
193
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
194
|
-
},
|
|
195
|
-
source: {
|
|
196
|
-
extension: plain.source_extension,
|
|
197
|
-
name: plain.source_name,
|
|
198
|
-
},
|
|
199
|
-
id: plain.id,
|
|
200
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
201
|
-
start: moment__default['default'](plain.start).toDate(),
|
|
202
|
-
end: plain.end ? moment__default['default'](plain.end).toDate() : null,
|
|
203
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
204
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
205
|
-
newMissedCall: session
|
|
206
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
207
|
-
});
|
|
191
|
+
const callLog = CallLog.parse(plain);
|
|
192
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
193
|
+
callLog.newMissedCall = session
|
|
194
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
195
|
+
return callLog;
|
|
208
196
|
}
|
|
209
197
|
|
|
210
198
|
static newFrom(profile ) {
|