genesys-cloud-streaming-client 16.1.3 → 16.2.0-develop.70

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.
@@ -48,7 +48,8 @@ class Client extends events_1.default {
48
48
  jidResource: options.jidResource,
49
49
  channelId: null,
50
50
  appName: options.appName,
51
- appVersion: options.appVersion
51
+ appVersion: options.appVersion,
52
+ appId: options.appId
52
53
  };
53
54
  this.backgroundAssistantMode = this.checkIsBackgroundAssistant();
54
55
  this.isGuest = !this.backgroundAssistantMode && !options.authToken;
@@ -433,7 +434,7 @@ class Client extends events_1.default {
433
434
  return Client.version;
434
435
  }
435
436
  static get version() {
436
- return '16.1.3';
437
+ return '16.2.0';
437
438
  }
438
439
  }
439
440
  exports.Client = Client;
@@ -1,7 +1,6 @@
1
1
  import { StatsEvent } from 'webrtc-stats-gatherer';
2
- export declare function formatStatsEvent(event: StatsEvent, extraDetails?: any): {
3
- actionName: string;
4
- actionDate: number;
5
- details: any;
6
- };
2
+ import { FlatObject, InsightAction } from './types/interfaces';
3
+ export declare function formatStatsEvent(event: StatsEvent, extraDetails?: FlatObject): InsightAction<{
4
+ _eventType: string;
5
+ } & FlatObject>;
7
6
  export declare function deepFlatten(obj: any, prefix?: string): any;
