An access token is required to authenticate with the Zujo SDK and make any API calls. You can generate one with the API key
and secret
mentioned in your developer portal at ZujoNow console.
const jwt = require("jsonwebtoken");const options = { expiresIn: "10m", algorithm: "HS256" };const payload = {apikey: apikey,permissions: ["allow_join", "allow_mod"], // also accepts "ask_join"};const token = jwt.sign(payload, secret, options);
Available permissions are:
allow_join
: The participant will be permitted entry without request.ask_join
: The participant will not be permitted entry without request.allow_mod
: Allow participant to enable/disable other participant's mic/webcam.This generated token must be sent in the Authorization
header for all API calls.
And it should also be used with the ZujoSDK.config(token)
method.
Get a meeting id for new meeting or validate an existing meeting id to join a meeting.
const options = {method: "POST",headers: {Authorization: "your jwt token goes here",},};fetch("https://call-api.zujonow.com/api/meetings", options).then((response) => response.json()).then((result) => console.log(result)) // result will contain meetingId.catch((error) => console.log("error", error));
OR
const options = {method: "POST",headers: {Authorization: "your jwt token goes here",},};// returns status code 400 if ID is invalidfetch(`https://call-api.zujonow.com/api/meetings/${meetingId}`, options).then((response) => response.text()).then((result) => console.log(result)).catch((error) => console.log("error", error));
To initialize meeting you need to provide the following parameters:
meetingId: string
from the previous step to specify which meeting to join in.name: string
which will be displayed as username of participant in the meeting.micEnabled: boolean
option to indicate if mic should be on while joining.webcamEnabled: boolean
option to indicate if webcam should be on while joining.maxResolution: "sd" | "hd"
defines the maximum available resolution for webcam video.const meeting = ZujoSDK.initMeeting({meetingId, // requiredname, // requiredmicEnabled, // optional, default: truewebcamEnabled, // optional, default: truemaxResolution, // optional, default: "hd"});
The meeting
object consists of:
Properties:
id: string
activeSpeakerId: string
activePresenterId: string
mainParticipantId: string
localParticipant: Participant
participants: Map<string, Participant>
messages: Array<{senderId: string, text: string, timestamp: number}>
Events:
participant-joined
, participant-left
speaker-changed
, presenter-changed
main-participant-changed
entry-requested
, entry-responded
recording-started
, recording-stopped
stream-enabled
, stream-disabled
chat-message
Methods:
join()
, leave()
muteMic()
, unmuteMic()
disableWebcam()
, enableWebcam()
disableScreenShare()
, enableScreenShare()
on(eventType: string)
, off(eventType: string)
respondEntry(participantId: string, decision: "allowed" | "denied")
startRecording(webhookUrl: string)
, stopRecording()
sendChatMessage(text: string)
You can get the local streams and participant meta from meeting.localParticipant
. And a Map
of joined participants is always available via meeting.participants
.
const localParticipant = meeting.localParticipant;const participants = meeting.participants;
Each participant
object consists of:
Properties:
id: string
displayName: string
streams: Map<string, Stream>
Events:
stream-enabled
stream-disabled
Methods:
setQuality(quality: "low" | "med" | "high")
enableMic()
, disableMic()
enableWebcam()
, disableWebcam()
on(eventType: string)
, off(eventType: string)
When participant asks for entry in a meeting that you are connected to, you will be notified via entry-requested
and when you or any other participant's entry is responded, entry-responded
will be fired.
meeting.on("entry-requested", (participantId, name) => {setEntryRequests([...entryRequestsRef.current, { id: participantId, name }]);// you can open a dialog to respond with// decision "allowed" or "denied" with the following methodmeeting.respondEntry(participantId, decision);});meeting.on("entry-responded", (participantId, decision) => {// decision parameter will be: "allowed" or "denied"setEntryRequests(entryRequestsRef.current.filter((r) => r.id !== participantId));});
When participant joins or leaves a meeting that you are connected to, you will be notified via participant-joined
and participant-left
events respectively.
meeting.on("participant-joined", (participant) => {setParticipants(new Map(meeting.participants));});meeting.on("participant-left", (participant) => {setParticipants(new Map(meeting.participants));});
When a participant from meeting enables or diables a audio/video stream, you will be notified via stream-enabled
and stream-disabled
events from the participant object.
participant.on("stream-enabled", (stream) => {if (stream.kind === "video") {// play video track on a <video /> element} else if (stream.kind === "audio") {// play audio track on a <audio /> element} else if (stream.kind === "share") {// play screen sharing video track on a <video /> element}});participant.on("stream-disabled", (stream) => {if (stream.kind === "video") {// remove video track or the <video /> element} else if (stream.kind === "audio") {// remove audio track or the <audio /> element} else if (stream.kind === "share") {// remove screen sharing video track or the <video /> element}});
Each stream
object consists of:
Properties:
id: string
kind: string
codec: string
track: MediaStreamTrack
Methods:
pause()
resume()
Chrome's autoplay policy does not allow audio autoplay unless user has interacted with the domain (click, tap, etc.) or the user's Media engagement Index threshold has been crossed. Thus, as a workaround before starting the meeting, user can either create a meeting join page or create a join meeting confirmation dialog by which we can perform a user click interaction to enable audio autoplay in chrome's newer versions.
When a participant who is currently presenting or speaking is changed in the meeting, you will be notified via main-participant-changed
event.
meeting.on("main-participant-changed", (participant) => {// show participant video stream on main screen});
After we set local participant, main-screen participant, other participants, participant event handlers and stream event handlers from the meeting, next step is to join the meeting by calling meeting.join()
. This will trigger participant-joined
event for all other participants.
meeting.join();
Toggle own mic with the unmuteMic()
and muteMic()
methods. Toggling mic will trigger stream-enabled
and stream-disabled
events for all other participants when enabling and disabling mic.
// unmute/mute your own micmeeting.unmuteMic();meeting.muteMic();// unmute/mute other participant's micparticipant.unmuteMic();participant.muteMic();
Toggle own webcam with the enableWebcam()
and disableWebcam()
methods. Toggling webcam will trigger stream-enabled
and stream-disabled
events for all other participants when enabling and disabling webcam.
// disable/enable your own webcammeeting.enableWebcam();meeting.disableWebcam();// disable/enable other participant's webcamparticipant.enableWebcam();participant.disableWebcam();
Share your screen with the enableScreenShare()
method and stop sharing with disableScreenShare()
. Toggling screen-share will trigger stream-enabled
and stream-disabled
events for all other participants when enabling and disabling screen-share.
meeting.enableScreenShare();meeting.disableScreenShare();
Record the meeting session with startRecording(webhookUrl)
method and stop recording with stopRecording()
. Toggling recording will trigger recording-started
and recording-stopped
events for all participants when starting and stopping recording respectively.
// The webhook will be called with the fileUrl as a POST request when the recording is processed.meeting.startRecording("https://your-app-server.com/api/recordings");meeting.stopRecording();// ...meeting.on("recording-started", () => {setRecordStatus("active");// 🔴 notify all users of recording start});meeting.on("recording-stopped", () => {setRecordStatus("inactive");// ⚫ notify all users of recording end});
Send messages with the sendChatMessage(text)
method and all other participants will be notified via chat-message
event.
meeting.sendChatMessage("Hello world!");// ...meeting.on("chat-message", (data) => {setChatMessages([...meeting.messages]);const { senderId, text, timestamp } = data;// 📢 notify user or show in the chat window});
The speaker-changed
event will be fired whenever the loudest speaking participant changes.
meeting.on("speaker-changed", (participant) => {// indicate participant as speaking});
The presenter-changed
event will be fired whenever someone enables screen sharing.
meeting.on("presenter-changed", (participant) => {// indicate participant as presenting screen});
Update the participant video quality based on use case to "low" | "med" | "high"
.
participant.setQuality("low");
You can disconnect from the meeting with meeting.leave()
method. This will trigger participant-left
event for all other participants.
meeting.leave();
Real time communication APIs for web and apps.
ZujoNow
Typically replies within 15 mins
Copyright © 2021 ZUJONOW