@wazo/sdk 0.37.26 → 0.37.30

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.
Files changed (121) hide show
  1. package/README.md +98 -59
  2. package/dist/wazo-sdk.js +3 -3
  3. package/esm/__tests__/api-client.test.js +1 -1
  4. package/esm/__tests__/web-rtc-client.test.js +18 -5
  5. package/esm/api/agentd.js +1 -1
  6. package/esm/api/amid.js +1 -1
  7. package/esm/api/application.js +1 -1
  8. package/esm/api/auth.js +1 -1
  9. package/esm/api/call-logd.js +1 -1
  10. package/esm/api/calld.js +1 -1
  11. package/esm/api/chatd.js +1 -1
  12. package/esm/api/confd.js +1 -1
  13. package/esm/api/ctid-ng.js +1 -1
  14. package/esm/api/dird.js +1 -1
  15. package/esm/api/webhookd.js +1 -1
  16. package/esm/api-client.js +1 -1
  17. package/esm/checker/Checker.js +18 -5
  18. package/esm/checker/checks/aor.js +1 -1
  19. package/esm/checker/checks/api.js +1 -1
  20. package/esm/checker/checks/index.js +18 -5
  21. package/esm/checker/checks/wazo-websocket.js +1 -1
  22. package/esm/checker/checks/webrtc-transport.js +18 -5
  23. package/esm/checker/checks/webrtc.js +18 -5
  24. package/esm/domain/AdHocAPIConference.js +1 -1
  25. package/esm/domain/CallSession.js +29 -2
  26. package/esm/domain/Features.js +1 -1
  27. package/esm/domain/Phone/CTIPhone.js +30 -3
  28. package/esm/domain/Phone/WebRTCPhone.js +55 -6
  29. package/esm/domain/SFUNotAvailableError.js +9 -0
  30. package/esm/domain/__tests__/CallSession.test.js +46 -2
  31. package/esm/domain/__tests__/IndirectTransfer.test.js +29 -2
  32. package/esm/domain/__tests__/Room.test.js +29 -2
  33. package/esm/index.js +83 -10
  34. package/esm/lib/WazoSessionDescriptionHandler.js +9 -4
  35. package/esm/service/CallApi.js +1 -1
  36. package/esm/service/IssueReporter.js +1 -1
  37. package/esm/service/__tests__/IssueReporter.test.js +1 -1
  38. package/esm/service/getApiClient.js +1 -1
  39. package/esm/simple/Auth.js +82 -10
  40. package/esm/simple/Configuration.js +82 -10
  41. package/esm/simple/Directory.js +1 -1
  42. package/esm/simple/Phone.js +82 -10
  43. package/esm/simple/Websocket.js +1 -1
  44. package/esm/simple/index.js +82 -10
  45. package/esm/simple/room/LocalParticipant.js +82 -10
  46. package/esm/simple/room/Participant.js +82 -10
  47. package/esm/simple/room/RemoteParticipant.js +82 -10
  48. package/esm/simple/room/Room.js +82 -10
  49. package/esm/simple/room/SipRoom.js +82 -10
  50. package/esm/simple/room/Stream.js +82 -10
  51. package/esm/simple/room/__tests__/RemoteParticipant.test.js +82 -10
  52. package/esm/simple/utils.js +82 -10
  53. package/esm/utils/__tests__/api-requester.test.js +1 -1
  54. package/esm/utils/api-requester.js +1 -1
  55. package/esm/web-rtc-client.js +18 -5
  56. package/esm/websocket-client.js +1 -1
  57. package/lib/__tests__/api-client.test.js +1 -1
  58. package/lib/__tests__/web-rtc-client.test.js +18 -5
  59. package/lib/api/agentd.js +1 -1
  60. package/lib/api/amid.js +1 -1
  61. package/lib/api/application.js +1 -1
  62. package/lib/api/auth.js +1 -1
  63. package/lib/api/call-logd.js +1 -1
  64. package/lib/api/calld.js +1 -1
  65. package/lib/api/chatd.js +1 -1
  66. package/lib/api/confd.js +1 -1
  67. package/lib/api/ctid-ng.js +1 -1
  68. package/lib/api/dird.js +1 -1
  69. package/lib/api/webhookd.js +1 -1
  70. package/lib/api-client.js +1 -1
  71. package/lib/checker/Checker.js +18 -5
  72. package/lib/checker/checks/aor.js +1 -1
  73. package/lib/checker/checks/api.js +1 -1
  74. package/lib/checker/checks/index.js +18 -5
  75. package/lib/checker/checks/wazo-websocket.js +1 -1
  76. package/lib/checker/checks/webrtc-transport.js +18 -5
  77. package/lib/checker/checks/webrtc.js +18 -5
  78. package/lib/domain/AdHocAPIConference.js +1 -1
  79. package/lib/domain/CallSession.js +29 -2
  80. package/lib/domain/Features.js +1 -1
  81. package/lib/domain/Phone/CTIPhone.js +30 -3
  82. package/lib/domain/Phone/WebRTCPhone.js +55 -5
  83. package/lib/domain/SFUNotAvailableError.js +11 -0
  84. package/lib/domain/__tests__/CallSession.test.js +46 -2
  85. package/lib/domain/__tests__/IndirectTransfer.test.js +29 -2
  86. package/lib/domain/__tests__/Room.test.js +29 -2
  87. package/lib/index.js +83 -10
  88. package/lib/lib/WazoSessionDescriptionHandler.js +9 -4
  89. package/lib/service/CallApi.js +1 -1
  90. package/lib/service/IssueReporter.js +1 -1
  91. package/lib/service/__tests__/IssueReporter.test.js +1 -1
  92. package/lib/service/getApiClient.js +1 -1
  93. package/lib/simple/Auth.js +82 -10
  94. package/lib/simple/Configuration.js +82 -10
  95. package/lib/simple/Directory.js +1 -1
  96. package/lib/simple/Phone.js +82 -10
  97. package/lib/simple/Websocket.js +1 -1
  98. package/lib/simple/index.js +82 -10
  99. package/lib/simple/room/LocalParticipant.js +82 -10
  100. package/lib/simple/room/Participant.js +82 -10
  101. package/lib/simple/room/RemoteParticipant.js +82 -10
  102. package/lib/simple/room/Room.js +82 -10
  103. package/lib/simple/room/SipRoom.js +82 -10
  104. package/lib/simple/room/Stream.js +82 -10
  105. package/lib/simple/room/__tests__/RemoteParticipant.test.js +82 -10
  106. package/lib/simple/utils.js +82 -10
  107. package/lib/utils/__tests__/api-requester.test.js +1 -1
  108. package/lib/utils/api-requester.js +1 -1
  109. package/lib/web-rtc-client.js +18 -5
  110. package/lib/websocket-client.js +1 -1
  111. package/package.json +1 -1
  112. package/src/domain/CallSession.js +32 -4
  113. package/src/domain/Phone/WebRTCPhone.js +24 -2
  114. package/src/domain/SFUNotAvailableError.js +7 -0
  115. package/src/domain/__tests__/CallSession.test.js +17 -0
  116. package/src/index.js +2 -0
  117. package/src/lib/WazoSessionDescriptionHandler.js +8 -3
  118. package/src/simple/Phone.js +2 -1
  119. package/src/simple/index.js +2 -0
  120. package/src/utils/api-requester.js +1 -1
  121. package/src/web-rtc-client.js +9 -1