@@ -1,43 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.deepFlatten = exports.formatStatsEvent = void 0;
4
+ function isGetStatsEvent(event) {
5
+ return event.name === 'getStats';
6
+ }
7
+ function prepGetStatsEvent(event) {
8
+ let details = {};
9
+ Object.assign(details, deepFlatten(event.tracks, 'localTrack'));
10
+ delete event.tracks;
11
+ Object.assign(details, deepFlatten(event.remoteTracks, `remoteTrack`));
12
+ delete event.remoteTracks;
13
+ return details;
14
+ }
4
15
  function formatStatsEvent(event, extraDetails = {}) {
5
- let details;
6
- const eventType = event.name;
7
- if (event.name === 'connect') {
8
- const e = event;
9
- details = e;
10
- Object.assign(details, deepFlatten(e.candidatePairDetails, 'candidatePairDetails'));
11
- delete details.candidatePairDetails;
12
- }
13
- else if (event.name === 'getStats') {
14
- const e = event;
15
- details = e;
16
- Object.assign(details, deepFlatten(e.tracks, 'localTrack'));
17
- delete details.tracks;
18
- Object.assign(details, deepFlatten(e.remoteTracks, `remoteTrack`));
19
- delete details.remoteTracks;
20
- }
21
- else {
22
- details = {};
23
- if (event.name !== 'failure') {
24
- // TODO: log this out when we get genesys-cloud-client-logger in place (allows logging from anywhere)
25
- }
26
- Object.assign(details, deepFlatten(event));
16
+ const details = {
17
+ _eventType: event.name,
18
+ _eventTimestamp: new Date().toISOString(),
19
+ ...extraDetails
20
+ };
21
+ // anything that needs to be renamed or massaged
22
+ if (isGetStatsEvent(event)) {
23
+ Object.assign(details, prepGetStatsEvent(event));
27
24
  }
25
+ // general case
26
+ Object.assign(details, deepFlatten(event));
28
27
  delete details.name;
29
- Object.assign(details, extraDetails, { '_eventType': eventType });
30
- // new relic doesn't accept booleans so we convert them to strings
31
- Object.keys(details).forEach((key) => {
32
- const val = details[key];
33
- if (typeof val === 'boolean') {
34
- details[key] = `${val}`;
35
- }
36
- });
37
28
  const formattedEvent = {
38
29
  actionName: 'WebrtcStats',
39
- actionDate: Date.now(),
40
- details
30
+ details,
41
31
  };
42
32
  return formattedEvent;
43
33
  }
@@ -186,3 +186,60 @@ export declare type HeadsetControlsRequest = TypedJsonRpcMessage<'headsetControl
186
186
  export declare type HeadsetControlsRejection = TypedJsonRpcMessage<'headsetControlsRejection', HeadsetControlsRejectionParams>;
187
187
  export declare type HeadsetControlsChanged = TypedJsonRpcMessage<'headsetControlsChanged', HeadsetControlsChangedParams>;
188
188
  export declare type GenesysMediaMessage = HeadsetControlsRequest | HeadsetControlsRejection | HeadsetControlsChanged;
189
+ export declare type FlatObject = {
190
+ [key: string]: string | number | boolean | null | Date;
191
+ };
192
+ export declare type GenericAction = {
193
+ _eventType: string;
194
+ };
195
+ export declare type InsightReport = {
196
+ appName: string;
197
+ appVersion: string;
198
+ originAppName?: string;
199
+ originAppVersion?: string;
200
+ actions: InsightAction<any>[];
201
+ };
202
+ export declare type InsightAction<T extends {
203
+ _eventType: string;
204
+ }> = {
205
+ actionName: 'WebrtcStats';
206
+ details: InsightActionDetails<T>;
207
+ };
208
+ export declare type InsightActionDetails<K extends {
209
+ _eventType: string;
210
+ }> = {
211
+ _eventType: K['_eventType'];
212
+ /**
213
+ * This should be an ISO string
214
+ */
215
+ _eventTimestamp: string;
216
+ _appId?: string;
217
+ _appName?: string;
218
+ _appVersion?: string;
219
+ } & K;
220
+ export declare type FirstProposeStat = InsightAction<{
221
+ _eventType: 'firstPropose';
222
+ sdpViaXmppRequested: boolean;
223
+ sessionType: SessionTypesAsStrings;
224
+ originAppId?: string;
225
+ conversationId: string;
226
+ sessionId: string;
227
+ }>;
228
+ export declare type FirstAlertingConversationStat = InsightAction<{
229
+ _eventType: 'firstAlertingConversationUpdate';
230
+ conversationId: string;
231
+ participantId: string;
232
+ }>;
233
+ export declare type MediaStat = InsightAction<{
234
+ _eventType: 'mediaRequested' | 'mediaStarted' | 'mediaError';
235
+ requestId?: string;
236
+ message?: string;
237
+ audioRequested: boolean;
238
+ videoRequested: boolean;
239
+ displayRequested: boolean;
240
+ conversationId?: string;
241
+ sessionType?: SessionTypesAsStrings;
242
+ sessionId?: string;
243
+ elapsedMsFromInitialRequest?: number;
244
+ }>;
245
+ export declare type NRProxyStat = FirstAlertingConversationStat | MediaStat;
@@ -4,7 +4,7 @@ import { IQ } from 'stanza/protocol';
4
4
  import { SessionManager } from 'stanza/jingle';
5
5
  import { SessionOpts } from 'stanza/jingle/Session';
6
6
  import { Client } from './client';
7
- import { ExtendedRTCIceServer, IClientOptions, SessionTypes, IPendingSession, StreamingClientExtension } from './types/interfaces';
7
+ import { ExtendedRTCIceServer, IClientOptions, SessionTypes, IPendingSession, StreamingClientExtension, NRProxyStat, InsightAction } from './types/interfaces';
8
8
  import { NamedAgent } from './types/named-agent';
9
9
  import { StanzaMediaSession } from './types/stanza-media-session';
10
10
  import { IMediaSession } from './types/media-session';
@@ -54,6 +54,9 @@ export declare class WebrtcExtension extends EventEmitter implements StreamingCl
54
54
  handleGenesysWebrtcStanza(iq: IQ): Promise<boolean | void>;
55
55
  prepareSession(options: SessionOpts): StanzaMediaSession | undefined;
56
56
  proxyStatsForSession(session: IMediaSession): void;
57
+ addStatToQueue<T extends {
58
+ _eventType: string;
59
+ }>(stat: InsightAction<T>): void;
57
60
  getLogDetailsForPendingSessionId(sessionId: string): {
58
61
  conversationId?: string;
59
62
  sessionId: string;
@@ -89,6 +92,7 @@ export declare class WebrtcExtension extends EventEmitter implements StreamingCl
89
92
  getSessionTypeByJid(jid: string): SessionTypes;
90
93
  getSessionManager(): SessionManager | undefined;
91
94
  getAllSessions(): IMediaSession[];
95
+ proxyNRStat(stat: NRProxyStat): void;
92
96
  get expose(): WebrtcExtensionAPI;
93
97
  }
94
98
  export interface WebrtcExtensionAPI {
@@ -108,4 +112,5 @@ export interface WebrtcExtensionAPI {
108
112
  getSessionTypeByJid(jid: string): SessionTypes;
109
113
  getSessionManager: () => SessionManager | undefined;
110
114
  getAllSessions: () => IMediaSession[];
115
+ proxyNRStat: (stat: NRProxyStat) => void;
111
116
  }
@@ -162,6 +162,7 @@ class WebrtcExtension extends events_1.EventEmitter {
162
162
  }
163
163
  const session = new genesys_cloud_media_session_1.GenesysCloudMediaSession(this, mediaSessionParams);
164
164
  await session.setRemoteDescription(params.sdp);
165
+ this.proxyStatsForSession(session);
165
166
  session.on('sendIq', (iq) => { var _a; return (_a = this.stanzaInstance) === null || _a === void 0 ? void 0 : _a.sendIQ(iq); });
166
167
  session.on('terminated', () => {
167
168
  this.webrtcSessions = this.webrtcSessions.filter(s => s.id !== session.id);
@@ -262,25 +263,51 @@ class WebrtcExtension extends events_1.EventEmitter {
262
263
  }
263
264
  const statsCopy = JSON.parse(JSON.stringify(statsEvent));
264
265
  const extraDetails = {
265
- conference: session.conversationId,
266
- session: session.id,
266
+ conversationId: session.conversationId,
267
+ sessionId: session.id,
267
268
  sessionType: session.sessionType
268
269
  };
269
270
  // format the event to what the api expects
270
271
  const event = stats_formatter_1.formatStatsEvent(statsCopy, extraDetails);
271
- const currentEventSize = utils_1.calculatePayloadSize(event);
272
- // Check if the size of the current event plus the size of the previous stats exceeds max size.
273
- const exceedsMaxStatSize = this.statBuffer + currentEventSize > this.currentMaxStatSize;
274
- this.statsArr.push(event);
275
- this.statBuffer += currentEventSize;
276
- // If it exceeds max size, don't append just send current payload.
277
- if (exceedsMaxStatSize) {
278
- this.flushStats();
279
- }
280
- else {
281
- this.throttledSendStats();
272
+ this.addStatToQueue(event);
273
+ });
274
+ }
275
+ // this fn checks to see if the new stat fits inside the buffer. If not, send the queue;
276
+ addStatToQueue(stat) {
277
+ if (this.config.optOutOfWebrtcStatsTelemetry) {
278
+ return;
279
+ }
280
+ if (!stat.details._appId) {
281
+ stat.details._appId = this.logger.clientId;
282
+ stat.details._appName = 'streamingclient';
283
+ stat.details._appVersion = client_1.Client.version;
284
+ }
285
+ stat.details._originAppId = this.client.config.appId;
286
+ // nr only accepts single level objects so we must flatten everything just in case
287
+ const flattenedDetails = stats_formatter_1.deepFlatten(stat.details);
288
+ // new relic doesn't accept booleans so we convert them to strings
289
+ Object.keys(flattenedDetails).forEach((key) => {
290
+ const val = flattenedDetails[key];
291
+ if (typeof val === 'boolean') {
292
+ flattenedDetails[key] = `${val}`;
282
293
  }
283
294
  });
295
+ const formattedStat = {
296
+ ...stat,
297
+ details: flattenedDetails
298
+ };
299
+ const currentEventSize = utils_1.calculatePayloadSize(formattedStat);
300
+ // Check if the size of the current event plus the size of the previous stats exceeds max size.
301
+ const exceedsMaxStatSize = this.statBuffer + currentEventSize > this.currentMaxStatSize;
302
+ this.statsArr.push(formattedStat);
303
+ this.statBuffer += currentEventSize;
304
+ // If it exceeds max size, don't append just send current payload.
305
+ if (exceedsMaxStatSize) {
306
+ this.flushStats();
307
+ }
308
+ else {
309
+ this.throttledSendStats();
310
+ }
284
311
  }
285
312
  getLogDetailsForPendingSessionId(sessionId) {
286
313
  const logDetails = {
@@ -388,6 +415,19 @@ class WebrtcExtension extends events_1.EventEmitter {
388
415
  const loggingParams = { sessionId: sessionId, conversationId: msg.propose.conversationId, sessionType, isDuplicatePropose };
389
416
  this.logger.info('propose received', loggingParams);
390
417
  if (!isDuplicatePropose) {
418
+ const { appId } = this.client.config;
419
+ const proposeStat = {
420
+ actionName: 'WebrtcStats',
421
+ details: {
422
+ _eventTimestamp: new Date().toISOString(),
423
+ _eventType: 'firstPropose',
424
+ conversationId: loggingParams.conversationId,
425
+ sdpViaXmppRequested: !!msg.propose.sdpOverXmpp,
426
+ sessionId: sessionId,
427
+ sessionType: sessionType,
428
+ }
429
+ };
430
+ this.addStatToQueue(proposeStat);
391
431
  // TODO: is ofrom used?
392
432
  // const roomJid = (msg.ofrom && msg.ofrom.full) || msg.from.full || msg.from;
393
433
  const fromJid = msg.from;
@@ -706,6 +746,9 @@ class WebrtcExtension extends events_1.EventEmitter {
706
746
  const stanzaSessions = stanzaSessionsObj && Object.values(stanzaSessionsObj) || [];
707
747
  return [...stanzaSessions, ...this.webrtcSessions];
708
748
  }
749
+ proxyNRStat(stat) {
750
+ this.addStatToQueue(stat);
751
+ }
709
752
  get expose() {
710
753
  return {
711
754
  on: this.on.bind(this),
@@ -723,7 +766,8 @@ class WebrtcExtension extends events_1.EventEmitter {
723
766
  initiateRtcSession: this.initiateRtcSession.bind(this),
724
767
  getSessionTypeByJid: this.getSessionTypeByJid.bind(this),
725
768
  getSessionManager: this.getSessionManager.bind(this),
726
- getAllSessions: this.getAllSessions.bind(this)
769
+ getAllSessions: this.getAllSessions.bind(this),
770
+ proxyNRStat: this.proxyNRStat.bind(this)
727
771
  };
728
772
  }
729
773
  }
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "developercenter-cdn/streaming-client",
3
- "version": "16.1.3",
3
+ "version": "16.2.0",
4
4
  "ecosystem": "pc",
5
5
  "team": "Genesys Client Media (WebRTC)",
6
6
  "indexFiles": [
7
7
  {
8
- "file": "v16.1.3/streaming-client.browser.ie.js"
8
+ "file": "v16.2.0/streaming-client.browser.ie.js"
9
9
  },
10
10
  {
11
- "file": "v16.1.3/streaming-client.browser.js"
11
+ "file": "v16.2.0/streaming-client.browser.js"
12
12
  },
13
13
  {
14
14
  "file": "v16/streaming-client.browser.ie.js"
@@ -17,6 +17,6 @@
17
17
  "file": "v16/streaming-client.browser.js"
18
18
  }
19
19
  ],
20
- "build": "81",
21
- "buildDate": "2023-12-08T18:10:28.471638Z"
20
+ "build": "70",
21
+ "buildDate": "2023-12-13T20:34:29.758938Z"
22
22
  }
package/dist/es/client.js CHANGED
@@ -46,7 +46,8 @@ export class Client extends EventEmitter {
46
46
  jidResource: options.jidResource,
47
47
  channelId: null,
48
48
  appName: options.appName,
49
- appVersion: options.appVersion
49
+ appVersion: options.appVersion,
50
+ appId: options.appId
50
51
  };
51
52
  this.backgroundAssistantMode = this.checkIsBackgroundAssistant();
52
53
  this.isGuest = !this.backgroundAssistantMode && !options.authToken;
@@ -443,6 +444,6 @@ export class Client extends EventEmitter {
443
444
  return Client.version;
444
445
  }
445
446
  static get version() {
446
- return '16.1.3';
447
+ return '16.2.0';
447
448
  }
448
449
  }
@@ -18114,41 +18114,29 @@ const definitions = [
18114
18114
  mediaMessage
18115
18115
  ];
18116
18116
 
18117
+ function isGetStatsEvent(event) {
18118
+ return event.name === 'getStats';
18119
+ }
18120
+ function prepGetStatsEvent(event) {
18121
+ let details = {};
18122
+ Object.assign(details, deepFlatten(event.tracks, 'localTrack'));
18123
+ delete event.tracks;
18124
+ Object.assign(details, deepFlatten(event.remoteTracks, `remoteTrack`));
18125
+ delete event.remoteTracks;
18126
+ return details;
18127
+ }
18117
18128
  function formatStatsEvent(event, extraDetails = {}) {
18118
- let details;
18119
- const eventType = event.name;
18120
- if (event.name === 'connect') {
18121
- const e = event;
18122
- details = e;
18123
- Object.assign(details, deepFlatten(e.candidatePairDetails, 'candidatePairDetails'));
18124
- delete details.candidatePairDetails;
18125
- }
18126
- else if (event.name === 'getStats') {
18127
- const e = event;
18128
- details = e;
18129
- Object.assign(details, deepFlatten(e.tracks, 'localTrack'));
18130
- delete details.tracks;
18131
- Object.assign(details, deepFlatten(e.remoteTracks, `remoteTrack`));
18132
- delete details.remoteTracks;
18133
- }
18134
- else {
18135
- details = {};
18136
- if (event.name !== 'failure') ;
18137
- Object.assign(details, deepFlatten(event));
18129
+ const details = Object.assign({ _eventType: event.name, _eventTimestamp: new Date().toISOString() }, extraDetails);
18130
+ // anything that needs to be renamed or massaged
18131
+ if (isGetStatsEvent(event)) {
18132
+ Object.assign(details, prepGetStatsEvent(event));
18138
18133
  }
18134
+ // general case
18135
+ Object.assign(details, deepFlatten(event));
18139
18136
  delete details.name;
18140
- Object.assign(details, extraDetails, { '_eventType': eventType });
18141
- // new relic doesn't accept booleans so we convert them to strings
18142
- Object.keys(details).forEach((key) => {
18143
- const val = details[key];
18144
- if (typeof val === 'boolean') {
18145
- details[key] = `${val}`;
18146
- }
18147
- });
18148
18137
  const formattedEvent = {
18149
18138
  actionName: 'WebrtcStats',
18150
- actionDate: Date.now(),
18151
- details
18139
+ details,
18152
18140
  };
18153
18141
  return formattedEvent;
18154
18142
  }
@@ -29466,6 +29454,7 @@ class WebrtcExtension extends EventEmitter {
29466
29454
  }
29467
29455
  const session = new GenesysCloudMediaSession(this, mediaSessionParams);
29468
29456
  yield session.setRemoteDescription(params.sdp);
29457
+ this.proxyStatsForSession(session);
29469
29458
  session.on('sendIq', (iq) => { var _a; return (_a = this.stanzaInstance) === null || _a === void 0 ? void 0 : _a.sendIQ(iq); });
29470
29459
  session.on('terminated', () => {
29471
29460
  this.webrtcSessions = this.webrtcSessions.filter(s => s.id !== session.id);
@@ -29577,26 +29566,49 @@ class WebrtcExtension extends EventEmitter {
29577
29566
  }
29578
29567
  const statsCopy = JSON.parse(JSON.stringify(statsEvent));
29579
29568
  const extraDetails = {
29580
- conference: session.conversationId,
29581
- session: session.id,
29569
+ conversationId: session.conversationId,
29570
+ sessionId: session.id,
29582
29571
  sessionType: session.sessionType
29583
29572
  };
29584
29573
  // format the event to what the api expects
29585
29574
  const event = formatStatsEvent(statsCopy, extraDetails);
29586
- const currentEventSize = calculatePayloadSize(event);
29587
- // Check if the size of the current event plus the size of the previous stats exceeds max size.
29588
- const exceedsMaxStatSize = this.statBuffer + currentEventSize > this.currentMaxStatSize;
29589
- this.statsArr.push(event);
29590
- this.statBuffer += currentEventSize;
29591
- // If it exceeds max size, don't append just send current payload.
29592
- if (exceedsMaxStatSize) {
29593
- this.flushStats();
29594
- }
29595
- else {
29596
- this.throttledSendStats();
29597
- }
29575
+ this.addStatToQueue(event);
29598
29576
  });
29599
29577
  }
29578
+ // this fn checks to see if the new stat fits inside the buffer. If not, send the queue;
29579
+ addStatToQueue(stat) {
29580
+ if (this.config.optOutOfWebrtcStatsTelemetry) {
29581
+ return;
29582
+ }
29583
+ if (!stat.details._appId) {
29584
+ stat.details._appId = this.logger.clientId;
29585
+ stat.details._appName = 'streamingclient';
29586
+ stat.details._appVersion = Client.version;
29587
+ }
29588
+ stat.details._originAppId = this.client.config.appId;
29589
+ // nr only accepts single level objects so we must flatten everything just in case
29590
+ const flattenedDetails = deepFlatten(stat.details);
29591
+ // new relic doesn't accept booleans so we convert them to strings
29592
+ Object.keys(flattenedDetails).forEach((key) => {
29593
+ const val = flattenedDetails[key];
29594
+ if (typeof val === 'boolean') {
29595
+ flattenedDetails[key] = `${val}`;
29596
+ }
29597
+ });
29598
+ const formattedStat = Object.assign(Object.assign({}, stat), { details: flattenedDetails });
29599
+ const currentEventSize = calculatePayloadSize(formattedStat);
29600
+ // Check if the size of the current event plus the size of the previous stats exceeds max size.
29601
+ const exceedsMaxStatSize = this.statBuffer + currentEventSize > this.currentMaxStatSize;
29602
+ this.statsArr.push(formattedStat);
29603
+ this.statBuffer += currentEventSize;
29604
+ // If it exceeds max size, don't append just send current payload.
29605
+ if (exceedsMaxStatSize) {
29606
+ this.flushStats();
29607
+ }
29608
+ else {
29609
+ this.throttledSendStats();
29610
+ }
29611
+ }
29600
29612
  getLogDetailsForPendingSessionId(sessionId) {
29601
29613
  const logDetails = {
29602
29614
  sessionId
@@ -29706,6 +29718,19 @@ class WebrtcExtension extends EventEmitter {
29706
29718
  const loggingParams = { sessionId: sessionId, conversationId: msg.propose.conversationId, sessionType, isDuplicatePropose };
29707
29719
  this.logger.info('propose received', loggingParams);
29708
29720
  if (!isDuplicatePropose) {
29721
+ this.client.config;
29722
+ const proposeStat = {
29723
+ actionName: 'WebrtcStats',
29724
+ details: {
29725
+ _eventTimestamp: new Date().toISOString(),
29726
+ _eventType: 'firstPropose',
29727
+ conversationId: loggingParams.conversationId,
29728
+ sdpViaXmppRequested: !!msg.propose.sdpOverXmpp,
29729
+ sessionId: sessionId,
29730
+ sessionType: sessionType,
29731
+ }
29732
+ };
29733
+ this.addStatToQueue(proposeStat);
29709
29734
  // TODO: is ofrom used?
29710
29735
  // const roomJid = (msg.ofrom && msg.ofrom.full) || msg.from.full || msg.from;
29711
29736
  const fromJid = msg.from;
@@ -30037,6 +30062,9 @@ class WebrtcExtension extends EventEmitter {
30037
30062
  const stanzaSessions = stanzaSessionsObj && Object.values(stanzaSessionsObj) || [];
30038
30063
  return [...stanzaSessions, ...this.webrtcSessions];
30039
30064
  }
30065
+ proxyNRStat(stat) {
30066
+ this.addStatToQueue(stat);
30067
+ }
30040
30068
  get expose() {
30041
30069
  return {
30042
30070
  on: this.on.bind(this),
@@ -30054,7 +30082,8 @@ class WebrtcExtension extends EventEmitter {
30054
30082
  initiateRtcSession: this.initiateRtcSession.bind(this),
30055
30083
  getSessionTypeByJid: this.getSessionTypeByJid.bind(this),
30056
30084
  getSessionManager: this.getSessionManager.bind(this),
30057
- getAllSessions: this.getAllSessions.bind(this)
30085
+ getAllSessions: this.getAllSessions.bind(this),
30086
+ proxyNRStat: this.proxyNRStat.bind(this)
30058
30087
  };
30059
30088
  }
30060
30089
  }
@@ -44904,7 +44933,8 @@ class Client extends EventEmitter {
44904
44933
  jidResource: options.jidResource,
44905
44934
  channelId: null,
44906
44935
  appName: options.appName,
44907
- appVersion: options.appVersion
44936
+ appVersion: options.appVersion,
44937
+ appId: options.appId
44908
44938
  };
44909
44939
  this.backgroundAssistantMode = this.checkIsBackgroundAssistant();
44910
44940
  this.isGuest = !this.backgroundAssistantMode && !options.authToken;
@@ -45301,7 +45331,7 @@ class Client extends EventEmitter {
45301
45331
  return Client.version;
45302
45332
  }
45303
45333
  static get version() {
45304
- return '16.1.3';
45334
+ return '16.2.0';
45305
45335
  }
45306
45336
  }
45307
45337
 
@@ -1,7 +1,6 @@
1
1
  import { StatsEvent } from 'webrtc-stats-gatherer';
2
- export declare function formatStatsEvent(event: StatsEvent, extraDetails?: any): {
3
- actionName: string;
4
- actionDate: number;
5
- details: any;
6
- };
2
+ import { FlatObject, InsightAction } from './types/interfaces';
3
+ export declare function formatStatsEvent(event: StatsEvent, extraDetails?: FlatObject): InsightAction<{
4
+ _eventType: string;
5
+ } & FlatObject>;
7
6
  export declare function deepFlatten(obj: any, prefix?: string): any;
@@ -1,40 +1,26 @@
1
+ function isGetStatsEvent(event) {
2
+ return event.name === 'getStats';
3
+ }
4
+ function prepGetStatsEvent(event) {
5
+ let details = {};
6
+ Object.assign(details, deepFlatten(event.tracks, 'localTrack'));
7
+ delete event.tracks;
8
+ Object.assign(details, deepFlatten(event.remoteTracks, `remoteTrack`));
9
+ delete event.remoteTracks;
10
+ return details;
11
+ }
1
12
  export function formatStatsEvent(event, extraDetails = {}) {
2
- let details;
3
- const eventType = event.name;
4
- if (event.name === 'connect') {
5
- const e = event;
6
- details = e;
7
- Object.assign(details, deepFlatten(e.candidatePairDetails, 'candidatePairDetails'));
8
- delete details.candidatePairDetails;
9
- }
10
- else if (event.name === 'getStats') {
11
- const e = event;
12
- details = e;
13
- Object.assign(details, deepFlatten(e.tracks, 'localTrack'));
14
- delete details.tracks;
15
- Object.assign(details, deepFlatten(e.remoteTracks, `remoteTrack`));
16
- delete details.remoteTracks;
17
- }
18
- else {
19
- details = {};
20
- if (event.name !== 'failure') {
21
- // TODO: log this out when we get genesys-cloud-client-logger in place (allows logging from anywhere)
22
- }
23
- Object.assign(details, deepFlatten(event));
13
+ const details = Object.assign({ _eventType: event.name, _eventTimestamp: new Date().toISOString() }, extraDetails);
14
+ // anything that needs to be renamed or massaged
15
+ if (isGetStatsEvent(event)) {
16
+ Object.assign(details, prepGetStatsEvent(event));
24
17
  }
18
+ // general case
19
+ Object.assign(details, deepFlatten(event));
25
20
  delete details.name;
26
- Object.assign(details, extraDetails, { '_eventType': eventType });
27
- // new relic doesn't accept booleans so we convert them to strings
28
- Object.keys(details).forEach((key) => {
29
- const val = details[key];
30
- if (typeof val === 'boolean') {
31
- details[key] = `${val}`;
32
- }
33
- });
34
21
  const formattedEvent = {
35
22
  actionName: 'WebrtcStats',
36
- actionDate: Date.now(),
37
- details
23
+ details,
38
24
  };
39
25
  return formattedEvent;
40
26
  }
@@ -186,3 +186,60 @@ export declare type HeadsetControlsRequest = TypedJsonRpcMessage<'headsetControl
186
186
  export declare type HeadsetControlsRejection = TypedJsonRpcMessage<'headsetControlsRejection', HeadsetControlsRejectionParams>;
187
187
  export declare type HeadsetControlsChanged = TypedJsonRpcMessage<'headsetControlsChanged', HeadsetControlsChangedParams>;
188
188
  export declare type GenesysMediaMessage = HeadsetControlsRequest | HeadsetControlsRejection | HeadsetControlsChanged;
189
+ export declare type FlatObject = {
190
+ [key: string]: string | number | boolean | null | Date;
191
+ };
192
+ export declare type GenericAction = {
193
+ _eventType: string;
194
+ };
195
+ export declare type InsightReport = {
196
+ appName: string;
197
+ appVersion: string;
198
+ originAppName?: string;
199
+ originAppVersion?: string;
200
+ actions: InsightAction<any>[];
201
+ };
202
+ export declare type InsightAction<T extends {
203
+ _eventType: string;
204
+ }> = {
205
+ actionName: 'WebrtcStats';
206
+ details: InsightActionDetails<T>;
207
+ };
208
+ export declare type InsightActionDetails<K extends {
209
+ _eventType: string;
210
+ }> = {
211
+ _eventType: K['_eventType'];
212
+ /**
213
+ * This should be an ISO string
214
+ */
215
+ _eventTimestamp: string;
216
+ _appId?: string;
217
+ _appName?: string;
218
+ _appVersion?: string;
219
+ } & K;
220
+ export declare type FirstProposeStat = InsightAction<{
221
+ _eventType: 'firstPropose';
222
+ sdpViaXmppRequested: boolean;
223
+ sessionType: SessionTypesAsStrings;
224
+ originAppId?: string;
225
+ conversationId: string;
226
+ sessionId: string;
227
+ }>;
228
+ export declare type FirstAlertingConversationStat = InsightAction<{
229
+ _eventType: 'firstAlertingConversationUpdate';
230
+ conversationId: string;
231
+ participantId: string;
232
+ }>;
233
+ export declare type MediaStat = InsightAction<{
234
+ _eventType: 'mediaRequested' | 'mediaStarted' | 'mediaError';
235
+ requestId?: string;
236
+ message?: string;
237
+ audioRequested: boolean;
238
+ videoRequested: boolean;
239
+ displayRequested: boolean;
240
+ conversationId?: string;
241
+ sessionType?: SessionTypesAsStrings;
242
+ sessionId?: string;
243
+ elapsedMsFromInitialRequest?: number;
244
+ }>;
245
+ export declare type NRProxyStat = FirstAlertingConversationStat | MediaStat;