@wazo/sdk 0.37.0 → 0.37.4

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 (144) hide show
  1. package/dist/wazo-sdk.js +5 -5
  2. package/esm/__tests__/api-client.test.js +91 -23
  3. package/esm/__tests__/web-rtc-client.test.js +165 -56
  4. package/esm/api/agentd.js +7 -1
  5. package/esm/api/amid.js +7 -1
  6. package/esm/api/application.js +7 -1
  7. package/esm/api/auth.js +7 -1
  8. package/esm/api/call-logd.js +17 -23
  9. package/esm/api/calld.js +10 -18
  10. package/esm/api/chatd.js +7 -1
  11. package/esm/api/confd.js +78 -1
  12. package/esm/api/ctid-ng.js +7 -1
  13. package/esm/api/dird.js +7 -1
  14. package/esm/api/webhookd.js +7 -1
  15. package/esm/api-client.js +91 -23
  16. package/esm/checker/Checker.js +169 -56
  17. package/esm/checker/checks/aor.js +91 -23
  18. package/esm/checker/checks/api.js +91 -23
  19. package/esm/checker/checks/index.js +169 -56
  20. package/esm/checker/checks/wazo-websocket.js +11 -1
  21. package/esm/checker/checks/webrtc-transport.js +165 -56
  22. package/esm/checker/checks/webrtc.js +165 -56
  23. package/esm/domain/AdHocAPIConference.js +1722 -1654
  24. package/esm/domain/CallLog.js +10 -22
  25. package/esm/domain/CallSession.js +1 -18
  26. package/esm/domain/Features.js +91 -23
  27. package/esm/domain/IndirectTransfer.js +0 -17
  28. package/esm/domain/Meeting.js +71 -0
  29. package/esm/domain/Phone/CTIPhone.js +98 -26
  30. package/esm/domain/Phone/Phone.js +0 -17
  31. package/esm/domain/Phone/WebRTCPhone.js +47 -27
  32. package/esm/domain/Room.js +0 -17
  33. package/esm/domain/SwitchboardCall.js +0 -17
  34. package/esm/domain/__tests__/CallLog.test.js +10 -22
  35. package/esm/domain/__tests__/CallSession.test.js +1 -18
  36. package/esm/domain/__tests__/IndirectTransfer.test.js +1 -18
  37. package/esm/domain/__tests__/Room.test.js +1 -18
  38. package/esm/index.js +3880 -3111
  39. package/esm/lib/WazoSessionDescriptionHandler.js +24 -10
  40. package/esm/service/CallApi.js +91 -23
  41. package/esm/service/IssueReporter.js +7 -1
  42. package/esm/service/__tests__/IssueReporter.test.js +9 -1
  43. package/esm/service/getApiClient.js +91 -23
  44. package/esm/simple/Auth.js +1126 -360
  45. package/esm/simple/Configuration.js +1126 -360
  46. package/esm/simple/Directory.js +91 -23
  47. package/esm/simple/Phone.js +3724 -2958
  48. package/esm/simple/Websocket.js +13 -1
  49. package/esm/simple/index.js +1128 -362
  50. package/esm/simple/room/LocalParticipant.js +1097 -331
  51. package/esm/simple/room/Participant.js +1097 -331
  52. package/esm/simple/room/RemoteParticipant.js +1097 -331
  53. package/esm/simple/room/Room.js +1097 -331
  54. package/esm/simple/room/SipRoom.js +12996 -0
  55. package/esm/simple/room/Stream.js +1128 -362
  56. package/esm/simple/room/__tests__/RemoteParticipant.test.js +5157 -4389
  57. package/esm/simple/utils.js +1128 -362
  58. package/esm/utils/__tests__/api-requester.test.js +7 -1
  59. package/esm/utils/api-requester.js +7 -1
  60. package/esm/web-rtc-client.js +165 -56
  61. package/esm/websocket-client.js +12 -2
  62. package/lib/__tests__/api-client.test.js +91 -23
  63. package/lib/__tests__/web-rtc-client.test.js +165 -56
  64. package/lib/api/agentd.js +7 -1
  65. package/lib/api/amid.js +7 -1
  66. package/lib/api/application.js +7 -1
  67. package/lib/api/auth.js +7 -1
  68. package/lib/api/call-logd.js +17 -23
  69. package/lib/api/calld.js +10 -18
  70. package/lib/api/chatd.js +7 -1
  71. package/lib/api/confd.js +78 -1
  72. package/lib/api/ctid-ng.js +7 -1
  73. package/lib/api/dird.js +7 -1
  74. package/lib/api/webhookd.js +7 -1
  75. package/lib/api-client.js +91 -23
  76. package/lib/checker/Checker.js +169 -56
  77. package/lib/checker/checks/aor.js +91 -23
  78. package/lib/checker/checks/api.js +91 -23
  79. package/lib/checker/checks/index.js +169 -56
  80. package/lib/checker/checks/wazo-websocket.js +11 -1
  81. package/lib/checker/checks/webrtc-transport.js +165 -56
  82. package/lib/checker/checks/webrtc.js +165 -56
  83. package/lib/domain/AdHocAPIConference.js +1722 -1654
  84. package/lib/domain/CallLog.js +10 -22
  85. package/lib/domain/CallSession.js +1 -18
  86. package/lib/domain/Features.js +91 -23
  87. package/lib/domain/IndirectTransfer.js +0 -17
  88. package/lib/domain/Meeting.js +73 -0
  89. package/lib/domain/Phone/CTIPhone.js +98 -26
  90. package/lib/domain/Phone/Phone.js +0 -16
  91. package/lib/domain/Phone/WebRTCPhone.js +47 -27
  92. package/lib/domain/Room.js +0 -17
  93. package/lib/domain/SwitchboardCall.js +0 -17
  94. package/lib/domain/__tests__/CallLog.test.js +10 -22
  95. package/lib/domain/__tests__/CallSession.test.js +1 -18
  96. package/lib/domain/__tests__/IndirectTransfer.test.js +1 -18
  97. package/lib/domain/__tests__/Room.test.js +1 -18
  98. package/lib/index.js +3880 -3111
  99. package/lib/lib/WazoSessionDescriptionHandler.js +24 -10
  100. package/lib/service/CallApi.js +91 -23
  101. package/lib/service/IssueReporter.js +7 -1
  102. package/lib/service/__tests__/IssueReporter.test.js +9 -1
  103. package/lib/service/getApiClient.js +91 -23
  104. package/lib/simple/Auth.js +1126 -360
  105. package/lib/simple/Configuration.js +1126 -360
  106. package/lib/simple/Directory.js +91 -23
  107. package/lib/simple/Phone.js +3724 -2958
  108. package/lib/simple/Websocket.js +13 -1
  109. package/lib/simple/index.js +1128 -362
  110. package/lib/simple/room/LocalParticipant.js +1097 -331
  111. package/lib/simple/room/Participant.js +1097 -331
  112. package/lib/simple/room/RemoteParticipant.js +1097 -331
  113. package/lib/simple/room/Room.js +1097 -331
  114. package/lib/simple/room/SipRoom.js +13006 -0
  115. package/lib/simple/room/Stream.js +1128 -362
  116. package/lib/simple/room/__tests__/RemoteParticipant.test.js +5157 -4389
  117. package/lib/simple/utils.js +1128 -362
  118. package/lib/utils/__tests__/api-requester.test.js +7 -1
  119. package/lib/utils/api-requester.js +7 -1
  120. package/lib/web-rtc-client.js +165 -56
  121. package/lib/websocket-client.js +13 -1
  122. package/package.json +1 -1
  123. package/src/api/calld.js +3 -0
  124. package/src/api/confd.js +13 -0
  125. package/src/domain/CallLog.js +10 -22
  126. package/src/domain/CallSession.js +1 -2
  127. package/src/domain/Meeting.js +59 -0
  128. package/src/domain/Phone/CTIPhone.js +6 -2
  129. package/src/domain/Phone/Phone.js +2 -0
  130. package/src/domain/Phone/WebRTCPhone.js +22 -8
  131. package/src/index.js +6 -0
  132. package/src/lib/WazoSessionDescriptionHandler.js +17 -9
  133. package/src/service/IssueReporter.js +7 -1
  134. package/src/service/__tests__/IssueReporter.test.js +2 -0
  135. package/src/simple/Phone.js +13 -4
  136. package/src/simple/index.js +8 -0
  137. package/src/simple/room/Participant.js +7 -0
  138. package/src/simple/room/Room.js +157 -79
  139. package/src/simple/room/SipRoom.js +147 -0
  140. package/src/simple/room/Stream.js +1 -3
  141. package/src/simple/room/__tests__/RemoteParticipant.test.js +3 -2
  142. package/src/types/WebSocketMessage.js +21 -0
  143. package/src/web-rtc-client.js +57 -24
  144. package/src/websocket-client.js +4 -0
