@webex/plugin-meetings 3.0.0-beta.162 → 3.0.0-beta.164

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 (64) hide show
  1. package/dist/breakouts/breakout.js +7 -3
  2. package/dist/breakouts/breakout.js.map +1 -1
  3. package/dist/breakouts/events.js +31 -29
  4. package/dist/breakouts/events.js.map +1 -1
  5. package/dist/breakouts/index.js +4 -2
  6. package/dist/breakouts/index.js.map +1 -1
  7. package/dist/constants.js +2 -4
  8. package/dist/constants.js.map +1 -1
  9. package/dist/interpretation/index.js +1 -1
  10. package/dist/interpretation/siLanguage.js +1 -1
  11. package/dist/locus-info/index.js +33 -17
  12. package/dist/locus-info/index.js.map +1 -1
  13. package/dist/meeting/index.js +699 -682
  14. package/dist/meeting/index.js.map +1 -1
  15. package/dist/meeting/util.js +47 -25
  16. package/dist/meeting/util.js.map +1 -1
  17. package/dist/meeting-info/index.js +48 -7
  18. package/dist/meeting-info/index.js.map +1 -1
  19. package/dist/meeting-info/meeting-info-v2.js +24 -10
  20. package/dist/meeting-info/meeting-info-v2.js.map +1 -1
  21. package/dist/meetings/index.js +12 -9
  22. package/dist/meetings/index.js.map +1 -1
  23. package/dist/metrics/index.js +1 -487
  24. package/dist/metrics/index.js.map +1 -1
  25. package/dist/reconnection-manager/index.js +27 -17
  26. package/dist/reconnection-manager/index.js.map +1 -1
  27. package/dist/roap/request.js +20 -14
  28. package/dist/roap/request.js.map +1 -1
  29. package/dist/types/breakouts/events.d.ts +7 -1
  30. package/dist/types/constants.d.ts +0 -1
  31. package/dist/types/meeting/index.d.ts +31 -133
  32. package/dist/types/meeting-info/index.d.ts +6 -1
  33. package/dist/types/meetings/index.d.ts +1 -0
  34. package/dist/types/metrics/index.d.ts +4 -128
  35. package/package.json +19 -19
  36. package/src/breakouts/breakout.ts +10 -2
  37. package/src/breakouts/events.ts +51 -32
  38. package/src/breakouts/index.ts +9 -5
  39. package/src/constants.ts +0 -2
  40. package/src/locus-info/index.ts +35 -17
  41. package/src/meeting/index.ts +474 -536
  42. package/src/meeting/util.ts +42 -19
  43. package/src/meeting-info/index.ts +54 -8
  44. package/src/meeting-info/meeting-info-v2.ts +24 -9
  45. package/src/meetings/index.ts +11 -6
  46. package/src/metrics/index.ts +1 -506
  47. package/src/reconnection-manager/index.ts +27 -17
  48. package/src/roap/request.ts +21 -9
  49. package/test/unit/spec/breakouts/breakout.ts +4 -2
  50. package/test/unit/spec/breakouts/events.ts +24 -18
  51. package/test/unit/spec/locus-info/index.js +112 -0
  52. package/test/unit/spec/meeting/index.js +178 -145
  53. package/test/unit/spec/meeting/utils.js +93 -7
  54. package/test/unit/spec/meeting-info/index.js +181 -0
  55. package/test/unit/spec/meeting-info/meetinginfov2.js +68 -68
  56. package/test/unit/spec/meetings/index.js +35 -55
  57. package/test/unit/spec/metrics/index.js +1 -148
  58. package/test/unit/spec/reconnection-manager/index.js +51 -2
  59. package/test/unit/spec/roap/index.ts +8 -2
  60. package/test/unit/spec/roap/request.ts +43 -5
  61. package/dist/metrics/config.js +0 -335
  62. package/dist/metrics/config.js.map +0 -1
  63. package/dist/types/metrics/config.d.ts +0 -195
  64. package/src/metrics/config.ts +0 -534
@@ -1,7 +1,8 @@
1
1
  import uuid from 'uuid';
2
- import {cloneDeep, isEqual, pick, defer, isEmpty} from 'lodash';
2
+ import {cloneDeep, isEqual, defer, isEmpty} from 'lodash';
3
3
  // @ts-ignore - Fix this
4
4
  import {StatelessWebexPlugin} from '@webex/webex-core';
