@webex/plugin-meetings 3.0.0-beta.326 → 3.0.0-beta.328
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/breakouts/breakout.js +1 -1
- package/dist/breakouts/index.js +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/meeting/index.js +84 -29
- package/dist/meeting/index.js.map +1 -1
- package/dist/meetings/index.js +17 -9
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -0
- package/dist/metrics/constants.js.map +1 -1
- package/dist/types/meeting/index.d.ts +41 -6
- package/dist/types/meetings/index.d.ts +6 -4
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +19 -19
- package/src/meeting/index.ts +95 -21
- package/src/meetings/index.ts +17 -10
- package/src/metrics/constants.ts +2 -0
- package/test/unit/spec/meeting/index.js +89 -26
- package/test/unit/spec/meetings/index.js +84 -8
|
@@ -38,6 +38,11 @@ export type AddMediaOptions = {
|
|
|
38
38
|
bundlePolicy?: BundlePolicy;
|
|
39
39
|
allowMediaInLobby?: boolean;
|
|
40
40
|
};
|
|
41
|
+
export type CallStateForMetrics = {
|
|
42
|
+
correlationId?: string;
|
|
43
|
+
joinTrigger?: string;
|
|
44
|
+
loginType?: string;
|
|
45
|
+
};
|
|
41
46
|
export declare const MEDIA_UPDATE_TYPE: {
|
|
42
47
|
TRANSCODED_MEDIA_CONNECTION: string;
|
|
43
48
|
SHARE_FLOOR_REQUEST: string;
|
|
@@ -302,7 +307,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
302
307
|
annotation: any;
|
|
303
308
|
webinar: any;
|
|
304
309
|
conversationUrl: string;
|
|
305
|
-
|
|
310
|
+
callStateForMetrics: CallStateForMetrics;
|
|
306
311
|
destination: string;
|
|
307
312
|
destinationType: string;
|
|
308
313
|
deviceUrl: string;
|
|
@@ -427,6 +432,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
427
432
|
* @returns {Boolean}
|
|
428
433
|
*/
|
|
429
434
|
isLocusCall(): boolean;
|
|
435
|
+
/**
|
|
436
|
+
* Getter - Returns callStateForMetrics.correlationId
|
|
437
|
+
* @returns {string}
|
|
438
|
+
*/
|
|
439
|
+
get correlationId(): string;
|
|
440
|
+
/**
|
|
441
|
+
* Setter - sets callStateForMetrics.correlationId
|
|
442
|
+
* @param {string} correlationId
|
|
443
|
+
*/
|
|
444
|
+
set correlationId(correlationId: string);
|
|
430
445
|
/**
|
|
431
446
|
* Internal method for fetching meeting info
|
|
432
447
|
*
|
|
@@ -911,13 +926,21 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
911
926
|
*/
|
|
912
927
|
unsetPeerConnections(): void;
|
|
913
928
|
/**
|
|
914
|
-
* Convenience method to set the correlation id for the
|
|
915
|
-
* @param {String} id correlation id to set on the
|
|
929
|
+
* Convenience method to set the correlation id for the callStateForMetrics
|
|
930
|
+
* @param {String} id correlation id to set on the callStateForMetrics
|
|
916
931
|
* @returns {undefined}
|
|
917
932
|
* @public
|
|
918
933
|
* @memberof Meeting
|
|
919
934
|
*/
|
|
920
935
|
setCorrelationId(id: string): void;
|
|
936
|
+
/**
|
|
937
|
+
* Update the callStateForMetrics
|
|
938
|
+
* @param {CallStateForMetrics} callStateForMetrics updated values for callStateForMetrics
|
|
939
|
+
* @returns {undefined}
|
|
940
|
+
* @public
|
|
941
|
+
* @memberof Meeting
|
|
942
|
+
*/
|
|
943
|
+
updateCallStateForMetrics(callStateForMetrics: CallStateForMetrics): void;
|
|
921
944
|
/**
|
|
922
945
|
* Enqueue request for screenshare floor and set the status to pending
|
|
923
946
|
* @returns {Promise}
|
|
@@ -1526,6 +1549,14 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1526
1549
|
* @returns {undefined}
|
|
1527
1550
|
*/
|
|
1528
1551
|
private handleShareAudioStreamEnded;
|
|
1552
|
+
/**
|
|
1553
|
+
* Functionality for when a share video is muted or unmuted.
|
|
1554
|
+
* @private
|
|
1555
|
+
* @memberof Meeting
|
|
1556
|
+
* @param {boolean} muted
|
|
1557
|
+
* @returns {undefined}
|
|
1558
|
+
*/
|
|
1559
|
+
private handleShareVideoStreamMuteStateChange;
|
|
1529
1560
|
/**
|
|
1530
1561
|
* Functionality for when a share video is ended.
|
|
1531
1562
|
* @private
|
|
@@ -1660,12 +1691,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1660
1691
|
*/
|
|
1661
1692
|
unpublishStreams(streams: LocalStream[]): Promise<void>;
|
|
1662
1693
|
/**
|
|
1663
|
-
* Gets
|
|
1694
|
+
* Gets permission token expiry information including timeLeft, expiryTime, currentTime
|
|
1664
1695
|
* (from the time the function has been fired)
|
|
1665
1696
|
*
|
|
1666
|
-
* @returns {
|
|
1697
|
+
* @returns {object} containing timeLeft, expiryTime, currentTime
|
|
1667
1698
|
*/
|
|
1668
|
-
|
|
1699
|
+
getPermissionTokenExpiryInfo(): {
|
|
1700
|
+
timeLeft?: number;
|
|
1701
|
+
expiryTime?: number;
|
|
1702
|
+
currentTime: number;
|
|
1703
|
+
};
|
|
1669
1704
|
/**
|
|
1670
1705
|
* Check if there is enough time left till the permission token expires
|
|
1671
1706
|
* If not - refresh the permission token
|
|
@@ -3,6 +3,7 @@ import '@webex/internal-plugin-conversation';
|
|
|
3
3
|
import '@webex/internal-plugin-metrics';
|
|
4
4
|
import { WebexPlugin } from '@webex/webex-core';
|
|
5
5
|
import 'webrtc-adapter';
|
|
6
|
+
import { CallStateForMetrics } from '../meeting';
|
|
6
7
|
import Reachability from '../reachability';
|
|
7
8
|
import { INoiseReductionEffect, IVirtualBackgroundEffect } from './meetings.types';
|
|
8
9
|
/**
|
|
@@ -281,24 +282,25 @@ export default class Meetings extends WebexPlugin {
|
|
|
281
282
|
*/
|
|
282
283
|
private destroy;
|
|
283
284
|
/**
|
|
284
|
-
* Create a meeting.
|
|
285
|
+
* Create a meeting or return an existing meeting.
|
|
285
286
|
* @param {string} destination - sipURL, phonenumber, or locus object}
|
|
286
287
|
* @param {string} [type] - the optional specified type, such as locusId
|
|
287
288
|
* @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
|
|
288
289
|
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
289
|
-
* @param {string} correlationId - the optional specified correlationId
|
|
290
|
+
* @param {string} correlationId - the optional specified correlationId (callStateForMetrics.correlationId can be provided instead)
|
|
290
291
|
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
292
|
+
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
291
293
|
* @returns {Promise<Meeting>} A new Meeting.
|
|
292
294
|
* @public
|
|
293
295
|
* @memberof Meetings
|
|
294
296
|
*/
|
|
295
|
-
create(destination: string, type?: string, useRandomDelayForInfo?: boolean, infoExtraParams?: {}, correlationId?: string, failOnMissingMeetingInfo?: boolean): any;
|
|
297
|
+
create(destination: string, type?: string, useRandomDelayForInfo?: boolean, infoExtraParams?: {}, correlationId?: string, failOnMissingMeetingInfo?: boolean, callStateForMetrics?: CallStateForMetrics): any;
|
|
296
298
|
/**
|
|
297
299
|
* @param {String} destination see create()
|
|
298
300
|
* @param {String} type see create()
|
|
299
301
|
* @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
|
|
300
302
|
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
301
|
-
* @param {
|
|
303
|
+
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
302
304
|
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
303
305
|
* @returns {Promise} a new meeting instance complete with meeting info and destination
|
|
304
306
|
* @private
|
|
@@ -23,9 +23,11 @@ declare const BEHAVIORAL_METRICS: {
|
|
|
23
23
|
MEETING_MEDIA_INACTIVE: string;
|
|
24
24
|
MEETING_RECONNECT_FAILURE: string;
|
|
25
25
|
MEETING_MAX_REJOIN_FAILURE: string;
|
|
26
|
+
MEETING_SHARE_SUCCESS: string;
|
|
26
27
|
MEETING_SHARE_FAILURE: string;
|
|
27
28
|
MEETING_START_WHITEBOARD_SHARE_FAILURE: string;
|
|
28
29
|
MEETING_STOP_WHITEBOARD_SHARE_FAILURE: string;
|
|
30
|
+
MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE: string;
|
|
29
31
|
MUTE_AUDIO_FAILURE: string;
|
|
30
32
|
MUTE_VIDEO_FAILURE: string;
|
|
31
33
|
SET_MEETING_QUALITY_FAILURE: string;
|
package/dist/webinar/index.js
CHANGED
|
@@ -62,7 +62,7 @@ var Webinar = _webexCore.WebexPlugin.extend({
|
|
|
62
62
|
updateCanManageWebcast: function updateCanManageWebcast(canManageWebcast) {
|
|
63
63
|
this.set('canManageWebcast', canManageWebcast);
|
|
64
64
|
},
|
|
65
|
-
version: "3.0.0-beta.
|
|
65
|
+
version: "3.0.0-beta.328"
|
|
66
66
|
});
|
|
67
67
|
var _default = Webinar;
|
|
68
68
|
exports.default = _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/plugin-meetings",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.328",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "Cisco EULA (https://www.cisco.com/c/en/us/products/end-user-license-agreement.html)",
|
|
6
6
|
"contributors": [
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@peculiar/webcrypto": "^1.4.3",
|
|
36
|
-
"@webex/plugin-meetings": "3.0.0-beta.
|
|
37
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
38
|
-
"@webex/test-helper-mocha": "3.0.0-beta.
|
|
39
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
40
|
-
"@webex/test-helper-retry": "3.0.0-beta.
|
|
41
|
-
"@webex/test-helper-test-users": "3.0.0-beta.
|
|
36
|
+
"@webex/plugin-meetings": "3.0.0-beta.328",
|
|
37
|
+
"@webex/test-helper-chai": "3.0.0-beta.328",
|
|
38
|
+
"@webex/test-helper-mocha": "3.0.0-beta.328",
|
|
39
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.328",
|
|
40
|
+
"@webex/test-helper-retry": "3.0.0-beta.328",
|
|
41
|
+
"@webex/test-helper-test-users": "3.0.0-beta.328",
|
|
42
42
|
"chai": "^4.3.4",
|
|
43
43
|
"chai-as-promised": "^7.1.1",
|
|
44
44
|
"jsdom-global": "3.0.2",
|
|
@@ -47,19 +47,19 @@
|
|
|
47
47
|
"typescript": "^4.7.4"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@webex/common": "3.0.0-beta.
|
|
50
|
+
"@webex/common": "3.0.0-beta.328",
|
|
51
51
|
"@webex/internal-media-core": "2.2.2",
|
|
52
|
-
"@webex/internal-plugin-conversation": "3.0.0-beta.
|
|
53
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
54
|
-
"@webex/internal-plugin-llm": "3.0.0-beta.
|
|
55
|
-
"@webex/internal-plugin-mercury": "3.0.0-beta.
|
|
56
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
57
|
-
"@webex/internal-plugin-support": "3.0.0-beta.
|
|
58
|
-
"@webex/internal-plugin-user": "3.0.0-beta.
|
|
59
|
-
"@webex/media-helpers": "3.0.0-beta.
|
|
60
|
-
"@webex/plugin-people": "3.0.0-beta.
|
|
61
|
-
"@webex/plugin-rooms": "3.0.0-beta.
|
|
62
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
52
|
+
"@webex/internal-plugin-conversation": "3.0.0-beta.328",
|
|
53
|
+
"@webex/internal-plugin-device": "3.0.0-beta.328",
|
|
54
|
+
"@webex/internal-plugin-llm": "3.0.0-beta.328",
|
|
55
|
+
"@webex/internal-plugin-mercury": "3.0.0-beta.328",
|
|
56
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.328",
|
|
57
|
+
"@webex/internal-plugin-support": "3.0.0-beta.328",
|
|
58
|
+
"@webex/internal-plugin-user": "3.0.0-beta.328",
|
|
59
|
+
"@webex/media-helpers": "3.0.0-beta.328",
|
|
60
|
+
"@webex/plugin-people": "3.0.0-beta.328",
|
|
61
|
+
"@webex/plugin-rooms": "3.0.0-beta.328",
|
|
62
|
+
"@webex/webex-core": "3.0.0-beta.328",
|
|
63
63
|
"ampersand-collection": "^2.0.2",
|
|
64
64
|
"bowser": "^2.11.0",
|
|
65
65
|
"btoa": "^1.2.1",
|
package/src/meeting/index.ts
CHANGED
|
@@ -178,6 +178,12 @@ export type AddMediaOptions = {
|
|
|
178
178
|
allowMediaInLobby?: boolean; // allows adding media when in the lobby
|
|
179
179
|
};
|
|
180
180
|
|
|
181
|
+
export type CallStateForMetrics = {
|
|
182
|
+
correlationId?: string;
|
|
183
|
+
joinTrigger?: string;
|
|
184
|
+
loginType?: string;
|
|
185
|
+
};
|
|
186
|
+
|
|
181
187
|
export const MEDIA_UPDATE_TYPE = {
|
|
182
188
|
TRANSCODED_MEDIA_CONNECTION: 'TRANSCODED_MEDIA_CONNECTION',
|
|
183
189
|
SHARE_FLOOR_REQUEST: 'SHARE_FLOOR_REQUEST',
|
|
@@ -470,7 +476,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
470
476
|
annotation: any;
|
|
471
477
|
webinar: any;
|
|
472
478
|
conversationUrl: string;
|
|
473
|
-
|
|
479
|
+
callStateForMetrics: CallStateForMetrics;
|
|
474
480
|
destination: string;
|
|
475
481
|
destinationType: string;
|
|
476
482
|
deviceUrl: string;
|
|
@@ -611,20 +617,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
611
617
|
*/
|
|
612
618
|
this.id = uuid.v4();
|
|
613
619
|
/**
|
|
614
|
-
*
|
|
620
|
+
* Call state used for metrics
|
|
615
621
|
* @instance
|
|
616
|
-
* @type {
|
|
622
|
+
* @type {CallStateForMetrics}
|
|
617
623
|
* @readonly
|
|
618
624
|
* @public
|
|
619
625
|
* @memberof Meeting
|
|
620
626
|
*/
|
|
621
|
-
|
|
627
|
+
this.callStateForMetrics = attrs.callStateForMetrics || {};
|
|
628
|
+
const correlationId = attrs.correlationId || attrs.callStateForMetrics?.correlationId;
|
|
629
|
+
if (correlationId) {
|
|
622
630
|
LoggerProxy.logger.log(
|
|
623
|
-
`Meetings:index#constructor --> Initializing the meeting object with correlation id from app ${
|
|
631
|
+
`Meetings:index#constructor --> Initializing the meeting object with correlation id from app ${correlationId}`
|
|
624
632
|
);
|
|
625
|
-
this.correlationId =
|
|
633
|
+
this.callStateForMetrics.correlationId = correlationId;
|
|
626
634
|
} else {
|
|
627
|
-
this.correlationId = this.id;
|
|
635
|
+
this.callStateForMetrics.correlationId = this.id;
|
|
628
636
|
}
|
|
629
637
|
/**
|
|
630
638
|
* @instance
|
|
@@ -1360,6 +1368,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1360
1368
|
return this.type === 'CALL';
|
|
1361
1369
|
}
|
|
1362
1370
|
|
|
1371
|
+
/**
|
|
1372
|
+
* Getter - Returns callStateForMetrics.correlationId
|
|
1373
|
+
* @returns {string}
|
|
1374
|
+
*/
|
|
1375
|
+
get correlationId() {
|
|
1376
|
+
return this.callStateForMetrics.correlationId;
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
/**
|
|
1380
|
+
* Setter - sets callStateForMetrics.correlationId
|
|
1381
|
+
* @param {string} correlationId
|
|
1382
|
+
*/
|
|
1383
|
+
set correlationId(correlationId: string) {
|
|
1384
|
+
this.callStateForMetrics.correlationId = correlationId;
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1363
1387
|
/**
|
|
1364
1388
|
* Internal method for fetching meeting info
|
|
1365
1389
|
*
|
|
@@ -1501,15 +1525,17 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1501
1525
|
: this.destination;
|
|
1502
1526
|
const destinationType = isStartingSpaceInstantV2Meeting ? _MEETING_LINK_ : this.destinationType;
|
|
1503
1527
|
|
|
1504
|
-
const timeLeft = this.
|
|
1528
|
+
const {timeLeft, expiryTime, currentTime} = this.getPermissionTokenExpiryInfo();
|
|
1505
1529
|
|
|
1506
1530
|
LoggerProxy.logger.info(
|
|
1507
|
-
`Meeting:index#refreshPermissionToken --> refreshing permission token, destinationType=${destinationType}, timeLeft=${timeLeft}, reason=${reason}`
|
|
1531
|
+
`Meeting:index#refreshPermissionToken --> refreshing permission token, destinationType=${destinationType}, timeLeft=${timeLeft}, permissionTokenExpiry=${expiryTime}, currentTimestamp=${currentTime},reason=${reason}`
|
|
1508
1532
|
);
|
|
1509
1533
|
|
|
1510
1534
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.PERMISSION_TOKEN_REFRESH, {
|
|
1511
1535
|
correlationId: this.correlationId,
|
|
1512
1536
|
timeLeft,
|
|
1537
|
+
expiryTime,
|
|
1538
|
+
currentTime,
|
|
1513
1539
|
reason,
|
|
1514
1540
|
destinationType,
|
|
1515
1541
|
});
|
|
@@ -3709,11 +3735,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3709
3735
|
private async setLocalShareVideoStream(localDisplayStream?: LocalDisplayStream) {
|
|
3710
3736
|
const oldStream = this.mediaProperties.shareVideoStream;
|
|
3711
3737
|
|
|
3738
|
+
oldStream?.off(StreamEventNames.MuteStateChange, this.handleShareVideoStreamMuteStateChange);
|
|
3712
3739
|
oldStream?.off(StreamEventNames.Ended, this.handleShareVideoStreamEnded);
|
|
3713
3740
|
oldStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3714
3741
|
|
|
3715
3742
|
this.mediaProperties.setLocalShareVideoStream(localDisplayStream);
|
|
3716
3743
|
|
|
3744
|
+
localDisplayStream?.on(
|
|
3745
|
+
StreamEventNames.MuteStateChange,
|
|
3746
|
+
this.handleShareVideoStreamMuteStateChange
|
|
3747
|
+
);
|
|
3717
3748
|
localDisplayStream?.on(StreamEventNames.Ended, this.handleShareVideoStreamEnded);
|
|
3718
3749
|
localDisplayStream?.on(
|
|
3719
3750
|
LocalStreamEventNames.OutputTrackChange,
|
|
@@ -3803,12 +3834,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3803
3834
|
videoStream?.off(StreamEventNames.MuteStateChange, this.localVideoStreamMuteStateHandler);
|
|
3804
3835
|
videoStream?.off(LocalStreamEventNames.OutputTrackChange, this.localOutputTrackChangeHandler);
|
|
3805
3836
|
|
|
3806
|
-
shareAudioStream?.off(StreamEventNames.
|
|
3837
|
+
shareAudioStream?.off(StreamEventNames.Ended, this.handleShareAudioStreamEnded);
|
|
3807
3838
|
shareAudioStream?.off(
|
|
3808
3839
|
LocalStreamEventNames.OutputTrackChange,
|
|
3809
3840
|
this.localOutputTrackChangeHandler
|
|
3810
3841
|
);
|
|
3811
|
-
shareVideoStream?.off(
|
|
3842
|
+
shareVideoStream?.off(
|
|
3843
|
+
StreamEventNames.MuteStateChange,
|
|
3844
|
+
this.handleShareVideoStreamMuteStateChange
|
|
3845
|
+
);
|
|
3846
|
+
shareVideoStream?.off(StreamEventNames.Ended, this.handleShareVideoStreamEnded);
|
|
3812
3847
|
shareVideoStream?.off(
|
|
3813
3848
|
LocalStreamEventNames.OutputTrackChange,
|
|
3814
3849
|
this.localOutputTrackChangeHandler
|
|
@@ -3950,14 +3985,25 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3950
3985
|
}
|
|
3951
3986
|
|
|
3952
3987
|
/**
|
|
3953
|
-
* Convenience method to set the correlation id for the
|
|
3954
|
-
* @param {String} id correlation id to set on the
|
|
3988
|
+
* Convenience method to set the correlation id for the callStateForMetrics
|
|
3989
|
+
* @param {String} id correlation id to set on the callStateForMetrics
|
|
3955
3990
|
* @returns {undefined}
|
|
3956
3991
|
* @public
|
|
3957
3992
|
* @memberof Meeting
|
|
3958
3993
|
*/
|
|
3959
3994
|
public setCorrelationId(id: string) {
|
|
3960
|
-
this.correlationId = id;
|
|
3995
|
+
this.callStateForMetrics.correlationId = id;
|
|
3996
|
+
}
|
|
3997
|
+
|
|
3998
|
+
/**
|
|
3999
|
+
* Update the callStateForMetrics
|
|
4000
|
+
* @param {CallStateForMetrics} callStateForMetrics updated values for callStateForMetrics
|
|
4001
|
+
* @returns {undefined}
|
|
4002
|
+
* @public
|
|
4003
|
+
* @memberof Meeting
|
|
4004
|
+
*/
|
|
4005
|
+
public updateCallStateForMetrics(callStateForMetrics: CallStateForMetrics) {
|
|
4006
|
+
this.callStateForMetrics = {...this.callStateForMetrics, ...callStateForMetrics};
|
|
3961
4007
|
}
|
|
3962
4008
|
|
|
3963
4009
|
/**
|
|
@@ -4609,7 +4655,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
4609
4655
|
this.webex.internal.newMetrics.submitClientEvent({
|
|
4610
4656
|
name: 'client.call.initiated',
|
|
4611
4657
|
payload: {
|
|
4612
|
-
trigger: 'user-interaction',
|
|
4658
|
+
trigger: this.callStateForMetrics.joinTrigger || 'user-interaction',
|
|
4613
4659
|
isRoapCallEnabled: true,
|
|
4614
4660
|
pstnAudioType: options?.pstnAudioType,
|
|
4615
4661
|
},
|
|
@@ -6910,6 +6956,11 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6910
6956
|
.then(() => {
|
|
6911
6957
|
this.screenShareFloorState = ScreenShareFloorStatus.GRANTED;
|
|
6912
6958
|
|
|
6959
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_SHARE_SUCCESS, {
|
|
6960
|
+
correlation_id: this.correlationId,
|
|
6961
|
+
locus_id: this.locusUrl.split('/').pop(),
|
|
6962
|
+
});
|
|
6963
|
+
|
|
6913
6964
|
return Promise.resolve();
|
|
6914
6965
|
})
|
|
6915
6966
|
.catch((error) => {
|
|
@@ -7331,6 +7382,23 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7331
7382
|
}
|
|
7332
7383
|
};
|
|
7333
7384
|
|
|
7385
|
+
/**
|
|
7386
|
+
* Functionality for when a share video is muted or unmuted.
|
|
7387
|
+
* @private
|
|
7388
|
+
* @memberof Meeting
|
|
7389
|
+
* @param {boolean} muted
|
|
7390
|
+
* @returns {undefined}
|
|
7391
|
+
*/
|
|
7392
|
+
private handleShareVideoStreamMuteStateChange = (muted: boolean) => {
|
|
7393
|
+
LoggerProxy.logger.log(
|
|
7394
|
+
`Meeting:index#handleShareVideoStreamMuteStateChange --> Share video stream mute state changed to muted ${muted}`
|
|
7395
|
+
);
|
|
7396
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE, {
|
|
7397
|
+
correlationId: this.correlationId,
|
|
7398
|
+
muted,
|
|
7399
|
+
});
|
|
7400
|
+
};
|
|
7401
|
+
|
|
7334
7402
|
/**
|
|
7335
7403
|
* Functionality for when a share video is ended.
|
|
7336
7404
|
* @private
|
|
@@ -7889,12 +7957,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7889
7957
|
}
|
|
7890
7958
|
|
|
7891
7959
|
/**
|
|
7892
|
-
* Gets
|
|
7960
|
+
* Gets permission token expiry information including timeLeft, expiryTime, currentTime
|
|
7893
7961
|
* (from the time the function has been fired)
|
|
7894
7962
|
*
|
|
7895
|
-
* @returns {
|
|
7963
|
+
* @returns {object} containing timeLeft, expiryTime, currentTime
|
|
7896
7964
|
*/
|
|
7897
|
-
public
|
|
7965
|
+
public getPermissionTokenExpiryInfo(): {
|
|
7966
|
+
timeLeft?: number;
|
|
7967
|
+
expiryTime?: number;
|
|
7968
|
+
currentTime: number;
|
|
7969
|
+
} {
|
|
7898
7970
|
if (!this.permissionTokenPayload) {
|
|
7899
7971
|
return undefined;
|
|
7900
7972
|
}
|
|
@@ -7907,7 +7979,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7907
7979
|
|
|
7908
7980
|
// substract current time from the permissionTokenExp
|
|
7909
7981
|
// (permissionTokenExp is a epoch timestamp, not a time to live duration)
|
|
7910
|
-
|
|
7982
|
+
const timeLeft = (permissionTokenExpValue - now) / 1000;
|
|
7983
|
+
|
|
7984
|
+
return {timeLeft, expiryTime: permissionTokenExpValue, currentTime: now};
|
|
7911
7985
|
}
|
|
7912
7986
|
|
|
7913
7987
|
/**
|
|
@@ -7919,9 +7993,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
7919
7993
|
* @returns {Promise<void>}
|
|
7920
7994
|
*/
|
|
7921
7995
|
public checkAndRefreshPermissionToken(threshold: number, reason: string): Promise<void> {
|
|
7922
|
-
const
|
|
7996
|
+
const {timeLeft} = this.getPermissionTokenExpiryInfo();
|
|
7923
7997
|
|
|
7924
|
-
if (
|
|
7998
|
+
if (timeLeft !== undefined && timeLeft <= threshold) {
|
|
7925
7999
|
return this.refreshPermissionToken(reason);
|
|
7926
8000
|
}
|
|
7927
8001
|
|
package/src/meetings/index.ts
CHANGED
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
import BEHAVIORAL_METRICS from '../metrics/constants';
|
|
50
50
|
import MeetingInfo from '../meeting-info';
|
|
51
51
|
import MeetingInfoV2 from '../meeting-info/meeting-info-v2';
|
|
52
|
-
import Meeting from '../meeting';
|
|
52
|
+
import Meeting, {CallStateForMetrics} from '../meeting';
|
|
53
53
|
import PersonalMeetingRoom from '../personal-meeting-room';
|
|
54
54
|
import Reachability from '../reachability';
|
|
55
55
|
import Request from './request';
|
|
@@ -1025,13 +1025,14 @@ export default class Meetings extends WebexPlugin {
|
|
|
1025
1025
|
}
|
|
1026
1026
|
|
|
1027
1027
|
/**
|
|
1028
|
-
* Create a meeting.
|
|
1028
|
+
* Create a meeting or return an existing meeting.
|
|
1029
1029
|
* @param {string} destination - sipURL, phonenumber, or locus object}
|
|
1030
1030
|
* @param {string} [type] - the optional specified type, such as locusId
|
|
1031
1031
|
* @param {Boolean} useRandomDelayForInfo - whether a random delay should be added to fetching meeting info
|
|
1032
1032
|
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
1033
|
-
* @param {string} correlationId - the optional specified correlationId
|
|
1033
|
+
* @param {string} correlationId - the optional specified correlationId (callStateForMetrics.correlationId can be provided instead)
|
|
1034
1034
|
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
1035
|
+
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
1035
1036
|
* @returns {Promise<Meeting>} A new Meeting.
|
|
1036
1037
|
* @public
|
|
1037
1038
|
* @memberof Meetings
|
|
@@ -1042,7 +1043,8 @@ export default class Meetings extends WebexPlugin {
|
|
|
1042
1043
|
useRandomDelayForInfo = false,
|
|
1043
1044
|
infoExtraParams = {},
|
|
1044
1045
|
correlationId: string = undefined,
|
|
1045
|
-
failOnMissingMeetingInfo = false
|
|
1046
|
+
failOnMissingMeetingInfo = false,
|
|
1047
|
+
callStateForMetrics: CallStateForMetrics = undefined
|
|
1046
1048
|
) {
|
|
1047
1049
|
// TODO: type should be from a dictionary
|
|
1048
1050
|
|
|
@@ -1050,6 +1052,10 @@ export default class Meetings extends WebexPlugin {
|
|
|
1050
1052
|
// type. This must be performed prior to determining if the meeting is
|
|
1051
1053
|
// found in the collection, as we mutate the destination for hydra person
|
|
1052
1054
|
// id values.
|
|
1055
|
+
if (correlationId) {
|
|
1056
|
+
callStateForMetrics = {...(callStateForMetrics || {}), correlationId};
|
|
1057
|
+
}
|
|
1058
|
+
|
|
1053
1059
|
return (
|
|
1054
1060
|
this.meetingInfo
|
|
1055
1061
|
.fetchInfoOptions(destination, type)
|
|
@@ -1096,7 +1102,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1096
1102
|
type,
|
|
1097
1103
|
useRandomDelayForInfo,
|
|
1098
1104
|
infoExtraParams,
|
|
1099
|
-
|
|
1105
|
+
callStateForMetrics,
|
|
1100
1106
|
failOnMissingMeetingInfo
|
|
1101
1107
|
).then((createdMeeting: any) => {
|
|
1102
1108
|
// If the meeting was successfully created.
|
|
@@ -1143,6 +1149,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1143
1149
|
return Promise.resolve(createdMeeting);
|
|
1144
1150
|
});
|
|
1145
1151
|
}
|
|
1152
|
+
meeting.setCallStateForMetrics(callStateForMetrics);
|
|
1146
1153
|
|
|
1147
1154
|
// Return the existing meeting.
|
|
1148
1155
|
return Promise.resolve(meeting);
|
|
@@ -1155,7 +1162,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1155
1162
|
* @param {String} type see create()
|
|
1156
1163
|
* @param {Boolean} useRandomDelayForInfo whether a random delay should be added to fetching meeting info
|
|
1157
1164
|
* @param {Object} infoExtraParams extra parameters to be provided when fetching meeting info
|
|
1158
|
-
* @param {
|
|
1165
|
+
* @param {CallStateForMetrics} callStateForMetrics - information about call state for metrics
|
|
1159
1166
|
* @param {Boolean} failOnMissingMeetingInfo - whether to throw an error if meeting info fails to fetch (for calls that are not 1:1 or content share)
|
|
1160
1167
|
* @returns {Promise} a new meeting instance complete with meeting info and destination
|
|
1161
1168
|
* @private
|
|
@@ -1166,7 +1173,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1166
1173
|
type: string = null,
|
|
1167
1174
|
useRandomDelayForInfo = false,
|
|
1168
1175
|
infoExtraParams = {},
|
|
1169
|
-
|
|
1176
|
+
callStateForMetrics: CallStateForMetrics = undefined,
|
|
1170
1177
|
failOnMissingMeetingInfo = false
|
|
1171
1178
|
) {
|
|
1172
1179
|
const meeting = new Meeting(
|
|
@@ -1181,7 +1188,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1181
1188
|
meetingInfoProvider: this.meetingInfo,
|
|
1182
1189
|
destination,
|
|
1183
1190
|
destinationType: type,
|
|
1184
|
-
|
|
1191
|
+
callStateForMetrics,
|
|
1185
1192
|
},
|
|
1186
1193
|
{
|
|
1187
1194
|
// @ts-ignore
|
|
@@ -1219,7 +1226,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1219
1226
|
() =>
|
|
1220
1227
|
meeting.fetchMeetingInfo({
|
|
1221
1228
|
extraParams: infoExtraParams,
|
|
1222
|
-
sendCAevents: !!correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
|
|
1229
|
+
sendCAevents: !!callStateForMetrics?.correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
|
|
1223
1230
|
}),
|
|
1224
1231
|
waitingTime
|
|
1225
1232
|
);
|
|
@@ -1227,7 +1234,7 @@ export default class Meetings extends WebexPlugin {
|
|
|
1227
1234
|
} else {
|
|
1228
1235
|
await meeting.fetchMeetingInfo({
|
|
1229
1236
|
extraParams: infoExtraParams,
|
|
1230
|
-
sendCAevents: !!correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
|
|
1237
|
+
sendCAevents: !!callStateForMetrics?.correlationId, // if client sends correlation id as argument of public create(), then it means that this meeting creation is part of a pre-join intent from user
|
|
1231
1238
|
});
|
|
1232
1239
|
}
|
|
1233
1240
|
} catch (err) {
|
package/src/metrics/constants.ts
CHANGED
|
@@ -26,9 +26,11 @@ const BEHAVIORAL_METRICS = {
|
|
|
26
26
|
MEETING_MEDIA_INACTIVE: 'js_sdk_meeting_media_inactive',
|
|
27
27
|
MEETING_RECONNECT_FAILURE: 'js_sdk_meeting_reconnect_failures',
|
|
28
28
|
MEETING_MAX_REJOIN_FAILURE: 'js_sdk_meeting_max_rejoin_failure',
|
|
29
|
+
MEETING_SHARE_SUCCESS: 'js_sdk_meeting_share_success',
|
|
29
30
|
MEETING_SHARE_FAILURE: 'js_sdk_meeting_share_failures',
|
|
30
31
|
MEETING_START_WHITEBOARD_SHARE_FAILURE: 'js_sdk_meeting_start_whiteboard_share_failures',
|
|
31
32
|
MEETING_STOP_WHITEBOARD_SHARE_FAILURE: 'js_sdk_meeting_stop_whiteboard_share_failures',
|
|
33
|
+
MEETING_SHARE_VIDEO_MUTE_STATE_CHANGE: 'js_sdk_meeting_share_video_mute_state_change',
|
|
32
34
|
MUTE_AUDIO_FAILURE: 'js_sdk_mute_audio_failures',
|
|
33
35
|
MUTE_VIDEO_FAILURE: 'js_sdk_mute_video_failures',
|
|
34
36
|
SET_MEETING_QUALITY_FAILURE: 'js_sdk_set_meeting_quality_failures',
|