@wazo/sdk 0.37.17 → 0.37.21

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 (118) hide show
  1. package/dist/wazo-sdk.js +3 -3
  2. package/esm/__tests__/api-client.test.js +52 -9
  3. package/esm/__tests__/web-rtc-client.test.js +96 -21
  4. package/esm/api/agentd.js +26 -3
  5. package/esm/api/amid.js +26 -3
  6. package/esm/api/application.js +26 -3
  7. package/esm/api/auth.js +26 -3
  8. package/esm/api/call-logd.js +28 -5
  9. package/esm/api/calld.js +26 -3
  10. package/esm/api/chatd.js +26 -3
  11. package/esm/api/confd.js +50 -7
  12. package/esm/api/ctid-ng.js +26 -3
  13. package/esm/api/dird.js +26 -3
  14. package/esm/api/webhookd.js +26 -3
  15. package/esm/api-client.js +52 -9
  16. package/esm/checker/Checker.js +98 -21
  17. package/esm/checker/checks/aor.js +52 -9
  18. package/esm/checker/checks/api.js +52 -9
  19. package/esm/checker/checks/index.js +98 -21
  20. package/esm/checker/checks/wazo-websocket.js +28 -3
  21. package/esm/checker/checks/webrtc-transport.js +96 -21
  22. package/esm/checker/checks/webrtc.js +96 -21
  23. package/esm/domain/AdHocAPIConference.js +52 -9
  24. package/esm/domain/CallLog.js +2 -2
  25. package/esm/domain/Features.js +52 -9
  26. package/esm/domain/Meeting.js +19 -2
  27. package/esm/domain/Phone/CTIPhone.js +52 -9
  28. package/esm/domain/Phone/WebRTCPhone.js +41 -5
  29. package/esm/domain/Recording.js +1 -1
  30. package/esm/domain/__tests__/CallLog.test.js +2 -2
  31. package/esm/index.js +119 -22
  32. package/esm/lib/WazoSessionDescriptionHandler.js +26 -3
  33. package/esm/service/CallApi.js +52 -9
  34. package/esm/service/IssueReporter.js +26 -3
  35. package/esm/service/__tests__/IssueReporter.test.js +26 -3
  36. package/esm/service/getApiClient.js +52 -9
  37. package/esm/simple/Auth.js +119 -22
  38. package/esm/simple/Configuration.js +119 -22
  39. package/esm/simple/Directory.js +52 -9
  40. package/esm/simple/Phone.js +119 -22
  41. package/esm/simple/Websocket.js +29 -3
  42. package/esm/simple/index.js +119 -22
  43. package/esm/simple/room/LocalParticipant.js +119 -22
  44. package/esm/simple/room/Participant.js +119 -22
  45. package/esm/simple/room/RemoteParticipant.js +119 -22
  46. package/esm/simple/room/Room.js +119 -22
  47. package/esm/simple/room/SipRoom.js +119 -22
  48. package/esm/simple/room/Stream.js +119 -22
  49. package/esm/simple/room/__tests__/RemoteParticipant.test.js +119 -22
  50. package/esm/simple/utils.js +119 -22
  51. package/esm/utils/__tests__/api-requester.test.js +26 -3
  52. package/esm/utils/api-requester.js +26 -3
  53. package/esm/web-rtc-client.js +96 -21
  54. package/esm/websocket-client.js +29 -4
  55. package/lib/__tests__/api-client.test.js +52 -9
  56. package/lib/__tests__/web-rtc-client.test.js +96 -21
  57. package/lib/api/agentd.js +26 -3
  58. package/lib/api/amid.js +26 -3
  59. package/lib/api/application.js +26 -3
  60. package/lib/api/auth.js +26 -3
  61. package/lib/api/call-logd.js +28 -5
  62. package/lib/api/calld.js +26 -3
  63. package/lib/api/chatd.js +26 -3
  64. package/lib/api/confd.js +50 -7
  65. package/lib/api/ctid-ng.js +26 -3
  66. package/lib/api/dird.js +26 -3
  67. package/lib/api/webhookd.js +26 -3
  68. package/lib/api-client.js +52 -9
  69. package/lib/checker/Checker.js +98 -21
  70. package/lib/checker/checks/aor.js +52 -9
  71. package/lib/checker/checks/api.js +52 -9
  72. package/lib/checker/checks/index.js +98 -21
  73. package/lib/checker/checks/wazo-websocket.js +28 -3
  74. package/lib/checker/checks/webrtc-transport.js +96 -21
  75. package/lib/checker/checks/webrtc.js +96 -21
  76. package/lib/domain/AdHocAPIConference.js +52 -9
  77. package/lib/domain/CallLog.js +2 -2
  78. package/lib/domain/Features.js +52 -9
  79. package/lib/domain/Meeting.js +19 -2
  80. package/lib/domain/Phone/CTIPhone.js +52 -9
  81. package/lib/domain/Phone/WebRTCPhone.js +41 -4
  82. package/lib/domain/Recording.js +1 -1
  83. package/lib/domain/__tests__/CallLog.test.js +2 -2
  84. package/lib/index.js +119 -22
  85. package/lib/lib/WazoSessionDescriptionHandler.js +26 -3
  86. package/lib/service/CallApi.js +52 -9
  87. package/lib/service/IssueReporter.js +26 -3
  88. package/lib/service/__tests__/IssueReporter.test.js +26 -3
  89. package/lib/service/getApiClient.js +52 -9
  90. package/lib/simple/Auth.js +119 -22
  91. package/lib/simple/Configuration.js +119 -22
  92. package/lib/simple/Directory.js +52 -9
  93. package/lib/simple/Phone.js +119 -22
  94. package/lib/simple/Websocket.js +29 -3
  95. package/lib/simple/index.js +119 -22
  96. package/lib/simple/room/LocalParticipant.js +119 -22
  97. package/lib/simple/room/Participant.js +119 -22
  98. package/lib/simple/room/RemoteParticipant.js +119 -22
  99. package/lib/simple/room/Room.js +119 -22
  100. package/lib/simple/room/SipRoom.js +119 -22
  101. package/lib/simple/room/Stream.js +119 -22
  102. package/lib/simple/room/__tests__/RemoteParticipant.test.js +119 -22
  103. package/lib/simple/utils.js +119 -22
  104. package/lib/utils/__tests__/api-requester.test.js +26 -3
  105. package/lib/utils/api-requester.js +26 -3
  106. package/lib/web-rtc-client.js +96 -21
  107. package/lib/websocket-client.js +29 -3
  108. package/package.json +2 -2
  109. package/src/api/confd.js +5 -2
  110. package/src/domain/CallLog.js +1 -1
  111. package/src/domain/Meeting.js +19 -2
  112. package/src/domain/Phone/WebRTCPhone.js +14 -1
  113. package/src/domain/Recording.js +1 -1
  114. package/src/service/IssueReporter.js +26 -3
  115. package/src/simple/Phone.js +5 -0
  116. package/src/types/WebSocketMessage.js +5 -1
  117. package/src/web-rtc-client.js +44 -12
  118. package/src/websocket-client.js +2 -0