5
+ import {ClientEvent, CALL_DIAGNOSTIC_CONFIG} from '@webex/internal-plugin-metrics';
5
6
  import {
6
7
  ConnectionState,
7
8
  Errors,
@@ -39,7 +40,6 @@ import MeetingStateMachine from './state';
39
40
  import {createMuteState} from './muteState';
40
41
  import LocusInfo from '../locus-info';
41
42
  import Metrics from '../metrics';
42
- import {trigger, error as MetricsError, eventType} from '../metrics/config';
43
43
  import ReconnectionManager from '../reconnection-manager';
44
44
  import MeetingRequest from './request';
45
45
  import Members from '../members/index';
@@ -74,7 +74,6 @@ import {
74
74
  MEETING_STATE_MACHINE,
75
75
  MEETING_STATE,
76
76
  MEETINGS,
77
- METRICS_JOIN_TIMES_MAX_DURATION,
78
77
  MQA_STATS,
79
78
  NETWORK_STATUS,
80
79
  ONLINE,
@@ -1224,6 +1223,18 @@ export default class Meeting extends StatelessWebexPlugin {
1224
1223
  };
1225
1224
  }
1226
1225
 
1226
+ /**
1227
+ * Temporary func to return webex object,
1228
+ * in order to access internal plugin metrics
1229
+ * in the utils file.
1230
+ * @internal
1231
+ * @returns {object} webex object
1232
+ */
1233
+ getWebexObject() {
1234
+ // @ts-ignore
1235
+ return this.webex;
1236
+ }
1237
+
1227
1238
  /**
1228
1239
  * returns meeting is joined
1229
1240
  * @private
@@ -1443,15 +1454,18 @@ export default class Meeting extends StatelessWebexPlugin {
1443
1454
 
1444
1455
  /**
1445
1456
  * Posts metrics event for this meeting. Allows the app to send Call Analyzer events.
1446
- * @param {String} eventName - Call Analyzer event, see eventType in src/metrics/config.ts for possible values
1457
+ * @param {String} eventName - Call Analyzer event
1447
1458
  * @public
1448
1459
  * @memberof Meeting
1449
1460
  * @returns {Promise}
1450
1461
  */
1451
- public postMetrics(eventName: string) {
1452
- Metrics.postEvent({
1453
- event: eventName,
1454
- meeting: this,
1462
+ public postMetrics(eventName: ClientEvent['name']) {
1463
+ // @ts-ignore
1464
+ this.webex.internal.newMetrics.submitClientEvent({
1465
+ name: eventName,
1466
+ options: {
1467
+ meetingId: this.id,
1468
+ },
1455
1469
  });
1456
1470
  }
1457
1471
 
@@ -1692,230 +1706,6 @@ export default class Meeting extends StatelessWebexPlugin {
1692
1706
  });
1693
1707
  }
1694
1708
 
1695
- /**
1696
- * get the metrics payload pre
1697
- * @param {Object} options
1698
- * @param {String} options.event
1699
- * @param {String} options.trackingId
1700
- * @param {Object} options.locus
1701
- * @param {Array} options.mediaConnections
1702
- * @param {Object} options.errors
1703
- * @returns {Object}
1704
- * @memberof Meeting
1705
- */
1706
- getAnalyzerMetricsPrePayload(options: {
1707
- type?: string;
1708
- event: string;
1709
- trackingId: string;
1710
- locus: object;
1711
- mediaConnections?: Array<any>;
1712
- errors?: object;
1713
- meetingLookupUrl?: string;
1714
- clientType?: any;
1715
- subClientType?: any;
1716
- [key: string]: any;
1717
- }) {
1718
- if (options) {
1719
- const {event, trackingId, mediaConnections, meetingLookupUrl} = options;
1720
-
1721
- if (!event) {
1722
- LoggerProxy.logger.error(
1723
- 'Meeting:index#getAnalyzerMetricsPrePayload --> Error [Call Analyzer Event',
1724
- event || '',
1725
- `]: invalid identifers or event type! ${this.correlationId}`
1726
- );
1727
-
1728
- return null;
1729
- }
1730
-
1731
- const identifiers: any = {
1732
- correlationId: this.correlationId,
1733
- userId: this.userId,
1734
- deviceId: this.deviceUrl,
1735
- orgId: this.orgId,
1736
- // @ts-ignore fix type
1737
- locusUrl: this.webex.internal.services.get('locus'),
1738
- };
1739
-
1740
- if (this.locusUrl && this.locusInfo.fullState) {
1741
- identifiers.locusUrl = this.locusUrl;
1742
- identifiers.locusId = this.locusUrl && this.locusUrl.split('/').pop();
1743
- identifiers.locusStartTime =
1744
- this.locusInfo.fullState && this.locusInfo.fullState.lastActive;
1745
- }
1746
-
1747
- // Check if mediaConnections has been passed in or else use this.mediaConnections
1748
- if (mediaConnections) {
1749
- identifiers.mediaAgentAlias = mediaConnections?.[0].mediaAgentAlias;
1750
- identifiers.mediaAgentGroupId = mediaConnections?.[0].mediaAgentGroupId;
1751
- identifiers.mediaAgentCluster = mediaConnections?.[0].mediaAgentCluster;
1752
- } else if (this.mediaConnections) {
1753
- identifiers.mediaAgentAlias = this.mediaConnections?.[0].mediaAgentAlias;
1754
- identifiers.mediaAgentGroupId = this.mediaConnections?.[0].mediaAgentGroupId;
1755
- identifiers.mediaAgentCluster = this.mediaConnections?.[0].mediaAgentCluster;
1756
- }
1757
-
1758
- if (meetingLookupUrl) {
1759
- identifiers.meetingLookupUrl = meetingLookupUrl;
1760
- }
1761
-
1762
- if (options.trackingId) {
1763
- identifiers.trackingId = trackingId;
1764
- }
1765
-
1766
- let payload = {};
1767
-
1768
- const joinRespRxStartAudio = this.getSetupDelayDuration('audio');
1769
-
1770
- if (joinRespRxStartAudio) {
1771
- options.audioSetupDelay = {
1772
- joinRespRxStart: joinRespRxStartAudio,
1773
- };
1774
- }
1775
-
1776
- const joinRespRxStartVideo = this.getSetupDelayDuration('video');
1777
-
1778
- if (joinRespRxStartAudio) {
1779
- options.videoSetupDelay = {
1780
- joinRespRxStart: joinRespRxStartVideo,
1781
- };
1782
- }
1783
-
1784
- const joinRespTxStartAudio = this.getSendingMediaDelayDuration('audio');
1785
-
1786
- if (joinRespTxStartAudio) {
1787
- options.audioSetupDelay = {
1788
- ...options.audioSetupDelay,
1789
- joinRespTxStart: joinRespTxStartAudio,
1790
- };
1791
- }
1792
-
1793
- const joinRespTxStartVideo = this.getSendingMediaDelayDuration('video');
1794
-
1795
- if (joinRespTxStartVideo) {
1796
- options.videoSetupDelay = {
1797
- ...options.videoSetupDelay,
1798
- joinRespTxStart: joinRespTxStartVideo,
1799
- };
1800
- }
1801
-
1802
- const localSDPGenRemoteSDPRecv = this.getLocalSDPGenRemoteSDPRecvDelay();
1803
-
1804
- if (localSDPGenRemoteSDPRecv) {
1805
- options.joinTimes = {
1806
- ...options.joinTimes,
1807
- localSDPGenRemoteSDPRecv,
1808
- };
1809
- }
1810
-
1811
- const callInitJoinReq = this.getCallInitJoinReq();
1812
-
1813
- if (callInitJoinReq) {
1814
- options.joinTimes = {
1815
- ...options.joinTimes,
1816
- callInitJoinReq,
1817
- };
1818
- }
1819
-
1820
- const joinReqResp = this.getJoinReqResp();
1821
-
1822
- if (joinReqResp) {
1823
- options.joinTimes = {
1824
- ...options.joinTimes,
1825
- joinReqResp,
1826
- };
1827
- }
1828
-
1829
- const totalJmt = this.getTotalJmt();
1830
-
1831
- if (totalJmt) {
1832
- options.joinTimes = {
1833
- ...options.joinTimes,
1834
- totalJmt,
1835
- };
1836
- }
1837
-
1838
- const curUserType = this.getCurUserType();
1839
-
1840
- if (curUserType) {
1841
- options.userType = curUserType;
1842
- }
1843
-
1844
- const curLoginType = this.getCurLoginType();
1845
-
1846
- if (curLoginType) {
1847
- options.loginType = curLoginType;
1848
- }
1849
-
1850
- if (this.environment) {
1851
- options.environment = this.environment;
1852
- }
1853
-
1854
- if (options.type === MQA_STATS.CA_TYPE) {
1855
- payload = Metrics.initMediaPayload(options.event, identifiers, options);
1856
- } else {
1857
- payload = Metrics.initPayload(options.event, identifiers, options);
1858
- }
1859
-
1860
- return payload;
1861
- }
1862
-
1863
- return null;
1864
- }
1865
-
1866
- /**
1867
- * Send the metrics to call-analyzer dashboard
1868
- * @param {Object} options
1869
- * @param {String} options.event
1870
- * @param {String} options.trackingId
1871
- * @param {Object} options.locus
1872
- * @param {Object} options.errors
1873
- * @returns {Promise}
1874
- * @private
1875
- * @memberof Meeting
1876
- */
1877
- private sendCallAnalyzerMetrics(options: {
1878
- event: string;
1879
- trackingId: string;
1880
- locus: object;
1881
- errors: object;
1882
- }) {
1883
- const payload = this.getAnalyzerMetricsPrePayload({
1884
- // @ts-ignore - config coming from registerPlugin
1885
- ...pick(this.config.metrics, ['clientType', 'subClientType']),
1886
- ...options,
1887
- });
1888
-
1889
- // @ts-ignore - fix type
1890
- return this.webex.internal.metrics.submitCallDiagnosticEvents(payload);
1891
- }
1892
-
1893
- /**
1894
- * Send the metrics to Media Quality Analyzer dashboard
1895
- * @param {Object} options
1896
- * @param {String} options.event
1897
- * @param {String} options.trackingId
1898
- * @param {Object} options.locus
1899
- * @returns {Promise}
1900
- * @private
1901
- * @memberof Meeting
1902
- */
1903
- private sendMediaQualityAnalyzerMetrics(options: {
1904
- event: string;
1905
- trackingId: string;
1906
- locus: object;
1907
- }) {
1908
- const payload = this.getAnalyzerMetricsPrePayload({
1909
- type: MQA_STATS.CA_TYPE,
1910
- // @ts-ignore - config coming from registerPlugin
1911
- ...pick(this.config.metrics, ['clientType', 'subClientType']),
1912
- ...options,
1913
- });
1914
-
1915
- // @ts-ignore
1916
- return this.webex.internal.metrics.submitCallDiagnosticEvents(payload);
1917
- }
1918
-
1919
1709
  /**
1920
1710
  * sets the network status on meeting object
1921
1711
  * @param {String} networkStatus
@@ -2448,7 +2238,14 @@ export default class Meeting extends StatelessWebexPlugin {
2448
2238
  },
2449
2239
  EVENT_TRIGGERS.MEETING_STARTED_SHARING_LOCAL
2450
2240
  );
2451
- Metrics.postEvent({event: eventType.LOCAL_SHARE_FLOOR_GRANTED, meeting: this});
2241
+ // @ts-ignore
2242
+ this.webex.internal.newMetrics.submitClientEvent({
2243
+ name: 'client.share.floor-granted.local',
2244
+ payload: {
2245
+ mediaType: 'share',
2246
+ },
2247
+ options: {meetingId: this.id},
2248
+ });
2452
2249
  break;
2453
2250
 
2454
2251
  case SHARE_STATUS.WHITEBOARD_SHARE_ACTIVE:
@@ -2464,7 +2261,16 @@ export default class Meeting extends StatelessWebexPlugin {
2464
2261
  memberId: whiteboardShare.beneficiaryId,
2465
2262
  }
2466
2263
  );
2467
- Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_FLOOR_GRANTED, meeting: this});
2264
+ // @ts-ignore
2265
+ this.webex.internal.newMetrics.submitClientEvent({
2266
+ name: 'client.share.floor-granted.local',
2267
+ payload: {
2268
+ mediaType: 'whiteboard',
2269
+ },
2270
+ options: {
2271
+ meetingId: this.id,
2272
+ },
2273
+ });
2468
2274
  break;
2469
2275
 
2470
2276
  case SHARE_STATUS.NO_SHARE:
@@ -2508,7 +2314,16 @@ export default class Meeting extends StatelessWebexPlugin {
2508
2314
  memberId: whiteboardShare.beneficiaryId,
2509
2315
  }
2510
2316
  );
2511
- Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_FLOOR_GRANTED, meeting: this});
2317
+ // @ts-ignore
2318
+ this.webex.internal.newMetrics.submitClientEvent({
2319
+ name: 'client.share.floor-granted.local',
2320
+ payload: {
2321
+ mediaType: 'whiteboard',
2322
+ },
2323
+ options: {
2324
+ meetingId: this.id,
2325
+ },
2326
+ });
2512
2327
  this.members.locusMediaSharesUpdate(payload);
2513
2328
  }
2514
2329
  });
@@ -2907,9 +2722,10 @@ export default class Meeting extends StatelessWebexPlugin {
2907
2722
  }
2908
2723
  );
2909
2724
 
2910
- Metrics.postEvent({
2911
- event: eventType.LOBBY_ENTERED,
2912
- meeting: this,
2725
+ // @ts-ignore
2726
+ this.webex.internal.newMetrics.submitClientEvent({
2727
+ name: 'client.lobby.entered',
2728
+ options: {meetingId: this.id},
2913
2729
  });
2914
2730
  }
2915
2731
  });
@@ -2929,9 +2745,10 @@ export default class Meeting extends StatelessWebexPlugin {
2929
2745
  }
2930
2746
  );
2931
2747
 
2932
- Metrics.postEvent({
2933
- event: eventType.LOBBY_EXITED,
2934
- meeting: this,
2748
+ // @ts-ignore
2749
+ this.webex.internal.newMetrics.submitClientEvent({
2750
+ name: 'client.lobby.exited',
2751
+ options: {meetingId: this.id},
2935
2752
  });
2936
2753
  }
2937
2754
  });
@@ -3595,9 +3412,10 @@ export default class Meeting extends StatelessWebexPlugin {
3595
3412
 
3596
3413
  // Only send restore event when it was disconnected before and for connected later
3597
3414
  if (!this.hasWebsocketConnected) {
3598
- Metrics.postEvent({
3599
- event: eventType.MERCURY_CONNECTION_RESTORED,
3600
- meeting: this,
3415
+ // @ts-ignore
3416
+ this.webex.internal.newMetrics.submitClientEvent({
3417
+ name: 'client.mercury.connection.restored',
3418
+ options: {meetingId: this.id},
3601
3419
  });
3602
3420
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MERCURY_CONNECTION_RESTORED, {
3603
3421
  correlation_id: this.correlationId,
@@ -3609,9 +3427,10 @@ export default class Meeting extends StatelessWebexPlugin {
3609
3427
  // @ts-ignore
3610
3428
  this.webex.internal.mercury.on(OFFLINE, () => {
3611
3429
  LoggerProxy.logger.error('Meeting:index#setMercuryListener --> Web socket offline');
3612
- Metrics.postEvent({
3613
- event: eventType.MERCURY_CONNECTION_LOST,
3614
- meeting: this,
3430
+ // @ts-ignore
3431
+ this.webex.internal.newMetrics.submitClientEvent({
3432
+ name: 'client.mercury.connection.lost',
3433
+ options: {meetingId: this.id},
3615
3434
  });
3616
3435
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MERCURY_CONNECTION_FAILURE, {
3617
3436
  correlation_id: this.correlationId,
@@ -3677,6 +3496,204 @@ export default class Meeting extends StatelessWebexPlugin {
3677
3496
  this.correlationId = id;
3678
3497
  }
3679
3498
 
3499
+ /**
3500
+ * Mute the audio for a meeting
3501
+ * @returns {Promise} resolves the data from muting audio {mute, self} or rejects if there is no audio set
3502
+ * @public
3503
+ * @memberof Meeting
3504
+ */
3505
+ public muteAudio() {
3506
+ if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
3507
+ return Promise.reject(new UserNotJoinedError());
3508
+ }
3509
+
3510
+ // @ts-ignore
3511
+ if (!this.mediaId) {
3512
+ // Happens when addMedia and mute are triggered in succession
3513
+ return Promise.reject(new NoMediaEstablishedYetError());
3514
+ }
3515
+
3516
+ if (!this.audio) {
3517
+ return Promise.reject(new ParameterError('no audio control associated to the meeting'));
3518
+ }
3519
+
3520
+ // First, stop sending the local audio media
3521
+ return logRequest(
3522
+ this.audio
3523
+ .handleClientRequest(this, true)
3524
+ .then(() => {
3525
+ MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
3526
+ // @ts-ignore
3527
+ this.webex.internal.newMetrics.submitClientEvent({
3528
+ name: 'client.muted',
3529
+ payload: {trigger: 'user-interaction', mediaType: 'audio'},
3530
+ options: {meetingId: this.id},
3531
+ });
3532
+ })
3533
+ .catch((error) => {
3534
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_AUDIO_FAILURE, {
3535
+ correlation_id: this.correlationId,
3536
+ locus_id: this.locusUrl.split('/').pop(),
3537
+ reason: error.message,
3538
+ stack: error.stack,
3539
+ });
3540
+
3541
+ throw error;
3542
+ }),
3543
+ {
3544
+ logText: `Meeting:index#muteAudio --> correlationId=${this.correlationId} muting audio`,
3545
+ }
3546
+ );
3547
+ }
3548
+
3549
+ /**
3550
+ * Unmute meeting audio
3551
+ * @returns {Promise} resolves data from muting audio {mute, self} or rejects if there is no audio set
3552
+ * @public
3553
+ * @memberof Meeting
3554
+ */
3555
+ public unmuteAudio() {
3556
+ if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
3557
+ return Promise.reject(new UserNotJoinedError());
3558
+ }
3559
+
3560
+ // @ts-ignore
3561
+ if (!this.mediaId) {
3562
+ // Happens when addMedia and mute are triggered in succession
3563
+ return Promise.reject(new NoMediaEstablishedYetError());
3564
+ }
3565
+
3566
+ if (!this.audio) {
3567
+ return Promise.reject(new ParameterError('no audio control associated to the meeting'));
3568
+ }
3569
+
3570
+ // First, send the control to unmute the participant on the server
3571
+ return logRequest(
3572
+ this.audio
3573
+ .handleClientRequest(this, false)
3574
+ .then(() => {
3575
+ MeetingUtil.handleAudioLogging(this.mediaProperties.audioTrack);
3576
+ // @ts-ignore
3577
+ this.webex.internal.newMetrics.submitClientEvent({
3578
+ name: 'client.unmuted',
3579
+ payload: {trigger: 'user-interaction', mediaType: 'audio'},
3580
+ options: {meetingId: this.id},
3581
+ });
3582
+ })
3583
+ .catch((error) => {
3584
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UNMUTE_AUDIO_FAILURE, {
3585
+ correlation_id: this.correlationId,
3586
+ locus_id: this.locusUrl.split('/').pop(),
3587
+ reason: error.message,
3588
+ stack: error.stack,
3589
+ });
3590
+
3591
+ throw error;
3592
+ }),
3593
+ {
3594
+ logText: `Meeting:index#unmuteAudio --> correlationId=${this.correlationId} unmuting audio`,
3595
+ }
3596
+ );
3597
+ }
3598
+
3599
+ /**
3600
+ * Mute the video for a meeting
3601
+ * @returns {Promise} resolves data from muting video {mute, self} or rejects if there is no video set
3602
+ * @public
3603
+ * @memberof Meeting
3604
+ */
3605
+ public muteVideo() {
3606
+ if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
3607
+ return Promise.reject(new UserNotJoinedError());
3608
+ }
3609
+
3610
+ // @ts-ignore
3611
+ if (!this.mediaId) {
3612
+ // Happens when addMedia and mute are triggered in succession
3613
+ return Promise.reject(new NoMediaEstablishedYetError());
3614
+ }
3615
+
3616
+ if (!this.video) {
3617
+ return Promise.reject(new ParameterError('no video control associated to the meeting'));
3618
+ }
3619
+
3620
+ return logRequest(
3621
+ this.video
3622
+ .handleClientRequest(this, true)
3623
+ .then(() => {
3624
+ MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
3625
+ // @ts-ignore
3626
+ this.webex.internal.newMetrics.submitClientEvent({
3627
+ name: 'client.muted',
3628
+ payload: {trigger: 'user-interaction', mediaType: 'video'},
3629
+ options: {meetingId: this.id},
3630
+ });
3631
+ })
3632
+ .catch((error) => {
3633
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MUTE_VIDEO_FAILURE, {
3634
+ correlation_id: this.correlationId,
3635
+ locus_id: this.locusUrl.split('/').pop(),
3636
+ reason: error.message,
3637
+ stack: error.stack,
3638
+ });
3639
+
3640
+ throw error;
3641
+ }),
3642
+ {
3643
+ logText: `Meeting:index#muteVideo --> correlationId=${this.correlationId} muting video`,
3644
+ }
3645
+ );
3646
+ }
3647
+
3648
+ /**
3649
+ * Unmute meeting video
3650
+ * @returns {Promise} resolves data from muting video {mute, self} or rejects if there is no video set
3651
+ * @public
3652
+ * @memberof Meeting
3653
+ */
3654
+ public unmuteVideo() {
3655
+ if (!MeetingUtil.isUserInJoinedState(this.locusInfo)) {
3656
+ return Promise.reject(new UserNotJoinedError());
3657
+ }
3658
+
3659
+ // @ts-ignore
3660
+ if (!this.mediaId) {
3661
+ // Happens when addMedia and mute are triggered in succession
3662
+ return Promise.reject(new NoMediaEstablishedYetError());
3663
+ }
3664
+
3665
+ if (!this.video) {
3666
+ return Promise.reject(new ParameterError('no audio control associated to the meeting'));
3667
+ }
3668
+
3669
+ return logRequest(
3670
+ this.video
3671
+ .handleClientRequest(this, false)
3672
+ .then(() => {
3673
+ MeetingUtil.handleVideoLogging(this.mediaProperties.videoTrack);
3674
+ // @ts-ignore
3675
+ this.webex.internal.newMetrics.submitClientEvent({
3676
+ name: 'client.unmuted',
3677
+ payload: {trigger: 'user-interaction', mediaType: 'video'},
3678
+ options: {meetingId: this.id},
3679
+ });
3680
+ })
3681
+ .catch((error) => {
3682
+ Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.UNMUTE_VIDEO_FAILURE, {
3683
+ correlation_id: this.correlationId,
3684
+ locus_id: this.locusUrl.split('/').pop(),
3685
+ reason: error.message,
3686
+ stack: error.stack,
3687
+ });
3688
+
3689
+ throw error;
3690
+ }),
3691
+ {
3692
+ logText: `Meeting:index#unmuteVideo --> correlationId=${this.correlationId} unmuting video`,
3693
+ }
3694
+ );
3695
+ }
3696
+
3680
3697
  /**
3681
3698
  * Shorthand function to join AND set up media
3682
3699
  * @param {Object} options - options to join with media
@@ -4092,24 +4109,27 @@ export default class Meeting extends StatelessWebexPlugin {
4092
4109
  this.meetingFiniteStateMachine.reset();
4093
4110
  }
4094
4111
 
4095
- Metrics.postEvent({
4096
- event: eventType.CALL_INITIATED,
4097
- meeting: this,
4098
- data: {trigger: trigger.USER_INTERACTION, isRoapCallEnabled: true},
4112
+ // @ts-ignore
4113
+ this.webex.internal.newMetrics.submitClientEvent({
4114
+ name: 'client.call.initiated',
4115
+ payload: {trigger: 'user-interaction', isRoapCallEnabled: true},
4116
+ options: {meetingId: this.id},
4099
4117
  });
4100
4118
 
4101
4119
  if (!isEmpty(this.meetingInfo)) {
4102
- Metrics.postEvent({
4103
- event: eventType.MEETING_INFO_REQUEST,
4104
- meeting: this,
4120
+ // @ts-ignore
4121
+ this.webex.internal.newMetrics.submitClientEvent({
4122
+ name: 'client.meetinginfo.request',
4123
+ options: {meetingId: this.id},
4105
4124
  });
4106
4125
 
4107
- Metrics.postEvent({
4108
- event: eventType.MEETING_INFO_RESPONSE,
4109
- meeting: this,
4110
- data: {
4111
- meetingLookupUrl: this.meetingInfo?.meetingLookupUrl,
4126
+ // @ts-ignore
4127
+ this.webex.internal.newMetrics.submitClientEvent({
4128
+ name: 'client.meetinginfo.response',
4129
+ payload: {
4130
+ identifiers: {meetingLookupUrl: this.meetingInfo?.meetingLookupUrl},
4112
4131
  },
4132
+ options: {meetingId: this.id},
4113
4133
  });
4114
4134
  }
4115
4135
 
@@ -4211,13 +4231,13 @@ export default class Meeting extends StatelessWebexPlugin {
4211
4231
  this.meetingFiniteStateMachine.fail(error);
4212
4232
  LoggerProxy.logger.error('Meeting:index#join --> Failed', error);
4213
4233
 
4214
- Metrics.postEvent({
4215
- event: eventType.LOCUS_JOIN_RESPONSE,
4216
- meeting: this,
4217
- meetingId: this.id,
4218
- data: {
4219
- errors: [Metrics.parseLocusError(error.error, true)],
4234
+ // @ts-ignore
4235
+ this.webex.internal.newMetrics.submitClientEvent({
4236
+ name: 'client.locus.join.response',
4237
+ payload: {
4238
+ identifiers: {meetingLookupUrl: this.meetingInfo?.meetingLookupUrl},
4220
4239
  },
4240
+ options: {meetingId: this.id, rawError: error, showToUser: true},
4221
4241
  });
4222
4242
 
4223
4243
  // TODO: change this to error codes and pre defined dictionary
@@ -4421,10 +4441,10 @@ export default class Meeting extends StatelessWebexPlugin {
4421
4441
  throw new ParameterError('Cannot move call without a resourceId.');
4422
4442
  }
4423
4443
 
4424
- Metrics.postEvent({
4425
- event: eventType.MEDIA_CAPABILITIES,
4426
- meeting: this,
4427
- data: {
4444
+ // @ts-ignore
4445
+ this.webex.internal.newMetrics.submitClientEvent({
4446
+ name: 'client.media.capabilities',
4447
+ payload: {
4428
4448
  mediaCapabilities: {
4429
4449
  rx: {
4430
4450
  audio: false,
@@ -4442,9 +4462,14 @@ export default class Meeting extends StatelessWebexPlugin {
4442
4462
  },
4443
4463
  },
4444
4464
  },
4465
+ options: {meetingId: this.id},
4445
4466
  });
4446
4467
 
4447
- Metrics.postEvent({event: eventType.MOVE_MEDIA, meeting: this});
4468
+ // @ts-ignore
4469
+ this.webex.internal.newMetrics.submitClientEvent({
4470
+ name: 'client.call.move-media',
4471
+ options: {meetingId: this.id},
4472
+ });
4448
4473
 
4449
4474
  this.locusInfo.once(LOCUSINFO.EVENTS.SELF_OBSERVING, async () => {
4450
4475
  // Clean up the camera , microphone track and re initiate it
@@ -4523,7 +4548,11 @@ export default class Meeting extends StatelessWebexPlugin {
4523
4548
  }
4524
4549
  const oldCorrelationId = this.correlationId;
4525
4550
 
4526
- Metrics.postEvent({event: eventType.MOVE_MEDIA, meeting: this});
4551
+ // @ts-ignore
4552
+ this.webex.internal.newMetrics.submitClientEvent({
4553
+ name: 'client.call.move-media',
4554
+ options: {meetingId: this.id},
4555
+ });
4527
4556
 
4528
4557
  return MeetingUtil.joinMeetingOptions(this)
4529
4558
  .then(() =>
@@ -4575,15 +4604,13 @@ export default class Meeting extends StatelessWebexPlugin {
4575
4604
  if (error instanceof Errors.SdpOfferCreationError) {
4576
4605
  sendBehavioralMetric(BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE, error, this.id);
4577
4606
 
4578
- Metrics.postEvent({
4579
- event: eventType.LOCAL_SDP_GENERATED,
4580
- meetingId: this.id,
4581
- data: {
4607
+ // @ts-ignore
4608
+ this.webex.internal.newMetrics.submitClientEvent({
4609
+ name: 'client.media-engine.local-sdp-generated',
4610
+ payload: {
4582
4611
  canProceed: false,
4583
- errors: [
4584
- Metrics.generateErrorPayload(2001, true, MetricsError.name.MEDIA_ENGINE, undefined),
4585
- ],
4586
4612
  },
4613
+ options: {meetingId: this.id, rawError: error, showToUser: true},
4587
4614
  });
4588
4615
  } else if (
4589
4616
  error instanceof Errors.SdpOfferHandlingError ||
@@ -4591,29 +4618,25 @@ export default class Meeting extends StatelessWebexPlugin {
4591
4618
  ) {
4592
4619
  sendBehavioralMetric(BEHAVIORAL_METRICS.PEERCONNECTION_FAILURE, error, this.id);
4593
4620
 
4594
- Metrics.postEvent({
4595
- event: eventType.REMOTE_SDP_RECEIVED,
4596
- meetingId: this.id,
4597
- data: {
4621
+ // @ts-ignore
4622
+ this.webex.internal.newMetrics.submitClientEvent({
4623
+ name: 'client.media-engine.remote-sdp-received',
4624
+ payload: {
4598
4625
  canProceed: false,
4599
- errors: [
4600
- Metrics.generateErrorPayload(2001, true, MetricsError.name.MEDIA_ENGINE, undefined),
4601
- ],
4602
4626
  },
4627
+ options: {meetingId: this.id, rawError: error, showToUser: true},
4603
4628
  });
4604
4629
  } else if (error instanceof Errors.SdpError) {
4605
4630
  // this covers also the case of Errors.IceGatheringError which extends Errors.SdpError
4606
4631
  sendBehavioralMetric(BEHAVIORAL_METRICS.INVALID_ICE_CANDIDATE, error, this.id);
4607
4632
 
4608
- Metrics.postEvent({
4609
- event: eventType.LOCAL_SDP_GENERATED,
4610
- meetingId: this.id,
4611
- data: {
4633
+ // @ts-ignore
4634
+ this.webex.internal.newMetrics.submitClientEvent({
4635
+ name: 'client.media-engine.local-sdp-generated',
4636
+ payload: {
4612
4637
  canProceed: false,
4613
- errors: [
4614
- Metrics.generateErrorPayload(2001, true, MetricsError.name.MEDIA_ENGINE, undefined),
4615
- ],
4616
4638
  },
4639
+ options: {meetingId: this.id, rawError: error, showToUser: true},
4617
4640
  });
4618
4641
  }
4619
4642
  };
@@ -4636,9 +4659,10 @@ export default class Meeting extends StatelessWebexPlugin {
4636
4659
 
4637
4660
  switch (event.roapMessage.messageType) {
4638
4661
  case 'OK':
4639
- Metrics.postEvent({
4640
- event: eventType.REMOTE_SDP_RECEIVED,
4641
- meetingId: this.id,
4662
+ // @ts-ignore
4663
+ this.webex.internal.newMetrics.submitClientEvent({
4664
+ name: 'client.media-engine.remote-sdp-received',
4665
+ options: {meetingId: this.id},
4642
4666
  });
4643
4667
 
4644
4668
  logRequest(
@@ -4654,9 +4678,10 @@ export default class Meeting extends StatelessWebexPlugin {
4654
4678
  break;
4655
4679
 
4656
4680
  case 'OFFER':
4657
- Metrics.postEvent({
4658
- event: eventType.LOCAL_SDP_GENERATED,
4659
- meetingId: this.id,
4681
+ // @ts-ignore
4682
+ this.webex.internal.newMetrics.submitClientEvent({
4683
+ name: 'client.media-engine.local-sdp-generated',
4684
+ options: {meetingId: this.id},
4660
4685
  });
4661
4686
 
4662
4687
  logRequest(
@@ -4674,9 +4699,10 @@ export default class Meeting extends StatelessWebexPlugin {
4674
4699
  break;
4675
4700
 
4676
4701
  case 'ANSWER':
4677
- Metrics.postEvent({
4678
- event: eventType.REMOTE_SDP_RECEIVED,
4679
- meetingId: this.id,
4702
+ // @ts-ignore
4703
+ this.webex.internal.newMetrics.submitClientEvent({
4704
+ name: 'client.media-engine.remote-sdp-received',
4705
+ options: {meetingId: this.id},
4680
4706
  });
4681
4707
 
4682
4708
  logRequest(
@@ -4795,15 +4821,22 @@ export default class Meeting extends StatelessWebexPlugin {
4795
4821
  this.reconnectionManager.resetReconnectionTimer();
4796
4822
 
4797
4823
  this.reconnect({networkDisconnect: true});
4798
- Metrics.postEvent({
4799
- event: eventType.ICE_END,
4800
- meeting: this,
4801
- data: {
4824
+ // @ts-ignore
4825
+ this.webex.internal.newMetrics.submitClientEvent({
4826
+ name: 'client.ice.end',
4827
+ payload: {
4802
4828
  canProceed: false,
4829
+ icePhase: 'IN_MEETING',
4803
4830
  errors: [
4804
- Metrics.generateErrorPayload(2004, false, MetricsError.name.MEDIA_ENGINE, undefined),
4831
+ // @ts-ignore
4832
+ this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
4833
+ CALL_DIAGNOSTIC_CONFIG.ICE_FAILURE_CLIENT_CODE
4834
+ ),
4805
4835
  ],
4806
4836
  },
4837
+ options: {
4838
+ meetingId: this.id,
4839
+ },
4807
4840
  });
4808
4841
 
4809
4842
  this.uploadLogs({
@@ -4822,10 +4855,22 @@ export default class Meeting extends StatelessWebexPlugin {
4822
4855
  );
4823
4856
  switch (event.state) {
4824
4857
  case ConnectionState.Connecting:
4825
- Metrics.postEvent({event: eventType.ICE_START, meeting: this});
4858
+ // @ts-ignore
4859
+ this.webex.internal.newMetrics.submitClientEvent({
4860
+ name: 'client.ice.start',
4861
+ options: {
4862
+ meetingId: this.id,
4863
+ },
4864
+ });
4826
4865
  break;
4827
4866
  case ConnectionState.Connected:
4828
- Metrics.postEvent({event: eventType.ICE_END, meeting: this});
4867
+ // @ts-ignore
4868
+ this.webex.internal.newMetrics.submitClientEvent({
4869
+ name: 'client.ice.end',
4870
+ options: {
4871
+ meetingId: this.id,
4872
+ },
4873
+ });
4829
4874
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.CONNECTION_SUCCESS, {
4830
4875
  correlation_id: this.correlationId,
4831
4876
  locus_id: this.locusId,
@@ -4929,10 +4974,16 @@ export default class Meeting extends StatelessWebexPlugin {
4929
4974
  this.webex.meetings.geoHintInfo?.clientAddress ||
4930
4975
  options.data.intervalMetadata.peerReflexiveIP ||
4931
4976
  MQA_STATS.DEFAULT_IP;
4932
- Metrics.postEvent({
4933
- event: eventType.MEDIA_QUALITY,
4934
- meeting: this,
4935
- data: {intervalData: options.data, networkType: options.networkType},
4977
+ // @ts-ignore
4978
+ this.webex.internal.newMetrics.submitMQE({
4979
+ name: 'client.mediaquality.event',
4980
+ options: {
4981
+ meetingId: this.id,
4982
+ networkType: options.networkType,
4983
+ },
4984
+ payload: {
4985
+ intervals: [options.data],
4986
+ },
4936
4987
  });
4937
4988
  });
4938
4989
  this.statsAnalyzer.on(StatsAnalyzerEvents.LOCAL_MEDIA_STARTED, (data) => {
@@ -4945,20 +4996,22 @@ export default class Meeting extends StatelessWebexPlugin {
4945
4996
  EVENT_TRIGGERS.MEETING_MEDIA_LOCAL_STARTED,
4946
4997
  data
4947
4998
  );
4948
- Metrics.postEvent({
4949
- event: eventType.SENDING_MEDIA_START,
4950
- meeting: this,
4951
- data: {
4952
- mediaType: data.type,
4999
+ // @ts-ignore
5000
+ this.webex.internal.newMetrics.submitClientEvent({
5001
+ name: 'client.media.tx.start',
5002
+ payload: {mediaType: data.type},
5003
+ options: {
5004
+ meetingId: this.id,
4953
5005
  },
4954
5006
  });
4955
5007
  });
4956
5008
  this.statsAnalyzer.on(StatsAnalyzerEvents.LOCAL_MEDIA_STOPPED, (data) => {
4957
- Metrics.postEvent({
4958
- event: eventType.SENDING_MEDIA_STOP,
4959
- meeting: this,
4960
- data: {
4961
- mediaType: data.type,
5009
+ // @ts-ignore
5010
+ this.webex.internal.newMetrics.submitClientEvent({
5011
+ name: 'client.media.tx.stop',
5012
+ payload: {mediaType: data.type},
5013
+ options: {
5014
+ meetingId: this.id,
4962
5015
  },
4963
5016
  });
4964
5017
  });
@@ -4972,20 +5025,22 @@ export default class Meeting extends StatelessWebexPlugin {
4972
5025
  EVENT_TRIGGERS.MEETING_MEDIA_REMOTE_STARTED,
4973
5026
  data
4974
5027
  );
4975
- Metrics.postEvent({
4976
- event: eventType.RECEIVING_MEDIA_START,
4977
- meeting: this,
4978
- data: {
4979
- mediaType: data.type,
5028
+ // @ts-ignore
5029
+ this.webex.internal.newMetrics.submitClientEvent({
5030
+ name: 'client.media.rx.start',
5031
+ payload: {mediaType: data.type},
5032
+ options: {
5033
+ meetingId: this.id,
4980
5034
  },
4981
5035
  });
4982
5036
  });
4983
5037
  this.statsAnalyzer.on(StatsAnalyzerEvents.REMOTE_MEDIA_STOPPED, (data) => {
4984
- Metrics.postEvent({
4985
- event: eventType.RECEIVING_MEDIA_STOP,
4986
- meeting: this,
4987
- data: {
4988
- mediaType: data.type,
5038
+ // @ts-ignore
5039
+ this.webex.internal.newMetrics.submitClientEvent({
5040
+ name: 'client.media.rx.stop',
5041
+ payload: {mediaType: data.type},
5042
+ options: {
5043
+ meetingId: this.id,
4989
5044
  },
4990
5045
  });
4991
5046
  });
@@ -5093,10 +5148,10 @@ export default class Meeting extends StatelessWebexPlugin {
5093
5148
  bundlePolicy,
5094
5149
  } = options;
5095
5150
 
5096
- Metrics.postEvent({
5097
- event: eventType.MEDIA_CAPABILITIES,
5098
- meeting: this,
5099
- data: {
5151
+ // @ts-ignore
5152
+ this.webex.internal.newMetrics.submitClientEvent({
5153
+ name: 'client.media.capabilities',
5154
+ payload: {
5100
5155
  mediaCapabilities: {
5101
5156
  rx: {
5102
5157
  audio: false,
@@ -5114,6 +5169,7 @@ export default class Meeting extends StatelessWebexPlugin {
5114
5169
  },
5115
5170
  },
5116
5171
  },
5172
+ options: {meetingId: this.id},
5117
5173
  });
5118
5174
 
5119
5175
  // when audioEnabled/videoEnabled is true, we set sendAudio/sendVideo to true even before any tracks are published
@@ -5266,6 +5322,23 @@ export default class Meeting extends StatelessWebexPlugin {
5266
5322
  )
5267
5323
  .then(() =>
5268
5324
  this.mediaProperties.waitForMediaConnectionConnected().catch(() => {
5325
+ // @ts-ignore
5326
+ this.webex.internal.newMetrics.submitClientEvent({
5327
+ name: 'client.ice.end',
5328
+ payload: {
5329
+ canProceed: false,
5330
+ icePhase: 'JOIN_MEETING_FINAL',
5331
+ errors: [
5332
+ // @ts-ignore
5333
+ this.webex.internal.newMetrics.callDiagnosticMetrics.getErrorPayloadForClientErrorCode(
5334
+ CALL_DIAGNOSTIC_CONFIG.ICE_FAILURE_CLIENT_CODE
5335
+ ),
5336
+ ],
5337
+ },
5338
+ options: {
5339
+ meetingId: this.id,
5340
+ },
5341
+ });
5269
5342
  throw new Error(
5270
5343
  `Timed out waiting for media connection to be connected, correlationId=${this.correlationId}`
5271
5344
  );
@@ -5284,6 +5357,13 @@ export default class Meeting extends StatelessWebexPlugin {
5284
5357
  connectionType,
5285
5358
  isMultistream: this.isMultistream,
5286
5359
  });
5360
+ // @ts-ignore
5361
+ this.webex.internal.newMetrics.submitClientEvent({
5362
+ name: 'client.media-engine.ready',
5363
+ options: {
5364
+ meetingId: this.id,
5365
+ },
5366
+ });
5287
5367
  })
5288
5368
  .catch((error) => {
5289
5369
  Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADD_MEDIA_FAILURE, {
@@ -5546,7 +5626,11 @@ export default class Meeting extends StatelessWebexPlugin {
5546
5626
  .then((response) => Promise.resolve(response))
5547
5627
  .then((response) => {
5548
5628
  this.meetingFiniteStateMachine.ring(type);
5549
- Metrics.postEvent({event: eventType.ALERT_DISPLAYED, meeting: this});
5629
+ // @ts-ignore
5630
+ this.webex.internal.newMetrics.submitClientEvent({
5631
+ name: 'client.alert.displayed',
5632
+ options: {meetingId: this.id},
5633
+ });
5550
5634
 
5551
5635
  return Promise.resolve({
5552
5636
  response,
@@ -5591,10 +5675,18 @@ export default class Meeting extends StatelessWebexPlugin {
5591
5675
  */
