@wazo/sdk 1.0.0-alpha.2 → 1.0.0-alpha.20

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 (158) hide show
  1. package/README.md +16 -7
  2. package/dist/wazo-sdk.js +2 -2
  3. package/esm/__tests__/__voice__/call.test.js +52 -3
  4. package/esm/api/auth.js +3 -0
  5. package/esm/checker/checks/webrtc.js +2 -2
  6. package/esm/domain/CallLog.js +2 -3
  7. package/esm/domain/Phone/CTIPhone.js +2 -2
  8. package/esm/domain/Phone/WebRTCPhone.js +59 -57
  9. package/esm/index.js +3 -1
  10. package/esm/service/CallApi.js +4 -4
  11. package/esm/simple/Auth.js +13 -3
  12. package/esm/simple/Phone.js +5 -5
  13. package/esm/simple/index.js +2 -1
  14. package/esm/simple/room/Room.js +2 -2
  15. package/esm/simple/room/SipRoom.js +2 -2
  16. package/esm/state-machine/call-state-machine.js +34 -19
  17. package/esm/state-machine/softphone-state-machine.js +1 -2
  18. package/esm/state-machine/utils.js +10 -4
  19. package/esm/types/api/auth.d.ts +3 -0
  20. package/esm/types/api/auth.d.ts.map +1 -1
  21. package/esm/types/checker/checks/index.d.ts +1 -1
  22. package/esm/types/checker/checks/webrtc-transport.d.ts +2 -2
  23. package/esm/types/checker/checks/webrtc-transport.d.ts.map +1 -1
  24. package/esm/types/domain/CallLog.d.ts.map +1 -1
  25. package/esm/types/domain/CallSession.d.ts +3 -3
  26. package/esm/types/domain/CallSession.d.ts.map +1 -1
  27. package/esm/types/domain/Phone/CTIPhone.d.ts.map +1 -1
  28. package/esm/types/domain/Phone/WebRTCPhone.d.ts +22 -22
  29. package/esm/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  30. package/esm/types/domain/types.d.ts +0 -4
  31. package/esm/types/domain/types.d.ts.map +1 -1
  32. package/esm/types/index.d.ts +3 -1
  33. package/esm/types/index.d.ts.map +1 -1
  34. package/esm/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
  35. package/esm/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
  36. package/esm/types/service/CallApi.d.ts +5 -5
  37. package/esm/types/service/CallApi.d.ts.map +1 -1
  38. package/esm/types/simple/Auth.d.ts +6 -1
  39. package/esm/types/simple/Auth.d.ts.map +1 -1
  40. package/esm/types/simple/Phone.d.ts +8 -8
  41. package/esm/types/simple/Phone.d.ts.map +1 -1
  42. package/esm/types/simple/index.d.ts +3 -1
  43. package/esm/types/simple/index.d.ts.map +1 -1
  44. package/esm/types/state-machine/call-state-machine.d.ts +12 -1
  45. package/esm/types/state-machine/call-state-machine.d.ts.map +1 -1
  46. package/esm/types/state-machine/softphone-state-machine.d.ts +1 -2
  47. package/esm/types/state-machine/softphone-state-machine.d.ts.map +1 -1
  48. package/esm/types/state-machine/utils.d.ts +1 -1
  49. package/esm/types/state-machine/utils.d.ts.map +1 -1
  50. package/esm/types/utils/sdp.d.ts +1 -2
  51. package/esm/types/utils/sdp.d.ts.map +1 -1
  52. package/esm/types/utils/update-from.d.ts +1 -1
  53. package/esm/types/utils/update-from.d.ts.map +1 -1
  54. package/esm/types/utils/webrtc.d.ts.map +1 -1
  55. package/esm/types/voice/call.d.ts +15 -3
  56. package/esm/types/voice/call.d.ts.map +1 -1
  57. package/esm/types/voice/softphone.d.ts +7 -0
  58. package/esm/types/voice/softphone.d.ts.map +1 -1
  59. package/esm/types/web-rtc-client.d.ts +39 -38
  60. package/esm/types/web-rtc-client.d.ts.map +1 -1
  61. package/esm/utils/sdp.js +16 -9
  62. package/esm/utils/update-from.js +2 -2
  63. package/esm/utils/webrtc.js +10 -4
  64. package/esm/voice/call.js +86 -28
  65. package/esm/voice/softphone.js +58 -17
  66. package/esm/web-rtc-client.js +67 -58
  67. package/lib/__tests__/__voice__/call.test.js +51 -2
  68. package/lib/api/auth.js +3 -0
  69. package/lib/checker/checks/webrtc.js +1 -1
  70. package/lib/domain/CallLog.js +2 -3
  71. package/lib/domain/Phone/CTIPhone.js +2 -2
  72. package/lib/domain/Phone/WebRTCPhone.js +58 -56
  73. package/lib/index.js +7 -3
  74. package/lib/service/CallApi.js +2 -2
  75. package/lib/simple/Auth.js +15 -3
  76. package/lib/simple/Phone.js +2 -2
  77. package/lib/simple/index.js +2 -1
  78. package/lib/simple/room/Room.js +1 -1
  79. package/lib/simple/room/SipRoom.js +1 -1
  80. package/lib/state-machine/call-state-machine.js +35 -20
  81. package/lib/state-machine/softphone-state-machine.js +1 -2
  82. package/lib/state-machine/utils.js +10 -4
  83. package/lib/types/api/auth.d.ts +3 -0
  84. package/lib/types/api/auth.d.ts.map +1 -1
  85. package/lib/types/checker/checks/index.d.ts +1 -1
  86. package/lib/types/checker/checks/webrtc-transport.d.ts +2 -2
  87. package/lib/types/checker/checks/webrtc-transport.d.ts.map +1 -1
  88. package/lib/types/domain/CallLog.d.ts.map +1 -1
  89. package/lib/types/domain/CallSession.d.ts +3 -3
  90. package/lib/types/domain/CallSession.d.ts.map +1 -1
  91. package/lib/types/domain/Phone/CTIPhone.d.ts.map +1 -1
  92. package/lib/types/domain/Phone/WebRTCPhone.d.ts +22 -22
  93. package/lib/types/domain/Phone/WebRTCPhone.d.ts.map +1 -1
  94. package/lib/types/domain/types.d.ts +0 -4
  95. package/lib/types/domain/types.d.ts.map +1 -1
  96. package/lib/types/index.d.ts +3 -1
  97. package/lib/types/index.d.ts.map +1 -1
  98. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts +3 -3
  99. package/lib/types/lib/WazoSessionDescriptionHandler.d.ts.map +1 -1
  100. package/lib/types/service/CallApi.d.ts +5 -5
  101. package/lib/types/service/CallApi.d.ts.map +1 -1
  102. package/lib/types/simple/Auth.d.ts +6 -1
  103. package/lib/types/simple/Auth.d.ts.map +1 -1
  104. package/lib/types/simple/Phone.d.ts +8 -8
  105. package/lib/types/simple/Phone.d.ts.map +1 -1
  106. package/lib/types/simple/index.d.ts +3 -1
  107. package/lib/types/simple/index.d.ts.map +1 -1
  108. package/lib/types/state-machine/call-state-machine.d.ts +12 -1
  109. package/lib/types/state-machine/call-state-machine.d.ts.map +1 -1
  110. package/lib/types/state-machine/softphone-state-machine.d.ts +1 -2
  111. package/lib/types/state-machine/softphone-state-machine.d.ts.map +1 -1
  112. package/lib/types/state-machine/utils.d.ts +1 -1
  113. package/lib/types/state-machine/utils.d.ts.map +1 -1
  114. package/lib/types/utils/sdp.d.ts +1 -2
  115. package/lib/types/utils/sdp.d.ts.map +1 -1
  116. package/lib/types/utils/update-from.d.ts +1 -1
  117. package/lib/types/utils/update-from.d.ts.map +1 -1
  118. package/lib/types/utils/webrtc.d.ts.map +1 -1
  119. package/lib/types/voice/call.d.ts +15 -3
  120. package/lib/types/voice/call.d.ts.map +1 -1
  121. package/lib/types/voice/softphone.d.ts +7 -0
  122. package/lib/types/voice/softphone.d.ts.map +1 -1
  123. package/lib/types/web-rtc-client.d.ts +39 -38
  124. package/lib/types/web-rtc-client.d.ts.map +1 -1
  125. package/lib/utils/sdp.js +17 -10
  126. package/lib/utils/update-from.js +2 -2
  127. package/lib/utils/webrtc.js +11 -4
  128. package/lib/voice/call.js +89 -27
  129. package/lib/voice/softphone.js +62 -17
  130. package/lib/web-rtc-client.js +66 -57
  131. package/package.json +1 -1
  132. package/src/__tests__/__voice__/call.test.ts +61 -3
  133. package/src/api/auth.ts +5 -0
  134. package/src/checker/checks/webrtc-transport.ts +2 -2
  135. package/src/checker/checks/webrtc.ts +2 -2
  136. package/src/domain/CallLog.ts +2 -3
  137. package/src/domain/CallSession.ts +3 -3
  138. package/src/domain/Phone/CTIPhone.ts +3 -2
  139. package/src/domain/Phone/WebRTCPhone.ts +87 -85
  140. package/src/domain/__tests__/CallSession.test.ts +4 -0
  141. package/src/domain/types.ts +0 -5
  142. package/src/index.ts +4 -1
  143. package/src/lib/WazoSessionDescriptionHandler.ts +3 -3
  144. package/src/service/CallApi.ts +7 -7
  145. package/src/simple/Auth.ts +15 -3
  146. package/src/simple/Phone.ts +11 -11
  147. package/src/simple/index.ts +2 -1
  148. package/src/simple/room/Room.ts +3 -3
  149. package/src/simple/room/SipRoom.ts +3 -3
  150. package/src/state-machine/call-state-machine.ts +38 -19
  151. package/src/state-machine/softphone-state-machine.ts +1 -2
  152. package/src/state-machine/utils.ts +12 -4
  153. package/src/utils/sdp.ts +18 -11
  154. package/src/utils/update-from.ts +2 -2
  155. package/src/utils/webrtc.ts +11 -4
  156. package/src/voice/call.ts +109 -36
  157. package/src/voice/softphone.ts +75 -18
  158. package/src/web-rtc-client.ts +112 -98
