@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
package/esm/api-client.js
CHANGED
|
@@ -2493,6 +2493,65 @@ class ExternalApp {
|
|
|
2493
2493
|
}
|
|
2494
2494
|
}
|
|
2495
2495
|
|
|
2496
|
+
//
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
|
|
2505
|
+
|
|
2506
|
+
|
|
2507
|
+
|
|
2508
|
+
class Meeting {
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
|
|
2512
|
+
|
|
2513
|
+
|
|
2514
|
+
|
|
2515
|
+
|
|
2516
|
+
|
|
2517
|
+
|
|
2518
|
+
|
|
2519
|
+
static parse(plain ) {
|
|
2520
|
+
return new Meeting({
|
|
2521
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
2522
|
+
hostname: plain.hostname,
|
|
2523
|
+
name: plain.name,
|
|
2524
|
+
ownerUuids: plain.owner_uuids,
|
|
2525
|
+
port: plain.port,
|
|
2526
|
+
uuid: plain.uuid,
|
|
2527
|
+
number: plain.number,
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
static newFrom(meeting ) {
|
|
2532
|
+
return newFrom(meeting, Meeting);
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
2536
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
2537
|
+
this.hostname = hostname;
|
|
2538
|
+
this.name = name;
|
|
2539
|
+
this.ownerUuids = ownerUuids;
|
|
2540
|
+
this.port = port;
|
|
2541
|
+
this.uuid = uuid;
|
|
2542
|
+
this.number = number;
|
|
2543
|
+
|
|
2544
|
+
// Useful to compare instead of instanceof with minified code
|
|
2545
|
+
this.type = 'Meeting';
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
getGuestSipCredentials() {
|
|
2549
|
+
// eslint-disable-next-line no-undef
|
|
2550
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
2551
|
+
return { username, secret };
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2496
2555
|
/* */
|
|
2497
2556
|
|
|
2498
2557
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -2557,6 +2616,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2557
2616
|
return null;
|
|
2558
2617
|
}
|
|
2559
2618
|
},
|
|
2619
|
+
|
|
2620
|
+
createMyMeeting: (name ) =>
|
|
2621
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
2622
|
+
|
|
2623
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
2624
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
2625
|
+
|
|
2626
|
+
getMeeting: (meetingUuid ) =>
|
|
2627
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2628
|
+
|
|
2629
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
2630
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2560
2631
|
});
|
|
2561
2632
|
|
|
2562
2633
|
//
|
|
@@ -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 ) {
|
|
@@ -3934,6 +3993,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
3934
3993
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
3935
3994
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
3936
3995
|
|
|
3996
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
3997
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
3998
|
+
|
|
3937
3999
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
3938
4000
|
|
|
3939
4001
|
mute: (callId ) =>
|
package/esm/checker/Checker.js
CHANGED
|
@@ -2511,6 +2511,65 @@ class ExternalApp {
|
|
|
2511
2511
|
}
|
|
2512
2512
|
}
|
|
2513
2513
|
|
|
2514
|
+
//
|
|
2515
|
+
|
|
2516
|
+
|
|
2517
|
+
|
|
2518
|
+
|
|
2519
|
+
|
|
2520
|
+
|
|
2521
|
+
|
|
2522
|
+
|
|
2523
|
+
|
|
2524
|
+
|
|
2525
|
+
|
|
2526
|
+
class Meeting {
|
|
2527
|
+
|
|
2528
|
+
|
|
2529
|
+
|
|
2530
|
+
|
|
2531
|
+
|
|
2532
|
+
|
|
2533
|
+
|
|
2534
|
+
|
|
2535
|
+
|
|
2536
|
+
|
|
2537
|
+
static parse(plain ) {
|
|
2538
|
+
return new Meeting({
|
|
2539
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
2540
|
+
hostname: plain.hostname,
|
|
2541
|
+
name: plain.name,
|
|
2542
|
+
ownerUuids: plain.owner_uuids,
|
|
2543
|
+
port: plain.port,
|
|
2544
|
+
uuid: plain.uuid,
|
|
2545
|
+
number: plain.number,
|
|
2546
|
+
});
|
|
2547
|
+
}
|
|
2548
|
+
|
|
2549
|
+
static newFrom(meeting ) {
|
|
2550
|
+
return newFrom(meeting, Meeting);
|
|
2551
|
+
}
|
|
2552
|
+
|
|
2553
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
2554
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
2555
|
+
this.hostname = hostname;
|
|
2556
|
+
this.name = name;
|
|
2557
|
+
this.ownerUuids = ownerUuids;
|
|
2558
|
+
this.port = port;
|
|
2559
|
+
this.uuid = uuid;
|
|
2560
|
+
this.number = number;
|
|
2561
|
+
|
|
2562
|
+
// Useful to compare instead of instanceof with minified code
|
|
2563
|
+
this.type = 'Meeting';
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2566
|
+
getGuestSipCredentials() {
|
|
2567
|
+
// eslint-disable-next-line no-undef
|
|
2568
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
2569
|
+
return { username, secret };
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2572
|
+
|
|
2514
2573
|
/* */
|
|
2515
2574
|
|
|
2516
2575
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -2575,6 +2634,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2575
2634
|
return null;
|
|
2576
2635
|
}
|
|
2577
2636
|
},
|
|
2637
|
+
|
|
2638
|
+
createMyMeeting: (name ) =>
|
|
2639
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
2640
|
+
|
|
2641
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
2642
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
2643
|
+
|
|
2644
|
+
getMeeting: (meetingUuid ) =>
|
|
2645
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2646
|
+
|
|
2647
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
2648
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2578
2649
|
});
|
|
2579
2650
|
|
|
2580
2651
|
//
|
|
@@ -3185,7 +3256,11 @@ class CallLog {
|
|
|
3185
3256
|
answered: plain.answered,
|
|
3186
3257
|
callDirection: plain.call_direction,
|
|
3187
3258
|
destination: {
|
|
3188
|
-
|
|
3259
|
+
// @TEMP: Temporarily assuming empty numbers are meetings
|
|
3260
|
+
// which is admittedly a very dangerous assumption. Did i mention it was temporary?
|
|
3261
|
+
extension: plain.requested_extension
|
|
3262
|
+
|| plain.destination_extension
|
|
3263
|
+
|| `meeting-${plain.requested_name || plain.destination_name || ''}`,
|
|
3189
3264
|
name: plain.requested_name || plain.destination_name || '',
|
|
3190
3265
|
},
|
|
3191
3266
|
source: {
|
|
@@ -3201,27 +3276,11 @@ class CallLog {
|
|
|
3201
3276
|
}
|
|
3202
3277
|
|
|
3203
3278
|
static parseNew(plain , session ) {
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
extension: plain.requested_extension || plain.destination_extension,
|
|
3210
|
-
name: plain.requested_name || plain.destination_name || '',
|
|
3211
|
-
},
|
|
3212
|
-
source: {
|
|
3213
|
-
extension: plain.source_extension,
|
|
3214
|
-
name: plain.source_name,
|
|
3215
|
-
},
|
|
3216
|
-
id: plain.id,
|
|
3217
|
-
duration: (plain.duration || 0) * 1000, // duration is in seconds
|
|
3218
|
-
start: moment(plain.start).toDate(),
|
|
3219
|
-
end: plain.end ? moment(plain.end).toDate() : null,
|
|
3220
|
-
recordings: Recording.parseMany(plain.recordings),
|
|
3221
|
-
// @TODO: FIXME add verification declined vs missed call
|
|
3222
|
-
newMissedCall: session
|
|
3223
|
-
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
|
|
3224
|
-
});
|
|
3279
|
+
const callLog = CallLog.parse(plain);
|
|
3280
|
+
// @TODO: FIXME add verification declined vs missed call
|
|
3281
|
+
callLog.newMissedCall = session
|
|
3282
|
+
&& session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
|
|
3283
|
+
return callLog;
|
|
3225
3284
|
}
|
|
3226
3285
|
|
|
3227
3286
|
static newFrom(profile ) {
|
|
@@ -3978,6 +4037,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
3978
4037
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
3979
4038
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
3980
4039
|
|
|
4040
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
4041
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
4042
|
+
|
|
3981
4043
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
3982
4044
|
|
|
3983
4045
|
mute: (callId ) =>
|
|
@@ -4712,6 +4774,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
|
|
|
4712
4774
|
const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
|
|
4713
4775
|
const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
|
|
4714
4776
|
const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
|
|
4777
|
+
const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
|
|
4778
|
+
const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
|
|
4715
4779
|
const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
|
|
4716
4780
|
const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
|
|
4717
4781
|
const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
|
|
@@ -5058,6 +5122,8 @@ WebSocketClient.eventLists = [
|
|
|
5058
5122
|
CHATD_USER_ROOM_CREATED,
|
|
5059
5123
|
CONFERENCE_USER_PARTICIPANT_JOINED,
|
|
5060
5124
|
CONFERENCE_USER_PARTICIPANT_LEFT,
|
|
5125
|
+
MEETING_USER_PARTICIPANT_JOINED,
|
|
5126
|
+
MEETING_USER_PARTICIPANT_LEFT,
|
|
5061
5127
|
CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
|
|
5062
5128
|
CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
|
|
5063
5129
|
SWITCHBOARD_QUEUED_CALLS_UPDATED,
|
|
@@ -5294,7 +5360,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
5294
5360
|
.then(() => {
|
|
5295
5361
|
if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
|
|
5296
5362
|
// Add a video an empty bundle to be able to replaceTrack when joining a conference without video
|
|
5297
|
-
this.peerConnection.addTransceiver
|
|
5363
|
+
if (this.peerConnection.addTransceiver) {
|
|
5364
|
+
this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
|
|
5365
|
+
}
|
|
5298
5366
|
}
|
|
5299
5367
|
})
|
|
5300
5368
|
.then(() => this.createLocalOfferOrAnswer(options))
|
|
@@ -5321,12 +5389,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
5321
5389
|
};
|
|
5322
5390
|
})
|
|
5323
5391
|
.then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
|
|
5324
|
-
.then((sessionDescription) => {
|
|
5325
|
-
// Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
|
|
5326
|
-
this.localMediaStreamConstraints = options.constraints;
|
|
5327
|
-
|
|
5328
|
-
return sessionDescription;
|
|
5329
|
-
})
|
|
5330
5392
|
.then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
|
|
5331
5393
|
.catch((error) => {
|
|
5332
5394
|
wazoLogger.error('error when creating media', error);
|
|
@@ -5521,6 +5583,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
5521
5583
|
|
|
5522
5584
|
// set the transceiver direction to the answer direction
|
|
5523
5585
|
this._peerConnection.getTransceivers().forEach((transceiver) => {
|
|
5586
|
+
if (transceiver.stopped) {
|
|
5587
|
+
return;
|
|
5588
|
+
}
|
|
5524
5589
|
if (transceiver.direction /* guarding, but should always be true */) {
|
|
5525
5590
|
const { receiver } = transceiver;
|
|
5526
5591
|
if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
|
|
@@ -5565,10 +5630,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
5565
5630
|
if (kind !== 'audio' && kind !== 'video') {
|
|
5566
5631
|
throw new Error(`Unknown new track kind ${kind}.`);
|
|
5567
5632
|
}
|
|
5568
|
-
const sender = pc.getSenders().find((otherSender) =>
|
|
5633
|
+
const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
|
|
5634
|
+
otherSender.track && otherSender.track.kind === kind);
|
|
5569
5635
|
|
|
5570
5636
|
// Do not reuse sender video tracks in SFU
|
|
5571
5637
|
if (sender && (!sfu || newTrack.kind === 'audio')) {
|
|
5638
|
+
if (sender.track) {
|
|
5639
|
+
// eslint-disable-next-line no-param-reassign
|
|
5640
|
+
newTrack.enabled = sender.track.enabled;
|
|
5641
|
+
}
|
|
5572
5642
|
trackUpdates.push(
|
|
5573
5643
|
new Promise((resolve) => {
|
|
5574
5644
|
this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
|
|
@@ -5602,7 +5672,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
5602
5672
|
// Review: could make streamless tracks a configurable option?
|
|
5603
5673
|
// https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
|
|
5604
5674
|
try {
|
|
5605
|
-
pc.addTrack
|
|
5675
|
+
if (pc.addTrack) {
|
|
5676
|
+
pc.addTrack(newTrack, localStream);
|
|
5677
|
+
} else {
|
|
5678
|
+
pc.addStream(localStream);
|
|
5679
|
+
}
|
|
5606
5680
|
} catch (error) {
|
|
5607
5681
|
this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
|
|
5608
5682
|
throw error;
|
|
@@ -5686,6 +5760,7 @@ const MAX_REGISTER_TRIES = 10;
|
|
|
5686
5760
|
|
|
5687
5761
|
|
|
5688
5762
|
|
|
5763
|
+
|
|
5689
5764
|
|
|
5690
5765
|
|
|
5691
5766
|
|
|
@@ -5712,6 +5787,7 @@ class WebRTCClient extends Emitter {
|
|
|
5712
5787
|
|
|
5713
5788
|
|
|
5714
5789
|
|
|
5790
|
+
|
|
5715
5791
|
|
|
5716
5792
|
// sugar
|
|
5717
5793
|
|
|
@@ -5750,6 +5826,8 @@ class WebRTCClient extends Emitter {
|
|
|
5750
5826
|
super();
|
|
5751
5827
|
this.uaConfigOverrides = uaConfigOverrides;
|
|
5752
5828
|
this.config = config;
|
|
5829
|
+
this.skipRegister = config.skipRegister;
|
|
5830
|
+
|
|
5753
5831
|
this._buildConfig(config, session).then((newConfig ) => {
|
|
5754
5832
|
this.config = newConfig;
|
|
5755
5833
|
this.userAgent = this.createUserAgent(uaConfigOverrides);
|
|
@@ -5877,14 +5955,22 @@ class WebRTCClient extends Emitter {
|
|
|
5877
5955
|
}
|
|
5878
5956
|
|
|
5879
5957
|
register(tries = 0) {
|
|
5880
|
-
|
|
5958
|
+
const logInfo = {
|
|
5881
5959
|
userAgent: !!this.userAgent,
|
|
5882
5960
|
registered: this.isRegistered(),
|
|
5883
5961
|
connectionPromise: !!this.connectionPromise,
|
|
5884
5962
|
registerer: !!this.registerer,
|
|
5885
5963
|
waiting: this.registerer && this.registerer.waiting,
|
|
5886
5964
|
tries,
|
|
5887
|
-
|
|
5965
|
+
skipRegister: this.skipRegister,
|
|
5966
|
+
};
|
|
5967
|
+
|
|
5968
|
+
if (this.skipRegister) {
|
|
5969
|
+
logger$1.info('sdk webrtc skip register...', logInfo);
|
|
5970
|
+
return Promise.resolve();
|
|
5971
|
+
}
|
|
5972
|
+
|
|
5973
|
+
logger$1.info('sdk webrtc registering...', logInfo);
|
|
5888
5974
|
|
|
5889
5975
|
if (!this.userAgent) {
|
|
5890
5976
|
logger$1.info('sdk webrtc recreating User Agent');
|
|
@@ -6215,12 +6301,18 @@ class WebRTCClient extends Emitter {
|
|
|
6215
6301
|
}
|
|
6216
6302
|
|
|
6217
6303
|
if (pc.getSenders) {
|
|
6304
|
+
if (!pc.getSenders().length) {
|
|
6305
|
+
return false;
|
|
6306
|
+
}
|
|
6218
6307
|
pc.getSenders().forEach(sender => {
|
|
6219
6308
|
if (sender && sender.track && sender.track.kind === 'audio') {
|
|
6220
6309
|
muted = muted && !sender.track.enabled;
|
|
6221
6310
|
}
|
|
6222
6311
|
});
|
|
6223
6312
|
} else {
|
|
6313
|
+
if (!pc.getLocalStreams().length) {
|
|
6314
|
+
return false;
|
|
6315
|
+
}
|
|
6224
6316
|
pc.getLocalStreams().forEach(stream => {
|
|
6225
6317
|
stream.getAudioTracks().forEach(track => {
|
|
6226
6318
|
muted = muted && !track.enabled;
|
|
@@ -6279,6 +6371,8 @@ class WebRTCClient extends Emitter {
|
|
|
6279
6371
|
}
|
|
6280
6372
|
options.sessionDescriptionHandlerOptions = {
|
|
6281
6373
|
constraints: options.constraints,
|
|
6374
|
+
hold: true,
|
|
6375
|
+
conference: isConference,
|
|
6282
6376
|
};
|
|
6283
6377
|
|
|
6284
6378
|
// Send re-INVITE
|
|
@@ -6321,6 +6415,8 @@ class WebRTCClient extends Emitter {
|
|
|
6321
6415
|
}
|
|
6322
6416
|
options.sessionDescriptionHandlerOptions = {
|
|
6323
6417
|
constraints: options.constraints,
|
|
6418
|
+
hold: false,
|
|
6419
|
+
conference: isConference,
|
|
6324
6420
|
};
|
|
6325
6421
|
|
|
6326
6422
|
// Send re-INVITE
|
|
@@ -6504,7 +6600,8 @@ class WebRTCClient extends Emitter {
|
|
|
6504
6600
|
}
|
|
6505
6601
|
const sdh = session.sessionDescriptionHandler;
|
|
6506
6602
|
const pc = sdh.peerConnection;
|
|
6507
|
-
const
|
|
6603
|
+
const sessionId = this.getSipSessionId(session);
|
|
6604
|
+
const localStream = this.getLocalStream(sessionId);
|
|
6508
6605
|
|
|
6509
6606
|
// Release old video stream
|
|
6510
6607
|
if (localStream) {
|
|
@@ -6530,11 +6627,8 @@ class WebRTCClient extends Emitter {
|
|
|
6530
6627
|
|
|
6531
6628
|
// let's update the local stream
|
|
6532
6629
|
this.eventEmitter.emit('onVideoInputChange', stream);
|
|
6533
|
-
|
|
6534
|
-
|
|
6535
|
-
} catch (_) {
|
|
6536
|
-
// Nothing to do
|
|
6537
|
-
}
|
|
6630
|
+
this.setLocalMediaStream(sessionId, stream);
|
|
6631
|
+
|
|
6538
6632
|
return stream;
|
|
6539
6633
|
});
|
|
6540
6634
|
}
|
|
@@ -6836,9 +6930,11 @@ class WebRTCClient extends Emitter {
|
|
|
6836
6930
|
remoteStream.removeTrack(track);
|
|
6837
6931
|
});
|
|
6838
6932
|
|
|
6839
|
-
pc.getReceivers
|
|
6840
|
-
|
|
6841
|
-
|
|
6933
|
+
if (pc.getReceivers) {
|
|
6934
|
+
pc.getReceivers().forEach(receiver => {
|
|
6935
|
+
remoteStream.addTrack(receiver.track);
|
|
6936
|
+
});
|
|
6937
|
+
}
|
|
6842
6938
|
}
|
|
6843
6939
|
|
|
6844
6940
|
getMediaConfiguration(enableVideo , conference = false, constraints = null) {
|
|
@@ -6873,6 +6969,25 @@ class WebRTCClient extends Emitter {
|
|
|
6873
6969
|
return sessionId in this.conferences;
|
|
6874
6970
|
}
|
|
6875
6971
|
|
|
6972
|
+
createAudioElementFor(sessionId ) {
|
|
6973
|
+
const audio = document.createElement('audio');
|
|
6974
|
+
audio.setAttribute('id', `audio-${sessionId}`);
|
|
6975
|
+
|
|
6976
|
+
if (audio.setSinkId && this.audioOutputDeviceId) {
|
|
6977
|
+
audio.setSinkId(this.audioOutputDeviceId);
|
|
6978
|
+
}
|
|
6979
|
+
|
|
6980
|
+
if (document.body) {
|
|
6981
|
+
document.body.appendChild(audio);
|
|
6982
|
+
}
|
|
6983
|
+
this.audioElements[sessionId] = audio;
|
|
6984
|
+
|
|
6985
|
+
audio.volume = this.audioOutputVolume;
|
|
6986
|
+
audio.autoplay = true;
|
|
6987
|
+
|
|
6988
|
+
return audio;
|
|
6989
|
+
}
|
|
6990
|
+
|
|
6876
6991
|
_onTransportError() {
|
|
6877
6992
|
this.eventEmitter.emit(TRANSPORT_ERROR);
|
|
6878
6993
|
this.attemptReconnection();
|
|
@@ -7102,7 +7217,7 @@ class WebRTCClient extends Emitter {
|
|
|
7102
7217
|
let hadRemoteVideo = false;
|
|
7103
7218
|
|
|
7104
7219
|
// Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
|
|
7105
|
-
//
|
|
7220
|
+
// Because when `onInvite` is called we already got the video track
|
|
7106
7221
|
session.onInviteRequest = (request) => {
|
|
7107
7222
|
hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
|
|
7108
7223
|
|
|
@@ -7177,20 +7292,10 @@ class WebRTCClient extends Emitter {
|
|
|
7177
7292
|
const isConference = this.isConference(sessionId);
|
|
7178
7293
|
|
|
7179
7294
|
if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
|
|
7180
|
-
|
|
7181
|
-
audio.setAttribute('id', `audio-${sessionId}`);
|
|
7182
|
-
|
|
7183
|
-
if (audio.setSinkId && this.audioOutputDeviceId) {
|
|
7184
|
-
audio.setSinkId(this.audioOutputDeviceId);
|
|
7185
|
-
}
|
|
7186
|
-
|
|
7187
|
-
if (document.body) {
|
|
7188
|
-
document.body.appendChild(audio);
|
|
7189
|
-
}
|
|
7190
|
-
this.audioElements[sessionId] = audio;
|
|
7295
|
+
this.createAudioElementFor(sessionId);
|
|
7191
7296
|
}
|
|
7192
7297
|
|
|
7193
|
-
const audioElement = this.audioElements[
|
|
7298
|
+
const audioElement = this.audioElements[sessionId];
|
|
7194
7299
|
const stream = newStream || this.getRemoteStream(sessionId);
|
|
7195
7300
|
|
|
7196
7301
|
if (!this._isWeb() || !stream) {
|
|
@@ -2493,6 +2493,65 @@ class ExternalApp {
|
|
|
2493
2493
|
}
|
|
2494
2494
|
}
|
|
2495
2495
|
|
|
2496
|
+
//
|
|
2497
|
+
|
|
2498
|
+
|
|
2499
|
+
|
|
2500
|
+
|
|
2501
|
+
|
|
2502
|
+
|
|
2503
|
+
|
|
2504
|
+
|
|
2505
|
+
|
|
2506
|
+
|
|
2507
|
+
|
|
2508
|
+
class Meeting {
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
|
|
2512
|
+
|
|
2513
|
+
|
|
2514
|
+
|
|
2515
|
+
|
|
2516
|
+
|
|
2517
|
+
|
|
2518
|
+
|
|
2519
|
+
static parse(plain ) {
|
|
2520
|
+
return new Meeting({
|
|
2521
|
+
guestSipAuthorization: plain.guest_sip_authorization,
|
|
2522
|
+
hostname: plain.hostname,
|
|
2523
|
+
name: plain.name,
|
|
2524
|
+
ownerUuids: plain.owner_uuids,
|
|
2525
|
+
port: plain.port,
|
|
2526
|
+
uuid: plain.uuid,
|
|
2527
|
+
number: plain.number,
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
static newFrom(meeting ) {
|
|
2532
|
+
return newFrom(meeting, Meeting);
|
|
2533
|
+
}
|
|
2534
|
+
|
|
2535
|
+
constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
|
|
2536
|
+
this.guestSipAuthorization = guestSipAuthorization;
|
|
2537
|
+
this.hostname = hostname;
|
|
2538
|
+
this.name = name;
|
|
2539
|
+
this.ownerUuids = ownerUuids;
|
|
2540
|
+
this.port = port;
|
|
2541
|
+
this.uuid = uuid;
|
|
2542
|
+
this.number = number;
|
|
2543
|
+
|
|
2544
|
+
// Useful to compare instead of instanceof with minified code
|
|
2545
|
+
this.type = 'Meeting';
|
|
2546
|
+
}
|
|
2547
|
+
|
|
2548
|
+
getGuestSipCredentials() {
|
|
2549
|
+
// eslint-disable-next-line no-undef
|
|
2550
|
+
const [username, secret] = atob(this.guestSipAuthorization).split(':');
|
|
2551
|
+
return { username, secret };
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2496
2555
|
/* */
|
|
2497
2556
|
|
|
2498
2557
|
var confdMethods = (client , baseUrl ) => ({
|
|
@@ -2557,6 +2616,18 @@ var confdMethods = (client , baseUrl ) => ({
|
|
|
2557
2616
|
return null;
|
|
2558
2617
|
}
|
|
2559
2618
|
},
|
|
2619
|
+
|
|
2620
|
+
createMyMeeting: (name ) =>
|
|
2621
|
+
client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
|
|
2622
|
+
|
|
2623
|
+
deleteMyMeeting: (meetingUuid ) =>
|
|
2624
|
+
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
|
2625
|
+
|
|
2626
|
+
getMeeting: (meetingUuid ) =>
|
|
2627
|
+
client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2628
|
+
|
|
2629
|
+
guestGetMeeting: (meetingUuid ) =>
|
|
2630
|
+
client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
|
|
2560
2631
|
});
|
|
2561
2632
|
|
|
2562
2633
|
//
|
|
@@ -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 ) {
|
|
@@ -3934,6 +3993,9 @@ var calldMethods = (client , baseUrl ) => ({
|
|
|
3934
3993
|
getConferenceParticipantsAsUser: async (conferenceId ) =>
|
|
3935
3994
|
client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
|
|
3936
3995
|
|
|
3996
|
+
getMeetingParticipantsAsUser: async (meetingUuid ) =>
|
|
3997
|
+
client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
|
|
3998
|
+
|
|
3937
3999
|
listTrunks: () => client.get(`${baseUrl}/trunks`),
|
|
3938
4000
|
|
|
3939
4001
|
mute: (callId ) =>
|