@@ -115,7 +115,7 @@ const logger$2 = IssueReporter$1 ? IssueReporter$1.loggerFor('api') : console;
115
115
 
116
116
  // Use a function here to be able to mock it in tests
117
117
  const realFetch = () => {
118
- if (typeof document !== 'undefined') {
118
+ if (typeof document !== 'undefined' && window.fetch) {
119
119
  // Browser
120
120
  return window.fetch;
121
121
  }
@@ -834,11 +834,16 @@ class WazoSessionDescriptionHandler extends sessionDescriptionHandler.SessionDes
834
834
 
835
835
  // $FlowFixMe
836
836
  setRemoteSessionDescription(sessionDescription ) {
837
- const result = super.setRemoteSessionDescription(sessionDescription);
837
+ try {
838
+ const result = super.setRemoteSessionDescription(sessionDescription);
838
839
 
839
- this.eventEmitter.emit('setDescription', sessionDescription);
840
+ this.eventEmitter.emit('setDescription', sessionDescription);
840
841
 
841
- return result;
842
+ return result;
843
+ } catch (error) {
844
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
845
+ throw error;
846
+ }
842
847
  }
843
848
 
844
849
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -5353,6 +5358,7 @@ const MAX_REGISTER_TRIES = 10;
5353
5358
 
5354
5359
 
5355
5360
 
5361
+
5356
5362
 
5357
5363
 
5358
5364
 
@@ -6969,6 +6975,13 @@ class WebRTCClient extends Emitter {
6969
6975
  }
6970
6976
 
6971
6977
  _createWebRTCConfiguration(configOverrides = {}) {
6978
+ let { host } = this.config;
6979
+ let port = this.config.port || 443;
6980
+
6981
+ if (this.config.websocketSip) {
6982
+ [host, port = 443] = this.config.websocketSip.split(':');
6983
+ }
6984
+
6972
6985
  const config = {
6973
6986
  authorizationUsername: this.config.authorizationUser,
6974
6987
  authorizationPassword: this.config.password,
@@ -7004,7 +7017,7 @@ class WebRTCClient extends Emitter {
7004
7017
  },
7005
7018
  transportOptions: {
7006
7019
  traceSip: configOverrides.traceSip || false,
7007
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
7020
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
7008
7021
  },
7009
7022
  sessionDescriptionHandlerFactoryOptions: {
7010
7023
  modifiers: [replaceLocalIpModifier],
@@ -49,7 +49,7 @@ 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 = () => {
52
- if (typeof document !== 'undefined') {
52
+ if (typeof document !== 'undefined' && window.fetch) {
53
53
  // Browser
54
54
  return window.fetch;
55
55
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "0.37.26",
3
+ "version": "0.37.30",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "dist/wazo-sdk.js",
6
6
  "author": "Wazo (http://wazo.io)",
@@ -1,5 +1,6 @@
1
1
  // @flow
2
2
  import { SessionState } from 'sip.js/lib/api/session-state';
3
+ import type { Session } from 'sip.js/lib/api/session';
3
4
 
4
5
  import Call from './Call';
5
6
  import newFrom from '../utils/new-from';
@@ -7,13 +8,16 @@ import updateFrom from '../utils/update-from';
7
8
 
8
9
  type CallSessionArguments = {
9
10
  answered: boolean,
11
+ answerTime?: ?Date,
10
12
  answeredBySystem: boolean,
11
13
  call: ?Call,
12
14
  callId: string,
13
15
  callerNumber: string,
14
16
  cameraEnabled: boolean,
17
+ creationTime?: ?Date,
15
18
  dialedExtension?: string | null,
16
19
  displayName: string,
20
+ endTime?: ?Date,
17
21
  isCaller: boolean,
18
22
  muted: boolean,
19
23
  videoMuted: boolean,
@@ -30,6 +34,7 @@ type CallSessionArguments = {
30
34
  screensharing: boolean,
31
35
  recording: boolean,
32
36
  recordingPaused: boolean,
37
+ sipSession?: Session,
33
38
  };
34
39
 
35
40
  export default class CallSession {
@@ -49,11 +54,15 @@ export default class CallSession {
49
54
 
50
55
  callerNumber: string;
51
56
 
52
- startTime: number;
57
+ creationTime: ?Date;
53
58
 
54
- isCaller: boolean;
59
+ startTime: number; // = creationTime
60
+
61
+ answerTime: ?Date;
55
62
 
56
- answered: boolean;
63
+ endTime: ?Date;
64
+
65
+ isCaller: boolean;
57
66
 
58
67
  answeredBySystem: boolean;
59
68
 
@@ -89,6 +98,8 @@ export default class CallSession {
89
98
 
90
99
  recordingPaused: boolean;
91
100
 
101
+ sipSession: Session;
102
+
92
103
  constructor({
93
104
  answered,
94
105
  answeredBySystem,
@@ -101,6 +112,8 @@ export default class CallSession {
101
112
  paused,
102
113
  ringing,
103
114
  startTime,
115
+ creationTime,
116
+ endTime,
104
117
  cameraEnabled,
105
118
  dialedExtension,
106
119
  sipCallId,
@@ -113,12 +126,16 @@ export default class CallSession {
113
126
  recording,
114
127
  recordingPaused,
115
128
  videoRemotelyDowngraded,
129
+ sipSession,
130
+ answerTime,
116
131
  }: CallSessionArguments) {
117
132
  this.callId = callId;
118
133
  this.sipCallId = sipCallId;
119
134
  this.displayName = displayName;
120
135
  this.number = number;
136
+ this.creationTime = creationTime;
121
137
  this.startTime = startTime;
138
+ this.endTime = endTime;
122
139
  this.isCaller = isCaller;
123
140
  this.answered = answered;
124
141
  this.answeredBySystem = answeredBySystem;
@@ -137,6 +154,8 @@ export default class CallSession {
137
154
  this.recording = recording || false;
138
155
  this.recordingPaused = recordingPaused || false;
139
156
  this.videoRemotelyDowngraded = videoRemotelyDowngraded;
157
+ this.sipSession = sipSession;
158
+ this.answerTime = answerTime || this.answerTime;
140
159
 
141
160
  // Useful to compare instead of instanceof with minified code
142
161
  this.type = 'CallSession';
@@ -167,7 +186,7 @@ export default class CallSession {
167
186
  }
168
187
 
169
188
  answer() {
170
- this.answered = true;
189
+ this.answerTime = new Date();
171
190
  }
172
191
 
173
192
  systemAnswer() {
@@ -323,6 +342,15 @@ export default class CallSession {
323
342
  return newFrom(callSession, CallSession);
324
343
  }
325
344
 
345
+ // Retro-compatibility: `answered` was a boolean before. We can reproduce the behaviour with a getter/setter
346
+ set answered(value: boolean) {
347
+ this.answerTime = value ? new Date() : null;
348
+ }
349
+
350
+ get answered(): boolean {
351
+ return !!this.answerTime;
352
+ }
353
+
326
354
  static parseCall(call: Call): CallSession {
327
355
  return new CallSession({
328
356
  callId: call.id,
@@ -30,6 +30,7 @@ export const ON_CAMERA_DISABLED = 'onCameraDisabled';
30
30
  export const ON_CAMERA_RESUMED = 'onCameraResumed';
31
31
  export const ON_CALL_CANCELED = 'onCallCanceled';
32
32
  export const ON_CALL_FAILED = 'onCallFailed';
33
+ export const ON_CALL_REJECTED = 'onCallRejected';
33
34
  export const ON_CALL_ENDED = 'onCallEnded';
34
35
  export const ON_CALL_ENDING = 'onCallEnding';
35
36
  export const ON_MESSAGE = 'onMessage';
@@ -74,6 +75,7 @@ export const events = [
74
75
  ON_CAMERA_DISABLED,
75
76
  ON_CALL_FAILED,
76
77
  ON_CALL_ENDED,
78
+ ON_CALL_REJECTED,
77
79
  ON_MESSAGE,
78
80
  ON_REINVITE,
79
81
  ON_TRACK,
@@ -430,6 +432,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
430
432
 
431
433
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
432
434
  const callSession = this._createCallSession(sipSession);
435
+ callSession.endTime = new Date();
433
436
  const wasCurrentSession = this._onCallTerminated(sipSession);
434
437
 
435
438
  return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
@@ -627,6 +630,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
627
630
  this.removeIncomingSessions(sipSessionId);
628
631
  }
629
632
 
633
+ callSession.answerTime = new Date();
630
634
  this.eventEmitter.emit(ON_CALL_ACCEPTED, callSession, cameraEnabled);
631
635
 
632
636
  return callSession;
@@ -684,6 +688,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
684
688
  _onCallTerminated(sipSession: Session) {
685
689
  logger.info('WebRTC phone - on call terminated', { sipId: sipSession.id });
686
690
 
691
+ const sipSessionId = this.getSipSessionId(sipSession);
687
692
  const callSession = this._createCallSession(sipSession);
688
693
  const isCurrentSession = this.isCurrentCallSipSession(callSession);
689
694
  const isCurrentIncomingCall = callSession.is(this.getIncomingCallSession());
@@ -701,7 +706,6 @@ export default class WebRTCPhone extends Emitter implements Phone {
701
706
  }, 5);
702
707
  }
703
708
 
704
- const sipSessionId = this.getSipSessionId(sipSession);
705
709
  if (sipSessionId) {
706
710
  this.removeIncomingSessions(sipSessionId);
707
711
  }
@@ -842,6 +846,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
842
846
  }
843
847
 
844
848
  this.shouldSendReinvite = false;
849
+ callSession.answerTime = new Date();
845
850
  this.acceptedSessions[callSession.getId()] = true;
846
851
 
847
852
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
@@ -1151,6 +1156,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1151
1156
  return Promise.resolve(null);
1152
1157
  }
1153
1158
  const callSession = this._createOutgoingCallSession(sipSession, cameraEnabled || false);
1159
+ callSession.creationTime = new Date();
1154
1160
 
1155
1161
  this.eventEmitter.emit(ON_PLAY_PROGRESS_SOUND, this.audioOutputDeviceId, this.audioOutputVolume);
1156
1162
 
@@ -1346,8 +1352,12 @@ export default class WebRTCPhone extends Emitter implements Phone {
1346
1352
  }
1347
1353
 
1348
1354
  const sessionId = this.incomingSessions[0];
1355
+ const sipSession = this.client.getSipSession(sessionId);
1356
+ if (!sipSession) {
1357
+ return null;
1358
+ }
1349
1359
 
1350
- return this._createCallSession(this.client.getSipSession(sessionId));
1360
+ return this._createCallSession(sipSession);
1351
1361
  }
1352
1362
 
1353
1363
  sendMessage(sipSession: Session = null, body: string, contentType: string = 'text/plain') {
@@ -1425,6 +1435,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1425
1435
  callSession);
1426
1436
  }
1427
1437
 
1438
+ callSession.creationTime = new Date();
1428
1439
  this.eventEmitter.emit(ON_CALL_INCOMING, callSession, wantsToDoVideo);
1429
1440
  });
1430
1441
 
@@ -1464,6 +1475,13 @@ export default class WebRTCPhone extends Emitter implements Phone {
1464
1475
  this.eventEmitter.emit(ON_CALL_ERROR, e);
1465
1476
  });
1466
1477
 
1478
+ this.client.on(this.client.REJECTED, session => {
1479
+ logger.info('WebRTC call rejected', session.id);
1480
+ const callSession = this._createCallSession(session);
1481
+ callSession.endTime = new Date();
1482
+ this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
1483
+ });
1484
+
1467
1485
  this.client.on(this.client.UNREGISTERED, () => {
1468
1486
  logger.info('WebRTC unregistered');
1469
1487
  this.eventEmitter.emit(ON_UNREGISTERED);
@@ -1678,6 +1696,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1678
1696
  const number = identity ? identity.uri._normal.user : null;
1679
1697
  const { state } = sipSession || {};
1680
1698
  const sessionId = this.getSipSessionId(sipSession);
1699
+ fromSession = fromSession || this.callSessions[sessionId];
1681
1700
 
1682
1701
  const callSession = new CallSession({
1683
1702
  callId: fromSession && fromSession.callId,
@@ -1685,6 +1704,8 @@ export default class WebRTCPhone extends Emitter implements Phone {
1685
1704
  sipStatus: state,
1686
1705
  displayName: identity ? identity.displayName || number : number,
1687
1706
  startTime: fromSession ? fromSession.startTime : new Date(),
1707
+ creationTime: fromSession ? fromSession.creationTime : null,
1708
+ endTime: fromSession ? fromSession.endTime : null,
1688
1709
  answered: state === SessionState.Established,
1689
1710
  paused: this.client.isCallHeld(sipSession),
1690
1711
  isCaller: 'incoming' in extra ? !extra.incoming : false,
@@ -1695,6 +1716,7 @@ export default class WebRTCPhone extends Emitter implements Phone {
1695
1716
  videoMuted: fromSession ? fromSession.isVideoMuted() : false,
1696
1717
  recording: fromSession ? fromSession.isRecording() : false,
1697
1718
  recordingPaused: false, // @TODO
1719
+ sipSession,
1698
1720
  ...extra,
1699
1721
  });
1700
1722
 
@@ -0,0 +1,7 @@
1
+ /* @flow */
2
+ export default class SFUNotAvailableError extends Error {
3
+ constructor(message: string = 'Sorry your user is not configured to support video conference') {
4
+ super(message);
5
+ this.name = 'SFUNotAvailableError';
6
+ }
7
+ }
@@ -37,4 +37,21 @@ describe('CallSession domain', () => {
37
37
  expect(cs1.is(cs2)).toBeTruthy();
38
38
  expect(cs2.is(cs1)).toBeTruthy();
39
39
  });
40
+
41
+ it('should set answerTime when setting answered', () => {
42
+ const cs1 = new CallSession({});
43
+ cs1.answered = true;
44
+
45
+ const cs2 = new CallSession({});
46
+ cs2.answer();
47
+
48
+ const cs3 = new CallSession({ answered: true });
49
+
50
+ expect(cs1.answered).toBeTruthy();
51
+ expect(cs1.answerTime).not.toBeNull();
52
+ expect(cs2.answered).toBeTruthy();
53
+ expect(cs2.answerTime).not.toBeNull();
54
+ expect(cs3.answered).toBeTruthy();
55
+ expect(cs3.answerTime).not.toBeNull();
56
+ });
40
57
  });
package/src/index.js CHANGED
@@ -9,6 +9,7 @@ import IssueReporter from './service/IssueReporter';
9
9
  // Domain
10
10
  import BadResponse from './domain/BadResponse';
11
11
  import ServerError from './domain/ServerError';
12
+ import SFUNotAvailableError from './domain/SFUNotAvailableError';
12
13
  import Call from './domain/Call';
13
14
  import CallLog from './domain/CallLog';
14
15
  import Recording from './domain/Recording';
@@ -95,6 +96,7 @@ export default {
95
96
  WazoWebSocketClient: WebSocketClient,
96
97
  BadResponse,
97
98
  ServerError,
99
+ SFUNotAvailableError,
98
100
  Call,
99
101
  CallSession,
100
102
  CTIPhone,
@@ -62,11 +62,16 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
62
62
 
63
63
  // $FlowFixMe
64
64
  setRemoteSessionDescription(sessionDescription: RTCSessionDescriptionInit): Promise<void> {
65
- const result = super.setRemoteSessionDescription(sessionDescription);
65
+ try {
66
+ const result = super.setRemoteSessionDescription(sessionDescription);
66
67
 
67
- this.eventEmitter.emit('setDescription', sessionDescription);
68
+ this.eventEmitter.emit('setDescription', sessionDescription);
68
69
 
69
- return result;
70
+ return result;
71
+ } catch (error) {
72
+ this.logger.error('SessionDescriptionHandler.setRemoteSessionDescription error', error);
73
+ throw error;
74
+ }
70
75
  }
71
76
 
72
77
  // Overridden to avoid to fix ice-candidates missing in the SDP in react-native and chrome canary.
@@ -14,6 +14,7 @@ import IssueReporter from '../service/IssueReporter';
14
14
  import Emitter from '../utils/Emitter';
15
15
 
16
16
  import Wazo from './index';
17
+ import SFUNotAvailableError from '../domain/SFUNotAvailableError';
17
18
 
18
19
  const logger = IssueReporter.loggerFor('simple-phone');
19
20
  const sipLogger = IssueReporter.loggerFor('sip.js');
@@ -397,7 +398,7 @@ class Phone extends Emitter {
397
398
 
398
399
  checkSfu() {
399
400
  if (!this.hasSfu()) {
400
- throw new Error('Sorry your user is not configured to support video conference');
401
+ throw new SFUNotAvailableError();
401
402
  }
402
403
  }
403
404
 
@@ -15,6 +15,7 @@ import { CanceledCallError } from '../web-rtc-client';
15
15
 
16
16
  import BadResponse from '../domain/BadResponse';
17
17
  import ServerError from '../domain/ServerError';
18
+ import SFUNotAvailableError from '../domain/SFUNotAvailableError';
18
19
  import Call from '../domain/Call';
19
20
  import CallLog from '../domain/CallLog';
20
21
  import Recording from '../domain/Recording';
@@ -101,6 +102,7 @@ const Wazo = {
101
102
  InvalidSubscription,
102
103
  InvalidAuthorization,
103
104
  CanceledCallError,
105
+ SFUNotAvailableError,
104
106
  };
105
107
 
106
108
  if (window) {
@@ -25,7 +25,7 @@ const logger = IssueReporter ? IssueReporter.loggerFor('api') : console;
25
25
 
26
26
  // Use a function here to be able to mock it in tests
27
27
  export const realFetch = () => {
28
- if (typeof document !== 'undefined') {
28
+ if (typeof document !== 'undefined' && window.fetch) {
29
29
  // Browser
30
30
  return window.fetch;
31
31
  }
@@ -87,6 +87,7 @@ type WebRtcConfig = {
87
87
  displayName: string,
88
88
  host: string,
89
89
  port?: number,
90
+ websocketSip?: ?string,
90
91
  authorizationUser: ?string,
91
92
  password: ?string,
92
93
  uri: string,
@@ -1703,6 +1704,13 @@ export default class WebRTCClient extends Emitter {
1703
1704
  }
1704
1705
 
1705
1706
  _createWebRTCConfiguration(configOverrides: Object = {}) {
1707
+ let { host } = this.config;
1708
+ let port = this.config.port || 443;
1709
+
1710
+ if (this.config.websocketSip) {
1711
+ [host, port = 443] = this.config.websocketSip.split(':');
1712
+ }
1713
+
1706
1714
  const config: Object = {
1707
1715
  authorizationUsername: this.config.authorizationUser,
1708
1716
  authorizationPassword: this.config.password,
@@ -1738,7 +1746,7 @@ export default class WebRTCClient extends Emitter {
1738
1746
  },
1739
1747
  transportOptions: {
1740
1748
  traceSip: configOverrides.traceSip || false,
1741
- wsServers: `wss://${this.config.host}:${this.config.port || 443}/api/asterisk/ws`,
1749
+ wsServers: `wss://${host}:${port}/api/asterisk/ws`,
1742
1750
  },
1743
1751
  sessionDescriptionHandlerFactoryOptions: {
1744
1752
  modifiers: [replaceLocalIpModifier],