@@ -2,7 +2,7 @@
2
2
  import { Inviter, UserAgent } from 'sip.js';
3
3
  import softphone from '../../voice/softphone';
4
4
  import Call from '../../voice/call';
5
- import { Actions, EstablishedStates, States } from '../../state-machine/call-state-machine';
5
+ import { Actions, EstablishedStates, EstablishedSubStates, States } from '../../state-machine/call-state-machine';
6
6
  import { Actions as SoftphoneActions } from '../../state-machine/softphone-state-machine';
7
7
  import ApiCall from '../../domain/Call';
8
8
  import InvalidStateTransition from '../../domain/InvalidStateTransition';
@@ -27,6 +27,9 @@ jest.mock('../..', () => ({
27
27
  }));
28
28
  jest.mock('../../web-rtc-client', () => jest.fn().mockImplementation(() => ({
29
29
  answer: jest.fn(() => Promise.resolve()),
30
+ mute: jest.fn(() => Promise.resolve()),
31
+ hold: jest.fn(() => Promise.resolve()),
32
+ unhold: jest.fn(() => Promise.resolve()),
30
33
  hangup: jest.fn(() => Promise.resolve()),
31
34
  register: jest.fn(() => Promise.resolve()),
32
35
  onCallEnded: jest.fn(() => Promise.resolve()),
@@ -66,9 +69,17 @@ describe('Call', () => {
66
69
  expect(call.id).toBe(apiCall.sipCallId);
67
70
  expect(call.apiId).toBe(apiCall.id);
68
71
  expect(call.number).toBe(apiCall.calleeNumber);
69
- expect(call.answerTime).toStrictEqual(apiCall.startingTime);
72
+ expect(call.answerTime).toStrictEqual(undefined);
73
+ expect(call.creationTime).toStrictEqual(apiCall.startingTime);
70
74
  expect(call.isMuted()).toBeTruthy();
71
- expect(call.state).toStrictEqual({ [States.ESTABLISHED]: EstablishedStates.MUTED });
75
+ expect(call.state).toStrictEqual({
76
+ [States.ESTABLISHED]: {
77
+ [EstablishedStates.ONGOING]: {},
78
+ [EstablishedSubStates.MUTE]: EstablishedStates.MUTED,
79
+ [EstablishedSubStates.HOLD]: EstablishedStates.UN_HELD,
80
+ },
81
+ });
82
+ expect(call.isEstablished()).toBeTruthy();
72
83
  });
73
84
  });
74
85
  describe('accept', () => {
@@ -111,4 +122,42 @@ describe('Call', () => {
111
122
  expect(softphone.client.hangup).toHaveBeenCalled();
112
123
  });
113
124
  });
125
+ describe('state propagation', () => {
126
+ it('Should update the call state in events', (done) => {
127
+ const call = new Call(sipCall, softphone);
128
+ // @ts-ignore: private method
129
+ call._sendAction(Actions.MAKE_CALL);
130
+ call.on('remotelyAccepted', () => {
131
+ expect(call.state).toStrictEqual({
132
+ [States.ESTABLISHED]: {
133
+ [EstablishedStates.ONGOING]: {},
134
+ [EstablishedSubStates.MUTE]: EstablishedStates.UN_MUTED,
135
+ [EstablishedSubStates.HOLD]: EstablishedStates.UN_HELD,
136
+ },
137
+ });
138
+ done();
139
+ });
140
+ call.onAccepted();
141
+ });
142
+ });
143
+ describe('Multiple sub state', () => {
144
+ it('Should mute and hold a call', () => {
145
+ const call = new Call(sipCall, softphone);
146
+ // @ts-ignore: private method
147
+ call._sendAction(Actions.MAKE_CALL);
148
+ expect(call.isMuted()).toBeFalsy();
149
+ expect(call.isHeld()).toBeFalsy();
150
+ // @ts-ignore: private method
151
+ call._sendAction(Actions.REMOTLY_ACCEPTED);
152
+ call.mute();
153
+ expect(call.isMuted()).toBeTruthy();
154
+ expect(call.isHeld()).toBeFalsy();
155
+ call.hold();
156
+ expect(call.isMuted()).toBeTruthy();
157
+ expect(call.isHeld()).toBeTruthy();
158
+ call.resume();
159
+ expect(call.isMuted()).toBeTruthy();
160
+ expect(call.isHeld()).toBeFalsy();
161
+ });
162
+ });
114
163
  });