@@ -305,7 +305,13 @@ class IssueReporter {
305
305
  }
306
306
 
307
307
  _isLevelAbove(level1 , level2 ) {
308
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
308
+ const index1 = LOG_LEVELS.indexOf(level1);
309
+ const index2 = LOG_LEVELS.indexOf(level2);
310
+ if (index1 === -1 || index2 === -1) {
311
+ return false;
312
+ }
313
+
314
+ return index1 > index2;
309
315
  }
310
316
 
311
317
  _makeCategory(category ) {
@@ -305,7 +305,13 @@ class IssueReporter {
305
305
  }
306
306
 
307
307
  _isLevelAbove(level1 , level2 ) {
308
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
308
+ const index1 = LOG_LEVELS.indexOf(level1);
309
+ const index2 = LOG_LEVELS.indexOf(level2);
310
+ if (index1 === -1 || index2 === -1) {
311
+ return false;
312
+ }
313
+
314
+ return index1 > index2;
309
315
  }
310
316
 
311
317
  _makeCategory(category ) {
@@ -591,7 +591,13 @@ class IssueReporter {
591
591
  }
592
592
 
593
593
  _isLevelAbove(level1 , level2 ) {
594
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
594
+ const index1 = LOG_LEVELS.indexOf(level1);
595
+ const index2 = LOG_LEVELS.indexOf(level2);
596
+ if (index1 === -1 || index2 === -1) {
597
+ return false;
598
+ }
599
+
600
+ return index1 > index2;
595
601
  }
596
602
 
597
603
  _makeCategory(category ) {
@@ -763,7 +769,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
763
769
  .then(() => {
764
770
  if (isConference && (options.constraints && !options.constraints.video) && !('hold' in options) && !audioOnly) {
765
771
  // Add a video an empty bundle to be able to replaceTrack when joining a conference without video
766
- this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
772
+ if (this.peerConnection.addTransceiver) {
773
+ this.peerConnection.addTransceiver('video', { streams: [this._localMediaStream], direction: 'sendrecv' });
774
+ }
767
775
  }
768
776
  })
769
777
  .then(() => this.createLocalOfferOrAnswer(options))
@@ -790,12 +798,6 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
790
798
  };
791
799
  })
