Title: Web SDK Production Credentials – Works Locally but Fails on Server
Description: We’re facing an issue where our production SDK Key/Secret works fine in our local environment, but when used in our server, we get a “Join Meeting Failed” error. Despite updating the Domain Allow List in the App Credentials, the error persists.
Browser Console Error:
{
“type”: “JOIN_MEETING_FAILED”,
“reason”: “Fail to join the meeting.”,
“errorCode”: 200
}
Which Web Meeting SDK version?
3.13.2
Meeting SDK Code Snippets:
async function startMeeting(payload: { studentId: string; activityId: string }) {
const { studentId, activityId } = payload;
const teachersQueueData = await getActiveTeacherQueue();
const existingTeacher = await TeacherService.getTeacherById(teachersQueueData[0]);
const meetingProps: CreateMeeting = {
agenda: `Ask for help - Meeting with ${existingTeacher?.firstName + ' ' + existingTeacher?.lastName}`,
default_password: false,
duration: 60,
password: '123456',
pre_schedule: false,
type: 1,
};
try {
const meeting = await createZoomMeeting(meetingProps);
const meetingPayload = {
meetingResponse: JSON.stringify(meeting),
studentId,
teacherId: existingTeacher.id,
activityId,
zak: meeting.zak,
};
const createdMeeting = await MeetingService.create(meetingPayload);
const msdkSignature = await getMsdkSignature({ meetingNumber: meeting.id, role: '1' });
const signatureAddedMeetingData = {
createdMeetingId: createdMeeting?.id,
...JSON.parse(createdMeeting.meetingResponse),
signature: msdkSignature.signature,
};
return {
data: signatureAddedMeetingData,
message: successResponseMessages.MEETING_CREATED_SUCCESSFULLY,
};
} catch (error) {
throw new DbTransactionError('AskForHelp', {}, errorResponseMessages.MEETING_CREATION_UNSUCCESSFUL);
}
}
const getMsdkSignature = asyncHandler(async (authCredentials) => {
const iat = Math.round(new Date().getTime() / 1000) - 30;
const exp = iat + 60 * 60 * 2;
const ouathHeader = { alg: 'HS256', typ: 'JWT' };
const ouathPayload = {
sdkKey: process.env.ZOOM_CLIENT_ID,
sdkSecret: process.env.ZOOM_CLIENT_SECRET,
mn: authCredentials.meetingNumber,
role: authCredentials.role,
iat: iat,
exp: exp,
tokenExp: iat + 60 * 60 * 2,
};
const sHeader = JSON.stringify(ouathHeader);
const sPayload = JSON.stringify(ouathPayload);
const signature = KJUR.jws.JWS.sign('HS256', sHeader, sPayload, process.env.ZOOM_CLIENT_SECRET);
process.env.ZOOM_JWT_TOKEN = signature;
return { signature: signature };
});
const createZoomMeeting = async (createParams: CreateMeeting) => {
const access_token = await getAccessToken();
try {
const response = await axios({
method: 'POST',
url: 'https://api.zoom.us/v2/users/me/meetings',
headers: {
Authorization: 'Bearer ' + `${access_token}`,
'Content-Type': 'application/json',
},
data: createParams,
});
const zakResponse = await axios({
method: 'GET',
url: `https://api.zoom.us/v2/users/me/token?type=zak`,
headers: {
Authorization: 'Bearer ' + `${access_token}`,
'Content-Type': 'application/json',
},
});
const res = { ...response.data, zak: zakResponse.data.token };
return res;
} catch (error) {
throw error;
}
};
const getAccessToken = async () => {
try {
const base_64 = btoa(process.env.OAUTH_CLIENT_ID + ':' + process.env.OAUTH_CLIENT_SECRET);
const response = await axios({
method: 'POST',
url: `https://zoom.us/oauth/token?grant_type=account_credentials&account_id=${process.env.OAUTH_ACCOUNT_ID}`,
headers: {
Authorization: 'Basic ' + `${base_64} `,
},
});
return response.data.access_token;
} catch (err) {
throw err;
}
};
To Reproduce:
Use production SDK Key/Secret in local environment → Works fine.
Use the same credentials in the server → Fails with error code 200.
Screenshots: