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.
- package/dist/cjs/client.js +3 -2
- package/dist/cjs/stats-formatter.d.ts +4 -5
- package/dist/cjs/stats-formatter.js +22 -32
- package/dist/cjs/types/interfaces.d.ts +57 -0
- package/dist/cjs/webrtc.d.ts +6 -1
- package/dist/cjs/webrtc.js +58 -14
- package/dist/deploy-info.json +5 -5
- package/dist/es/client.js +3 -2
- package/dist/es/index.bundle.js +77 -47
- package/dist/es/stats-formatter.d.ts +4 -5
- package/dist/es/stats-formatter.js +18 -32
- package/dist/es/types/interfaces.d.ts +57 -0
- package/dist/es/webrtc.d.ts +6 -1
- package/dist/es/webrtc.js +56 -15
- package/dist/npm/CHANGELOG.md +4 -1
- package/dist/npm/client.js +3 -2
- package/dist/npm/stats-formatter.d.ts +4 -5
- package/dist/npm/stats-formatter.js +22 -32
- package/dist/npm/types/interfaces.d.ts +57 -0
- package/dist/npm/webrtc.d.ts +6 -1
- package/dist/npm/webrtc.js +58 -14
- package/dist/streaming-client.browser.ie.js +4 -4
- package/dist/streaming-client.browser.js +2 -2
- package/dist/v16/streaming-client.browser.ie.js +4 -4
- package/dist/v16/streaming-client.browser.js +2 -2
- package/dist/{v16.1.3 → v16.2.0}/streaming-client.browser.ie.js +4 -4
- package/dist/v16.2.0/streaming-client.browser.js +40 -0
- package/package.json +118 -116
- package/dist/v16.1.3/streaming-client.browser.js +0 -40
package/dist/cjs/client.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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;
|
package/dist/cjs/webrtc.d.ts
CHANGED
|
@@ -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
|
}
|
package/dist/cjs/webrtc.js
CHANGED
|
@@ -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
|
-
|
|
266
|
-
|
|
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
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
}
|
package/dist/deploy-info.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "developercenter-cdn/streaming-client",
|
|
3
|
-
"version": "16.
|
|
3
|
+
"version": "16.2.0",
|
|
4
4
|
"ecosystem": "pc",
|
|
5
5
|
"team": "Genesys Client Media (WebRTC)",
|
|
6
6
|
"indexFiles": [
|
|
7
7
|
{
|
|
8
|
-
"file": "v16.
|
|
8
|
+
"file": "v16.2.0/streaming-client.browser.ie.js"
|
|
9
9
|
},
|
|
10
10
|
{
|
|
11
|
-
"file": "v16.
|
|
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": "
|
|
21
|
-
"buildDate": "2023-12-
|
|
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.
|
|
447
|
+
return '16.2.0';
|
|
447
448
|
}
|
|
448
449
|
}
|
package/dist/es/index.bundle.js
CHANGED
|
@@ -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
|
-
|
|
18119
|
-
|
|
18120
|
-
if (event
|
|
18121
|
-
|
|
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
|
-
|
|
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
|
-
|
|
29581
|
-
|
|
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
|
-
|
|
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.
|
|
45334
|
+
return '16.2.0';
|
|
45305
45335
|
}
|
|
45306
45336
|
}
|
|
45307
45337
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { StatsEvent } from 'webrtc-stats-gatherer';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
if (event
|
|
5
|
-
|
|
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
|
-
|
|
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;
|