792
800
  .then((sessionDescription) => this.applyModifiers(sessionDescription, modifiers))
793
- .then((sessionDescription) => {
794
- // Set new constraints to avoid the constraints check issue in `sdh.getLocalMediaStream` later.
795
- this.localMediaStreamConstraints = options.constraints;
796
-
797
- return sessionDescription;
798
- })
799
801
  .then((sessionDescription) => ({ body: sessionDescription.sdp, contentType: 'application/sdp' }))
800
802
  .catch((error) => {
801
803
  wazoLogger.error('error when creating media', error);
@@ -990,6 +992,9 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
990
992
 
991
993
  // set the transceiver direction to the answer direction
992
994
  this._peerConnection.getTransceivers().forEach((transceiver) => {
995
+ if (transceiver.stopped) {
996
+ return;
997
+ }
993
998
  if (transceiver.direction /* guarding, but should always be true */) {
994
999
  const { receiver } = transceiver;
995
1000
  if (isConference && audioOnly && receiver.track && receiver.track.kind === 'video') {
@@ -1034,10 +1039,15 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
1034
1039
  if (kind !== 'audio' && kind !== 'video') {
1035
1040
  throw new Error(`Unknown new track kind ${kind}.`);
1036
1041
  }
1037
- const sender = pc.getSenders().find((otherSender) => otherSender.track && otherSender.track.kind === kind);
1042
+ const sender = pc.getSenders && pc.getSenders().find((otherSender) =>
1043
+ otherSender.track && otherSender.track.kind === kind);
1038
1044
 
1039
1045
  // Do not reuse sender video tracks in SFU
1040
1046
  if (sender && (!sfu || newTrack.kind === 'audio')) {
1047
+ if (sender.track) {
1048
+ // eslint-disable-next-line no-param-reassign
1049
+ newTrack.enabled = sender.track.enabled;
1050
+ }
1041
1051
  trackUpdates.push(
1042
1052
  new Promise((resolve) => {
1043
1053
  this.logger.debug(`SessionDescriptionHandler.setLocalMediaStream - replacing sender ${kind} track`);
@@ -1071,7 +1081,11 @@ class WazoSessionDescriptionHandler extends SessionDescriptionHandler {
1071
1081
  // Review: could make streamless tracks a configurable option?
1072
1082
  // https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/addTrack#Usage_notes
1073
1083
  try {
1074
- pc.addTrack(newTrack, localStream);
1084
+ if (pc.addTrack) {
1085
+ pc.addTrack(newTrack, localStream);
1086
+ } else {
1087
+ pc.addStream(localStream);
1088
+ }
1075
1089
  } catch (error) {
1076
1090
  this.logger.error(`SessionDescriptionHandler.setLocalMediaStream - failed to add sender ${kind} track`);
1077
1091
  throw error;
@@ -3028,6 +3042,65 @@ class ExternalApp {
3028
3042
  }
3029
3043
  }
3030
3044
 
3045
+ //
3046
+
3047
+
3048
+
3049
+
3050
+
3051
+
3052
+
3053
+
3054
+
3055
+
3056
+
3057
+ class Meeting {
3058
+
3059
+
3060
+
3061
+
3062
+
3063
+
3064
+
3065
+
3066
+
3067
+
3068
+ static parse(plain ) {
3069
+ return new Meeting({
3070
+ guestSipAuthorization: plain.guest_sip_authorization,
3071
+ hostname: plain.hostname,
3072
+ name: plain.name,
3073
+ ownerUuids: plain.owner_uuids,
3074
+ port: plain.port,
3075
+ uuid: plain.uuid,
3076
+ number: plain.number,
3077
+ });
3078
+ }
3079
+
3080
+ static newFrom(meeting ) {
3081
+ return newFrom(meeting, Meeting);
3082
+ }
3083
+
3084
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
3085
+ this.guestSipAuthorization = guestSipAuthorization;
3086
+ this.hostname = hostname;
3087
+ this.name = name;
3088
+ this.ownerUuids = ownerUuids;
3089
+ this.port = port;
3090
+ this.uuid = uuid;
3091
+ this.number = number;
3092
+
3093
+ // Useful to compare instead of instanceof with minified code
3094
+ this.type = 'Meeting';
3095
+ }
3096
+
3097
+ getGuestSipCredentials() {
3098
+ // eslint-disable-next-line no-undef
3099
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
3100
+ return { username, secret };
3101
+ }
3102
+ }
3103
+
3031
3104
  /* */
3032
3105
 
3033
3106
  var confdMethods = (client , baseUrl ) => ({
@@ -3092,6 +3165,18 @@ var confdMethods = (client , baseUrl ) => ({
3092
3165
  return null;
3093
3166
  }
3094
3167
  },
3168
+
3169
+ createMyMeeting: (name ) =>
3170
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
3171
+
3172
+ deleteMyMeeting: (meetingUuid ) =>
3173
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
3174
+
3175
+ getMeeting: (meetingUuid ) =>
3176
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
3177
+
3178
+ guestGetMeeting: (meetingUuid ) =>
3179
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
3095
3180
  });
3096
3181
 
3097
3182
  //
@@ -3676,7 +3761,11 @@ class CallLog {
3676
3761
  answered: plain.answered,
3677
3762
  callDirection: plain.call_direction,
3678
3763
  destination: {
3679
- extension: plain.requested_extension || plain.destination_extension,
3764
+ // @TEMP: Temporarily assuming empty numbers are meetings
3765
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3766
+ extension: plain.requested_extension
3767
+ || plain.destination_extension
3768
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3680
3769
  name: plain.requested_name || plain.destination_name || '',
3681
3770
  },
3682
3771
  source: {
@@ -3692,27 +3781,11 @@ class CallLog {
3692
3781
  }
3693
3782
 
3694
3783
  static parseNew(plain , session ) {
3695
- return new CallLog({
3696
- answer: plain.answer ? moment(plain.answer).toDate() : null,
3697
- answered: plain.answered,
3698
- callDirection: plain.call_direction,
3699
- destination: {
3700
- extension: plain.requested_extension || plain.destination_extension,
3701
- name: plain.requested_name || plain.destination_name || '',
3702
- },
3703
- source: {
3704
- extension: plain.source_extension,
3705
- name: plain.source_name,
3706
- },
3707
- id: plain.id,
3708
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3709
- start: moment(plain.start).toDate(),
3710
- end: plain.end ? moment(plain.end).toDate() : null,
3711
- recordings: Recording.parseMany(plain.recordings),
3712
- // @TODO: FIXME add verification declined vs missed call
3713
- newMissedCall: session
3714
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3715
- });
3784
+ const callLog = CallLog.parse(plain);
3785
+ // @TODO: FIXME add verification declined vs missed call
3786
+ callLog.newMissedCall = session
3787
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3788
+ return callLog;
3716
3789
  }
3717
3790
 
3718
3791
  static newFrom(profile ) {
@@ -4469,6 +4542,9 @@ var calldMethods = (client , baseUrl ) => ({
4469
4542
  getConferenceParticipantsAsUser: async (conferenceId ) =>
4470
4543
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
4471
4544
 
4545
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4546
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4547
+
4472
4548
  listTrunks: () => client.get(`${baseUrl}/trunks`),
4473
4549
 
4474
4550
  mute: (callId ) =>
@@ -5104,6 +5180,7 @@ const MAX_REGISTER_TRIES = 10;
5104
5180
 
5105
5181
 
5106
5182
 
5183
+
5107
5184
 
5108
5185
 
5109
5186
 
@@ -5130,6 +5207,7 @@ class WebRTCClient extends Emitter {
5130
5207
 
5131
5208
 
5132
5209
 
5210
+
5133
5211
 
5134
5212
  // sugar
5135
5213
 
@@ -5168,6 +5246,8 @@ class WebRTCClient extends Emitter {
5168
5246
  super();
5169
5247
  this.uaConfigOverrides = uaConfigOverrides;
5170
5248
  this.config = config;
5249
+ this.skipRegister = config.skipRegister;
5250
+
5171
5251
  this._buildConfig(config, session).then((newConfig ) => {
5172
5252
  this.config = newConfig;
5173
5253
  this.userAgent = this.createUserAgent(uaConfigOverrides);
@@ -5295,14 +5375,22 @@ class WebRTCClient extends Emitter {
5295
5375
  }
5296
5376
 
5297
5377
  register(tries = 0) {
5298
- logger.info('sdk webrtc registering...', {
5378
+ const logInfo = {
5299
5379
  userAgent: !!this.userAgent,
5300
5380
  registered: this.isRegistered(),
5301
5381
  connectionPromise: !!this.connectionPromise,
5302
5382
  registerer: !!this.registerer,
5303
5383
  waiting: this.registerer && this.registerer.waiting,
5304
5384
  tries,
5305
- });
5385
+ skipRegister: this.skipRegister,
5386
+ };
5387
+
5388
+ if (this.skipRegister) {
5389
+ logger.info('sdk webrtc skip register...', logInfo);
5390
+ return Promise.resolve();
5391
+ }
5392
+
5393
+ logger.info('sdk webrtc registering...', logInfo);
5306
5394
 
5307
5395
  if (!this.userAgent) {
5308
5396
  logger.info('sdk webrtc recreating User Agent');
@@ -5633,12 +5721,18 @@ class WebRTCClient extends Emitter {
5633
5721
  }
5634
5722
 
5635
5723
  if (pc.getSenders) {
5724
+ if (!pc.getSenders().length) {
5725
+ return false;
5726
+ }
5636
5727
  pc.getSenders().forEach(sender => {
5637
5728
  if (sender && sender.track && sender.track.kind === 'audio') {
5638
5729
  muted = muted && !sender.track.enabled;
5639
5730
  }
5640
5731
  });
5641
5732
  } else {
5733
+ if (!pc.getLocalStreams().length) {
5734
+ return false;
5735
+ }
5642
5736
  pc.getLocalStreams().forEach(stream => {
5643
5737
  stream.getAudioTracks().forEach(track => {
5644
5738
  muted = muted && !track.enabled;
@@ -5695,6 +5789,9 @@ class WebRTCClient extends Emitter {
5695
5789
  if (!this._isWeb()) {
5696
5790
  options.sessionDescriptionHandlerModifiers = [holdModifier];
5697
5791
  }
5792
+ options.sessionDescriptionHandlerOptions = {
5793
+ constraints: options.constraints,
5794
+ };
5698
5795
 
5699
5796
  // Send re-INVITE
5700
5797
  return session.invite(options);
@@ -5734,6 +5831,9 @@ class WebRTCClient extends Emitter {
5734
5831
  // (eg: holdModifier)
5735
5832
  options.sessionDescriptionHandlerModifiers = [];
5736
5833
  }
5834
+ options.sessionDescriptionHandlerOptions = {
5835
+ constraints: options.constraints,
5836
+ };
5737
5837
 
5738
5838
  // Send re-INVITE
5739
5839
  return session.invite(options);
@@ -5916,7 +6016,8 @@ class WebRTCClient extends Emitter {
5916
6016
  }
5917
6017
  const sdh = session.sessionDescriptionHandler;
5918
6018
  const pc = sdh.peerConnection;
5919
- const localStream = this.getLocalStream(this.getSipSessionId(session));
6019
+ const sessionId = this.getSipSessionId(session);
6020
+ const localStream = this.getLocalStream(sessionId);
5920
6021
 
5921
6022
  // Release old video stream
5922
6023
  if (localStream) {
@@ -5942,11 +6043,8 @@ class WebRTCClient extends Emitter {
5942
6043
 
5943
6044
  // let's update the local stream
5944
6045
  this.eventEmitter.emit('onVideoInputChange', stream);
5945
- try {
5946
- await sdh.setLocalMediaStream(stream);
5947
- } catch (_) {
5948
- // Nothing to do
5949
- }
6046
+ this.setLocalMediaStream(sessionId, stream);
6047
+
5950
6048
  return stream;
5951
6049
  });
5952
6050
  }
@@ -6248,9 +6346,11 @@ class WebRTCClient extends Emitter {
6248
6346
  remoteStream.removeTrack(track);
6249
6347
  });
6250
6348
 
6251
- pc.getReceivers().forEach(receiver => {
6252
- remoteStream.addTrack(receiver.track);
6253
- });
6349
+ if (pc.getReceivers) {
6350
+ pc.getReceivers().forEach(receiver => {
6351
+ remoteStream.addTrack(receiver.track);
6352
+ });
6353
+ }
6254
6354
  }
6255
6355
 
6256
6356
  getMediaConfiguration(enableVideo , conference = false, constraints = null) {
@@ -6285,6 +6385,25 @@ class WebRTCClient extends Emitter {
6285
6385
  return sessionId in this.conferences;
6286
6386
  }
6287
6387
 
6388
+ createAudioElementFor(sessionId ) {
6389
+ const audio = document.createElement('audio');
6390
+ audio.setAttribute('id', `audio-${sessionId}`);
6391
+
6392
+ if (audio.setSinkId && this.audioOutputDeviceId) {
6393
+ audio.setSinkId(this.audioOutputDeviceId);
6394
+ }
6395
+
6396
+ if (document.body) {
6397
+ document.body.appendChild(audio);
6398
+ }
6399
+ this.audioElements[sessionId] = audio;
6400
+
6401
+ audio.volume = this.audioOutputVolume;
6402
+ audio.autoplay = true;
6403
+
6404
+ return audio;
6405
+ }
6406
+
6288
6407
  _onTransportError() {
6289
6408
  this.eventEmitter.emit(TRANSPORT_ERROR);
6290
6409
  this.attemptReconnection();
@@ -6514,7 +6633,7 @@ class WebRTCClient extends Emitter {
6514
6633
  let hadRemoteVideo = false;
6515
6634
 
6516
6635
  // Monkey patch `onInviteRequest` to be able to know if there was a remote video stream before `onInvite` is called
6517
- // Becase when `onInvite` is called we already got the video track
6636
+ // Because when `onInvite` is called we already got the video track
6518
6637
  session.onInviteRequest = (request) => {
6519
6638
  hadRemoteVideo = this.hasARemoteVideoTrack(sipSessionId);
6520
6639
 
@@ -6589,20 +6708,10 @@ class WebRTCClient extends Emitter {
6589
6708
  const isConference = this.isConference(sessionId);
6590
6709
 
6591
6710
  if (this._hasAudio() && this._isWeb() && !(sessionId in this.audioElements)) {
6592
- const audio = document.createElement('audio');
6593
- audio.setAttribute('id', `audio-${sessionId}`);
6594
-
6595
- if (audio.setSinkId && this.audioOutputDeviceId) {
6596
- audio.setSinkId(this.audioOutputDeviceId);
6597
- }
6598
-
6599
- if (document.body) {
6600
- document.body.appendChild(audio);
6601
- }
6602
- this.audioElements[sessionId] = audio;
6711
+ this.createAudioElementFor(sessionId);
6603
6712
  }
6604
6713
 
6605
- const audioElement = this.audioElements[this.getSipSessionId(session)];
6714
+ const audioElement = this.audioElements[sessionId];
6606
6715
  const stream = newStream || this.getRemoteStream(sessionId);
6607
6716
 
6608
6717
  if (!this._isWeb() || !stream) {
@@ -300,7 +300,13 @@ class IssueReporter {
300
300
  }
301
301
 
302
302
  _isLevelAbove(level1 , level2 ) {
303
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
303
+ const index1 = LOG_LEVELS.indexOf(level1);
304
+ const index2 = LOG_LEVELS.indexOf(level2);
305
+ if (index1 === -1 || index2 === -1) {
306
+ return false;
307
+ }
308
+
309
+ return index1 > index2;
304
310
  }
305
311
 
306
312
  _makeCategory(category ) {
@@ -459,6 +465,8 @@ const CONFERENCE_USER_PARTICIPANT_JOINED = 'conference_user_participant_joined';
459
465
  const CONFERENCE_USER_PARTICIPANT_LEFT = 'conference_user_participant_left';
460
466
  const CONFERENCE_USER_PARTICIPANT_TALK_STARTED = 'conference_user_participant_talk_started';
461
467
  const CONFERENCE_USER_PARTICIPANT_TALK_STOPPED = 'conference_user_participant_talk_stopped';
468
+ const MEETING_USER_PARTICIPANT_JOINED = 'meeting_user_participant_joined';
469
+ const MEETING_USER_PARTICIPANT_LEFT = 'meeting_user_participant_left';
462
470
  const SWITCHBOARD_QUEUED_CALLS_UPDATED = 'switchboard_queued_calls_updated';
463
471
  const SWITCHBOARD_QUEUED_CALL_ANSWERED = 'switchboard_queued_call_answered';
464
472
  const SWITCHBOARD_HELD_CALLS_UPDATED = 'switchboard_held_calls_updated';
@@ -805,6 +813,8 @@ WebSocketClient.eventLists = [
805
813
  CHATD_USER_ROOM_CREATED,
806
814
  CONFERENCE_USER_PARTICIPANT_JOINED,
807
815
  CONFERENCE_USER_PARTICIPANT_LEFT,
816
+ MEETING_USER_PARTICIPANT_JOINED,
817
+ MEETING_USER_PARTICIPANT_LEFT,
808
818
  CONFERENCE_USER_PARTICIPANT_TALK_STARTED,
809
819
  CONFERENCE_USER_PARTICIPANT_TALK_STOPPED,
810
820
  SWITCHBOARD_QUEUED_CALLS_UPDATED,
@@ -842,4 +852,4 @@ WebSocketClient.eventLists = [
842
852
  ];
843
853
 
844
854
  export default WebSocketClient;
845
- export { AGENT_PAUSED, AGENT_STATUS_UPDATE, AGENT_UNPAUSED, APPLICATION_CALL_ANSWERED, APPLICATION_CALL_DELETED, APPLICATION_CALL_DTMF_RECEIVED, APPLICATION_CALL_ENTERED, APPLICATION_CALL_INITIATED, APPLICATION_CALL_UPDATED, APPLICATION_DESTINATION_NODE_CREATED, APPLICATION_NODE_CREATED, APPLICATION_NODE_DELETED, APPLICATION_NODE_UPDATED, APPLICATION_PLAYBACK_CREATED, APPLICATION_PLAYBACK_DELETED, APPLICATION_PROGRESS_STARTED, APPLICATION_PROGRESS_STOPPED, APPLICATION_SNOOP_CREATED, APPLICATION_SNOOP_DELETED, APPLICATION_SNOOP_UPDATED, APPLICATION_USER_OUTGOING_CALL_CREATED, AUTH_SESSION_EXPIRE_SOON, AUTH_USER_EXTERNAL_AUTH_ADDED, AUTH_USER_EXTERNAL_AUTH_DELETED, CALL_ANSWERED, CALL_CREATED, CALL_DTMF_CREATED, CALL_ENDED, CALL_HELD, CALL_LOG_USER_CREATED, CALL_RESUMED, CALL_UPDATED, CHATD_PRESENCE_UPDATED, CHATD_USER_ROOM_CREATED, CHATD_USER_ROOM_MESSAGE_CREATED, CHAT_MESSAGE_RECEIVED, CHAT_MESSAGE_SENT, CONFERENCE_ADHOC_DELETED, CONFERENCE_ADHOC_PARTICIPANT_LEFT, CONFERENCE_USER_PARTICIPANT_JOINED, CONFERENCE_USER_PARTICIPANT_LEFT, CONFERENCE_USER_PARTICIPANT_TALK_STARTED, CONFERENCE_USER_PARTICIPANT_TALK_STOPPED, ENDPOINT_STATUS_UPDATE, FAVORITE_ADDED, FAVORITE_DELETED, FAX_OUTBOUND_USER_CREATED, FAX_OUTBOUND_USER_FAILED, FAX_OUTBOUND_USER_SUCCEEDED, HEARTBEAT_ENGINE_VERSION, LINE_STATUS_UPDATED, SOCKET_EVENTS, SWITCHBOARD_HELD_CALLS_UPDATED, SWITCHBOARD_HELD_CALL_ANSWERED, SWITCHBOARD_QUEUED_CALLS_UPDATED, SWITCHBOARD_QUEUED_CALL_ANSWERED, TRUNK_STATUS_UPDATED, USERS_FORWARDS_BUSY_UPDATED, USERS_FORWARDS_NOANSWER_UPDATED, USERS_FORWARDS_UNCONDITIONAL_UPDATED, USERS_SERVICES_DND_UPDATED, USER_STATUS_UPDATE, USER_VOICEMAIL_MESSAGE_CREATED, USER_VOICEMAIL_MESSAGE_DELETED, USER_VOICEMAIL_MESSAGE_UPDATED };
855
+ export { AGENT_PAUSED, AGENT_STATUS_UPDATE, AGENT_UNPAUSED, APPLICATION_CALL_ANSWERED, APPLICATION_CALL_DELETED, APPLICATION_CALL_DTMF_RECEIVED, APPLICATION_CALL_ENTERED, APPLICATION_CALL_INITIATED, APPLICATION_CALL_UPDATED, APPLICATION_DESTINATION_NODE_CREATED, APPLICATION_NODE_CREATED, APPLICATION_NODE_DELETED, APPLICATION_NODE_UPDATED, APPLICATION_PLAYBACK_CREATED, APPLICATION_PLAYBACK_DELETED, APPLICATION_PROGRESS_STARTED, APPLICATION_PROGRESS_STOPPED, APPLICATION_SNOOP_CREATED, APPLICATION_SNOOP_DELETED, APPLICATION_SNOOP_UPDATED, APPLICATION_USER_OUTGOING_CALL_CREATED, AUTH_SESSION_EXPIRE_SOON, AUTH_USER_EXTERNAL_AUTH_ADDED, AUTH_USER_EXTERNAL_AUTH_DELETED, CALL_ANSWERED, CALL_CREATED, CALL_DTMF_CREATED, CALL_ENDED, CALL_HELD, CALL_LOG_USER_CREATED, CALL_RESUMED, CALL_UPDATED, CHATD_PRESENCE_UPDATED, CHATD_USER_ROOM_CREATED, CHATD_USER_ROOM_MESSAGE_CREATED, CHAT_MESSAGE_RECEIVED, CHAT_MESSAGE_SENT, CONFERENCE_ADHOC_DELETED, CONFERENCE_ADHOC_PARTICIPANT_LEFT, CONFERENCE_USER_PARTICIPANT_JOINED, CONFERENCE_USER_PARTICIPANT_LEFT, CONFERENCE_USER_PARTICIPANT_TALK_STARTED, CONFERENCE_USER_PARTICIPANT_TALK_STOPPED, ENDPOINT_STATUS_UPDATE, FAVORITE_ADDED, FAVORITE_DELETED, FAX_OUTBOUND_USER_CREATED, FAX_OUTBOUND_USER_FAILED, FAX_OUTBOUND_USER_SUCCEEDED, HEARTBEAT_ENGINE_VERSION, LINE_STATUS_UPDATED, MEETING_USER_PARTICIPANT_JOINED, MEETING_USER_PARTICIPANT_LEFT, SOCKET_EVENTS, SWITCHBOARD_HELD_CALLS_UPDATED, SWITCHBOARD_HELD_CALL_ANSWERED, SWITCHBOARD_QUEUED_CALLS_UPDATED, SWITCHBOARD_QUEUED_CALL_ANSWERED, TRUNK_STATUS_UPDATED, USERS_FORWARDS_BUSY_UPDATED, USERS_FORWARDS_NOANSWER_UPDATED, USERS_FORWARDS_UNCONDITIONAL_UPDATED, USERS_SERVICES_DND_UPDATED, USER_STATUS_UPDATE, USER_VOICEMAIL_MESSAGE_CREATED, USER_VOICEMAIL_MESSAGE_DELETED, USER_VOICEMAIL_MESSAGE_UPDATED };
@@ -315,7 +315,13 @@ class IssueReporter {
315
315
  }
316
316
 
317
317
  _isLevelAbove(level1 , level2 ) {
318
- return LOG_LEVELS.indexOf(level1) > LOG_LEVELS.indexOf(level2);
318
+ const index1 = LOG_LEVELS.indexOf(level1);
319
+ const index2 = LOG_LEVELS.indexOf(level2);
320
+ if (index1 === -1 || index2 === -1) {
321
+ return false;
322
+ }
323
+
324
+ return index1 > index2;
319
325
  }
320
326
 
321
327
  _makeCategory(category ) {
@@ -2493,6 +2499,65 @@ class ExternalApp {
2493
2499
  }
2494
2500
  }
2495
2501
 
2502
+ //
2503
+
2504
+
2505
+
2506
+
2507
+
2508
+
2509
+
2510
+
2511
+
2512
+
2513
+
2514
+ class Meeting {
2515
+
2516
+
2517
+
2518
+
2519
+
2520
+
2521
+
2522
+
2523
+
2524
+
2525
+ static parse(plain ) {
2526
+ return new Meeting({
2527
+ guestSipAuthorization: plain.guest_sip_authorization,
2528
+ hostname: plain.hostname,
2529
+ name: plain.name,
2530
+ ownerUuids: plain.owner_uuids,
2531
+ port: plain.port,
2532
+ uuid: plain.uuid,
2533
+ number: plain.number,
2534
+ });
2535
+ }
2536
+
2537
+ static newFrom(meeting ) {
2538
+ return newFrom(meeting, Meeting);
2539
+ }
2540
+
2541
+ constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, hostname, number } = {}) {
2542
+ this.guestSipAuthorization = guestSipAuthorization;
2543
+ this.hostname = hostname;
2544
+ this.name = name;
2545
+ this.ownerUuids = ownerUuids;
2546
+ this.port = port;
2547
+ this.uuid = uuid;
2548
+ this.number = number;
2549
+
2550
+ // Useful to compare instead of instanceof with minified code
2551
+ this.type = 'Meeting';
2552
+ }
2553
+
2554
+ getGuestSipCredentials() {
2555
+ // eslint-disable-next-line no-undef
2556
+ const [username, secret] = atob(this.guestSipAuthorization).split(':');
2557
+ return { username, secret };
2558
+ }
2559
+ }
2560
+
2496
2561
  /* */
2497
2562
 
2498
2563
  var confdMethods = (client , baseUrl ) => ({
@@ -2557,6 +2622,18 @@ var confdMethods = (client , baseUrl ) => ({
2557
2622
  return null;
2558
2623
  }
2559
2624
  },
2625
+
2626
+ createMyMeeting: (name ) =>
2627
+ client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
2628
+
2629
+ deleteMyMeeting: (meetingUuid ) =>
2630
+ client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
2631
+
2632
+ getMeeting: (meetingUuid ) =>
2633
+ client.get(`${baseUrl}/meetings/${meetingUuid}`, null).then(Meeting.parse),
2634
+
2635
+ guestGetMeeting: (meetingUuid ) =>
2636
+ client.get(`${baseUrl}/guests/me/meetings/${meetingUuid}`, null).then(Meeting.parse),
2560
2637
  });
2561
2638
 
2562
2639
  //
@@ -3141,7 +3218,11 @@ class CallLog {
3141
3218
  answered: plain.answered,
3142
3219
  callDirection: plain.call_direction,
3143
3220
  destination: {
3144
- extension: plain.requested_extension || plain.destination_extension,
3221
+ // @TEMP: Temporarily assuming empty numbers are meetings
3222
+ // which is admittedly a very dangerous assumption. Did i mention it was temporary?
3223
+ extension: plain.requested_extension
3224
+ || plain.destination_extension
3225
+ || `meeting-${plain.requested_name || plain.destination_name || ''}`,
3145
3226
  name: plain.requested_name || plain.destination_name || '',
3146
3227
  },
3147
3228
  source: {
@@ -3157,27 +3238,11 @@ class CallLog {
3157
3238
  }
3158
3239
 
3159
3240
  static parseNew(plain , session ) {
3160
- return new CallLog({
3161
- answer: plain.answer ? moment__default['default'](plain.answer).toDate() : null,
3162
- answered: plain.answered,
3163
- callDirection: plain.call_direction,
3164
- destination: {
3165
- extension: plain.requested_extension || plain.destination_extension,
3166
- name: plain.requested_name || plain.destination_name || '',
3167
- },
3168
- source: {
3169
- extension: plain.source_extension,
3170
- name: plain.source_name,
3171
- },
3172
- id: plain.id,
3173
- duration: (plain.duration || 0) * 1000, // duration is in seconds
3174
- start: moment__default['default'](plain.start).toDate(),
3175
- end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3176
- recordings: Recording.parseMany(plain.recordings),
3177
- // @TODO: FIXME add verification declined vs missed call
3178
- newMissedCall: session
3179
- && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered,
3180
- });
3241
+ const callLog = CallLog.parse(plain);
3242
+ // @TODO: FIXME add verification declined vs missed call
3243
+ callLog.newMissedCall = session
3244
+ && session.hasExtension(plain.requested_extension || plain.destination_extension) && !plain.answered;
3245
+ return callLog;
3181
3246
  }
3182
3247
 
3183
3248
  static newFrom(profile ) {
@@ -3934,6 +3999,9 @@ var calldMethods = (client , baseUrl ) => ({
3934
3999
  getConferenceParticipantsAsUser: async (conferenceId ) =>
3935
4000
  client.get(`${baseUrl}/users/me/conferences/${conferenceId}/participants`),
3936
4001
 
4002
+ getMeetingParticipantsAsUser: async (meetingUuid ) =>
4003
+ client.get(`${baseUrl}/users/me/meetings/${meetingUuid}/participants`),
4004
+
3937
4005
  listTrunks: () => client.get(`${baseUrl}/trunks`),
3938
4006
 
3939
4007
  mute: (callId ) =>