Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 126 additions & 6 deletions packages/@webex/plugin-meetings/src/meeting-info/meeting-info-v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const CAPTCHA_ERROR_DEFAULT_MESSAGE =
'Captcha required. Call fetchMeetingInfo() with captchaInfo argument';
const ADHOC_MEETING_DEFAULT_ERROR =
'Failed starting the adhoc meeting, Please contact support team ';
const MEETING_IS_IN_PROGRESS_MESSAGE = 'Meeting is in progress';
const STATIC_MEETING_LINK_ALREADY_EXISTS_MESSAGE = 'Static meeting link already exists';
const CAPTCHA_ERROR_REQUIRES_PASSWORD_CODES = [423005, 423006];
const CAPTCHA_ERROR_REQUIRES_REGISTRATION_ID_CODES = [423007];

Expand Down Expand Up @@ -193,6 +195,55 @@ export class MeetingInfoV2JoinForbiddenError extends Error {
}
}

/**
* Error enabling/disabling static meeting link
*/
export class MeetingInfoV2MeetingIsInProgressError extends Error {
sdkMessage: any;
wbxAppApiCode: any;
body: any;
/**
*
* @constructor
* @param {Number} [wbxAppApiErrorCode]
* @param {String} [message]
* @param {Boolean} [enable]
*/
constructor(
wbxAppApiErrorCode?: number,
message = MEETING_IS_IN_PROGRESS_MESSAGE,
enable = false
) {
super(`${message}, code=${wbxAppApiErrorCode}, enable=${enable}`);
this.name = 'MeetingInfoV2MeetingIsInProgressError';
this.sdkMessage = message;
this.stack = new Error().stack;
this.wbxAppApiCode = wbxAppApiErrorCode;
}
}

/**
* Error enabling/disabling static meeting link
*/
export class MeetingInfoV2StaticMeetingLinkAlreadyExists extends Error {
sdkMessage: any;
wbxAppApiCode: any;
body: any;
/**
*
* @constructor
* @param {Number} [wbxAppApiErrorCode]
* @param {String} [message]
*/
constructor(wbxAppApiErrorCode?: number, message = STATIC_MEETING_LINK_ALREADY_EXISTS_MESSAGE) {
super(`${message}, code=${wbxAppApiErrorCode}`);
this.name = 'MeetingInfoV2StaticMeetingLinkAlreadyExists';
this.sdkMessage = message;
this.stack = new Error().stack;
this.wbxAppApiCode = wbxAppApiErrorCode;
}
}

/**
* @class MeetingInfo
*/
Expand Down Expand Up @@ -293,17 +344,20 @@ export default class MeetingInfoV2 {
};

/**
* Creates adhoc space meetings for a space by fetching the conversation infomation
* helper function to either create an adhoc space meeting or enable static meeting link
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
* @param {String} installedOrgID org ID of user's machine
* @param {Boolean} enableStaticMeetingLink whether or not to enable static meeting link
* @returns {Promise} returns a meeting info object
* @public
* @memberof MeetingInfo
*/
async createAdhocSpaceMeeting(conversationUrl: string, installedOrgID?: string) {
if (!this.webex.meetings.preferredWebexSite) {
throw Error('No preferred webex site found');
}
async createAdhocSpaceMeetingOrEnableStaticMeetingLink(
conversationUrl: string,
installedOrgID?: string,
// setting this to true enables static meeting link
enableStaticMeetingLink = false
) {
const getInvitees = (particpants = []) => {
const invitees = [];

Expand All @@ -329,6 +383,7 @@ export default class MeetingInfoV2 {
kroUrl: conversation.kmsResourceObjectUrl,
invitees: getInvitees(conversation.participants?.items),
installedOrgID,
schedule: enableStaticMeetingLink,
};

if (installedOrgID) {
Expand All @@ -344,7 +399,23 @@ export default class MeetingInfoV2 {
uri,
body,
});
})
});
}

