@wazo/sdk 0.37.20 → 0.37.24
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 +6 -6
- package/esm/__tests__/api-client.test.js +91 -21
- package/esm/__tests__/web-rtc-client.test.js +214 -165
- package/esm/api/agentd.js +25 -2
- package/esm/api/amid.js +26 -3
- package/esm/api/application.js +25 -2
- package/esm/api/auth.js +25 -2
- package/esm/api/call-logd.js +34 -4
- package/esm/api/calld.js +35 -2
- package/esm/api/chatd.js +32 -2
- package/esm/api/confd.js +56 -9
- package/esm/api/ctid-ng.js +38 -5
- package/esm/api/dird.js +29 -3
- package/esm/api/webhookd.js +26 -3
- package/esm/api-client.js +91 -21
- package/esm/checker/Checker.js +241 -190
- package/esm/checker/checks/aor.js +91 -21
- package/esm/checker/checks/api.js +91 -21
- package/esm/checker/checks/index.js +231 -180
- package/esm/checker/checks/wazo-websocket.js +42 -17
- package/esm/checker/checks/webrtc-transport.js +214 -165
- package/esm/checker/checks/webrtc.js +214 -165
- package/esm/domain/AdHocAPIConference.js +91 -21
- package/esm/domain/Call.js +3 -0
- package/esm/domain/CallLog.js +8 -1
- package/esm/domain/ChatMessage.js +4 -0
- package/esm/domain/ChatRoom.js +3 -0
- package/esm/domain/Contact.js +4 -1
- package/esm/domain/Features.js +91 -21
- package/esm/domain/Meeting.js +28 -5
- package/esm/domain/Phone/CTIPhone.js +109 -35
- package/esm/domain/Phone/WebRTCPhone.js +159 -102
- package/esm/domain/Recording.js +3 -0
- package/esm/domain/Voicemail.js +3 -0
- package/esm/domain/__tests__/Call.test.js +3 -0
- package/esm/domain/__tests__/CallLog.test.js +8 -1
- package/esm/domain/__tests__/Contact.test.js +4 -1
- package/esm/domain/__tests__/Meeting.test.js +144 -0
- package/esm/domain/__tests__/Voicemail.test.js +3 -0
- package/esm/index.js +509 -414
- package/esm/lib/WazoSessionDescriptionHandler.js +26 -41
- package/esm/service/CallApi.js +91 -21
- package/esm/service/IssueReporter.js +26 -3
- package/esm/service/__tests__/IssueReporter.test.js +26 -3
- package/esm/service/getApiClient.js +91 -21
- package/esm/simple/Auth.js +499 -404
- package/esm/simple/Configuration.js +499 -404
- package/esm/simple/Directory.js +91 -21
- package/esm/simple/Phone.js +499 -404
- package/esm/simple/Websocket.js +45 -19
- package/esm/simple/index.js +503 -408
- package/esm/simple/room/LocalParticipant.js +503 -408
- package/esm/simple/room/Participant.js +503 -408
- package/esm/simple/room/RemoteParticipant.js +503 -408
- package/esm/simple/room/Room.js +504 -409
- package/esm/simple/room/SipRoom.js +503 -408
- package/esm/simple/room/Stream.js +503 -408
- package/esm/simple/room/__tests__/RemoteParticipant.test.js +503 -408
- package/esm/simple/utils.js +503 -408
- package/esm/types/WebSocketMessage.js +1 -1
- package/esm/utils/__tests__/api-requester.test.js +25 -2
- package/esm/utils/api-requester.js +25 -2
- package/esm/web-rtc-client.js +214 -165
- package/esm/websocket-client.js +43 -18
- package/lib/__tests__/api-client.test.js +91 -21
- package/lib/__tests__/web-rtc-client.test.js +214 -165
- package/lib/api/agentd.js +25 -2
- package/lib/api/amid.js +26 -3
- package/lib/api/application.js +25 -2
- package/lib/api/auth.js +25 -2
- package/lib/api/call-logd.js +34 -4
- package/lib/api/calld.js +35 -2
- package/lib/api/chatd.js +32 -2
- package/lib/api/confd.js +56 -9
- package/lib/api/ctid-ng.js +38 -5
- package/lib/api/dird.js +29 -3
- package/lib/api/webhookd.js +26 -3
- package/lib/api-client.js +91 -21
- package/lib/checker/Checker.js +241 -190
- package/lib/checker/checks/aor.js +91 -21
- package/lib/checker/checks/api.js +91 -21
- package/lib/checker/checks/index.js +231 -180
- package/lib/checker/checks/wazo-websocket.js +42 -17
- package/lib/checker/checks/webrtc-transport.js +214 -165
- package/lib/checker/checks/webrtc.js +214 -165
- package/lib/domain/AdHocAPIConference.js +91 -21
- package/lib/domain/Call.js +3 -0
- package/lib/domain/CallLog.js +8 -1
- package/lib/domain/ChatMessage.js +4 -0
- package/lib/domain/ChatRoom.js +3 -0
- package/lib/domain/Contact.js +4 -1
- package/lib/domain/Features.js +91 -21
- package/lib/domain/Meeting.js +32 -5
- package/lib/domain/Phone/CTIPhone.js +109 -35
- package/lib/domain/Phone/WebRTCPhone.js +159 -102
- package/lib/domain/Recording.js +3 -0
- package/lib/domain/Voicemail.js +3 -0
- package/lib/domain/__tests__/Call.test.js +3 -0
- package/lib/domain/__tests__/CallLog.test.js +8 -1
- package/lib/domain/__tests__/Contact.test.js +4 -1
- package/lib/domain/__tests__/Meeting.test.js +150 -0
- package/lib/domain/__tests__/Voicemail.test.js +3 -0
- package/lib/index.js +509 -414
- package/lib/lib/WazoSessionDescriptionHandler.js +26 -41
- package/lib/service/CallApi.js +91 -21
- package/lib/service/IssueReporter.js +26 -3
- package/lib/service/__tests__/IssueReporter.test.js +26 -3
- package/lib/service/getApiClient.js +91 -21
- package/lib/simple/Auth.js +499 -404
- package/lib/simple/Configuration.js +499 -404
- package/lib/simple/Directory.js +91 -21
- package/lib/simple/Phone.js +499 -404
- package/lib/simple/Websocket.js +45 -19
- package/lib/simple/index.js +503 -408
- package/lib/simple/room/LocalParticipant.js +503 -408
- package/lib/simple/room/Participant.js +503 -408
- package/lib/simple/room/RemoteParticipant.js +503 -408
- package/lib/simple/room/Room.js +504 -409
- package/lib/simple/room/SipRoom.js +503 -408
- package/lib/simple/room/Stream.js +503 -408
- package/lib/simple/room/__tests__/RemoteParticipant.test.js +503 -408
- package/lib/simple/utils.js +503 -408
- package/lib/types/WebSocketMessage.js +2 -0
- package/lib/utils/__tests__/api-requester.test.js +25 -2
- package/lib/utils/api-requester.js +25 -2
- package/lib/web-rtc-client.js +214 -165
- package/lib/websocket-client.js +43 -17
- package/package.json +1 -1
- package/src/api/confd.js +5 -2
- package/src/domain/Call.js +3 -0
- package/src/domain/CallLog.js +4 -0
- package/src/domain/ChatMessage.js +4 -0
- package/src/domain/ChatRoom.js +3 -0
- package/src/domain/Contact.js +3 -0
- package/src/domain/Meeting.js +28 -5
- package/src/domain/Phone/CTIPhone.js +4 -0
- package/src/domain/Phone/Phone.js +2 -0
- package/src/domain/Phone/WebRTCPhone.js +49 -15
- package/src/domain/Recording.js +3 -0
- package/src/domain/Voicemail.js +3 -0
- package/src/domain/__tests__/Meeting.test.js +50 -0
- package/src/lib/WazoSessionDescriptionHandler.js +1 -35
- package/src/service/IssueReporter.js +25 -2
- package/src/simple/Phone.js +5 -0
- package/src/types/WebSocketMessage.js +5 -1
- package/src/web-rtc-client.js +41 -24
- package/src/websocket-client.js +2 -0
package/lib/websocket-client.js
CHANGED
|
@@ -45,7 +45,7 @@ const isMobile = () => typeof navigator !== 'undefined' && navigator.product ===
|
|
|
45
45
|
|
|
46
46
|
/* */
|
|
47
47
|
|
|
48
|
-
IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
48
|
+
const logger = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
|
|
49
49
|
|
|
50
50
|
// Use a function here to be able to mock it in tests
|
|
51
51
|
const realFetch = () => {
|
|
@@ -131,6 +131,7 @@ class IssueReporter {
|
|
|
131
131
|
|
|
132
132
|
|
|
133
133
|
|
|
134
|
+
|
|
134
135
|
|
|
135
136
|
constructor() {
|
|
136
137
|
addLevelsTo(this);
|
|
@@ -142,12 +143,17 @@ class IssueReporter {
|
|
|
142
143
|
this.bufferTimeout = null;
|
|
143
144
|
this._boundProcessBuffer = this._processBuffer.bind(this);
|
|
144
145
|
this._boundParseLoggerBody = this._parseLoggerBody.bind(this);
|
|
146
|
+
this._callback = null;
|
|
145
147
|
}
|
|
146
148
|
|
|
147
149
|
init() {
|
|
148
150
|
this._catchConsole();
|
|
149
151
|
}
|
|
150
152
|
|
|
153
|
+
setCallback(cb ) {
|
|
154
|
+
this._callback = cb;
|
|
155
|
+
}
|
|
156
|
+
|
|
151
157
|
configureRemoteClient(configuration = { tag: 'wazo-sdk', host: null, port: null, level: null, extra: {} }) {
|
|
152
158
|
this.remoteClientConfiguration = configuration;
|
|
153
159
|
}
|
|
@@ -183,6 +189,7 @@ class IssueReporter {
|
|
|
183
189
|
|
|
184
190
|
// Handle category label
|
|
185
191
|
let category = null;
|
|
192
|
+
let skipSendToRemote = false;
|
|
186
193
|
let extra = {};
|
|
187
194
|
if (args[0].indexOf(CATEGORY_PREFIX) === 0) {
|
|
188
195
|
category = args[0].split('=')[1];
|
|
@@ -198,6 +205,7 @@ class IssueReporter {
|
|
|
198
205
|
errorMessage: lastArg.message,
|
|
199
206
|
errorStack: lastArg.stack,
|
|
200
207
|
errorType: lastArg.constructor.name,
|
|
208
|
+
skipSendToRemote: lastArg.skipSendToRemote,
|
|
201
209
|
};
|
|
202
210
|
} else {
|
|
203
211
|
extra = lastArg;
|
|
@@ -206,6 +214,11 @@ class IssueReporter {
|
|
|
206
214
|
args.splice(1, 1);
|
|
207
215
|
}
|
|
208
216
|
|
|
217
|
+
if (extra.skipSendToRemote) {
|
|
218
|
+
skipSendToRemote = true;
|
|
219
|
+
delete extra.skipSendToRemote;
|
|
220
|
+
}
|
|
221
|
+
|
|
209
222
|
const date = moment__default['default']().format('YYYY-MM-DD HH:mm:ss.SSS');
|
|
210
223
|
const message = args.join(', ');
|
|
211
224
|
let consoleMessage = message;
|
|
@@ -226,7 +239,13 @@ class IssueReporter {
|
|
|
226
239
|
const oldMethod = this.oldConsoleMethods[consoleLevel] || this.oldConsoleMethods.log;
|
|
227
240
|
oldMethod.apply(oldMethod, [date, consoleMessage]);
|
|
228
241
|
|
|
229
|
-
this.
|
|
242
|
+
if (this._callback) {
|
|
243
|
+
this._callback(level, consoleMessage);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (!skipSendToRemote) {
|
|
247
|
+
this._sendToRemoteLogger(level, { date, message, category, ...extra });
|
|
248
|
+
}
|
|
230
249
|
}
|
|
231
250
|
|
|
232
251
|
logRequest(url , options , response , start ) {
|
|
@@ -371,7 +390,11 @@ class IssueReporter {
|
|
|
371
390
|
},
|
|
372
391
|
// $FlowFixMe
|
|
373
392
|
body,
|
|
374
|
-
}).catch(() => {
|
|
393
|
+
}).catch((e ) => {
|
|
394
|
+
// $FlowFixMe
|
|
395
|
+
e.skipSendToRemote = true;
|
|
396
|
+
this.log('error', this._makeCategory('grafana'), 'Sending log to grafana, error', e);
|
|
397
|
+
|
|
375
398
|
setTimeout(() => {
|
|
376
399
|
if (isArray) {
|
|
377
400
|
payload = payload.map(message => {
|
|
@@ -588,6 +611,7 @@ const AGENT_PAUSED = 'agent_paused';
|
|
|
588
611
|
const AGENT_UNPAUSED = 'agent_unpaused';
|
|
589
612
|
const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
|
|
590
613
|
const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
|
|
614
|
+
const MEETING_USER_PROGRESS = 'meeting_user_progress';
|
|
591
615
|
|
|
592
616
|
const BLACKLIST_EVENTS = [
|
|
593
617
|
CHAT_MESSAGE_SENT,
|
|
@@ -597,7 +621,7 @@ const BLACKLIST_EVENTS = [
|
|
|
597
621
|
];
|
|
598
622
|
|
|
599
623
|
const HEARTBEAT_ENGINE_VERSION = '20.09';
|
|
600
|
-
const logger = IssueReporter$1.loggerFor('wazo-ws');
|
|
624
|
+
const logger$1 = IssueReporter$1.loggerFor('wazo-ws');
|
|
601
625
|
const messageLogger = IssueReporter$1.loggerFor('wazo-ws-message');
|
|
602
626
|
|
|
603
627
|
class WebSocketClient extends Emitter {
|
|
@@ -646,19 +670,19 @@ class WebSocketClient extends Emitter {
|
|
|
646
670
|
}
|
|
647
671
|
|
|
648
672
|
connect() {
|
|
649
|
-
logger.info('connect method started', { host: this.host, token: this.token });
|
|
673
|
+
logger$1.info('connect method started', { host: this.host, token: this.token });
|
|
650
674
|
this.socket = new ReconnectingWebSocket__default['default'](this._getUrl.bind(this), [], this.options);
|
|
651
675
|
if (this.options.binaryType) {
|
|
652
676
|
this.socket.binaryType = this.options.binaryType;
|
|
653
677
|
}
|
|
654
678
|
|
|
655
679
|
this.socket.onopen = () => {
|
|
656
|
-
logger.info('on Wazo WS open', { method: 'connect', host: this.host });
|
|
680
|
+
logger$1.info('on Wazo WS open', { method: 'connect', host: this.host });
|
|
657
681
|
this.eventEmitter.emit(SOCKET_EVENTS.ON_OPEN);
|
|
658
682
|
};
|
|
659
683
|
|
|
660
684
|
this.socket.onerror = event => {
|
|
661
|
-
logger.error('on Wazo WS error', event.target);
|
|
685
|
+
logger$1.error('on Wazo WS error', event.target);
|
|
662
686
|
this.eventEmitter.emit(SOCKET_EVENTS.ON_ERROR, event);
|
|
663
687
|
};
|
|
664
688
|
|
|
@@ -688,7 +712,7 @@ class WebSocketClient extends Emitter {
|
|
|
688
712
|
|
|
689
713
|
this.socket.onclose = event => {
|
|
690
714
|
// Can't be converted to JSON (circular structure)
|
|
691
|
-
logger.info('on Wazo WS close', {
|
|
715
|
+
logger$1.info('on Wazo WS close', {
|
|
692
716
|
reason: event.reason,
|
|
693
717
|
code: event.code,
|
|
694
718
|
readyState: event.target.readyState,
|
|
@@ -706,12 +730,12 @@ class WebSocketClient extends Emitter {
|
|
|
706
730
|
};
|
|
707
731
|
|
|
708
732
|
this.socket.onerror = event => {
|
|
709
|
-
logger.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
|
|
733
|
+
logger$1.info('Wazo WS error', { message: event.message, code: event.code, readyState: event.target.readyState });
|
|
710
734
|
};
|
|
711
735
|
}
|
|
712
736
|
|
|
713
737
|
close(force = false) {
|
|
714
|
-
logger.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
|
|
738
|
+
logger$1.info('Wazo WS close', { socket: !!this.socket, host: this.host, token: this.token });
|
|
715
739
|
|
|
716
740
|
if (!this.socket) {
|
|
717
741
|
return;
|
|
@@ -729,7 +753,7 @@ class WebSocketClient extends Emitter {
|
|
|
729
753
|
|
|
730
754
|
updateToken(token ) {
|
|
731
755
|
this.token = token;
|
|
732
|
-
logger.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
|
|
756
|
+
logger$1.info('Wazo WS updating token', { url: this._getUrl(), token, socket: !!this.socket });
|
|
733
757
|
|
|
734
758
|
if (this.socket) {
|
|
735
759
|
// If still connected, send the token to the WS
|
|
@@ -747,7 +771,7 @@ class WebSocketClient extends Emitter {
|
|
|
747
771
|
}
|
|
748
772
|
|
|
749
773
|
startHeartbeat() {
|
|
750
|
-
logger.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
|
|
774
|
+
logger$1.info('Wazo WS start heartbeat', { host: this.host, token: this.token });
|
|
751
775
|
|
|
752
776
|
if (!this.socket) {
|
|
753
777
|
this.heartbeat.stop();
|
|
@@ -761,7 +785,7 @@ class WebSocketClient extends Emitter {
|
|
|
761
785
|
}
|
|
762
786
|
|
|
763
787
|
stopHeartbeat() {
|
|
764
|
-
logger.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
|
|
788
|
+
logger$1.info('Wazo WS stop heartbeat', { host: this.host, token: this.token });
|
|
765
789
|
|
|
766
790
|
this.heartbeat.stop();
|
|
767
791
|
}
|
|
@@ -791,7 +815,7 @@ class WebSocketClient extends Emitter {
|
|
|
791
815
|
}
|
|
792
816
|
|
|
793
817
|
reconnect(reason ) {
|
|
794
|
-
logger.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
|
|
818
|
+
logger$1.info('Wazo WS reconnect', { reason, socket: !!this.socket, host: this.host, token: this.token });
|
|
795
819
|
if (!this.socket) {
|
|
796
820
|
return;
|
|
797
821
|
}
|
|
@@ -847,7 +871,7 @@ class WebSocketClient extends Emitter {
|
|
|
847
871
|
this.close();
|
|
848
872
|
}
|
|
849
873
|
const url = `wss://${this.host || ''}/api/websocketd/?token=${this.token || ''}&version=${this.version}`;
|
|
850
|
-
logger.log('Wazo WS url computed to reconnect', { url });
|
|
874
|
+
logger$1.log('Wazo WS url computed to reconnect', { url });
|
|
851
875
|
|
|
852
876
|
return url;
|
|
853
877
|
}
|
|
@@ -855,12 +879,12 @@ class WebSocketClient extends Emitter {
|
|
|
855
879
|
_onHeartbeat(message ) {
|
|
856
880
|
if (message.payload === 'pong') {
|
|
857
881
|
this.heartbeat.onHeartbeat();
|
|
858
|
-
logger.log('on heartbeat received from Wazo WS');
|
|
882
|
+
logger$1.log('on heartbeat received from Wazo WS');
|
|
859
883
|
}
|
|
860
884
|
}
|
|
861
885
|
|
|
862
886
|
async _onHeartbeatTimeout() {
|
|
863
|
-
logger.log('heartbeat timed out', { host: this.host, token: this.token });
|
|
887
|
+
logger$1.log('heartbeat timed out', { host: this.host, token: this.token });
|
|
864
888
|
|
|
865
889
|
this.close();
|
|
866
890
|
this.eventEmitter.emit(SOCKET_EVENTS.ON_CLOSE, new Error('Websocket ping failure.'));
|
|
@@ -938,6 +962,7 @@ WebSocketClient.eventLists = [
|
|
|
938
962
|
AGENT_UNPAUSED,
|
|
939
963
|
CONFERENCE_ADHOC_PARTICIPANT_LEFT,
|
|
940
964
|
CONFERENCE_ADHOC_DELETED,
|
|
965
|
+
MEETING_USER_PROGRESS,
|
|
941
966
|
];
|
|
942
967
|
|
|
943
968
|
exports.AGENT_PAUSED = AGENT_PAUSED;
|
|
@@ -993,6 +1018,7 @@ exports.HEARTBEAT_ENGINE_VERSION = HEARTBEAT_ENGINE_VERSION;
|
|
|
993
1018
|
exports.LINE_STATUS_UPDATED = LINE_STATUS_UPDATED;
|
|
994
1019
|
exports.MEETING_USER_PARTICIPANT_JOINED = MEETING_USER_PARTICIPANT_JOINED;
|
|
995
1020
|
exports.MEETING_USER_PARTICIPANT_LEFT = MEETING_USER_PARTICIPANT_LEFT;
|
|
1021
|
+
exports.MEETING_USER_PROGRESS = MEETING_USER_PROGRESS;
|
|
996
1022
|
exports.SOCKET_EVENTS = SOCKET_EVENTS;
|
|
997
1023
|
exports.SWITCHBOARD_HELD_CALLS_UPDATED = SWITCHBOARD_HELD_CALLS_UPDATED;
|
|
998
1024
|
exports.SWITCHBOARD_HELD_CALL_ANSWERED = SWITCHBOARD_HELD_CALL_ANSWERED;
|
package/package.json
CHANGED
package/src/api/confd.js
CHANGED
|
@@ -69,8 +69,11 @@ export default (client: ApiRequester, baseUrl: string) => ({
|
|
|
69
69
|
}
|
|
70
70
|
},
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
client.
|
|
72
|
+
getMyMeetings: (): Promise<Meeting> =>
|
|
73
|
+
client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
|
|
74
|
+
|
|
75
|
+
createMyMeeting: (name: string, persistent: boolean): Promise<Meeting> =>
|
|
76
|
+
client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
|
|
74
77
|
|
|
75
78
|
deleteMyMeeting: (meetingUuid: string): Promise<Meeting> =>
|
|
76
79
|
client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
|
package/src/domain/Call.js
CHANGED
package/src/domain/CallLog.js
CHANGED
package/src/domain/ChatRoom.js
CHANGED
package/src/domain/Contact.js
CHANGED
|
@@ -281,6 +281,9 @@ export default class Contact {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
static parseMany(response: ContactsResponse): Array<Contact> {
|
|
284
|
+
if (!response || !response.results) {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
284
287
|
return response.results.map(r => Contact.parse(r, response.column_types));
|
|
285
288
|
}
|
|
286
289
|
|
package/src/domain/Meeting.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
// @flow
|
|
2
|
+
import moment from 'moment';
|
|
3
|
+
|
|
2
4
|
import newFrom from '../utils/new-from';
|
|
3
5
|
|
|
4
6
|
export type MeetingCreationResponse = {
|
|
@@ -8,8 +10,9 @@ export type MeetingCreationResponse = {
|
|
|
8
10
|
owner_uuids: Array<string>,
|
|
9
11
|
port: string,
|
|
10
12
|
uuid: string,
|
|
11
|
-
|
|
13
|
+
exten: string,
|
|
12
14
|
persistent: boolean,
|
|
15
|
+
creation_time: string,
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
export default class Meeting {
|
|
@@ -20,9 +23,10 @@ export default class Meeting {
|
|
|
20
23
|
uuid: string;
|
|
21
24
|
name: string;
|
|
22
25
|
port: string;
|
|
23
|
-
|
|
26
|
+
extension: string;
|
|
24
27
|
persistent: boolean;
|
|
25
28
|
ownerUuids: Array<string>;
|
|
29
|
+
creationTime: Date;
|
|
26
30
|
|
|
27
31
|
static parse(plain: MeetingCreationResponse): Meeting {
|
|
28
32
|
return new Meeting({
|
|
@@ -32,24 +36,43 @@ export default class Meeting {
|
|
|
32
36
|
ownerUuids: plain.owner_uuids,
|
|
33
37
|
port: plain.port,
|
|
34
38
|
uuid: plain.uuid,
|
|
35
|
-
|
|
39
|
+
extension: plain.exten,
|
|
36
40
|
persistent: plain.persistent,
|
|
41
|
+
creationTime: moment(plain.creation_time).toDate(),
|
|
37
42
|
});
|
|
38
43
|
}
|
|
39
44
|
|
|
45
|
+
static parseMany(items: MeetingCreationResponse[]): Array<Meeting> {
|
|
46
|
+
if (!items) {
|
|
47
|
+
return [];
|
|
48
|
+
}
|
|
49
|
+
return items.map(plain => Meeting.parse(plain));
|
|
50
|
+
}
|
|
51
|
+
|
|
40
52
|
static newFrom(meeting: Meeting) {
|
|
41
53
|
return newFrom(meeting, Meeting);
|
|
42
54
|
}
|
|
43
55
|
|
|
44
|
-
constructor({
|
|
56
|
+
constructor({
|
|
57
|
+
uuid,
|
|
58
|
+
name,
|
|
59
|
+
guestSipAuthorization,
|
|
60
|
+
ownerUuids,
|
|
61
|
+
port,
|
|
62
|
+
uri,
|
|
63
|
+
extension,
|
|
64
|
+
persistent,
|
|
65
|
+
creationTime,
|
|
66
|
+
}: Object = {}) {
|
|
45
67
|
this.guestSipAuthorization = guestSipAuthorization;
|
|
46
68
|
this.uri = uri;
|
|
47
69
|
this.name = name;
|
|
48
70
|
this.ownerUuids = ownerUuids;
|
|
49
71
|
this.port = port;
|
|
50
72
|
this.uuid = uuid;
|
|
51
|
-
this.
|
|
73
|
+
this.extension = extension;
|
|
52
74
|
this.persistent = persistent;
|
|
75
|
+
this.creationTime = creationTime;
|
|
53
76
|
|
|
54
77
|
// Useful to compare instead of instanceof with minified code
|
|
55
78
|
this.type = 'Meeting';
|
|
@@ -306,6 +306,11 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
306
306
|
|
|
307
307
|
this.client.downgradeToAudio(sipSession);
|
|
308
308
|
|
|
309
|
+
if (callSession) {
|
|
310
|
+
callSession.cameraEnabled = false;
|
|
311
|
+
this._updateCallSession(callSession);
|
|
312
|
+
}
|
|
313
|
+
|
|
309
314
|
if (withMessage) {
|
|
310
315
|
this._sendReinviteMessage(callSession, false);
|
|
311
316
|
}
|
|
@@ -333,6 +338,11 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
333
338
|
|
|
334
339
|
const newStream = await this.client.upgradeToVideo(sipSession, constraints, isConference);
|
|
335
340
|
|
|
341
|
+
if (callSession) {
|
|
342
|
+
callSession.cameraEnabled = true;
|
|
343
|
+
this._updateCallSession(callSession);
|
|
344
|
+
}
|
|
345
|
+
|
|
336
346
|
// If no stream is returned, it means we have to reinvite
|
|
337
347
|
if (!newStream) {
|
|
338
348
|
return true;
|
|
@@ -385,7 +395,10 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
385
395
|
|
|
386
396
|
onCancel(message);
|
|
387
397
|
const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
|
|
388
|
-
|
|
398
|
+
const callSession = this._createCallSession(sipSession);
|
|
399
|
+
delete this.callSessions[callSession.getId()];
|
|
400
|
+
|
|
401
|
+
this.eventEmitter.emit(ON_CALL_CANCELED, callSession, elsewhere);
|
|
389
402
|
};
|
|
390
403
|
} else if (sipSession instanceof Invitation) {
|
|
391
404
|
console.warn('sipSession._onCancel not found, please update the wazo SDK accordingly');
|
|
@@ -414,9 +427,11 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
414
427
|
case SessionState.Terminated: {
|
|
415
428
|
logger.info('WebRTC phone - call terminated', { sipId: sipSession.id });
|
|
416
429
|
|
|
430
|
+
// Should be called before `_onCallTerminated` or the callCount will not decrement...
|
|
431
|
+
const callSession = this._createCallSession(sipSession);
|
|
417
432
|
const wasCurrentSession = this._onCallTerminated(sipSession);
|
|
418
433
|
|
|
419
|
-
return this.eventEmitter.emit(ON_CALL_ENDED,
|
|
434
|
+
return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
|
|
420
435
|
}
|
|
421
436
|
default:
|
|
422
437
|
break;
|
|
@@ -566,18 +581,20 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
566
581
|
screenTrack,
|
|
567
582
|
});
|
|
568
583
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
584
|
+
if (screenTrack) {
|
|
585
|
+
screenTrack.onended = () => {
|
|
586
|
+
logger.info('WebRTC phone - on screenshare ended', {
|
|
587
|
+
hadVideo,
|
|
588
|
+
id: this.getSipSessionId(sipSession),
|
|
589
|
+
screenTrack,
|
|
590
|
+
});
|
|
591
|
+
|
|
592
|
+
this.eventEmitter.emit(
|
|
593
|
+
ON_SHARE_SCREEN_ENDING,
|
|
594
|
+
this._createCallSession(sipSession, callSession),
|
|
595
|
+
);
|
|
596
|
+
};
|
|
597
|
+
}
|
|
581
598
|
|
|
582
599
|
this.currentScreenShare = {
|
|
583
600
|
stream: screenStream,
|
|
@@ -1366,6 +1383,10 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1366
1383
|
return callSession ? this.client.getRemoteVideoStream(callSession.sipCallId) : null;
|
|
1367
1384
|
}
|
|
1368
1385
|
|
|
1386
|
+
getRemoteVideoStreamFromPc(callSession: CallSession): ?MediaStream {
|
|
1387
|
+
return callSession ? this.client.getRemoteVideoStreamFromPc(callSession.sipCallId) : null;
|
|
1388
|
+
}
|
|
1389
|
+
|
|
1369
1390
|
hasRemoteVideo(callSession: CallSession): boolean {
|
|
1370
1391
|
return callSession ? this.client.hasRemoteVideo(callSession.sipCallId) : false;
|
|
1371
1392
|
}
|
|
@@ -1466,9 +1487,13 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1466
1487
|
if (this.shouldSendReinvite && this.currentSipSession
|
|
1467
1488
|
&& this.currentSipSession.state === SessionState.Established) {
|
|
1468
1489
|
this.shouldSendReinvite = false;
|
|
1490
|
+
const pc = this.currentSipSession.sessionDescriptionHandler.peerConnection;
|
|
1491
|
+
const isConference = pc ? pc.sfu : false;
|
|
1492
|
+
const hasVideo = this.currentCallSession && this.currentCallSession.cameraEnabled;
|
|
1493
|
+
|
|
1469
1494
|
try {
|
|
1470
1495
|
// Send reinvite with iceRestart
|
|
1471
|
-
this.sendReinvite(this.currentCallSession, null,
|
|
1496
|
+
this.sendReinvite(this.currentCallSession, null, isConference, !hasVideo, true);
|
|
1472
1497
|
} catch (e) {
|
|
1473
1498
|
logger.error('WebRTC reinvite after register, error', { message: e.message, stack: e.stack });
|
|
1474
1499
|
}
|
|
@@ -1552,6 +1577,15 @@ export default class WebRTCPhone extends Emitter implements Phone {
|
|
|
1552
1577
|
return this.client.getSipSessionId(sipSession);
|
|
1553
1578
|
}
|
|
1554
1579
|
|
|
1580
|
+
_updateCallSession(callSession: CallSession) {
|
|
1581
|
+
const sipSession = this.findSipSession(callSession);
|
|
1582
|
+
const sipSessionId = sipSession ? this.getSipSessionId(sipSession) : null;
|
|
1583
|
+
|
|
1584
|
+
if (sipSessionId) {
|
|
1585
|
+
this.callSessions[sipSessionId] = callSession;
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
|
|
1555
1589
|
_onMessage(message: Message) {
|
|
1556
1590
|
if (!message || message.method !== 'MESSAGE') {
|
|
1557
1591
|
return;
|
package/src/domain/Recording.js
CHANGED
package/src/domain/Voicemail.js
CHANGED
|
@@ -61,6 +61,9 @@ export default class Voicemail {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
static parseMany(plain: Response): Array<Voicemail> {
|
|
64
|
+
if (!plain) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
64
67
|
const plainUnread = plain.folders.filter(folder => folder.type === 'new')[0].messages;
|
|
65
68
|
const plainRead = plain.folders.filter(folder => folder.type === 'old')[0].messages;
|
|
66
69
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
/* global btoa */
|
|
3
|
+
|
|
4
|
+
import Meeting from '../Meeting';
|
|
5
|
+
|
|
6
|
+
describe('Meeting domain', () => {
|
|
7
|
+
it('can return username and secret from an base64 encrypted string', () => {
|
|
8
|
+
const USERNAME = 'username';
|
|
9
|
+
const SECRET = 'secret';
|
|
10
|
+
|
|
11
|
+
const args = {
|
|
12
|
+
guest_sip_authorization: btoa(`${USERNAME}:${SECRET}`),
|
|
13
|
+
creation_time: '',
|
|
14
|
+
ingress_http_uri: '',
|
|
15
|
+
name: '',
|
|
16
|
+
owner_uuids: [],
|
|
17
|
+
port: '',
|
|
18
|
+
uuid: '',
|
|
19
|
+
exten: '',
|
|
20
|
+
persistent: false,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const meeting = Meeting.parse(args);
|
|
24
|
+
|
|
25
|
+
const { username, secret } = meeting.getGuestSipCredentials();
|
|
26
|
+
|
|
27
|
+
expect(username).toEqual(USERNAME);
|
|
28
|
+
expect(secret).toEqual(SECRET);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should return a date from a string', () => {
|
|
32
|
+
const args = {
|
|
33
|
+
creation_time: '2021-12-21T15:56:42.880Z',
|
|
34
|
+
guest_sip_authorization: '',
|
|
35
|
+
ingress_http_uri: '',
|
|
36
|
+
name: '',
|
|
37
|
+
owner_uuids: [],
|
|
38
|
+
port: '',
|
|
39
|
+
uuid: '',
|
|
40
|
+
exten: '',
|
|
41
|
+
persistent: false,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const { creationTime } = Meeting.parse(args);
|
|
45
|
+
|
|
46
|
+
expect(creationTime.getDate()).toEqual(21);
|
|
47
|
+
expect(creationTime.getFullYear()).toEqual(2021);
|
|
48
|
+
expect(creationTime.getMonth()).toEqual(11);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -12,11 +12,9 @@ import { SessionDescriptionHandler }
|
|
|
12
12
|
import { SessionDescriptionHandlerOptions }
|
|
13
13
|
from 'sip.js/lib/platform/web/session-description-handler/session-description-handler-options';
|
|
14
14
|
import IssueReporter from '../service/IssueReporter';
|
|
15
|
-
import {
|
|
15
|
+
import { fixSdp, parseCandidate } from '../utils/sdp';
|
|
16
16
|
|
|
17
17
|
const wazoLogger = IssueReporter ? IssueReporter.loggerFor('webrtc-sdh') : console;
|
|
18
|
-
const MAX_WAIT_FOR_ICE_TRIES = 20;
|
|
19
|
-
const WAIT_FOR_ICE_TIMEOUT = 500;
|
|
20
18
|
|
|
21
19
|
// Customized mediaStreamFactory allowing to send screensharing stream directory when upgrading
|
|
22
20
|
export const wazoMediaStreamFactory = (constraints: Object): Promise<MediaStream> => {
|
|
@@ -206,38 +204,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
|
|
|
206
204
|
this._peerConnection = undefined;
|
|
207
205
|
}
|
|
208
206
|
|
|
209
|
-
async _waitForValidGatheredIce(): Object {
|
|
210
|
-
let tries = 0;
|
|
211
|
-
|
|
212
|
-
while (!areCandidateValid(this.gatheredCandidates) && tries < MAX_WAIT_FOR_ICE_TRIES) {
|
|
213
|
-
wazoLogger.trace('SessionDescriptionHandler._waitForValidGatheredIce, waiting for ice', {
|
|
214
|
-
tries,
|
|
215
|
-
max: MAX_WAIT_FOR_ICE_TRIES,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
tries++;
|
|
219
|
-
|
|
220
|
-
// eslint-disable-next-line no-await-in-loop
|
|
221
|
-
await new Promise(resolve => setTimeout(resolve, WAIT_FOR_ICE_TIMEOUT));
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
if (tries >= MAX_WAIT_FOR_ICE_TRIES) {
|
|
225
|
-
const errorMsg = 'No valid candidates found, can\'t answer the call';
|
|
226
|
-
const error = new Error(errorMsg);
|
|
227
|
-
wazoLogger.error(errorMsg, { tries, max: MAX_WAIT_FOR_ICE_TRIES });
|
|
228
|
-
|
|
229
|
-
// Emit an error, because sip.js catches the exception and switch to status Terminated.
|
|
230
|
-
this.eventEmitter.emit('error', error);
|
|
231
|
-
|
|
232
|
-
wazoLogger.error('No valid candidates found', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// eslint-disable-next-line
|
|
236
|
-
wazoLogger.trace('Found valid candidates', { tries, candidates: JSON.stringify(this.gatheredCandidates) });
|
|
237
|
-
|
|
238
|
-
return this.getLocalSessionDescription();
|
|
239
|
-
}
|
|
240
|
-
|
|
241
207
|
// Overridden to send `inactive` in conference
|
|
242
208
|
updateDirection(options?: SessionDescriptionHandlerOptions, isConference: boolean = false,
|
|
243
209
|
audioOnly: boolean = false): Promise<void> {
|