@webex/plugin-meetings 3.5.0 → 3.6.0-next.10
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/common/errors/webinar-registration-error.js +50 -0
- package/dist/common/errors/webinar-registration-error.js.map +1 -0
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/interpretation/index.js +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/locus-info/parser.js +5 -1
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/media/index.js +3 -1
- package/dist/media/index.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js +3 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +185 -103
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/muteState.js +5 -2
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/util.js +8 -10
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +68 -17
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meetings/index.js +102 -27
- package/dist/meetings/index.js.map +1 -1
- package/dist/metrics/constants.js +2 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/multistream/remoteMedia.js +4 -0
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/roap/request.js +1 -1
- package/dist/roap/request.js.map +1 -1
- package/dist/types/common/errors/webinar-registration-error.d.ts +14 -0
- package/dist/types/config.d.ts +2 -0
- package/dist/types/constants.d.ts +8 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/meeting/in-meeting-actions.d.ts +2 -0
- package/dist/types/meeting/index.d.ts +11 -0
- package/dist/types/meeting/muteState.d.ts +2 -1
- package/dist/types/meeting-info/meeting-info-v2.d.ts +23 -0
- package/dist/types/meetings/index.d.ts +43 -2
- package/dist/types/metrics/constants.d.ts +1 -0
- package/dist/types/multistream/remoteMedia.d.ts +1 -0
- package/dist/webinar/index.js +1 -1
- package/package.json +22 -22
- package/src/common/errors/webinar-registration-error.ts +27 -0
- package/src/config.ts +3 -0
- package/src/constants.ts +7 -0
- package/src/index.ts +2 -0
- package/src/locus-info/parser.ts +8 -1
- package/src/media/index.ts +4 -1
- package/src/meeting/in-meeting-actions.ts +3 -0
- package/src/meeting/index.ts +82 -13
- package/src/meeting/muteState.ts +6 -2
- package/src/meeting/util.ts +27 -31
- package/src/meeting-info/meeting-info-v2.ts +51 -0
- package/src/meetings/index.ts +129 -38
- package/src/metrics/constants.ts +1 -0
- package/src/multistream/remoteMedia.ts +5 -0
- package/src/roap/request.ts +3 -1
- package/test/unit/spec/locus-info/index.js +29 -0
- package/test/unit/spec/media/index.ts +4 -0
- package/test/unit/spec/meeting/in-meeting-actions.ts +2 -0
- package/test/unit/spec/meeting/index.js +118 -18
- package/test/unit/spec/meeting/muteState.js +8 -4
- package/test/unit/spec/meeting/utils.js +50 -85
- package/test/unit/spec/meeting-info/meetinginfov2.js +37 -0
- package/test/unit/spec/meetings/index.js +128 -13
- package/test/unit/spec/multistream/remoteMedia.ts +16 -2
- package/dist/networkQualityMonitor/index.js +0 -227
- package/dist/networkQualityMonitor/index.js.map +0 -1
- package/dist/rtcMetrics/constants.js +0 -11
- package/dist/rtcMetrics/constants.js.map +0 -1
- package/dist/rtcMetrics/index.js +0 -197
- package/dist/rtcMetrics/index.js.map +0 -1
- package/dist/types/networkQualityMonitor/index.d.ts +0 -70
- package/dist/types/rtcMetrics/constants.d.ts +0 -4
- package/dist/types/rtcMetrics/index.d.ts +0 -71
- package/src/rtcMetrics/constants.ts +0 -3
- package/src/rtcMetrics/index.ts +0 -186
- package/test/unit/spec/rtcMetrics/index.ts +0 -154
|
@@ -82,6 +82,7 @@ interface IInMeetingActions {
|
|
|
82
82
|
supportHDV?: boolean;
|
|
83
83
|
canShareWhiteBoard?: boolean;
|
|
84
84
|
enforceVirtualBackground?: boolean;
|
|
85
|
+
canPollingAndQA?: boolean;
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
/**
|
|
@@ -236,6 +237,7 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
236
237
|
|
|
237
238
|
canShareWhiteBoard = null;
|
|
238
239
|
|
|
240
|
+
canPollingAndQA = null;
|
|
239
241
|
/**
|
|
240
242
|
* Returns all meeting action options
|
|
241
243
|
* @returns {Object}
|
|
@@ -314,6 +316,7 @@ export default class InMeetingActions implements IInMeetingActions {
|
|
|
314
316
|
supportHQV: this.supportHQV,
|
|
315
317
|
supportHDV: this.supportHDV,
|
|
316
318
|
canShareWhiteBoard: this.canShareWhiteBoard,
|
|
319
|
+
canPollingAndQA: this.canPollingAndQA,
|
|
317
320
|
});
|
|
318
321
|
|
|
319
322
|
/**
|
package/src/meeting/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
ClientEventLeaveReason,
|
|
11
11
|
CallDiagnosticUtils,
|
|
12
12
|
CALL_DIAGNOSTIC_CONFIG,
|
|
13
|
+
RtcMetrics,
|
|
13
14
|
} from '@webex/internal-plugin-metrics';
|
|
14
15
|
import {ClientEvent as RawClientEvent} from '@webex/event-dictionary-ts';
|
|
15
16
|
|
|
@@ -127,6 +128,7 @@ import {
|
|
|
127
128
|
MeetingInfoV2PasswordError,
|
|
128
129
|
MeetingInfoV2CaptchaError,
|
|
129
130
|
MeetingInfoV2PolicyError,
|
|
131
|
+
MeetingInfoV2WebinarRegistrationError,
|
|
130
132
|
} from '../meeting-info/meeting-info-v2';
|
|
131
133
|
import {CSI, ReceiveSlotManager} from '../multistream/receiveSlotManager';
|
|
132
134
|
import SendSlotManager from '../multistream/sendSlotManager';
|
|
@@ -155,7 +157,7 @@ import ControlsOptionsManager from '../controls-options-manager';
|
|
|
155
157
|
import PermissionError from '../common/errors/permission';
|
|
156
158
|
import {LocusMediaRequest} from './locusMediaRequest';
|
|
157
159
|
import {ConnectionStateHandler, ConnectionStateEvent} from './connectionStateHandler';
|
|
158
|
-
import
|
|
160
|
+
import WebinarRegistrationError from '../common/errors/webinar-registration-error';
|
|
159
161
|
|
|
160
162
|
// default callback so we don't call an undefined function, but in practice it should never be used
|
|
161
163
|
const DEFAULT_ICE_PHASE_CALLBACK = () => 'JOIN_MEETING_FINAL';
|
|
@@ -227,6 +229,7 @@ export type AddMediaOptions = {
|
|
|
227
229
|
|
|
228
230
|
export type CallStateForMetrics = {
|
|
229
231
|
correlationId?: string;
|
|
232
|
+
sessionCorrelationId?: string;
|
|
230
233
|
joinTrigger?: string;
|
|
231
234
|
loginType?: string;
|
|
232
235
|
};
|
|
@@ -742,12 +745,29 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
742
745
|
*/
|
|
743
746
|
this.callStateForMetrics = attrs.callStateForMetrics || {};
|
|
744
747
|
const correlationId = attrs.correlationId || attrs.callStateForMetrics?.correlationId;
|
|
748
|
+
const sessionCorrelationId =
|
|
749
|
+
attrs.sessionCorrelationId || attrs.callStateForMetrics?.sessionCorrelationId;
|
|
750
|
+
if (sessionCorrelationId) {
|
|
751
|
+
LoggerProxy.logger.log(
|
|
752
|
+
`Meetings:index#constructor --> Initializing the meeting object with session correlation id from app ${correlationId}`
|
|
753
|
+
);
|
|
754
|
+
this.callStateForMetrics.sessionCorrelationId = sessionCorrelationId;
|
|
755
|
+
} else {
|
|
756
|
+
LoggerProxy.logger.log(
|
|
757
|
+
`Meetings:index#constructor --> No session correlation id supplied. None will be generated and this field will remain blank`
|
|
758
|
+
);
|
|
759
|
+
// TODO: supply a session from the meetings instance
|
|
760
|
+
this.callStateForMetrics.sessionCorrelationId = '';
|
|
761
|
+
}
|
|
745
762
|
if (correlationId) {
|
|
746
763
|
LoggerProxy.logger.log(
|
|
747
764
|
`Meetings:index#constructor --> Initializing the meeting object with correlation id from app ${correlationId}`
|
|
748
765
|
);
|
|
749
766
|
this.callStateForMetrics.correlationId = correlationId;
|
|
750
767
|
} else {
|
|
768
|
+
LoggerProxy.logger.log(
|
|
769
|
+
`Meetings:index#constructor --> Initializing the meeting object with generated correlation id from sdk ${this.id}`
|
|
770
|
+
);
|
|
751
771
|
this.callStateForMetrics.correlationId = this.id;
|
|
752
772
|
}
|
|
753
773
|
/**
|
|
@@ -1581,6 +1601,22 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1581
1601
|
this.callStateForMetrics.correlationId = correlationId;
|
|
1582
1602
|
}
|
|
1583
1603
|
|
|
1604
|
+
/**
|
|
1605
|
+
* Getter - Returns callStateForMetrics.sessionCorrelationId
|
|
1606
|
+
* @returns {string}
|
|
1607
|
+
*/
|
|
1608
|
+
get sessionCorrelationId() {
|
|
1609
|
+
return this.callStateForMetrics.sessionCorrelationId;
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
/**
|
|
1613
|
+
* Setter - sets callStateForMetrics.sessionCorrelationId
|
|
1614
|
+
* @param {string} sessionCorrelationId
|
|
1615
|
+
*/
|
|
1616
|
+
set sessionCorrelationId(sessionCorrelationId: string) {
|
|
1617
|
+
this.callStateForMetrics.sessionCorrelationId = sessionCorrelationId;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1584
1620
|
/**
|
|
1585
1621
|
* Getter - Returns isoLocalClientMeetingJoinTime
|
|
1586
1622
|
* This will be set once on meeting join, and not updated again
|
|
@@ -1725,8 +1761,16 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
1725
1761
|
if (err.meetingInfo) {
|
|
1726
1762
|
this.meetingInfo = err.meetingInfo;
|
|
1727
1763
|
}
|
|
1728
|
-
|
|
1729
1764
|
throw new PermissionError();
|
|
1765
|
+
} else if (err instanceof MeetingInfoV2WebinarRegistrationError) {
|
|
1766
|
+
this.meetingInfoFailureReason = MEETING_INFO_FAILURE_REASON.WEBINAR_REGISTRATION;
|
|
1767
|
+
this.meetingInfoFailureCode = err.wbxAppApiCode;
|
|
1768
|
+
|
|
1769
|
+
if (err.meetingInfo) {
|
|
1770
|
+
this.meetingInfo = err.meetingInfo;
|
|
1771
|
+
}
|
|
1772
|
+
|
|
1773
|
+
throw new WebinarRegistrationError();
|
|
1730
1774
|
} else if (err instanceof MeetingInfoV2PasswordError) {
|
|
1731
1775
|
LoggerProxy.logger.info(
|
|
1732
1776
|
// @ts-ignore
|
|
@@ -2705,6 +2749,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
2705
2749
|
newShareStatus = SHARE_STATUS.NO_SHARE;
|
|
2706
2750
|
}
|
|
2707
2751
|
|
|
2752
|
+
LoggerProxy.logger.info(
|
|
2753
|
+
`Meeting:index#setUpLocusInfoMediaInactiveListener --> this.shareStatus=${this.shareStatus} newShareStatus=${newShareStatus}`
|
|
2754
|
+
);
|
|
2708
2755
|
if (newShareStatus !== this.shareStatus) {
|
|
2709
2756
|
const oldShareStatus = this.shareStatus;
|
|
2710
2757
|
|
|
@@ -3057,7 +3104,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3057
3104
|
private setUpLocusInfoSelfListener() {
|
|
3058
3105
|
this.locusInfo.on(LOCUSINFO.EVENTS.LOCAL_UNMUTE_REQUIRED, (payload) => {
|
|
3059
3106
|
if (this.audio) {
|
|
3060
|
-
this.audio.handleServerLocalUnmuteRequired(this);
|
|
3107
|
+
this.audio.handleServerLocalUnmuteRequired(this, payload.unmuteAllowed);
|
|
3061
3108
|
Trigger.trigger(
|
|
3062
3109
|
this,
|
|
3063
3110
|
{
|
|
@@ -3792,6 +3839,10 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
3792
3839
|
requiredPolicies: [SELF_POLICY.SUPPORT_CHAT],
|
|
3793
3840
|
policies: this.selfUserPolicies,
|
|
3794
3841
|
}),
|
|
3842
|
+
canPollingAndQA: ControlsOptionsUtil.hasPolicies({
|
|
3843
|
+
requiredPolicies: [SELF_POLICY.SUPPORT_POLLING_AND_QA],
|
|
3844
|
+
policies: this.selfUserPolicies,
|
|
3845
|
+
}),
|
|
3795
3846
|
canShareApplication:
|
|
3796
3847
|
(ControlsOptionsUtil.hasHints({
|
|
3797
3848
|
requiredHints: [DISPLAY_HINTS.SHARE_APPLICATION],
|
|
@@ -6338,7 +6389,7 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6338
6389
|
private async createMediaConnection(turnServerInfo, bundlePolicy?: BundlePolicy) {
|
|
6339
6390
|
this.rtcMetrics = this.isMultistream
|
|
6340
6391
|
? // @ts-ignore
|
|
6341
|
-
new RtcMetrics(this.webex, this.id, this.correlationId)
|
|
6392
|
+
new RtcMetrics(this.webex, {meetingId: this.id}, this.correlationId)
|
|
6342
6393
|
: undefined;
|
|
6343
6394
|
|
|
6344
6395
|
const mc = Media.createMediaConnection(
|
|
@@ -6355,6 +6406,8 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
6355
6406
|
enableExtmap: this.config.enableExtmap,
|
|
6356
6407
|
turnServerInfo,
|
|
6357
6408
|
bundlePolicy,
|
|
6409
|
+
// @ts-ignore - config coming from registerPlugin
|
|
6410
|
+
iceCandidatesTimeout: this.config.iceCandidatesGatheringTimeout,
|
|
6358
6411
|
}
|
|
6359
6412
|
);
|
|
6360
6413
|
|
|
@@ -8142,6 +8195,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8142
8195
|
* @returns {undefined}
|
|
8143
8196
|
*/
|
|
8144
8197
|
private handleShareAudioStreamEnded = async () => {
|
|
8198
|
+
LoggerProxy.logger.info(
|
|
8199
|
+
`Meeting:index#handleShareAudioStreamEnded --> audio share stream ended`
|
|
8200
|
+
);
|
|
8145
8201
|
// current share audio stream has ended, but there might be an active
|
|
8146
8202
|
// share video stream. we only leave from wireless share if share has
|
|
8147
8203
|
// completely ended, which means no share audio or video streams active
|
|
@@ -8184,6 +8240,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8184
8240
|
* @returns {undefined}
|
|
8185
8241
|
*/
|
|
8186
8242
|
private handleShareVideoStreamEnded = async () => {
|
|
8243
|
+
LoggerProxy.logger.info(
|
|
8244
|
+
`Meeting:index#handleShareVideoStreamEnded --> video share stream ended`
|
|
8245
|
+
);
|
|
8187
8246
|
// current share video stream has ended, but there might be an active
|
|
8188
8247
|
// share audio stream. we only leave from wireless share if share has
|
|
8189
8248
|
// completely ended, which means no share audio or video streams active
|
|
@@ -8672,6 +8731,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8672
8731
|
* @returns {Promise}
|
|
8673
8732
|
*/
|
|
8674
8733
|
async publishStreams(streams: LocalStreams): Promise<void> {
|
|
8734
|
+
LoggerProxy.logger.info(
|
|
8735
|
+
`Meeting:index#publishStreams --> called with: ${JSON.stringify(streams)}`
|
|
8736
|
+
);
|
|
8675
8737
|
this.checkMediaConnection();
|
|
8676
8738
|
if (
|
|
8677
8739
|
!streams.microphone &&
|
|
@@ -8683,15 +8745,19 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8683
8745
|
return;
|
|
8684
8746
|
}
|
|
8685
8747
|
|
|
8686
|
-
|
|
8687
|
-
streams?.microphone
|
|
8688
|
-
streams?.camera
|
|
8689
|
-
streams?.screenShare?.audio
|
|
8690
|
-
streams?.screenShare?.video
|
|
8691
|
-
|
|
8692
|
-
|
|
8693
|
-
|
|
8694
|
-
)
|
|
8748
|
+
const streamChecks = [
|
|
8749
|
+
{stream: streams?.microphone, name: 'microphone'},
|
|
8750
|
+
{stream: streams?.camera, name: 'camera'},
|
|
8751
|
+
{stream: streams?.screenShare?.audio, name: 'screenShare audio'},
|
|
8752
|
+
{stream: streams?.screenShare?.video, name: 'screenShare video'},
|
|
8753
|
+
];
|
|
8754
|
+
|
|
8755
|
+
for (const {stream, name} of streamChecks) {
|
|
8756
|
+
if (stream?.readyState === 'ended') {
|
|
8757
|
+
throw new Error(
|
|
8758
|
+
`Attempted to publish ${name} stream with ended readyState, correlationId=${this.correlationId}`
|
|
8759
|
+
);
|
|
8760
|
+
}
|
|
8695
8761
|
}
|
|
8696
8762
|
|
|
8697
8763
|
let floorRequestNeeded = false;
|
|
@@ -8753,6 +8819,9 @@ export default class Meeting extends StatelessWebexPlugin {
|
|
|
8753
8819
|
* @returns {Promise}
|
|
8754
8820
|
*/
|
|
8755
8821
|
async unpublishStreams(streams: LocalStream[]): Promise<void> {
|
|
8822
|
+
LoggerProxy.logger.info(
|
|
8823
|
+
`Meeting:index#unpublishStreams --> called with: ${JSON.stringify(streams)}`
|
|
8824
|
+
);
|
|
8756
8825
|
this.checkMediaConnection();
|
|
8757
8826
|
|
|
8758
8827
|
const promises = [];
|
package/src/meeting/muteState.ts
CHANGED
|
@@ -394,21 +394,25 @@ export class MuteState {
|
|
|
394
394
|
* @public
|
|
395
395
|
* @memberof MuteState
|
|
396
396
|
* @param {Object} [meeting] the meeting object
|
|
397
|
+
* @param {Boolean} [unmuteAllowed] whether the user is allowed to unmute self
|
|
397
398
|
* @returns {undefined}
|
|
398
399
|
*/
|
|
399
|
-
public handleServerLocalUnmuteRequired(meeting
|
|
400
|
+
public handleServerLocalUnmuteRequired(meeting: any, unmuteAllowed: boolean) {
|
|
400
401
|
if (!this.state.client.enabled) {
|
|
401
402
|
LoggerProxy.logger.warn(
|
|
402
403
|
`Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received while ${this.type} is disabled -> local unmute will not result in ${this.type} being sent`
|
|
403
404
|
);
|
|
404
405
|
} else {
|
|
405
406
|
LoggerProxy.logger.info(
|
|
406
|
-
`Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute`
|
|
407
|
+
`Meeting:muteState#handleServerLocalUnmuteRequired --> ${this.type}: localAudioUnmuteRequired received -> doing local unmute (unmuteAllowed=${unmuteAllowed})`
|
|
407
408
|
);
|
|
408
409
|
}
|
|
409
410
|
|
|
410
411
|
// todo: I'm seeing "you can now unmute yourself " popup when this happens - but same thing happens on web.w.c so we can ignore for now
|
|
411
412
|
this.state.server.remoteMute = false;
|
|
413
|
+
this.state.server.unmuteAllowed = unmuteAllowed;
|
|
414
|
+
|
|
415
|
+
this.applyUnmuteAllowedToStream(meeting);
|
|
412
416
|
|
|
413
417
|
// change user mute state to false, but keep localMute true if overall mute state is still true
|
|
414
418
|
this.muteLocalStream(meeting, false, 'localUnmuteRequired');
|
package/src/meeting/util.ts
CHANGED
|
@@ -89,8 +89,12 @@ const MeetingUtil = {
|
|
|
89
89
|
getIpVersion(webex: any): IP_VERSION | undefined {
|
|
90
90
|
const {supportsIpV4, supportsIpV6} = webex.internal.device.ipNetworkDetector;
|
|
91
91
|
|
|
92
|
-
if (
|
|
93
|
-
|
|
92
|
+
if (
|
|
93
|
+
!webex.config.meetings.backendIpv6NativeSupport &&
|
|
94
|
+
BrowserDetection().isBrowser('firefox')
|
|
95
|
+
) {
|
|
96
|
+
// when backend doesn't support native ipv6,
|
|
97
|
+
// then our NAT64/DNS64 based solution relies on FQDN ICE candidates, but Firefox doesn't support them,
|
|
94
98
|
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1713128
|
|
95
99
|
// so for Firefox we don't want the backend to activate the "ipv6 feature"
|
|
96
100
|
return undefined;
|
|
@@ -150,7 +154,9 @@ const MeetingUtil = {
|
|
|
150
154
|
ipVersion: MeetingUtil.getIpVersion(meeting.getWebexObject()),
|
|
151
155
|
})
|
|
152
156
|
.then((res) => {
|
|
153
|
-
|
|
157
|
+
const parsed = MeetingUtil.parseLocusJoin(res);
|
|
158
|
+
meeting.setLocus(parsed);
|
|
159
|
+
|
|
154
160
|
webex.internal.newMetrics.submitClientEvent({
|
|
155
161
|
name: 'client.locus.join.response',
|
|
156
162
|
payload: {
|
|
@@ -161,11 +167,11 @@ const MeetingUtil = {
|
|
|
161
167
|
},
|
|
162
168
|
options: {
|
|
163
169
|
meetingId: meeting.id,
|
|
164
|
-
mediaConnections:
|
|
170
|
+
mediaConnections: parsed.mediaConnections,
|
|
165
171
|
},
|
|
166
172
|
});
|
|
167
173
|
|
|
168
|
-
return
|
|
174
|
+
return parsed;
|
|
169
175
|
});
|
|
170
176
|
},
|
|
171
177
|
|
|
@@ -313,34 +319,24 @@ const MeetingUtil = {
|
|
|
313
319
|
}
|
|
314
320
|
|
|
315
321
|
// normal join meeting, scenario A, D
|
|
316
|
-
return MeetingUtil.joinMeeting(meeting, options)
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
// @ts-ignore
|
|
326
|
-
webex.internal.newMetrics.submitClientEvent({
|
|
327
|
-
name: 'client.pin.prompt',
|
|
328
|
-
options: {
|
|
329
|
-
meetingId: meeting.id,
|
|
330
|
-
},
|
|
331
|
-
});
|
|
322
|
+
return MeetingUtil.joinMeeting(meeting, options).catch((err) => {
|
|
323
|
+
// joining a claimed PMR that is not my own, scenario B
|
|
324
|
+
if (MeetingUtil.isPinOrGuest(err)) {
|
|
325
|
+
webex.internal.newMetrics.submitClientEvent({
|
|
326
|
+
name: 'client.pin.prompt',
|
|
327
|
+
options: {
|
|
328
|
+
meetingId: meeting.id,
|
|
329
|
+
},
|
|
330
|
+
});
|
|
332
331
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
'Meeting:util#joinMeetingOptions --> Error joining the call, ',
|
|
339
|
-
err
|
|
340
|
-
);
|
|
332
|
+
// request host pin or non host for unclaimed PMR, start of Scenario C
|
|
333
|
+
// see https://sqbu-github.cisco.com/WebExSquared/locus/wiki/Locus-Lobby-and--IVR-Feature
|
|
334
|
+
return Promise.reject(new IntentToJoinError('Error Joining Meeting', err));
|
|
335
|
+
}
|
|
336
|
+
LoggerProxy.logger.error('Meeting:util#joinMeetingOptions --> Error joining the call, ', err);
|
|
341
337
|
|
|
342
|
-
|
|
343
|
-
|
|
338
|
+
return Promise.reject(new JoinMeetingError(options, 'Error Joining Meeting', err));
|
|
339
|
+
});
|
|
344
340
|
},
|
|
345
341
|
|
|
346
342
|
/**
|
|
@@ -18,6 +18,7 @@ const ADHOC_MEETING_DEFAULT_ERROR =
|
|
|
18
18
|
'Failed starting the adhoc meeting, Please contact support team ';
|
|
19
19
|
const CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES = [423005, 423006];
|
|
20
20
|
const POLICY_ERROR_CODES = [403049, 403104, 403103, 403048, 403102, 403101];
|
|
21
|
+
const WEBINAR_REGISTRATION_ERROR_CODES = [403021, 403022, 403024];
|
|
21
22
|
/**
|
|
22
23
|
* Error to indicate that wbxappapi requires a password
|
|
23
24
|
*/
|
|
@@ -124,6 +125,31 @@ export class MeetingInfoV2CaptchaError extends Error {
|
|
|
124
125
|
}
|
|
125
126
|
}
|
|
126
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Error preventing join because of a webinar registration error
|
|
130
|
+
*/
|
|
131
|
+
export class MeetingInfoV2WebinarRegistrationError extends Error {
|
|
132
|
+
meetingInfo: any;
|
|
133
|
+
sdkMessage: any;
|
|
134
|
+
wbxAppApiCode: any;
|
|
135
|
+
body: any;
|
|
136
|
+
/**
|
|
137
|
+
*
|
|
138
|
+
* @constructor
|
|
139
|
+
* @param {Number} [wbxAppApiErrorCode]
|
|
140
|
+
* @param {Object} [meetingInfo]
|
|
141
|
+
* @param {String} [message]
|
|
142
|
+
*/
|
|
143
|
+
constructor(wbxAppApiErrorCode?: number, meetingInfo?: object, message?: string) {
|
|
144
|
+
super(`${message}, code=${wbxAppApiErrorCode}`);
|
|
145
|
+
this.name = 'MeetingInfoV2WebinarRegistrationError';
|
|
146
|
+
this.sdkMessage = message;
|
|
147
|
+
this.stack = new Error().stack;
|
|
148
|
+
this.wbxAppApiCode = wbxAppApiErrorCode;
|
|
149
|
+
this.meetingInfo = meetingInfo;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
127
153
|
/**
|
|
128
154
|
* @class MeetingInfo
|
|
129
155
|
*/
|
|
@@ -177,6 +203,29 @@ export default class MeetingInfoV2 {
|
|
|
177
203
|
}
|
|
178
204
|
};
|
|
179
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Raises a handleWebinarRegistrationError for webinar registration error codes
|
|
208
|
+
* @param {any} err the error from the request
|
|
209
|
+
* @returns {void}
|
|
210
|
+
*/
|
|
211
|
+
handleWebinarRegistrationError = (err) => {
|
|
212
|
+
if (!err.body) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (WEBINAR_REGISTRATION_ERROR_CODES.includes(err.body?.code)) {
|
|
217
|
+
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.WEBINAR_REGISTRATION_ERROR, {
|
|
218
|
+
code: err.body?.code,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
throw new MeetingInfoV2WebinarRegistrationError(
|
|
222
|
+
err.body?.code,
|
|
223
|
+
err.body?.data?.meetingInfo,
|
|
224
|
+
err.body?.message
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
180
229
|
/**
|
|
181
230
|
* Creates adhoc space meetings for a space by fetching the conversation infomation
|
|
182
231
|
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
|
|
@@ -237,6 +286,7 @@ export default class MeetingInfoV2 {
|
|
|
237
286
|
})
|
|
238
287
|
.catch((err) => {
|
|
239
288
|
this.handlePolicyError(err);
|
|
289
|
+
this.handleWebinarRegistrationError(err);
|
|
240
290
|
|
|
241
291
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADHOC_MEETING_FAILURE, {
|
|
242
292
|
reason: err.message,
|
|
@@ -391,6 +441,7 @@ export default class MeetingInfoV2 {
|
|
|
391
441
|
|
|
392
442
|
if (err?.statusCode === 403) {
|
|
393
443
|
this.handlePolicyError(err);
|
|
444
|
+
this.handleWebinarRegistrationError(err);
|
|
394
445
|
|
|
395
446
|
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.VERIFY_PASSWORD_ERROR, {
|
|
396
447
|
reason: err.message,
|