@@ -423,6 +423,7 @@ class IssueReporter {
423
423
 
424
424
 
425
425
 
426
+
426
427
 
427
428
  constructor() {
428
429
  addLevelsTo(this);
@@ -434,12 +435,17 @@ class IssueReporter {
434
435
  this.bufferTimeout = null;
435
436
  this._boundProcessBuffer = this._processBuffer.bind(this);
436
437
  this._boundParseLoggerBody = this._parseLoggerBody.bind(this);
438
+ this._callback = null;
437
439
  }
438
440
 
439
441
  init() {
440
442
  this._catchConsole();
441
443
  }
442
444
 
445
+ setCallback(cb ) {
446
+ this._callback = cb;
447
+ }
448
+
443
449
  configureRemoteClient(configuration = { tag: 'wazo-sdk', host: null, port: null, level: null, extra: {} }) {
444
450
  this.remoteClientConfiguration = configuration;
445
451
  }
@@ -475,6 +481,7 @@ class IssueReporter {
475
481
 
476
482
  // Handle category label
477
483
  let category = null;
484
+ let skipSendToRemote = false;
478
485
  let extra = {};
479
486
  if (args[0].indexOf(CATEGORY_PREFIX) === 0) {
480
487
  category = args[0].split('=')[1];
@@ -490,6 +497,7 @@ class IssueReporter {
490
497
  errorMessage: lastArg.message,
491
498
  errorStack: lastArg.stack,
492
499
  errorType: lastArg.constructor.name,
500
+ skipSendToRemote: lastArg.skipSendToRemote,
493
501
  };
494
502
  } else {
495
503
  extra = lastArg;
@@ -498,6 +506,11 @@ class IssueReporter {
498
506
  args.splice(1, 1);
499
507
  }
500
508
 
509
+ if (extra.skipSendToRemote) {
510
+ skipSendToRemote = true;
511
+ delete extra.skipSendToRemote;
512
+ }
513
+
501
514
  const date = moment__default['default']().format('YYYY-MM-DD HH:mm:ss.SSS');
502
515
  const message = args.join(', ');
503
516
  let consoleMessage = message;
@@ -518,7 +531,13 @@ class IssueReporter {
518
531
  const oldMethod = this.oldConsoleMethods[consoleLevel] || this.oldConsoleMethods.log;
519
532
  oldMethod.apply(oldMethod, [date, consoleMessage]);
520
533
 
521
- this._sendToRemoteLogger(level, { date, message, category, ...extra });
534
+ if (this._callback) {
535
+ this._callback(level, consoleMessage);
536
+ }
537
+
538
+ if (!skipSendToRemote) {
539
+ this._sendToRemoteLogger(level, { date, message, category, ...extra });
540
+ }
522
541
  }
523
542
 
524
543
  logRequest(url , options , response , start ) {
@@ -663,7 +682,11 @@ class IssueReporter {
663
682
  },
664
683
  // $FlowFixMe
665
684
  body,
666
- }).catch(() => {
685
+ }).catch((e ) => {
686
+ // $FlowFixMe
687
+ e.skipSendToRemote = true;
688
+ this.log('error', this._makeCategory('grafana'), 'Sending log to grafana, error', e);
689
+
667
690
  setTimeout(() => {
668
691
  if (isArray) {
669
692
  payload = payload.map(message => {
@@ -675,7 +698,7 @@ class IssueReporter {
675
698
  payload._retry = retry + 1;
676
699
  }
677
700
 
678
- this._sendDebugToGrafana(body, retry + 1);
701
+ this._sendDebugToGrafana(payload, retry + 1);
679
702
  }, 5000 + retry * 1000);
680
703
  });
681
704
  }
@@ -3177,7 +3200,8 @@ class ExternalApp {
3177
3200
 
3178
3201
 
3179
3202
 
3180
-
3203
+
3204
+
3181
3205
 
3182
3206
 
3183
3207
  class Meeting {
@@ -3189,6 +3213,7 @@ class Meeting {
3189
3213
 
3190
3214
 
3191
3215
 
3216
+
3192
3217
 
3193
3218
 
3194
3219
  static parse(plain ) {
@@ -3200,14 +3225,28 @@ class Meeting {
3200
3225
  port: plain.port,
3201
3226
  uuid: plain.uuid,
3202
3227
  number: plain.number,
3228
+ persistent: plain.persistent,
3203
3229
  });
3204
3230
  }
3205
3231
 
3232
+ static parseMany(items ) {
3233
+ return items.map(plain => Meeting.parse(plain));
3234
+ }
3235
+
3206
3236
  static newFrom(meeting ) {
3207
3237
  return newFrom(meeting, Meeting);
3208
3238
  }
3209
3239
 
3210
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number } = {}) {
3240
+ constructor({
3241
+ uuid,
3242
+ name,
3243
+ guestSipAuthorization,
3244
+ ownerUuids,
3245
+ port,
3246
+ uri,
3247
+ number,
3248
+ persistent,
3249
+ } = {}) {
3211
3250
  this.guestSipAuthorization = guestSipAuthorization;
3212
3251
  this.uri = uri;
3213
3252
  this.name = name;
@@ -3215,6 +3254,7 @@ class Meeting {
3215
3254
  this.port = port;
3216
3255
  this.uuid = uuid;
3217
3256
  this.number = number;
3257
+ this.persistent = persistent;
3218
3258
 
3219
3259
  // Useful to compare instead of instanceof with minified code
3220
3260
  this.type = 'Meeting';
@@ -3292,8 +3332,11 @@ var confdMethods = (client , baseUrl ) => ({
3292
3332
  }
3293
3333
  },
3294
3334
 
3295
- createMyMeeting: (name ) =>
3296
- client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
3335
+ getMyMeetings: () =>
3336
+ client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
3337
+
3338
+ createMyMeeting: (name , persistent ) =>
3339
+ client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
3297
3340
 
3298
3341
  deleteMyMeeting: (meetingUuid ) =>
3299
3342
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -3778,7 +3821,7 @@ class Recording {
3778
3821
 
3779
3822
 
3780
3823
 
3781
- static parseMany(recordings ) {
3824
+ static parseMany(recordings = []) {
3782
3825
  return recordings.map(item => Recording.parse(item));
3783
3826
  }
3784
3827
 
@@ -3904,7 +3947,7 @@ class CallLog {
3904
3947
  duration: (plain.duration || 0) * 1000, // duration is in seconds
3905
3948
  start: moment__default['default'](plain.start).toDate(),
3906
3949
  end: plain.end ? moment__default['default'](plain.end).toDate() : null,
3907
- recordings: Recording.parseMany(plain.recordings),
3950
+ recordings: Recording.parseMany(plain.recordings || []),
3908
3951
  });
3909
3952
  }
3910
3953
 
@@ -5299,6 +5342,7 @@ const ON_REINVITE = 'reinvite';
5299
5342
  const ON_ERROR = 'onError';
5300
5343
  const ON_SCREEN_SHARING_REINVITE = 'onScreenSharingReinvite';
5301
5344
  const ON_NETWORK_STATS = 'onNetworkStats';
5345
+ const ON_DISCONNECTED = 'onDisconnected';
5302
5346
 
5303
5347
  const events = [REGISTERED, UNREGISTERED, REGISTRATION_FAILED, INVITE];
5304
5348
  const transportEvents = [CONNECTED, DISCONNECTED, TRANSPORT_ERROR, MESSAGE];
@@ -5375,6 +5419,7 @@ class WebRTCClient extends Emitter {
5375
5419
 
5376
5420
 
5377
5421
 
5422
+
5378
5423
 
5379
5424
  static isAPrivateIp(ip ) {
5380
5425
  const regex = /^(?:10|127|172\.(?:1[6-9]|2[0-9]|3[01])|192\.168)\..*/;
@@ -5440,6 +5485,7 @@ class WebRTCClient extends Emitter {
5440
5485
  this.ON_ERROR = ON_ERROR;
5441
5486
  this.ON_SCREEN_SHARING_REINVITE = ON_SCREEN_SHARING_REINVITE;
5442
5487
  this.ON_NETWORK_STATS = ON_NETWORK_STATS;
5488
+ this.ON_DISCONNECTED = ON_DISCONNECTED;
5443
5489
  }
5444
5490
 
5445
5491
  configureMedia(media ) {
@@ -5705,7 +5751,9 @@ class WebRTCClient extends Emitter {
5705
5751
  const inviteOptions = {
5706
5752
  requestDelegate: {
5707
5753
  onAccept: (response ) => {
5708
- session.sessionDescriptionHandler.peerConnection.sfu = conference;
5754
+ if (session.sessionDescriptionHandler.peerConnection) {
5755
+ session.sessionDescriptionHandler.peerConnection.sfu = conference;
5756
+ }
5709
5757
  this._onAccepted(session, response.session, true);
5710
5758
  },
5711
5759
  onReject: (response ) => {
@@ -6041,7 +6089,7 @@ class WebRTCClient extends Emitter {
6041
6089
  // We search for the last transceiver without `video-` in the mid (video- means remote transceiver)
6042
6090
  const transceivers = pc.getTransceivers();
6043
6091
  const transceiverIdx = lastIndexOf(transceivers, transceiver =>
6044
- transceiver.sender.track === null && transceiver.mid.indexOf('video') === -1);
6092
+ transceiver.sender.track === null && transceiver.mid && transceiver.mid.indexOf('video') === -1);
6045
6093
 
6046
6094
  videoSender = transceiverIdx !== -1 ? transceivers[transceiverIdx].sender : null;
6047
6095
  } else {
@@ -6577,6 +6625,16 @@ class WebRTCClient extends Emitter {
6577
6625
  return this.hasRemoteVideo(sessionId) ? this.getRemoteStream(sessionId) : null;
6578
6626
  }
6579
6627
 
6628
+ // Useful in a react-native environment when remoteMediaStream is not updated
6629
+ getRemoteVideoStreamFromPc(sessionId ) {
6630
+ const pc = this.getPeerConnection(sessionId);
6631
+ if (!pc) {
6632
+ return null;
6633
+ }
6634
+
6635
+ return pc.getRemoteStreams().find(stream => !!stream.getVideoTracks().length);
6636
+ }
6637
+
6580
6638
  hasVideo(sessionId ) {
6581
6639
  return this.hasLocalVideo(sessionId) || this.hasRemoteVideo(sessionId);
6582
6640
  }
@@ -7066,6 +7124,7 @@ class WebRTCClient extends Emitter {
7066
7124
 
7067
7125
  this.updateRemoteStream(this.getSipSessionId(session));
7068
7126
 
7127
+ const pc = session.sessionDescriptionHandler.peerConnection;
7069
7128
  const onTrack = (event ) => {
7070
7129
  const isAudioOnly = this._isAudioOnly(session);
7071
7130
  const { kind, label, readyState, id, muted } = event.track;
@@ -7085,6 +7144,12 @@ class WebRTCClient extends Emitter {
7085
7144
 
7086
7145
  session.sessionDescriptionHandler.remoteMediaStream.onaddtrack = onTrack;
7087
7146
 
7147
+ pc.oniceconnectionstatechange = () => {
7148
+ if (pc.iceConnectionState === 'disconnected') {
7149
+ this.eventEmitter.emit(ON_DISCONNECTED);
7150
+ }
7151
+ };
7152
+
7088
7153
  if (withEvent) {
7089
7154
  this.eventEmitter.emit(ACCEPTED, session, sessionDialog);
7090
7155
  }
@@ -7304,6 +7369,7 @@ class WebRTCClient extends Emitter {
7304
7369
  let videoBytesReceived = 0;
7305
7370
  let transportSent = 0;
7306
7371
  let transportReceived = 0;
7372
+ let packetsLost = 0;
7307
7373
 
7308
7374
  stats.forEach(report => {
7309
7375
  if (report.type === 'outbound-rtp' && report.kind === 'audio') {
@@ -7316,7 +7382,7 @@ class WebRTCClient extends Emitter {
7316
7382
  videoBytesSent += report.bytesSent + report.headerBytesSent;
7317
7383
  }
7318
7384
  if (report.type === 'inbound-rtp' && report.kind === 'audio') {
7319
- networkStats.packetsLost = report.packetsLost;
7385
+ packetsLost += report.packetsLost;
7320
7386
  networkStats.packetsReceived = report.packetsReceived;
7321
7387
  audioBytesReceived += report.bytesReceived + report.headerBytesReceived;
7322
7388
  }
@@ -7333,27 +7399,36 @@ class WebRTCClient extends Emitter {
7333
7399
  }
7334
7400
  }
7335
7401
  if (report.type === 'remote-inbound-rtp' && report.kind === 'audio') {
7402
+ packetsLost += report.packetsLost;
7336
7403
  networkStats.roundTripTime = report.roundTripTime;
7337
7404
  networkStats.jitter = report.jitter;
7338
7405
  }
7406
+ if (report.type === 'remote-inbound-rtp' && report.kind === 'video') {
7407
+ packetsLost += report.packetsLost;
7408
+ }
7339
7409
  if (report.type === 'transport') {
7340
7410
  transportSent += report.bytesSent;
7341
7411
  transportReceived += report.bytesReceived;
7342
7412
  }
7343
7413
  });
7344
7414
 
7345
- networkStats.audioBytesSent = audioBytesSent;
7415
+ networkStats.packetsLost = packetsLost;
7416
+ networkStats.totalAudioBytesSent = audioBytesSent;
7417
+ networkStats.audioBytesSent = audioBytesSent - lastAudioSent;
7418
+ networkStats.totalAudioBytesReceived = audioBytesReceived - lastAudioReceived;
7346
7419
  networkStats.audioBytesReceived = audioBytesReceived;
7347
- networkStats.videoBytesSent = videoBytesSent;
7348
- networkStats.videoBytesReceived = videoBytesReceived;
7420
+ networkStats.totalVideoBytesSent = videoBytesSent;
7421
+ networkStats.videoBytesSent = videoBytesSent - lastVideoSent;
7422
+ networkStats.totalVideoBytesReceived = videoBytesReceived;
7423
+ networkStats.videoBytesReceived = videoBytesReceived - lastVideoReceived;
7424
+ networkStats.totalTransportSent = transportSent - lastTransportSent;
7349
7425
  networkStats.transportSent = transportSent;
7350
- networkStats.transportReceived = transportReceived;
7351
-
7352
- const bandwidth = (networkStats.audioBytesSent - lastAudioSent) + (networkStats.videoBytesSent - lastVideoSent)
7353
- + (networkStats.audioBytesReceived - lastAudioReceived) + (networkStats.videoBytesReceived - lastVideoReceived)
7354
- + (networkStats.transportReceived - lastTransportReceived) + (networkStats.transportSent - lastTransportSent);
7426
+ networkStats.totalTransportReceived = transportReceived;
7427
+ networkStats.transportReceived = transportReceived - lastTransportReceived;
7355
7428
 
7356
- networkStats.bandwidth = bandwidth;
7429
+ networkStats.bandwidth = networkStats.audioBytesSent + networkStats.audioBytesReceived
7430
+ + networkStats.videoBytesSent + networkStats.videoBytesReceived + networkStats.transportReceived
7431
+ + networkStats.transportSent;
7357
7432
 
7358
7433
  this.eventEmitter.emit(ON_NETWORK_STATS, session, networkStats, this.sessionNetworkStats[sessionId]);
7359
7434
  this.sessionNetworkStats[sessionId].push(networkStats);
@@ -131,6 +131,7 @@ class IssueReporter {
131
131
 
132
132
 
133
133
 
134
+
134
135
 
135
136
  constructor() {
136
137
  addLevelsTo(this);
@@ -142,12 +143,17 @@ class IssueReporter {
142
143
  this.bufferTimeout = null;
143
144
  this._boundProcessBuffer = this._processBuffer.bind(this);
144
145
  this._boundParseLoggerBody = this._parseLoggerBody.bind(this);
146
+ this._callback = null;
145
147
  }
146
148
 
147
149
  init() {
148
150
  this._catchConsole();
149
151
  }
150
152
 
153
+ setCallback(cb ) {
154
+ this._callback = cb;
155
+ }
156
+
151
157
  configureRemoteClient(configuration = { tag: 'wazo-sdk', host: null, port: null, level: null, extra: {} }) {
152
158
  this.remoteClientConfiguration = configuration;
153
159
  }
@@ -183,6 +189,7 @@ class IssueReporter {
183
189
 
184
190
  // Handle category label
185
191
  let category = null;
192
+ let skipSendToRemote = false;
186
193
  let extra = {};
187
194
  if (args[0].indexOf(CATEGORY_PREFIX) === 0) {
188
195
  category = args[0].split('=')[1];
@@ -198,6 +205,7 @@ class IssueReporter {
198
205
  errorMessage: lastArg.message,
199
206
  errorStack: lastArg.stack,
200
207
  errorType: lastArg.constructor.name,
208
+ skipSendToRemote: lastArg.skipSendToRemote,
201
209
  };
202
210
  } else {
203
211
  extra = lastArg;
@@ -206,6 +214,11 @@ class IssueReporter {
206
214
  args.splice(1, 1);
207
215
  }
208
216
 
217
+ if (extra.skipSendToRemote) {
218
+ skipSendToRemote = true;
219
+ delete extra.skipSendToRemote;
220
+ }
221
+
209
222
  const date = moment__default['default']().format('YYYY-MM-DD HH:mm:ss.SSS');
210
223
  const message = args.join(', ');
211
224
  let consoleMessage = message;
@@ -226,7 +239,13 @@ class IssueReporter {
226
239
  const oldMethod = this.oldConsoleMethods[consoleLevel] || this.oldConsoleMethods.log;
227
240
  oldMethod.apply(oldMethod, [date, consoleMessage]);
228
241
 
229
- this._sendToRemoteLogger(level, { date, message, category, ...extra });
242
+ if (this._callback) {
243
+ this._callback(level, consoleMessage);
244
+ }
245
+
246
+ if (!skipSendToRemote) {
247
+ this._sendToRemoteLogger(level, { date, message, category, ...extra });
248
+ }
230
249
  }
231
250
 
232
251
  logRequest(url , options , response , start ) {
@@ -371,7 +390,11 @@ class IssueReporter {
371
390
  },
372
391
  // $FlowFixMe
373
392
  body,
374
- }).catch(() => {
393
+ }).catch((e ) => {
394
+ // $FlowFixMe
395
+ e.skipSendToRemote = true;
396
+ this.log('error', this._makeCategory('grafana'), 'Sending log to grafana, error', e);
397
+
375
398
  setTimeout(() => {
376
399
  if (isArray) {
377
400
  payload = payload.map(message => {
@@ -383,7 +406,7 @@ class IssueReporter {
383
406
  payload._retry = retry + 1;
384
407
  }
385
408
 
386
- this._sendDebugToGrafana(body, retry + 1);
409
+ this._sendDebugToGrafana(payload, retry + 1);
387
410
  }, 5000 + retry * 1000);
388
411
  });
389
412
  }
@@ -588,6 +611,7 @@ const AGENT_PAUSED = 'agent_paused';
588
611
  const AGENT_UNPAUSED = 'agent_unpaused';
589
612
  const CONFERENCE_ADHOC_PARTICIPANT_LEFT = 'conference_adhoc_participant_left';
590
613
  const CONFERENCE_ADHOC_DELETED = 'conference_adhoc_deleted';
614
+ const MEETING_USER_PROGRESS = 'meeting_user_progress';
591
615
 
592
616
  const BLACKLIST_EVENTS = [
593
617
  CHAT_MESSAGE_SENT,
@@ -938,6 +962,7 @@ WebSocketClient.eventLists = [
938
962
  AGENT_UNPAUSED,
939
963
  CONFERENCE_ADHOC_PARTICIPANT_LEFT,
940
964
  CONFERENCE_ADHOC_DELETED,
965
+ MEETING_USER_PROGRESS,
941
966
  ];
942
967
 
943
968
  exports.AGENT_PAUSED = AGENT_PAUSED;
@@ -993,6 +1018,7 @@ exports.HEARTBEAT_ENGINE_VERSION = HEARTBEAT_ENGINE_VERSION;
993
1018
  exports.LINE_STATUS_UPDATED = LINE_STATUS_UPDATED;
994
1019
  exports.MEETING_USER_PARTICIPANT_JOINED = MEETING_USER_PARTICIPANT_JOINED;
995
1020
  exports.MEETING_USER_PARTICIPANT_LEFT = MEETING_USER_PARTICIPANT_LEFT;
1021
+ exports.MEETING_USER_PROGRESS = MEETING_USER_PROGRESS;
996
1022
  exports.SOCKET_EVENTS = SOCKET_EVENTS;
997
1023
  exports.SWITCHBOARD_HELD_CALLS_UPDATED = SWITCHBOARD_HELD_CALLS_UPDATED;
998
1024
  exports.SWITCHBOARD_HELD_CALL_ANSWERED = SWITCHBOARD_HELD_CALL_ANSWERED;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wazo/sdk",
3
- "version": "0.37.17",
3
+ "version": "0.37.21",
4
4
  "description": "Wazo's JavaScript Software Development Kit.",
5
5
  "main": "dist/wazo-sdk.js",
6
6
  "author": "Wazo (http://wazo.io)",
@@ -47,7 +47,7 @@
47
47
  "dependencies": {
48
48
  "events": "^3.3.0",
49
49
  "fstream": "^1.0.12",
50
- "getstats": "manuquentin/getStats#fix_undefined_results",
50
+ "getstats": "manuquentin/getStats#fix_stats_mobile",
51
51
  "globby": "^11.0.3",
52
52
  "google-libphonenumber": "^3.2.18",
53
53
  "js-base64": "^3.6.0",
package/src/api/confd.js CHANGED
@@ -69,8 +69,11 @@ export default (client: ApiRequester, baseUrl: string) => ({
69
69
  }
70
70
  },
71
71
 
72
- createMyMeeting: (name: string): Promise<Meeting> =>
73
- client.post(`${baseUrl}/users/me/meetings`, { name }).then(Meeting.parse),
72
+ getMyMeetings: (): Promise<Meeting> =>
73
+ client.get(`${baseUrl}/users/me/meetings`).then(response => Meeting.parseMany(response.items)),
74
+
75
+ createMyMeeting: (name: string, persistent: boolean): Promise<Meeting> =>
76
+ client.post(`${baseUrl}/users/me/meetings`, { name, persistent }).then(Meeting.parse),
74
77
 
75
78
  deleteMyMeeting: (meetingUuid: string): Promise<Meeting> =>
76
79
  client.delete(`${baseUrl}/users/me/meetings/${meetingUuid}`, null),
@@ -108,7 +108,7 @@ export default class CallLog {
108
108
  duration: (plain.duration || 0) * 1000, // duration is in seconds
109
109
  start: moment(plain.start).toDate(),
110
110
  end: plain.end ? moment(plain.end).toDate() : null,
111
- recordings: Recording.parseMany(plain.recordings),
111
+ recordings: Recording.parseMany(plain.recordings || []),
112
112
  });
113
113
  }
114
114
 
@@ -8,7 +8,8 @@ export type MeetingCreationResponse = {
8
8
  owner_uuids: Array<string>,
9
9
  port: string,
10
10
  uuid: string,
11
- number: string
11
+ number: string,
12
+ persistent: boolean,
12
13
  }
13
14
 
14
15
  export default class Meeting {
@@ -20,6 +21,7 @@ export default class Meeting {
20
21
  name: string;
21
22
  port: string;
22
23
  number: string;
24
+ persistent: boolean;
23
25
  ownerUuids: Array<string>;
24
26
 
25
27
  static parse(plain: MeetingCreationResponse): Meeting {
@@ -31,14 +33,28 @@ export default class Meeting {
31
33
  port: plain.port,
32
34
  uuid: plain.uuid,
33
35
  number: plain.number,
36
+ persistent: plain.persistent,
34
37
  });
35
38
  }
36
39
 
40
+ static parseMany(items: MeetingCreationResponse[]): Array<Meeting> {
41
+ return items.map(plain => Meeting.parse(plain));
42
+ }
43
+
37
44
  static newFrom(meeting: Meeting) {
38
45
  return newFrom(meeting, Meeting);
39
46
  }
40
47
 
41
- constructor({ uuid, name, guestSipAuthorization, ownerUuids, port, uri, number }: Object = {}) {
48
+ constructor({
49
+ uuid,
50
+ name,
51
+ guestSipAuthorization,
52
+ ownerUuids,
53
+ port,
54
+ uri,
55
+ number,
56
+ persistent,
57
+ }: Object = {}) {
42
58
  this.guestSipAuthorization = guestSipAuthorization;
43
59
  this.uri = uri;
44
60
  this.name = name;
@@ -46,6 +62,7 @@ export default class Meeting {
46
62
  this.port = port;
47
63
  this.uuid = uuid;
48
64
  this.number = number;
65
+ this.persistent = persistent;
49
66
 
50
67
  // Useful to compare instead of instanceof with minified code
51
68
  this.type = 'Meeting';
@@ -52,6 +52,7 @@ export const ON_MESSAGE_TRACK_UPDATED = 'onTrackUpdated';
52
52
  export const ON_NETWORK_STATS = 'onNetworkStats';
53
53
  export const ON_CHAT = 'phone/ON_CHAT';
54
54
  export const ON_SIGNAL = 'phone/ON_SIGNAL';
55
+ export const ON_DISCONNECTED = 'onDisconnected';
55
56
 
56
57
  export const MESSAGE_TYPE_CHAT = 'message/TYPE_CHAT';
57
58
  export const MESSAGE_TYPE_SIGNAL = 'message/TYPE_SIGNAL';
@@ -91,6 +92,7 @@ export const events = [
91
92
  ON_CHAT,
92
93
  ON_SIGNAL,
93
94
  ON_NETWORK_STATS,
95
+ ON_DISCONNECTED,
94
96
  ];
95
97
 
96
98
  const logger = IssueReporter.loggerFor('webrtc-phone');
@@ -412,9 +414,11 @@ export default class WebRTCPhone extends Emitter implements Phone {
412
414
  case SessionState.Terminated: {
413
415
  logger.info('WebRTC phone - call terminated', { sipId: sipSession.id });
414
416
 
417
+ // Should be called before `_onCallTerminated` or the callCount will not decrement...
418
+ const callSession = this._createCallSession(sipSession);
415
419
  const wasCurrentSession = this._onCallTerminated(sipSession);
416
420
 
417
- return this.eventEmitter.emit(ON_CALL_ENDED, this._createCallSession(sipSession), wasCurrentSession);
421
+ return this.eventEmitter.emit(ON_CALL_ENDED, callSession, wasCurrentSession);
418
422
  }
419
423
  default:
420
424
  break;
@@ -1364,6 +1368,10 @@ export default class WebRTCPhone extends Emitter implements Phone {
1364
1368
  return callSession ? this.client.getRemoteVideoStream(callSession.sipCallId) : null;
1365
1369
  }
1366
1370
 
1371
+ getRemoteVideoStreamFromPc(callSession: CallSession): ?MediaStream {
1372
+ return callSession ? this.client.getRemoteVideoStreamFromPc(callSession.sipCallId) : null;
1373
+ }
1374
+
1367
1375
  hasRemoteVideo(callSession: CallSession): boolean {
1368
1376
  return callSession ? this.client.hasRemoteVideo(callSession.sipCallId) : false;
1369
1377
  }
@@ -1445,6 +1453,11 @@ export default class WebRTCPhone extends Emitter implements Phone {
1445
1453
  this.eventEmitter.emit(ON_UNREGISTERED);
1446
1454
  });
1447
1455
 
1456
+ this.client.on(this.client.ON_DISCONNECTED, () => {
1457
+ logger.info('WebRTC disconnected');
1458
+ this.eventEmitter.emit(ON_DISCONNECTED);
1459
+ });
1460
+
1448
1461
  this.client.on(this.client.REGISTERED, () => {
1449
1462
  logger.info('WebRTC registered', {
1450
1463
  shouldSendReinvite: this.shouldSendReinvite,
@@ -24,7 +24,7 @@ export default class Recording {
24
24
  start: Date;
25
25
  uuid: string;
26
26
 
27
- static parseMany(recordings: RecordingResponse[]): Recording[] {
27
+ static parseMany(recordings: RecordingResponse[] = []): Recording[] {
28
28
  return recordings.map(item => Recording.parse(item));
29
29
  }
30
30
 
@@ -64,6 +64,7 @@ class IssueReporter {
64
64
  bufferTimeout: ?TimeoutID;
65
65
  _boundProcessBuffer: Function;
66
66
  _boundParseLoggerBody: Function;
67
+ _callback: ?Function;
67
68
 
68
69
  constructor() {
69
70
  addLevelsTo(this);
@@ -75,12 +76,17 @@ class IssueReporter {
75
76
  this.bufferTimeout = null;
76
77
  this._boundProcessBuffer = this._processBuffer.bind(this);
77
78
  this._boundParseLoggerBody = this._parseLoggerBody.bind(this);
79
+ this._callback = null;
78
80
  }
79
81
 
80
82
  init() {
81
83
  this._catchConsole();
82
84
  }
83
85
 
86
+ setCallback(cb: Function) {
87
+ this._callback = cb;
88
+ }
89
+
84
90
  configureRemoteClient(configuration: Object = { tag: 'wazo-sdk', host: null, port: null, level: null, extra: {} }) {
85
91
  this.remoteClientConfiguration = configuration;
86
92
  }
@@ -116,6 +122,7 @@ class IssueReporter {
116
122
 
117
123
  // Handle category label
118
124
  let category = null;
125
+ let skipSendToRemote = false;
119
126
  let extra = {};
120
127
  if (args[0].indexOf(CATEGORY_PREFIX) === 0) {
121
128
  category = args[0].split('=')[1];
@@ -131,6 +138,7 @@ class IssueReporter {
131
138
  errorMessage: lastArg.message,
132
139
  errorStack: lastArg.stack,
133
140
  errorType: lastArg.constructor.name,
141
+ skipSendToRemote: lastArg.skipSendToRemote,
134
142
  };
135
143
  } else {
136
144
  extra = lastArg;
@@ -139,6 +147,11 @@ class IssueReporter {
139
147
  args.splice(1, 1);
140
148
  }
141
149
 
150
+ if (extra.skipSendToRemote) {
151
+ skipSendToRemote = true;
152
+ delete extra.skipSendToRemote;
153
+ }
154
+
142
155
  const date = moment().format('YYYY-MM-DD HH:mm:ss.SSS');
143
156
  const message = args.join(', ');
144
157
  let consoleMessage = message;
@@ -159,7 +172,13 @@ class IssueReporter {
159
172
  const oldMethod = this.oldConsoleMethods[consoleLevel] || this.oldConsoleMethods.log;
160
173
  oldMethod.apply(oldMethod, [date, consoleMessage]);
161
174
 
162
- this._sendToRemoteLogger(level, { date, message, category, ...extra });
175
+ if (this._callback) {
176
+ this._callback(level, consoleMessage);
177
+ }
178
+
179
+ if (!skipSendToRemote) {
180
+ this._sendToRemoteLogger(level, { date, message, category, ...extra });
181
+ }
163
182
  }
164
183
 
165
184
  logRequest(url: string, options: Object, response: Object, start: Date) {
@@ -304,7 +323,11 @@ class IssueReporter {
304
323
  },
305
324
  // $FlowFixMe
306
325
  body,
307
- }).catch(() => {
326
+ }).catch((e: Error) => {
327
+ // $FlowFixMe
328
+ e.skipSendToRemote = true;
329
+ this.log('error', this._makeCategory('grafana'), 'Sending log to grafana, error', e);
330
+
308
331
  setTimeout(() => {
309
332
  if (isArray) {
310
333
  payload = payload.map(message => {
@@ -316,7 +339,7 @@ class IssueReporter {
316
339
  payload._retry = retry + 1;
317
340
  }
318
341
 
319
- this._sendDebugToGrafana(body, retry + 1);
342
+ this._sendDebugToGrafana(payload, retry + 1);
320
343
  }, 5000 + retry * 1000);
321
344
  });
322
345
  }
@@ -347,6 +347,11 @@ class Phone extends Emitter {
347
347
  return this.getRemoteVideoStream(callSession);
348
348
  }
349
349
 
350
+ // Useful in a react-native environment when remoteMediaStream is not updated
351
+ getRemoteVideoStreamFromPc(callSession: CallSession) {
352
+ return this.phone ? this.phone.getRemoteVideoStreamFromPc(callSession) : false;
353
+ }
354
+
350
355
  hasVideo(callSession: CallSession): boolean {
351
356
  return this.phone ? this.phone.hasVideo(callSession) : false;
352
357
  }