@chunsiong.zoom just in case the code would be required for understanding this better, here’s the meeting page js
window.addEventListener("DOMContentLoaded", handleDomContentLoaded);
let mediaCapturePermissionInterval;
let mediaCapturePermissionResponsed = false;
function handleDomContentLoaded(event) {
console.log("DOM fully loaded and parsed");
initializeWebSdk();
}
function initializeWebSdk() {
const meetingSdkUtils = window.meetingSdkUtils;
const meetingArgs = meetingSdkUtils.meeting.parseQuery();
const meetingConfig = {
sdkKey: meetingArgs.sdkKey,
meetingNumber: meetingArgs.meetingNumber,
userName: "Dive Assistant",
passWord: meetingArgs.password,
leaveUrl: "/index.html",
role: parseInt(meetingArgs.role, 10),
userEmail: meetingArgs.email || "",
lang: "en-US",
signature: meetingArgs.signature || "",
};
ZoomMtg.preLoadWasm();
ZoomMtg.prepareJssdk();
function beginJoin(signature) {
ZoomMtg.init({
leaveUrl: meetingConfig.leaveUrl,
webEndpoint: meetingConfig.webEndpoint,
disableCORP: !window.crossOriginIsolated,
externalLinkPage: "./externalLinkPage.html",
success: () => {
logMessage("[zoomSdk-page] ZoomMtg.init Successful", "info", { meetingConfig, signature });
ZoomMtg.i18n.load(meetingConfig.lang);
ZoomMtg.i18n.reload(meetingConfig.lang);
ZoomMtg.join({
meetingNumber: meetingConfig.meetingNumber,
userName: meetingConfig.userName,
signature: meetingConfig.signature,
sdkKey: meetingConfig.sdkKey,
userEmail: meetingConfig.userEmail,
passWord: meetingConfig.passWord,
success: handleJoinSuccess,
error: handleLeaveError,
});
},
error: error => {
logMessage("[zoomSdk-page] ZoomMtg.init Error", "error", { error });
},
});
}
beginJoin(meetingConfig.signature);
}
// ------------- Bot Helper functions ------------------//
function handleJoinSuccess(success) {
logMessage("[zoomSdk-page] join Successful", "info", {
success,
});
startMediaCapturePermissionTimer();
setupMediaCaptureListeners();
}
function startMediaCapturePermissionTimer() {
mediaCapturePermissionInterval = setInterval(() => {
if (mediaCapturePermissionResponsed && mediaCapturePermissionInterval) {
clearInterval(mediaCapturePermissionInterval);
} else {
requestMediaCapturePermission();
console.log("pinging every 5 seconds");
}
}, 5000);
}
function requestMediaCapturePermission() {
ZoomMtg.mediaCapturePermission({
operate: "request",
});
}
function handleMediaCapturePermissionSuccess(success) {
logMessage("[zoomSdk-page] media capture permission success", "info", {
success,
});
mediaCapturePermissionResponsed = true;
if (success.allow) {
startMediaCapture();
logMessage("[zoomSdk-page] Media capture permission changed to ALLOW", "info");
} else {
stopMediaCapture();
logMessage("[zoomSdk-page] Media capture permission changed to DENY", "warn");
leaveMeetingAndHandleError();
}
}
function handleMediaCapturePermissionError(error) {
if (error.errorCode == "1") {
logMessage("[zoomSdk-page] Media capture permission Active", "info", {
error,
});
startMediaCapture();
} else {
logMessage("[zoomSdk-page] Media capture permission error", "error", {
error,
});
}
}
function startMediaCapture() {
ZoomMtg.mediaCapture({ record: "start" });
}
function stopMediaCapture() {
ZoomMtg.mediaCapture({ record: "stop" });
}
function pauseMediaCapture() {
ZoomMtg.mediaCapture({ record: "pause" });
}
function leaveMeetingAndHandleError() {
ZoomMtg.leaveMeeting({
success: handleLeaveSuccess,
error: handleLeaveError,
});
}
function handleLeaveSuccess(success) {
logMessage("[zoomSdk-page] Bot has left the meeting", "info", {
success,
});
window?.leaveZoomMtg("zoom_sdk_permission_rejected");
}
function handleLeaveError(error) {
logMessage(
"[zoomSdk-page] Bot failed to leave the meeting, use visibilityState of hidden to trigger leave",
"error",
{
error,
},
);
setupAccidentalLeaveListener(document, ZoomMtg);
}
function setupAccidentalLeaveListener(doc, zoom) {
doc.addEventListener("visibilitychange", function () {
if (doc.visibilityState === "hidden") {
window?.leaveZoomMtg("everyone_left");
}
});
}
function setupMediaCaptureListeners() {
ZoomMtg.inMeetingServiceListener("onMediaCapturePermissionChange", handleMediaCapturePermissionChange);
ZoomMtg.inMeetingServiceListener("onMediaCaptureStatusChange", handleMediaCaptureStatusChange);
ZoomMtg.inMeetingServiceListener("onUserLeave", handleUserLeave);
ZoomMtg.inMeetingServiceListener("onMeetingStatus", handleMeetingStatusChange);
}
function handleMeetingStatusChange(data) {
logMessage("[zoomSdk-page] onMeetingStatus -->", "info", {
data,
});
if (data?.meetingStatus === 3) {
window?.leaveZoomMtg("everyone_left");
}
}
function handleMediaCapturePermissionChange({ allow: boolean }) {
logMessage("[zoomSdk-page] onMediaCapturePermissionChange -->", "info", {
boolean,
});
if (boolean) {
startMediaCapture();
logMessage("[zoomSdk-page] Media capture permission changed to ALLOW -->", "info", {
boolean,
});
} else {
logMessage("[zoomSdk-page] Media capture permission changed to DENY -->", "info", {
boolean,
});
stopMediaCapture();
leaveMeetingAndHandleError();
}
}
function handleMediaCaptureStatusChange(data) {
logMessage("[zoomSdk-page] onMediaCaptureStatusChange -->", "info", {
data,
});
const { status, userId } = data;
ZoomMtg.mute({ userId: userId, mute: true });
}
function handleUserLeave(data) {
setupAccidentalLeaveListener(document, ZoomMtg);
}
function handleJoinError(error) {
logMessage("[zoomSdk-page] join error", "error", {
error,
});
}
async function logMessage(message, type, obj = {}) {
switch (type) {
case "info": {
await window?.loggerInfo(message, obj);
break;
}
case "warn": {
await window?.loggerWarn(message, obj);
break;
}
case "error": {
await window?.loggerError(message, obj);
break;
}
default: {
break;
}
}
}