/**
* Creates adhoc space meetings for a space by fetching the conversation infomation
* @param {String} conversationUrl conversationUrl to start adhoc meeting on
* @param {String} installedOrgID org ID of user's machine
* @returns {Promise} returns a meeting info object
* @public
* @memberof MeetingInfo
*/
async createAdhocSpaceMeeting(conversationUrl: string, installedOrgID?: string) {
if (!this.webex.meetings.preferredWebexSite) {
throw Error('No preferred webex site found');
}

return this.createAdhocSpaceMeetingOrEnableStaticMeetingLink(conversationUrl, installedOrgID)
.then((requestResult) => {
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ADHOC_MEETING_SUCCESS);

Expand All @@ -363,6 +434,55 @@ export default class MeetingInfoV2 {
});
}

/**
* Enables static meeting link
* @param {String} conversationUrl conversationUrl that's required to enable static meeting link
* @returns {Promise} returns a meeting info object
* @public
* @memberof MeetingInfo
*/
async enableStaticMeetingLink(conversationUrl: string) {
if (!this.webex.meetings.preferredWebexSite) {
throw Error('No preferred webex site found');
}

return this.createAdhocSpaceMeetingOrEnableStaticMeetingLink(conversationUrl, undefined, true)
.then((requestResult) => {
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ENABLE_STATIC_METTING_LINK_SUCCESS);

return requestResult;
})
.catch((err) => {
if (err?.statusCode === 403) {
Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.MEETING_IS_IN_PROGRESS_ERROR, {
reason: err.message,
stack: err.stack,
});

throw new MeetingInfoV2MeetingIsInProgressError(err.body?.code, err.body?.message, true);
}

if (err?.statusCode === 409) {
Metrics.sendBehavioralMetric(
BEHAVIORAL_METRICS.STATIC_MEETING_LINK_ALREADY_EXISTS_ERROR,
{
reason: err.message,
stack: err.stack,
}
);

throw new MeetingInfoV2StaticMeetingLinkAlreadyExists(err.body?.code, err.body?.message);
}

Metrics.sendBehavioralMetric(BEHAVIORAL_METRICS.ENABLE_STATIC_METTING_LINK_FAILURE, {
reason: err.message,
stack: err.stack,
});

throw err;
});
}

/**
* Fetches meeting info from the server
* @param {String} destination one of many different types of destinations to look up info for
Expand Down
24 changes: 24 additions & 0 deletions packages/@webex/plugin-meetings/src/meetings/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1369,6 +1369,30 @@ export default class Meetings extends WebexPlugin {
);
}

/**
* Enable static meeting links for given conversation url.
*
*
* @param {string} conversationUrl - url for conversation
* @returns {Promise<Meeting>} A new Meeting.
* @public
* @memberof Meetings
*/
public enableStaticMeetingLink(conversationUrl: string): Promise<Meeting> {
return (
this.meetingInfo
.enableStaticMeetingLink(conversationUrl)
// Catch a failure to enable static meeting link.
.catch((error) => {
LoggerProxy.logger.error(
`Meetings:index#enableStaticMeetingLink --> ERROR, unable to enable static meeting link: ${error.message}`
);

return Promise.reject(error);
})
);
}

/**
* Create meeting
*
Expand Down
4 changes: 4 additions & 0 deletions packages/@webex/plugin-meetings/src/metrics/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ const BEHAVIORAL_METRICS = {
UPLOAD_LOGS_FAILURE: 'js_sdk_upload_logs_failure',
UPLOAD_LOGS_SUCCESS: 'js_sdk_upload_logs_success',
RECEIVE_TRANSCRIPTION_FAILURE: 'js_sdk_receive_transcription_failure',
ENABLE_STATIC_METTING_LINK_SUCCESS: 'js_sdk_enable_static_meeting_link_success',
ENABLE_STATIC_METTING_LINK_FAILURE: 'js_sdk_enable_static_meeting_link_failure',
MEETING_IS_IN_PROGRESS_ERROR: 'js_sdk_meeting_is_in_progress_error',
STATIC_MEETING_LINK_ALREADY_EXISTS_ERROR: 'js_sdk_static_meeting_link_already_exists_error',
FETCH_MEETING_INFO_V1_SUCCESS: 'js_sdk_fetch_meeting_info_v1_success',
FETCH_MEETING_INFO_V1_FAILURE: 'js_sdk_fetch_meeting_info_v1_failure',
ADHOC_MEETING_SUCCESS: 'js_sdk_adhoc_meeting_success',
Expand Down
Loading