5592
5676
  public leave(options: {resourceId?: string; reason?: any} = {} as any) {
5593
5677
  const leaveReason = options.reason || MEETING_REMOVED_REASON.CLIENT_LEAVE_REQUEST;
5594
- Metrics.postEvent({
5595
- event: eventType.LEAVE,
5596
- meeting: this,
5597
- data: {trigger: trigger.USER_INTERACTION, canProceed: false, reason: leaveReason},
5678
+ /// @ts-ignore
5679
+ this.webex.internal.newMetrics.submitInternalEvent({name: 'internal.reset.join.latencies'});
5680
+
5681
+ // @ts-ignore
5682
+ this.webex.internal.newMetrics.submitClientEvent({
5683
+ name: 'client.call.leave',
5684
+ payload: {
5685
+ trigger: 'user-interaction',
5686
+ canProceed: false,
5687
+ leaveReason,
5688
+ },
5689
+ options: {meetingId: this.id},
5598
5690
  });
5599
5691
  LoggerProxy.logger.log('Meeting:index#leave --> Leaving a meeting');
5600
5692
 
@@ -5675,7 +5767,16 @@ export default class Meeting extends StatelessWebexPlugin {
5675
5767
  }
5676
5768
 
5677
5769
  if (whiteboard) {
5678
- Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_INITIATED, meeting: this});
5770
+ // @ts-ignore
5771
+ this.webex.internal.newMetrics.submitClientEvent({
5772
+ name: 'client.share.initiated',
5773
+ payload: {
5774
+ mediaType: 'whiteboard',
5775
+ },
5776
+ options: {
5777
+ meetingId: this.id,
5778
+ },
5779
+ });
5679
5780
 
5680
5781
  const body: any = {
5681
5782
  disposition: FLOOR_ACTION.GRANTED,
@@ -5725,7 +5826,16 @@ export default class Meeting extends StatelessWebexPlugin {
5725
5826
  const whiteboard = this.locusInfo.mediaShares.find((element) => element.name === 'whiteboard');
5726
5827
 
5727
5828
  if (whiteboard) {
5728
- Metrics.postEvent({event: eventType.WHITEBOARD_SHARE_STOPPED, meeting: this});
5829
+ // @ts-ignore
5830
+ this.webex.internal.newMetrics.submitClientEvent({
5831
+ name: 'client.share.stopped',
5832
+ payload: {
5833
+ mediaType: 'whiteboard',
5834
+ },
5835
+ options: {
5836
+ meetingId: this.id,
5837
+ },
5838
+ });
5729
5839
 
5730
5840
  return this.meetingRequest
5731
5841
  .changeMeetingFloor({
@@ -5777,7 +5887,14 @@ export default class Meeting extends StatelessWebexPlugin {
5777
5887
  const content = this.locusInfo.mediaShares.find((element) => element.name === CONTENT);
5778
5888
 
5779
5889
  if (content && this.shareStatus !== SHARE_STATUS.LOCAL_SHARE_ACTIVE) {
5780
- Metrics.postEvent({event: eventType.SHARE_INITIATED, meeting: this});
5890
+ // @ts-ignore
5891
+ this.webex.internal.newMetrics.submitClientEvent({
5892
+ name: 'client.share.initiated',
5893
+ payload: {
5894
+ mediaType: 'share',
5895
+ },
5896
+ options: {meetingId: this.id},
5897
+ });
5781
5898
 
5782
5899
  return this.meetingRequest
5783
5900
  .changeMeetingFloor({
@@ -5838,7 +5955,14 @@ export default class Meeting extends StatelessWebexPlugin {
5838
5955
  const content = this.locusInfo.mediaShares.find((element) => element.name === CONTENT);
5839
5956
 
5840
5957
  if (content) {
5841
- Metrics.postEvent({event: eventType.SHARE_STOPPED, meeting: this});
5958
+ // @ts-ignore
5959
+ this.webex.internal.newMetrics.submitClientEvent({
5960
+ name: 'client.share.stopped',
5961
+ payload: {
5962
+ mediaType: 'share',
5963
+ },
5964
+ options: {meetingId: this.id},
5965
+ });
5842
5966
 
5843
5967
  if (content.floor?.beneficiary.id !== this.selfId) {
5844
5968
  // remote participant started sharing and caused our sharing to stop, we don't want to send any floor action request in that case
@@ -6251,179 +6375,6 @@ export default class Meeting extends StatelessWebexPlugin {
6251
6375
  MeetingUtil.handleAudioLogging(mediaProperties.audioTrack);
6252
6376
  }
6253
6377
 
6254
- /**
6255
- * @param {string} typeMedia 'audio' or 'video'
6256
- * @returns {undefined}
6257
- */
6258
- setStartSetupDelay(typeMedia: string) {
6259
- this[`startSetupDelay${typeMedia}`] = performance.now();
6260
- this[`endSetupDelay${typeMedia}`] = undefined;
6261
- }
6262
-
6263
- /**
6264
- * @param {string} typeMedia 'audio' or 'video'
6265
- * @returns {undefined}
6266
- */
6267
- setEndSetupDelay(typeMedia: string) {
6268
- this[`endSetupDelay${typeMedia}`] = performance.now();
6269
- }
6270
-
6271
- /**
6272
- * @param {string} typeMedia 'audio' or 'video'
6273
- * @returns {string} duration between start and end of setup
6274
- */
6275
- getSetupDelayDuration(typeMedia: string) {
6276
- const start = this[`startSetupDelay${typeMedia}`];
6277
- const end = this[`endSetupDelay${typeMedia}`];
6278
-
6279
- return start && end ? end - start : undefined;
6280
- }
6281
-
6282
- /**
6283
- * @param {string} typeMedia 'audio' or 'video'
6284
- * @returns {undefined}
6285
- */
6286
- setStartSendingMediaDelay(typeMedia: string) {
6287
- this[`startSendingMediaDelay${typeMedia}`] = performance.now();
6288
- this[`endSendingMediaDelay${typeMedia}`] = undefined;
6289
- }
6290
-
6291
- /**
6292
- * @param {string} typeMedia 'audio' or 'video'
6293
- * @returns {undefined}
6294
- */
6295
- setEndSendingMediaDelay(typeMedia: string) {
6296
- this[`endSendingMediaDelay${typeMedia}`] = performance.now();
6297
- }
6298
-
6299
- /**
6300
- * @param {string} typeMedia 'audio' or 'video'
6301
- * @returns {string} duration between join response and first media tx
6302
- */
6303
- getSendingMediaDelayDuration(typeMedia: string) {
6304
- const start = this[`startSendingMediaDelay${typeMedia}`];
6305
- const end = this[`endSendingMediaDelay${typeMedia}`];
6306
-
6307
- return start && end ? end - start : undefined;
6308
- }
6309
-
6310
- /**
6311
- *
6312
- * @returns {undefined}
6313
- */
6314
- setStartLocalSDPGenRemoteSDPRecvDelay() {
6315
- if (!this.startLocalSDPGenRemoteSDPRecvDelay) {
6316
- this.startLocalSDPGenRemoteSDPRecvDelay = performance.now();
6317
- this.endLocalSDPGenRemoteSDPRecvDelay = undefined;
6318
- }
6319
- }
6320
-
6321
- /**
6322
- *
6323
- * @returns {undefined}
6324
- */
6325
- setEndLocalSDPGenRemoteSDPRecvDelay() {
6326
- if (!this.endLocalSDPGenRemoteSDPRecvDelay) {
6327
- this.endLocalSDPGenRemoteSDPRecvDelay = performance.now();
6328
- }
6329
- }
6330
-
6331
- /**
6332
- *
6333
- * @returns {string} duration between local SDP generation and remote SDP reception
6334
- */
6335
- getLocalSDPGenRemoteSDPRecvDelay() {
6336
- const start = this.startLocalSDPGenRemoteSDPRecvDelay;
6337
- const end = this.endLocalSDPGenRemoteSDPRecvDelay;
6338
-
6339
- if (start && end) {
6340
- const calculatedDelay = Math.round(end - start);
6341
-
6342
- return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
6343
- }
6344
-
6345
- return undefined;
6346
- }
6347
-
6348
- /**
6349
- *
6350
- * @returns {undefined}
6351
- */
6352
- setStartCallInitJoinReq() {
6353
- this.startCallInitJoinReq = performance.now();
6354
- this.endCallInitJoinReq = undefined;
6355
- }
6356
-
6357
- /**
6358
- *
6359
- * @returns {undefined}
6360
- */
6361
- setEndCallInitJoinReq() {
6362
- this.endCallInitJoinReq = performance.now();
6363
- }
6364
-
6365
- /**
6366
- *
6367
- * @returns {string} duration between call initiate and sending join request to locus
6368
- */
6369
- getCallInitJoinReq() {
6370
- const start = this.startCallInitJoinReq;
6371
- const end = this.endCallInitJoinReq;
6372
-
6373
- if (start && end) {
6374
- const calculatedDelay = end - start;
6375
-
6376
- return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
6377
- }
6378
-
6379
- return undefined;
6380
- }
6381
-
6382
- /**
6383
- *
6384
- * @returns {undefined}
6385
- */
6386
- setStartJoinReqResp() {
6387
- this.startJoinReqResp = performance.now();
6388
- this.endJoinReqResp = undefined;
6389
- }
6390
-
6391
- /**
6392
- *
6393
- * @returns {undefined}
6394
- */
6395
- setEndJoinReqResp() {
6396
- this.endJoinReqResp = performance.now();
6397
- }
6398
-
6399
- /**
6400
- *
6401
- * @returns {string} duration between sending locus join request and receiving join response
6402
- */
6403
- getJoinReqResp() {
6404
- const start = this.startJoinReqResp;
6405
- const end = this.endJoinReqResp;
6406
-
6407
- if (start && end) {
6408
- const calculatedDelay = Math.round(end - start);
6409
-
6410
- return calculatedDelay > METRICS_JOIN_TIMES_MAX_DURATION ? undefined : calculatedDelay;
6411
- }
6412
-
6413
- return undefined;
6414
- }
6415
-
6416
- /**
6417
- *
6418
- * @returns {string} duration between call initiate and successful locus join (even if it is in lobby)
6419
- */
6420
- getTotalJmt() {
6421
- const start = this.startCallInitJoinReq;
6422
- const end = this.endJoinReqResp;
6423
-
6424
- return start && end ? Math.round(end - start) : undefined;
6425
- }
6426
-
6427
6378
  /**
6428
6379
  *
6429
6380
  * @returns {string} one of 'attendee','host','cohost', returns the user type of the current user
@@ -6445,20 +6396,6 @@ export default class Meeting extends StatelessWebexPlugin {
6445
6396
  return null;
6446
6397
  }
6447
6398
 
6448
- /**
6449
- *
6450
- * @returns {string} one of 'login-ci','unverified-guest', returns the login type of the current user
6451
- */
6452
- getCurLoginType() {
6453
- // @ts-ignore
6454
- if (this.webex.canAuthorize) {
6455
- // @ts-ignore
6456
- return this.webex.credentials.isUnverifiedGuest ? 'unverified-guest' : 'login-ci';
6457
- }
6458
-
6459
- return null;
6460
- }
6461
-
6462
6399
  /**
6463
6400
  * End the current meeting for all
6464
6401
  * @returns {Promise}
@@ -6466,10 +6403,11 @@ export default class Meeting extends StatelessWebexPlugin {
6466
6403
  * @memberof Meeting
6467
6404
  */
6468
6405
  public endMeetingForAll() {
6469
- Metrics.postEvent({
6470
- event: eventType.LEAVE,
6471
- meeting: this,
6472
- data: {trigger: trigger.USER_INTERACTION, canProceed: false},
6406
+ // @ts-ignore
6407
+ this.webex.internal.newMetrics.submitClientEvent({
6408
+ name: 'client.call.leave',
6409
+ payload: {trigger: 'user-interaction', canProceed: false},
6410
+ options: {meetingId: this.id},
6473
6411
  });
6474
6412
 
6475
6413
  LoggerProxy.logger.log('Meeting:index#endMeetingForAll --> End meeting for All');