package/esm/api/auth.js CHANGED
@@ -49,6 +49,9 @@ export default ((client, baseUrl) => ({
49
49
  }
50
50
  return client.post(`${baseUrl}/token`, body, headers).then(Session.parse);
51
51
  },
52
+ samlLogOut() {
53
+ return client.get(`${baseUrl}/saml/logout`, null, null);
54
+ },
52
55
  initiateIdpAuthentication: async (domain, redirectUrl) => {
53
56
  const body = {
54
57
  domain,
@@ -1,5 +1,5 @@
1
1
  /* global MediaStream */
2
- import { getSipSessionId } from '../../utils/sdp';
2
+ import { getSipCallId } from '../../utils/sdp';
3
3
  import WebRTCClient from '../../web-rtc-client';
4
4
  export default {
5
5
  name: 'WebRTC',
@@ -29,7 +29,7 @@ export default {
29
29
  });
30
30
  client.on(client.REGISTERED, () => {
31
31
  const sipSession = client.call('*10');
32
- if (!sipSession || !getSipSessionId(sipSession)) {
32
+ if (!sipSession || !getSipCallId(sipSession)) {
33
33
  return handleError('Unable to make call through WebRTC');
34
34
  }
35
35
  setTimeout(() => {
@@ -53,8 +53,7 @@ export default class CallLog {
53
53
  }
54
54
  static parseNew(plain, session) {
55
55
  const callLog = CallLog.parse(plain);
56
- // @TODO: FIXME add verification declined vs missed call
57
- callLog.newMissedCall = session && session.hasExtension((plain.requested_extension || plain.destination_extension)) && !plain.answered;
56
+ callLog.newMissedCall = session && plain.destination_user_uuid === session.uuid && !plain.answered;
58
57
  return callLog;
59
58
  }
60
59
  static newFrom(profile) {
@@ -112,7 +111,7 @@ export default class CallLog {
112
111
  return this.callDirection === 'inbound';
113
112
  }
114
113
  isAnOutgoingCall(session) {
115
- console.warn(`@wazo/sdk
114
+ console.warn(`@wazo/sdk
116
115
  CallLog.isAnOutgoingcall(session) method is obsolete.
117
116
  Please use CallLog.isOutgoing(session).
118
117
  `);
@@ -105,7 +105,7 @@ export default class CTIPhone extends Emitter {
105
105
  number: callSession.number,
106
106
  });
107
107
  try {
108
- await CallApi.cancelCall(callSession);
108
+ await CallApi.cancelCall({ apiId: callSession.getId() });
109
109
  if (this.currentCall && callSession.callId === this.currentCall.id) {
110
110
  this.endCurrentCall(callSession);
111
111
  }
@@ -127,7 +127,7 @@ export default class CTIPhone extends Emitter {
127
127
  callId: callSession.getId(),
128
128
  number: callSession.number,
129
129
  });
130
- await CallApi.cancelCall(callSession);
130
+ await CallApi.cancelCall({ id: callSession.getId() });
131
131
  this.eventEmitter.emit('onCallEnded', callSession);
132
132
  }
133
133
  async transfer(callSession, number) {
@@ -3,7 +3,7 @@ import { Invitation } from 'sip.js/lib/api';
3
3
  import CallSession from '../CallSession';
4
4
  import Emitter from '../../utils/Emitter';
5
5
  import IssueReporter from '../../service/IssueReporter';
6
- import { getCallDisplayName, getCallNumber, getSipSessionId } from '../../utils/sdp';
6
+ import { getCallDisplayName, getCallNumber, getSipCallId } from '../../utils/sdp';
7
7
  import { downgradeToAudio, getStreamFromConstraints, getWebRtcStats, setLocalMediaStream, upgradeToVideo } from '../../utils/webrtc';
8
8
  export const ON_USER_AGENT = 'onUserAgent';
9
9
  export const ON_REGISTERED = 'onRegistered';
@@ -126,7 +126,7 @@ export default class WebRTCPhone extends Emitter {
126
126
  async sendReinvite(callSession, constraints = null, conference = false, audioOnly = false, iceRestart = false) {
127
127
  const sipSession = this.findSipSession(callSession);
128
128
  logger.info('WebRTC phone - send reinvite', {
129
- sessionId: sipSession ? sipSession.id : null,
129
+ sessionId: getSipCallId(sipSession),
130
130
  constraints,
131
131
  audioOnly,
132
132
  conference,
@@ -280,7 +280,7 @@ export default class WebRTCPhone extends Emitter {
280
280
  content: {
281
281
  type: ON_MESSAGE_TRACK_UPDATED,
282
282
  update: isUpgrade ? 'upgrade' : 'downgrade',
283
- sipCallId: sipSession && getSipSessionId(sipSession),
283
+ sipCallId: sipSession && getSipCallId(sipSession),
284
284
  callId: callSession ? callSession.callId : null,
285
285
  number: callSession ? callSession.number : null,
286
286
  },
@@ -288,7 +288,7 @@ export default class WebRTCPhone extends Emitter {
288
288
  }, 2500);
289
289
  }
290
290
  _bindEvents(sipSession) {
291
- const sipSessionId = getSipSessionId(sipSession);
291
+ const sipSessionId = getSipCallId(sipSession);
292
292
  if (sipSession instanceof Invitation) {
293
293
  // Monkey patch to know when canceled with the CANCEL message
294
294
  const onCancel = sipSession._onCancel.bind(sipSession);
@@ -300,7 +300,9 @@ export default class WebRTCPhone extends Emitter {
300
300
  onCancel(message);
301
301
  const elsewhere = message.data.indexOf('cause=26') !== -1 && message.data.indexOf('completed elsewhere') !== -1;
302
302
  const callSession = this._createCallSession(sipSession);
303
- delete this.callSessions[sipSessionId];
303
+ if (sipSessionId) {
304
+ delete this.callSessions[sipSessionId];
305
+ }
304
306
  this.eventEmitter.emit(ON_CALL_CANCELED, callSession, elsewhere);
305
307
  };
306
308
  }
@@ -308,14 +310,14 @@ export default class WebRTCPhone extends Emitter {
308
310
  switch (newState) {
309
311
  case SessionState.Terminating:
310
312
  logger.info('WebRTC phone - call terminating', {
311
- sipId: sipSession.id,
313
+ sipId: getSipCallId(sipSession),
312
314
  });
313
315
  this.eventEmitter.emit(ON_CALL_ENDING, this._createCallSession(sipSession));
314
316
  break;
315
317
  case SessionState.Terminated:
316
318
  {
317
319
  logger.info('WebRTC phone - call terminated', {
318
- sipId: sipSession.id,
320
+ sipId: getSipCallId(sipSession),
319
321
  });
320
322
  // Should be called before `_onCallTerminated` or the callCount will not decrement...
321
323
  const callSession = this._createCallSession(sipSession);
@@ -342,7 +344,7 @@ export default class WebRTCPhone extends Emitter {
342
344
  const [stream] = event.streams;
343
345
  const kind = event && event.track && event.track.kind;
344
346
  logger.info('on track stream called on the peer connection', {
345
- callId: getSipSessionId(sipSession),
347
+ callId: getSipCallId(sipSession),
346
348
  streamId: stream ? stream.id : null,
347
349
  tracks: stream ? stream.getTracks() : null,
348
350
  kind,
@@ -371,9 +373,9 @@ export default class WebRTCPhone extends Emitter {
371
373
  }
372
374
  const screenTrack = screenShareStream.getVideoTracks()[0];
373
375
  const sipSession = this.currentSipSession;
374
- const pc = sipSession && this.client.getPeerConnection(getSipSessionId(sipSession));
376
+ const pc = sipSession && this.client.getPeerConnection(getSipCallId(sipSession));
375
377
  const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
376
- const localStream = sipSession && this.client.getLocalStream(getSipSessionId(sipSession));
378
+ const localStream = sipSession && this.client.getLocalStream(getSipCallId(sipSession));
377
379
  const videoTrack = localStream ? localStream.getTracks().find(track => track.kind === 'video') : null;
378
380
  const hadVideo = !!videoTrack;
379
381
  // Stop local video tracks
@@ -435,19 +437,19 @@ export default class WebRTCPhone extends Emitter {
435
437
  }
436
438
  _onScreenSharing(screenStream, sipSession, callSession, hadVideo, desktop) {
437
439
  const screenTrack = screenStream.getVideoTracks()[0];
438
- const sipSessionId = getSipSessionId(sipSession);
440
+ const sipSessionId = getSipCallId(sipSession);
439
441
  const pc = this.client.getPeerConnection(sipSessionId);
440
442
  const sender = pc && pc.getSenders && pc.getSenders().find((s) => s && s.track && s.track.kind === 'video');
441
443
  logger.info('WebRTC phone - on screensharing', {
442
444
  hadVideo,
443
- id: getSipSessionId(sipSession),
445
+ id: getSipCallId(sipSession),
444
446
  screenTrack,
445
447
  });
446
448
  if (screenTrack) {
447
449
  screenTrack.onended = () => {
448
450
  logger.info('WebRTC phone - on screenshare ended', {
449
451
  hadVideo,
450
- id: getSipSessionId(sipSession),
452
+ id: getSipCallId(sipSession),
451
453
  screenTrack,
452
454
  });
453
455
  this.eventEmitter.emit(ON_SHARE_SCREEN_ENDING, this._createCallSession(sipSession, callSession));
@@ -467,13 +469,13 @@ export default class WebRTCPhone extends Emitter {
467
469
  }
468
470
  _onCallAccepted(sipSession, cameraEnabled) {
469
471
  logger.info('WebRTC phone - on call accepted', {
470
- sipId: sipSession.id,
472
+ sipId: getSipCallId(sipSession),
471
473
  cameraEnabled,
472
474
  });
473
475
  const callSession = this._createAcceptedCallSession(sipSession, cameraEnabled);
474
476
  if (this.currentSipSession && !this.isCurrentCallSipSession(callSession)) {
475
477
  logger.info('WebRTC phone - on call accepted with another ongoing call, holding it', {
476
- sipId: sipSession.id,
478
+ sipId: getSipCallId(sipSession),
477
479
  cameraEnabled,
478
480
  });
479
481
  this.holdSipSession(this.currentSipSession, this.currentCallSession, true);
@@ -481,7 +483,7 @@ export default class WebRTCPhone extends Emitter {
481
483
  this.currentSipSession = sipSession;
482
484
  this.currentCallSession = callSession;
483
485
  this.eventEmitter.emit(ON_TERMINATE_SOUND, callSession, 'call accepted');
484
- const sipSessionId = getSipSessionId(sipSession);
486
+ const sipSessionId = getSipCallId(sipSession);
485
487
  if (sipSessionId) {
486
488
  this.removeIncomingSessions(sipSessionId);
487
489
  }
@@ -540,9 +542,9 @@ export default class WebRTCPhone extends Emitter {
540
542
  return this.currentSipSession && this.client.changeSessionVideoInputDevice(id, this.currentSipSession);
541
543
  }
542
544
  _onCallTerminated(sipSession) {
543
- const sipSessionId = getSipSessionId(sipSession);
545
+ const sipSessionId = getSipCallId(sipSession);
544
546
  logger.info('WebRTC phone - on call terminated', {
545
- sipId: sipSession.id,
547
+ sipId: getSipCallId(sipSession),
546
548
  sipSessionId,
547
549
  ids: Object.keys(this.callSessions),
548
550
  });
@@ -562,8 +564,8 @@ export default class WebRTCPhone extends Emitter {
562
564
  }
563
565
  if (sipSessionId) {
564
566
  this.removeIncomingSessions(sipSessionId);
567
+ delete this.callSessions[sipSessionId];
565
568
  }
566
- delete this.callSessions[sipSessionId];
567
569
  if (isCurrentSession) {
568
570
  this.currentSipSession = undefined;
569
571
  this.currentCallSession = undefined;
@@ -571,7 +573,7 @@ export default class WebRTCPhone extends Emitter {
571
573
  const hasIncomingCallSession = this.hasIncomingCallSession();
572
574
  // Re-trigger incoming call event for remaining incoming calls
573
575
  logger.info('WebRTC phone - check to re-trigger incoming call', {
574
- sipId: sipSession.id,
576
+ sipId: getSipCallId(sipSession),
575
577
  shouldRetrigger,
576
578
  hasIncomingCallSession,
577
579
  });
@@ -632,7 +634,7 @@ export default class WebRTCPhone extends Emitter {
632
634
  if (!this.currentSipSession) {
633
635
  return false;
634
636
  }
635
- return this.currentSipSession && getSipSessionId(this.currentSipSession) === callSession.getId();
637
+ return this.currentSipSession && getSipCallId(this.currentSipSession) === callSession.getId();
636
638
  }
637
639
  hasVideo(callSession) {
638
640
  return this.client.hasVideo(callSession.getId());
@@ -666,7 +668,7 @@ export default class WebRTCPhone extends Emitter {
666
668
  logger.warn('no CallSession to accept.');
667
669
  return Promise.resolve(null);
668
670
  }
669
- const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
671
+ const sipSessionId = this.getSipCallIdFromCallSession(callSession);
670
672
  if (sipSessionId && !(sipSessionId in this.callSessions)) {
671
673
  logger.warn('Call session already ended or not found, can\'t accept it.', {
672
674
  sipSessionId,
@@ -686,7 +688,7 @@ export default class WebRTCPhone extends Emitter {
686
688
  this.eventEmitter.emit(ON_CALL_ANSWERED, callSession);
687
689
  const sipSession = this.client.getSipSession(callSession.getId());
688
690
  if (sipSession) {
689
- logger.info('accept call, session found', { sipId: sipSession.id });
691
+ logger.info('accept call, session found', { sipId: getSipCallId(sipSession) });
690
692
  return this.client.answer(sipSession, this.allowVideo ? cameraEnabled : false).then(() => {
691
693
  return callSession.sipCallId;
692
694
  }).catch(e => {
@@ -698,7 +700,7 @@ export default class WebRTCPhone extends Emitter {
698
700
  const error = 'No CallSession found to accept.';
699
701
  logger.warn(error, {
700
702
  id: callSession ? callSession.getId() : 'n/a',
701
- ids: this.client.getSipSessionIds(),
703
+ ids: this.client.getSipCallIds(),
702
704
  });
703
705
  if (callSession) {
704
706
  this.eventEmitter.emit(ON_CALL_ERROR, new Error(error), callSession);
@@ -721,7 +723,7 @@ export default class WebRTCPhone extends Emitter {
721
723
  const sipSession = this.findSipSession(callSession);
722
724
  if (sipSession) {
723
725
  logger.info('WebRTC rejecting', {
724
- sipId: sipSession.id,
726
+ sipId: getSipCallId(sipSession),
725
727
  });
726
728
  this.client.hangup(sipSession);
727
729
  }
@@ -739,7 +741,7 @@ export default class WebRTCPhone extends Emitter {
739
741
  const sipSession = this.findSipSession(callSession);
740
742
  if (sipSession) {
741
743
  logger.info('WebRTC atxfer', {
742
- sipId: sipSession.id,
744
+ sipId: getSipCallId(sipSession),
743
745
  });
744
746
  return this.client.atxfer(sipSession);
745
747
  }
@@ -765,12 +767,12 @@ export default class WebRTCPhone extends Emitter {
765
767
  return new Promise((resolve, reject) => reject(new Error('No session to resume')));
766
768
  }
767
769
  logger.info('WebRTC resuming', {
768
- sipId: sipSession.id,
770
+ sipId: getSipCallId(sipSession),
769
771
  });
770
772
  // Hold current session if different from the current one (we don't want 2 sessions active at the same time).
771
- if (this.currentSipSession && this.currentSipSession.id !== sipSession.id) {
773
+ if (this.currentSipSession && getSipCallId(this.currentSipSession) !== getSipCallId(sipSession)) {
772
774
  logger.info('WebRTC hold call after resume', {
773
- id: this.currentSipSession.id,
775
+ id: getSipCallId(this.currentSipSession),
774
776
  });
775
777
  this.holdSipSession(this.currentSipSession, this.currentCallSession, withEvent);
776
778
  }
@@ -785,10 +787,10 @@ export default class WebRTCPhone extends Emitter {
785
787
  if (!sipSession) {
786
788
  return new Promise((resolve, reject) => reject(new Error('No session to hold')));
787
789
  }
788
- const sessionId = getSipSessionId(sipSession);
790
+ const sessionId = getSipCallId(sipSession);
789
791
  const hasVideo = this.client.hasLocalVideo(sessionId);
790
792
  logger.info('WebRTC hold sip session', {
791
- sipId: sipSession.id,
793
+ sipId: getSipCallId(sipSession),
792
794
  hasVideo,
793
795
  });
794
796
  // Stop screenshare if needed
@@ -812,7 +814,7 @@ export default class WebRTCPhone extends Emitter {
812
814
  return new Promise((resolve, reject) => reject(new Error('No session to unhold')));
813
815
  }
814
816
  const isConference = !!callSession && callSession.isConference();
815
- const sessionId = getSipSessionId(sipSession);
817
+ const sessionId = getSipCallId(sipSession);
816
818
  logger.info('WebRTC unhold sip session', {
817
819
  sessionId,
818
820
  isConference,
@@ -864,7 +866,7 @@ export default class WebRTCPhone extends Emitter {
864
866
  return;
865
867
  }
866
868
  logger.info('WebRTC muting', {
867
- sipId: sipSession.id,
869
+ sipId: getSipCallId(sipSession),
868
870
  });
869
871
  this.client.mute(sipSession);
870
872
  const newCallSession = this._createCallSession(sipSession, callSession, {
@@ -886,7 +888,7 @@ export default class WebRTCPhone extends Emitter {
886
888
  return;
887
889
  }
888
890
  logger.info('WebRTC unmuting', {
889
- sipId: sipSession.id,
891
+ sipId: getSipCallId(sipSession),
890
892
  });
891
893
  this.client.unmute(sipSession);
892
894
  const newCallSession = this._createCallSession(sipSession, callSession, {
@@ -912,7 +914,7 @@ export default class WebRTCPhone extends Emitter {
912
914
  return;
913
915
  }
914
916
  logger.info('WebRTC turn camera on', {
915
- sipId: sipSession.id,
917
+ sipId: getSipCallId(sipSession),
916
918
  });
917
919
  this.client.toggleCameraOn(sipSession);
918
920
  this.eventEmitter.emit(ON_CAMERA_RESUMED, this._createCameraResumedCallSession(sipSession, callSession));
@@ -923,7 +925,7 @@ export default class WebRTCPhone extends Emitter {
923
925
  return;
924
926
  }
925
927
  logger.info('WebRTC turn camera off', {
926
- sipId: sipSession.id,
928
+ sipId: getSipCallId(sipSession),
927
929
  });
928
930
  this.client.toggleCameraOff(sipSession);
929
931
  this.eventEmitter.emit(ON_CAMERA_DISABLED, this._createCameraDisabledCallSession(sipSession, callSession));
@@ -934,7 +936,7 @@ export default class WebRTCPhone extends Emitter {
934
936
  return;
935
937
  }
936
938
  logger.info('WebRTC send key', {
937
- sipId: sipSession.id,
939
+ sipId: getSipCallId(sipSession),
938
940
  tone,
939
941
  });
940
942
  this.client.sendDTMF(sipSession, tone);
@@ -997,7 +999,7 @@ export default class WebRTCPhone extends Emitter {
997
999
  return;
998
1000
  }
999
1001
  logger.info('WebRTC transfer', {
1000
- sipId: sipSession.id,
1002
+ sipId: getSipCallId(sipSession),
1001
1003
  target,
1002
1004
  });
1003
1005
  this.client.transfer(sipSession, target);
@@ -1006,8 +1008,8 @@ export default class WebRTCPhone extends Emitter {
1006
1008
  const sipSession = this.client.getSipSession(source.sipCallId);
1007
1009
  const sipSessionTarget = this.client.getSipSession(destination.sipCallId);
1008
1010
  logger.info('WebRTC indirect transfer', {
1009
- sipId: sipSession ? sipSession.id : null,
1010
- target: sipSessionTarget ? sipSessionTarget.id : null,
1011
+ sipId: sipSession ? getSipCallId(sipSession) : null,
1012
+ target: sipSessionTarget ? getSipCallId(sipSessionTarget) : null,
1011
1013
  });
1012
1014
  if (!sipSessionTarget) {
1013
1015
  return Promise.reject();
@@ -1035,9 +1037,9 @@ export default class WebRTCPhone extends Emitter {
1035
1037
  console.error('Call is unknown to the WebRTC phone', callSession ? callSession.sipCallId : null, callSession ? callSession.callId : null);
1036
1038
  return false;
1037
1039
  }
1038
- const sipSessionId = getSipSessionId(sipSession);
1040
+ const sipSessionId = getSipCallId(sipSession);
1039
1041
  logger.info('WebRTC hangup', {
1040
- sipId: sipSession.id,
1042
+ sipId: getSipCallId(sipSession),
1041
1043
  sipSessionId,
1042
1044
  });
1043
1045
  await this.client.hangup(sipSession);
@@ -1190,7 +1192,7 @@ export default class WebRTCPhone extends Emitter {
1190
1192
  const autoAnswer = sipSession.request.getHeader('Answer-Mode') === 'Auto';
1191
1193
  const withVideo = this.allowVideo ? wantsToDoVideo : false;
1192
1194
  logger.info('WebRTC invite received', {
1193
- sipId: sipSession.id,
1195
+ sipId: getSipCallId(sipSession),
1194
1196
  withVideo,
1195
1197
  autoAnswer,
1196
1198
  });
@@ -1222,12 +1224,12 @@ export default class WebRTCPhone extends Emitter {
1222
1224
  // if `_createCallSession` is called too soon `hasVideo` will return false because the stream doesn't exists yet
1223
1225
  setTimeout(() => {
1224
1226
  // Update callSession
1225
- this._createCallSession(sipSession, this.callSessions[getSipSessionId(sipSession)]);
1227
+ this._createCallSession(sipSession, this.callSessions[getSipCallId(sipSession)]);
1226
1228
  this.eventEmitter.emit.apply(this.eventEmitter, [this.client.ON_REINVITE, ...args]);
1227
1229
  }, 2000);
1228
1230
  });
1229
1231
  this.client.on(this.client.ACCEPTED, async (sipSession) => {
1230
- const sessionId = getSipSessionId(sipSession);
1232
+ const sessionId = getSipCallId(sipSession);
1231
1233
  const hasSession = (sessionId in this.callSessions);
1232
1234
  logger.info('WebRTC call accepted', {
1233
1235
  sipId: sessionId,
@@ -1250,11 +1252,11 @@ export default class WebRTCPhone extends Emitter {
1250
1252
  this.eventEmitter.emit(ON_CALL_ERROR, e);
1251
1253
  });
1252
1254
  this.client.on(this.client.REJECTED, session => {
1253
- logger.info('WebRTC call rejected', session.id);
1255
+ logger.info('WebRTC call rejected', { id: getSipCallId(session) });
1254
1256
  const callSession = this._createCallSession(session);
1255
1257
  // `_createCallSession` add the CallSession in `this.callSessions`.
1256
1258
  // so we have to remove it or `callCount` will always return 1 even if the call was rejected
1257
- delete this.callSessions[getSipSessionId(session)];
1259
+ delete this.callSessions[getSipCallId(session)];
1258
1260
  callSession.endTime = new Date();
1259
1261
  this.eventEmitter.emit(ON_CALL_REJECTED, callSession);
1260
1262
  });
@@ -1271,7 +1273,7 @@ export default class WebRTCPhone extends Emitter {
1271
1273
  const callSession = this._createCallSession(session, null, {
1272
1274
  incoming: false,
1273
1275
  ringing: true,
1274
- callId: getSipSessionId(session),
1276
+ callId: getSipCallId(session),
1275
1277
  });
1276
1278
  this.eventEmitter.emit(ON_PROGRESS, callSession, this.audioOutputDeviceId, this.audioOutputVolume);
1277
1279
  });
@@ -1280,7 +1282,7 @@ export default class WebRTCPhone extends Emitter {
1280
1282
  const callSession = this._createCallSession(session, null, {
1281
1283
  incoming: false,
1282
1284
  ringing: true,
1283
- callId: getSipSessionId(session),
1285
+ callId: getSipCallId(session),
1284
1286
  });
1285
1287
  this.eventEmitter.emit(ON_EARLY_MEDIA, callSession, this.audioOutputDeviceId, this.audioOutputVolume);
1286
1288
  });
@@ -1336,12 +1338,12 @@ export default class WebRTCPhone extends Emitter {
1336
1338
  this.eventEmitter.emit(ON_MESSAGE, message);
1337
1339
  });
1338
1340
  this.client.on(this.client.ON_NETWORK_STATS, (session, stats, previousStats) => {
1339
- const callSession = this.getCallSession(getSipSessionId(session));
1341
+ const callSession = this.getCallSession(getSipCallId(session));
1340
1342
  this.eventEmitter.emit(ON_NETWORK_STATS, callSession, stats, previousStats);
1341
1343
  });
1342
1344
  // Used when upgrading directly in screenshare mode
1343
1345
  this.client.on(this.client.ON_SCREEN_SHARING_REINVITE, (sipSession, response, desktop) => {
1344
- const sipSessionId = getSipSessionId(sipSession);
1346
+ const sipSessionId = getSipCallId(sipSession);
1345
1347
  const localStream = this.client.getLocalStream(sipSessionId);
1346
1348
  const callSession = this.callSessions[sipSessionId];
1347
1349
  logger.info('Updrading directly in screensharing mode', {
@@ -1353,10 +1355,10 @@ export default class WebRTCPhone extends Emitter {
1353
1355
  }
1354
1356
  // Find a corresponding sipSession from a CallSession
1355
1357
  findSipSession(callSession) {
1356
- const keys = this.client.getSipSessionIds();
1358
+ const keys = this.client.getSipCallIds();
1357
1359
  const keyIndex = keys.findIndex(sessionId => callSession && callSession.isId(sessionId));
1358
1360
  if (keyIndex === -1) {
1359
- const currentSipSessionId = this.currentSipSession ? getSipSessionId(this.currentSipSession) : this.client.getSipSessionIds()[0];
1361
+ const currentSipSessionId = this.currentSipSession ? getSipCallId(this.currentSipSession) : this.client.getSipCallIds()[0];
1360
1362
  return currentSipSessionId ? this.client.getSipSession(currentSipSessionId) : null;
1361
1363
  }
1362
1364
  return this.client.getSipSession(keys[keyIndex]);
@@ -1364,12 +1366,12 @@ export default class WebRTCPhone extends Emitter {
1364
1366
  getCallSession(sipSessionId) {
1365
1367
  return this.callSessions[sipSessionId];
1366
1368
  }
1367
- getSipSessionIdFromCallSession(callSession) {
1369
+ getSipCallIdFromCallSession(callSession) {
1368
1370
  const sipSession = this.findSipSession(callSession);
1369
- return sipSession ? getSipSessionId(sipSession) : null;
1371
+ return sipSession ? getSipCallId(sipSession) : null;
1370
1372
  }
1371
1373
  _updateCallSession(callSession) {
1372
- const sipSessionId = this.getSipSessionIdFromCallSession(callSession);
1374
+ const sipSessionId = this.getSipCallIdFromCallSession(callSession);
1373
1375
  if (sipSessionId) {
1374
1376
  this.callSessions[sipSessionId] = callSession;
1375
1377
  }
@@ -1442,7 +1444,7 @@ export default class WebRTCPhone extends Emitter {
1442
1444
  const number = getCallNumber(sipSession);
1443
1445
  const displayName = getCallDisplayName(sipSession);
1444
1446
  const { state } = sipSession || {};
1445
- const sessionId = getSipSessionId(sipSession);
1447
+ const sessionId = getSipCallId(sipSession);
1446
1448
  fromSession = fromSession || this.callSessions[sessionId];
1447
1449
  const callSession = new CallSession({
1448
1450
  callId: fromSession && fromSession.callId,
package/esm/index.js CHANGED
@@ -6,7 +6,7 @@ export { default as ServerError } from './domain/ServerError';
6
6
  export { default as InvalidStateTransition } from './domain/InvalidStateTransition';
7
7
  export { default as InvalidState } from './domain/InvalidState';
8
8
  export { default as SFUNotAvailableError } from './domain/SFUNotAvailableError';
9
- export { default as Call } from './domain/Call';
9
+ export { default as ApiCall } from './domain/Call';
10
10
  export { default as CallLog } from './domain/CallLog';
11
11
  export { default as Recording } from './domain/Recording';
12
12
  export { default as ChatMessage } from './domain/ChatMessage';
@@ -45,6 +45,8 @@ export { default as WazoApiClient } from './api-client';
45
45
  export { default as Agent } from './domain/Agent';
46
46
  export { default as ExternalApp } from './domain/ExternalApp';
47
47
  export { default as SessionDescriptionHandler } from './lib/WazoSessionDescriptionHandler';
48
+ export { default as Call } from './voice/call';
49
+ export { Softphone } from './voice/softphone';
48
50
  export * from './types/WebSocketMessage';
49
51
  export * from './utils/PhoneNumberUtil';
50
52
  export * from './utils/string';
@@ -1,4 +1,4 @@
1
- import Call from '../domain/Call';
1
+ import ApiCall from '../domain/Call';
2
2
  import getApiClient from './getApiClient';
3
3
  export default class CallApi {
4
4
  static async fetchCallLogs(offset, limit) {
@@ -23,13 +23,13 @@ export default class CallApi {
23
23
  const lineToUse = line || session.primaryLine();
24
24
  return getApiClient().confd.getUserLineSip(session.uuid, lineToUse ? lineToUse.id : '');
25
25
  }
26
- static async cancelCall(callSession) {
27
- return getApiClient().calld.cancelCall(callSession.callId);
26
+ static async cancelCall(call) {
27
+ return getApiClient().calld.cancelCall(call.apiId || '');
28
28
  }
29
29
  static async makeCall(callFromLine, extension, isMobile = false, callbackAllLines = false) {
30
30
  const lineId = callFromLine ? callFromLine.id : null;
31
31
  const response = await getApiClient().calld.makeCall(extension, isMobile, lineId, callbackAllLines);
32
- return Call.parse(response);
32
+ return ApiCall.parse(response);
33
33
  }
34
34
  static async relocateCall(callId, line, contactIdentifier) {
35
35
  return getApiClient().calld.relocateCall(callId, 'line', line, contactIdentifier);