### Install Dependencies and Start Server
Source: https://github.com/zoom/skills/blob/main/skills/zoom-apps-sdk/examples/quick-start.md
Installs project dependencies using npm and starts the development server. Ensure you have Node.js and npm installed.
```bash
# 1. Install dependencies
npm install
# 2. Start ngrok tunnel
ngrok http 3000
# 3. Copy the https URL (e.g., https://abc123.ngrok.io)
# 4. Update .env with ngrok URL
# ZOOM_APP_REDIRECT_URI=https://abc123.ngrok.io/auth
# 5. Start server
npm run dev
```
--------------------------------
### Quick Start Example
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/examples/react-hooks.md
A basic example demonstrating how to use the `useSession` and `useSessionUsers` hooks to join a session and display participants.
```APIDOC
## Quick Start
```tsx
import {
useSession,
useSessionUsers,
VideoPlayerComponent,
VideoPlayerContainerComponent
} from '@zoom/videosdk-react';
function VideoChat() {
const { isInSession, isLoading, isError } = useSession(
"session123",
"your_jwt_token",
"User Name"
);
const participants = useSessionUsers();
if (isLoading) return
);
}
```
```
--------------------------------
### Complete Customer Example with SDK Integration
Source: https://github.com/zoom/skills/blob/main/skills/cobrowse-sdk/get-started.md
A full HTML example demonstrating customer-side integration. This includes loading the SDK, initializing it with custom PII masking, handling PIN updates, and starting a session.
```html
Customer - Cobrowse Support
Need Help?
```
--------------------------------
### Complete Workflow Example for Breakout Rooms
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/windows/examples/breakout-rooms.md
A comprehensive example demonstrating the full lifecycle of breakout room management, from setup and creation to assignment and starting rooms, for various roles.
```cpp
void OnInMeeting() {
// Set up listener first
SetupBreakoutRoomListener();
// Wait for role callbacks...
}
```
```cpp
void OnCreatorRoleReceived(IBOCreator* creator, IBOData* data) {
// Step 1: Configure options
ConfigureBreakoutRooms(creator);
// Step 2: Create rooms
creator->CreateBO(L"Team Alpha");
creator->CreateBO(L"Team Beta");
// Step 3: Wait for onCreateBOResponse callback...
```
```cpp
void OnRoomsCreated(IBOCreator* creator, IBOData* data, IBOAdmin* admin) {
// Step 4: Assign users
PreassignUser(creator, data, L"John", L"Team Alpha");
PreassignUser(creator, data, L"Jane", L"Team Beta");
// Step 5: Start rooms
StartBreakoutRooms(admin);
}
```
```cpp
void OnAttendeeRoleReceived(IBOAttendee* attendee) {
// As a participant, join your assigned room
JoinMyBreakoutRoom(attendee);
}
```
--------------------------------
### Quick Start: Immersive Mode Setup and Drawing
Source: https://github.com/zoom/skills/blob/main/skills/zoom-apps-sdk/examples/layers-immersive.md
Initializes the SDK with Layers capabilities, starts immersive mode, draws a background image, and positions participants. Ensure all required capabilities are listed in the config.
```javascript
import zoomSdk from '@zoom/appssdk';
// 1. Config with Layers capabilities
await zoomSdk.config({
capabilities: [
'getRunningContext',
'runRenderingContext', 'closeRenderingContext',
'drawParticipant', 'clearParticipant',
'drawImage', 'clearImage',
'drawWebView', 'clearWebView',
'getMeetingParticipants', 'onParticipantChange',
'postMessage', 'onMessage',
'sendAppInvitationToAllParticipants',
'onRenderedAppOpened'
],
version: '0.16'
});
// 2. Start immersive mode (Team = person cutout, Presentation = rectangle)
await zoomSdk.runRenderingContext({
view: 'immersive',
defaultCutout: 'person' // Removes backgrounds via AI segmentation
});
// 3. Draw a background (imageData = JS ImageData object, NOT base64)
const canvas = document.createElement('canvas');
canvas.width = 1280;
canvas.height = 720;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#1a1a2e';
ctx.fillRect(0, 0, 1280, 720);
const imageData = ctx.getImageData(0, 0, 1280, 720);
await zoomSdk.drawImage({
imageData,
x: 0, y: 0,
zIndex: 0
});
// 4. Position participants
const { participants } = await zoomSdk.getMeetingParticipants();
await zoomSdk.drawParticipant({
participantUUID: participants[0].participantUUID,
x: 50, y: 100,
width: 500, height: 400,
zIndex: 1,
cutout: 'person' // Override default if needed
});
await zoomSdk.drawParticipant({
participantUUID: participants[1].participantUUID,
x: 730, y: 100,
width: 500, height: 400,
zIndex: 1,
cutout: 'person'
});
```
--------------------------------
### Node.js JWT Generator Service Setup
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/SKILL.md
Steps to clone the sample repository, install dependencies, configure environment variables, and start the JWT generation server.
```bash
git clone https://github.com/zoom/videosdk-auth-endpoint-sample.git
cd videosdk-auth-endpoint-sample
bun install
# or
npm install
# Rename .env.example to .env, edit the file contents to include your Zoom Video SDK key and secret, save the file contents, and close the file
mv .env.example .env
# Start the server
# server code https://raw.githubusercontent.com/zoom/videosdk-auth-endpoint-sample/refs/heads/master/src/index.js
bun run start
# or
npm run start
```
--------------------------------
### Setup and Use Audio Features
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/windows/concepts/sdk-architecture-pattern.md
Demonstrates how to initialize and use the audio controller. This includes getting the controller instance, setting the event listener, joining VoIP, and controlling mute states for self and others.
```cpp
void SetupAudioFeatures() {
// 1. Get the controller (singleton)
IMeetingAudioController* audioCtrl = meetingService->GetMeetingAudioController();
if (!audioCtrl) {
std::cerr << "Failed to get audio controller"
return;
}
// 2. Set event listener
audioCtrl->SetEvent(new AudioEventListener());
// 3. Use controller methods
// Join audio (connect to VoIP)
SDKError err = audioCtrl->JoinVoip();
if (err == SDKError::SDKERR_SUCCESS) {
std::cout << "[AUDIO] Joined VoIP successfully"
}
// Mute yourself (userId = 0 or your own user ID)
audioCtrl->MuteAudio(0, true);
std::cout << "[AUDIO] Muted self"
// Unmute yourself
audioCtrl->UnMuteAudio(0);
std::cout << "[AUDIO] Unmuted self"
// Mute all participants (host only, userId = 0 for all)
audioCtrl->MuteAudio(0, false); // false = don't allow self-unmute
std::cout << "[AUDIO] Muted all participants"
}
```
--------------------------------
### Install Zoom SDK and Development Dependencies
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/references/svelte.md
Install the core Zoom Video SDK, Biome for linting/formatting, and optional UI components like shadcn-svelte. Initialize Biome for project setup.
```bash
# Core dependencies
bun add @zoom/videosdk
# Development tools
bun add -D @biomejs/biome
# UI components (optional - shadcn-svelte)
bunx shadcn-svelte@latest init
bunx shadcn-svelte@latest add button card avatar badge dialog input scroll-area
# Initialize Biome for linting/formatting
bunx biome init
```
--------------------------------
### Set Up Token Server with npm
Source: https://github.com/zoom/skills/blob/main/skills/cobrowse-sdk/get-started.md
This bash script demonstrates setting up a token server using Node.js. It clones a sample repository, installs dependencies, creates an environment file with your SDK credentials, and starts the server.
```bash
# Clone the sample
git clone https://github.com/zoom/cobrowsesdk-auth-endpoint-sample.git
cd cobrowsesdk-auth-endpoint-sample
# Install dependencies
npm install
# Create .env file
cat > .env << EOF
ZOOM_SDK_KEY=your_sdk_key_here
ZOOM_SDK_SECRET=your_sdk_secret_here
PORT=4000
EOF
# Start the server
npm start
```
--------------------------------
### Clone and Run Zoom Auth Endpoint Sample
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/references/react.md
Clone the sample authentication endpoint, install dependencies, configure environment variables with your Zoom Video SDK credentials, and start the server.
```bash
git clone https://github.com/zoom/videosdk-auth-endpoint-sample.git
cd videosdk-auth-endpoint-sample
bun install
# or
npm install
# Rename .env.example to .env, edit the file contents to include your Zoom Video SDK key and secret, save the file contents, and close the file
mv .env.example .env
# Start the server
# server code https://raw.githubusercontent.com/zoom/videosdk-auth-endpoint-sample/refs/heads/master/src/index.js
bun run start
# call
# or
npm run start
```
--------------------------------
### Correct SDK Lifecycle Order
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/SKILL.md
Demonstrates the correct sequence for SDK operations: create client, initialize, join session, get media stream, and start media. Getting the media stream before joining will result in `undefined`.
```javascript
// ā CORRECT: Get stream after joining
const client = ZoomVideo.createClient();
await client.init('en-US', 'Global');
await client.join(...);
const stream = client.getMediaStream(); // Works!
```
--------------------------------
### Complete Zoom SDK Navigation Example
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/linux/concepts/singleton-hierarchy.md
This C++ snippet shows how to initialize the SDK, join a session, retrieve user information, subscribe to remote video, control local audio and video, send chat messages, and start cloud recording. Ensure the SDK is initialized before calling session-related methods.
```cpp
// Level 1: SDK Singleton
IZoomVideoSDK* sdk = CreateZoomVideoSDKObj();
sdk->initialize(init_params);
sdk->joinSession(session_context);
// Level 2A: Session Info
IZoomVideoSDKSession* session = sdk->getSessionInfo();
// Level 3: Users
IZoomVideoSDKUser* myself = session->getMyself();
IVideoSDKVector* remote = session->getRemoteUsers();
// Level 4: Subscribe to remote user's video
IZoomVideoSDKUser* remoteUser = remote->GetItem(0);
IZoomVideoSDKRawDataPipe* videoPipe = remoteUser->GetVideoPipe();
videoPipe->subscribe(ZoomVideoSDKResolution_720P, videoDelegate);
// Level 2B: Control my audio
IZoomVideoSDKAudioHelper* audio = sdk->getAudioHelper();
audio->startAudio();
audio->subscribe(); // For raw audio callbacks
// Level 2B: Control my video
IZoomVideoSDKVideoHelper* video = sdk->getVideoHelper();
video->startVideo();
// Level 2B: Send chat
IZoomVideoSDKChatHelper* chat = sdk->getChatHelper();
chat->sendChatToAll("Hello!");
// Level 2B: Start recording
IZoomVideoSDKRecordingHelper* rec = sdk->getRecordingHelper();
if (rec->canStartRecording() == ZoomVideoSDKErrors_Success) {
rec->startCloudRecording();
}
```
--------------------------------
### Quick Start: Initialize and Join Zoom Session (C++)
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/linux/SKILL.md
Initializes the Zoom Video SDK and joins a session. This example demonstrates setting up initialization parameters, adding a delegate, and configuring session context for a headless bot with virtual audio.
```cpp
#include "zoom_video_sdk_api.h"
#include "zoom_video_sdk_interface.h"
#include "zoom_video_sdk_delegate_interface.h"
USING_ZOOM_VIDEO_SDK_NAMESPACE
// 1. Create SDK
IZoomVideoSDK* sdk = CreateZoomVideoSDKObj();
// 2. Initialize
ZoomVideoSDKInitParams init_params;
init_params.domain = "https://zoom.us";
init_params.enableLog = true;
init_params.logFilePrefix = "bot";
init_params.videoRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;
init_params.shareRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;
init_params.audioRawDataMemoryMode = ZoomVideoSDKRawDataMemoryModeHeap;
sdk->initialize(init_params);
// 3. Add delegate
sdk->addListener(myDelegate);
// 4. Join session
ZoomVideoSDKSessionContext ctx;
ctx.sessionName = "my-session";
ctx.userName = "Linux Bot";
ctx.token = "jwt-token";
ctx.audioOption.connect = true;
ctx.audioOption.mute = false;
ctx.videoOption.localVideoOn = false;
// For headless: Virtual audio speaker
ctx.virtualAudioSpeaker = new VirtualSpeaker();
IZoomVideoSDKSession* session = sdk->joinSession(ctx);
```
--------------------------------
### Immersive Mode Quick Start
Source: https://github.com/zoom/skills/blob/main/skills/zoom-apps-sdk/examples/layers-immersive.md
A step-by-step guide to configuring the SDK for immersive mode and drawing initial elements.
```APIDOC
## Quick Start
This section provides a quick start guide to using the Layers API for immersive mode.
### 1. Configuration
Configure the Zoom SDK with the necessary capabilities for immersive mode.
```javascript
await zoomSdk.config({
capabilities: [
'getRunningContext',
'runRenderingContext', 'closeRenderingContext',
'drawParticipant', 'clearParticipant',
'drawImage', 'clearImage',
'drawWebView', 'clearWebView',
'getMeetingParticipants', 'onParticipantChange',
'postMessage', 'onMessage',
'sendAppInvitationToAllParticipants',
'onRenderedAppOpened'
],
version: '0.16'
});
```
### 2. Start Immersive Mode
Initiate immersive mode with a specified default cutout.
```javascript
await zoomSdk.runRenderingContext({
view: 'immersive',
defaultCutout: 'person' // Removes backgrounds via AI segmentation
});
```
### 3. Draw Background
Draw a background image onto the canvas.
```javascript
const canvas = document.createElement('canvas');
canvas.width = 1280;
canvas.height = 720;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#1a1a2e';
ctx.fillRect(0, 0, 1280, 720);
const imageData = ctx.getImageData(0, 0, 1280, 720);
await zoomSdk.drawImage({
imageData,
x: 0, y: 0,
zIndex: 0
});
```
### 4. Position Participants
Retrieve meeting participants and draw them onto the canvas.
```javascript
const { participants } = await zoomSdk.getMeetingParticipants();
await zoomSdk.drawParticipant({
participantUUID: participants[0].participantUUID,
x: 50, y: 100,
width: 500, height: 400,
zIndex: 1,
cutout: 'person' // Override default if needed
});
await zoomSdk.drawParticipant({
participantUUID: participants[1].participantUUID,
x: 730, y: 100,
width: 500, height: 400,
zIndex: 1,
cutout: 'person'
});
```
```
--------------------------------
### Expose Local Server with ngrok for Zoom Webhooks
Source: https://github.com/zoom/skills/blob/main/skills/rest-api/examples/webhook-server.md
This bash snippet guides you through installing ngrok, starting your Node.js server, and then exposing it to a public HTTPS URL using ngrok. This URL can be used in Zoom's webhook configuration for local development.
```bash
# Install ngrok
npm install -g ngrok
# Start your server
node server.js
# In another terminal, expose to public URL
ngrok http 3000
# Use the HTTPS URL in Zoom webhook configuration
# Example: https://abc123.ngrok.io/webhook
```
--------------------------------
### Start Live Transcription
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/references/features.md
Starts the live transcription service. Also provides methods to get the current status and supported languages.
```typescript
await transcription.startLiveTranscription();
// Get supported languages
const status = transcription.getLiveTranscriptionStatus();
const languages = status.transcriptionLanguage;
```
--------------------------------
### Initialize and Start Rivet Team Chat Client
Source: https://github.com/zoom/skills/blob/main/skills/rivet-sdk/examples/getting-started-pattern.md
Bootstrap a Team Chat client with OAuth installation support. Configure client credentials, webhook tokens, installer options, and the server port. This snippet starts the Rivet server and registers an event listener for chat messages.
```javascript
import { TeamChatClient } from "@zoom/rivet/teamchat";
(async () => {
const teamchatClient = new TeamChatClient({
clientId: process.env.RIVET_CLIENT_ID,
clientSecret: process.env.RIVET_CLIENT_SECRET,
webhooksSecretToken: process.env.RIVET_WEBHOOK_SECRET_TOKEN,
installerOptions: {
redirectUri: process.env.RIVET_REDIRECT_URI,
stateStore: process.env.RIVET_STATE_STORE_SECRET,
},
port: Number(process.env.RIVET_PORT || 8080),
});
teamchatClient.webEventConsumer.event("chat_message.sent", ({ payload }) => {
console.log("event", payload);
});
const server = await teamchatClient.start();
console.log("rivet server", server.address());
})();
```
--------------------------------
### Complete Zoom SDK Command Channel Example
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/examples/command-channel.md
A full example demonstrating initialization, joining a session, activating the command channel, listening for status and messages, and sending commands.
```javascript
import ZoomVideo from '@zoom/videosdk';
const client = ZoomVideo.createClient();
async function joinAndSetupCommandChannel(topic, jwt, userName) {
// 1. Initialize
await client.init('en-US', 'Global', { patchJsMedia: true });
// 2. Join session
await client.join(topic, jwt, userName);
// 3. Activate command channel (MUST be after join)
const cmdClient = client.getCommandClient();
// 4. Listen for connection status
client.on('command-channel-status', (status) => {
console.log('Command channel status:', status);
if (status === true) {
console.log('Command channel connected - ready to send');
}
});
// 5. Listen for incoming commands
client.on('command-channel-message', (payload) => {
try {
const data = JSON.parse(payload.text);
console.log('Command received:', data);
handleCommand(data);
} catch (e) {
console.log('Raw command received:', payload.text);
}
});
return cmdClient;
}
// Send a command (broadcast to all participants in session)
function sendCommand(cmdClient, type, data) {
const message = JSON.stringify({ type, data });
cmdClient.send(message);
}
// Send to a specific participant
function sendCommandToUser(cmdClient, userId, type, data) {
const message = JSON.stringify({ type, data });
cmdClient.send(message, userId);
}
// Handle incoming commands
function handleCommand(data) {
switch (data.type) {
case 'ping':
console.log('Received ping');
break;
case 'transfer':
console.log('Transfer info:', data);
break;
default:
console.log('Unknown command type:', data.type);
}
}
```
--------------------------------
### Start Annotation and Get Controller
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/references/screen-share.md
Initiate the annotation mode after starting or viewing a share. Obtain the annotation controller to manage drawing tools and actions.
```typescript
// After starting share or viewing share
await stream.startAnnotation();
// Get annotation controller
const controller = stream.getAnnotationController();
```
--------------------------------
### Minimal RTMS SDK Example
Source: https://github.com/zoom/skills/blob/main/skills/rtms/examples/sdk-quickstart.md
A minimal example demonstrating how to set up the RTMS SDK to receive transcript data. The SDK automatically starts a webhook server.
```javascript
import rtms from "@zoom/rtms";
const RTMS_EVENTS = ["meeting.rtms_started", "webinar.rtms_started", "session.rtms_started"];
// Handle webhook events - SDK starts webhook server automatically
rtms.onWebhookEvent(({ event, payload }) => {
if (!RTMS_EVENTS.includes(event)) return;
const client = new rtms.Client();
client.onTranscriptData((data, timestamp, metadata) => {
const text = data.toString('utf8');
console.log(`${metadata.userName}: ${text}`);
});
// SDK handles all WebSocket complexity
// Accepts both meeting_uuid and session_id transparently
client.join(payload);
});
```
--------------------------------
### Build Qt Framework Quickstart for Zoom Video SDK
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/linux/linux.md
Compile the Qt framework quickstart template for the Zoom Video SDK on Linux. Requires Qt6 development libraries and ALSA.
```bash
# Prerequisites
sudo apt install -y qt6-base-dev qt6-tools-dev libasound2-dev cmake
# Build
cd videosdk-linux-qt-quickstart/src
mkdir build && cd build
export Qt6_DIR=/usr/lib/x86_64-linux-gnu/cmake/Qt6
cmake .. && make -j$(nproc)
# Run
./run_qt_demo.sh
```
--------------------------------
### Webhook Payload Example for Meeting Started
Source: https://github.com/zoom/skills/blob/main/skills/rest-api/examples/meeting-lifecycle.md
Illustrates the structure of a JSON payload received when a meeting starts. Includes event details and meeting object information.
```json
{
"event": "meeting.started",
"event_ts": 1707486720000,
"payload": {
"account_id": "abc123",
"object": {
"id": "93123456789",
"uuid": "xyzAbC1234==",
"host_id": "def456",
"topic": "Q1 Planning Meeting",
"type": 2,
"start_time": "2025-03-15T14:00:00Z",
"duration": 60,
"timezone": "America/New_York"
}
}
}
```
--------------------------------
### Minimal Working Example
Source: https://github.com/zoom/skills/blob/main/skills/ui-toolkit/SKILL.md
A basic JavaScript example demonstrating how to initialize and join a Zoom video session using the UI Toolkit.
```APIDOC
## Minimal Working Example
```javascript
import uitoolkit from "@zoom/videosdk-zoom-ui-toolkit";
import "@zoom/videosdk-ui-toolkit/dist/videosdk-zoom-ui-toolkit.css";
const config = {
videoSDKJWT: "YOUR_JWT",
sessionName: "test-session",
userName: "User",
featuresOptions: {
video: { enable: true },
audio: { enable: true }
}
};
uitoolkit.joinSession(document.getElementById("container"), config);
uitoolkit.onSessionJoined(() => console.log("Joined"));
uitoolkit.onSessionClosed(() => uitoolkit.destroy());
```
```
--------------------------------
### Install and Configure PulseAudio for Headless Docker
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/linux/SKILL.md
Essential for raw audio capture in Docker/headless environments. Installs PulseAudio, creates a configuration file, and starts PulseAudio with virtual devices.
```bash
# Install PulseAudio
apt-get install -y pulseaudio pulseaudio-utils
# Create config file
mkdir -p ~/.config
cat > ~/.config/zoomus.conf << EOF
[General]
system.audio.type=default
EOF
# Start PulseAudio with virtual devices
pulseaudio --start --exit-idle-time=-1
pactl load-module module-null-sink sink_name=virtual_speaker
pactl load-module module-null-sink sink_name=virtual_mic
```
--------------------------------
### Qt Platform Options for Running Demo
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/linux/linux.md
Demonstrates how to run the Qt demo application in different environments, including headless, Wayland, and X11 with SSH forwarding.
```bash
# Desktop
./run_qt_demo.sh
# Headless/Server
QT_QPA_PLATFORM=offscreen ./run_qt_demo.sh
# Wayland
QT_QPA_PLATFORM=wayland ./run_qt_demo.sh
# X11 with SSH forwarding
ssh -X user@host
export DISPLAY=:10.0
./run_qt_demo.sh
```
--------------------------------
### Start Basic Screen Share
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/examples/screen-share.md
Initiates screen sharing by getting the media stream and starting the share with a specified canvas element for preview. Ensure the canvas element exists in your HTML.
```javascript
const stream = client.getMediaStream();
const shareCanvas = document.getElementById('share-canvas');
await stream.startShareScreen(shareCanvas);
```
--------------------------------
### Build GTK Framework Quickstart for Zoom Video SDK
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/linux/linux.md
Compile the GTK framework quickstart template for the Zoom Video SDK on Linux. Requires GTKmm, SDL2, and ALSA development libraries.
```bash
# Prerequisites
sudo apt install -y libgtkmm-3.0-dev libsdl2-dev libasound2-dev libcurl4-openssl-dev cmake
# Build
cd videosdk-linux-gtk-quickstart/src
mkdir build && cd build
cmake .. && make
# Run
cd ../bin && ./SkeletonDemo
```
--------------------------------
### Full Client View Initialization and Join Example
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/web/references/web.md
A comprehensive example demonstrating the initialization of the Zoom Meeting SDK, checking system requirements, preloading WASM, and joining a meeting. Includes success and error callbacks for both initialization and joining.
```javascript
import { ZoomMtg } from '@zoom/meetingsdk';
// Check system requirements
console.log(ZoomMtg.checkSystemRequirements());
// Preload WebAssembly for faster init
ZoomMtg.preLoadWasm();
ZoomMtg.prepareWebSDK();
// Initialize and join
ZoomMtg.init({
leaveUrl: '/meeting-ended',
disableCORP: !window.crossOriginIsolated, // Disable if no COOP/COEP
success: () => {
ZoomMtg.join({
meetingNumber: '123456789',
userName: 'User Name',
signature: signature, // From auth endpoint
userEmail: 'user@example.com',
passWord: 'meeting-password',
success: (res) => {
console.log('Joined meeting');
ZoomMtg.getAttendeeslist({});
ZoomMtg.getCurrentUser({
success: (res) => console.log('Current user:', res.result.currentUser)
});
},
error: (err) => console.error('Join error:', err)
});
},
error: (err) => console.error('Init error:', err)
});
```
--------------------------------
### Quick Start: Initialize and Join Meeting (Client View)
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/web/SKILL.md
This JavaScript snippet demonstrates the Client View integration. It covers checking system requirements, preloading WebAssembly, loading language files, initializing the SDK, and joining a meeting. Note the 'passWord' parameter requires a capital 'W'.
```javascript
import { ZoomMtg } from '@zoom/meetingsdk';
// Step 1: Check browser compatibility
console.log('System requirements:', ZoomMtg.checkSystemRequirements());
// Step 2: Preload WebAssembly for faster initialization
ZoomMtg.preLoadWasm();
ZoomMtg.prepareWebSDK();
// Step 3: Load language files (MUST complete before init)
ZoomMtg.i18n.load('en-US');
ZoomMtg.i18n.onLoad(() => {
// Step 4: Initialize SDK
ZoomMtg.init({
leaveUrl: 'https://yoursite.com/meeting-ended',
disableCORP: !window.crossOriginIsolated, // Auto-detect SharedArrayBuffer
patchJsMedia: true, // Auto-apply media dependency fixes
leaveOnPageUnload: true, // Clean up when page unloads
externalLinkPage: './external.html', // Page for external links
success: () => {
// Step 5: Join meeting (note: passWord with capital W!)
ZoomMtg.join({
signature: signature, // From your auth endpoint
meetingNumber: '1234567890',
userName: 'User Name',
passWord: 'meeting-password', // Capital W!
success: (res) => {
console.log('Joined meeting:', res);
// Post-join: Get meeting info
ZoomMtg.getAttendeeslist({});
ZoomMtg.getCurrentUser({
success: (res) => console.log('Current user:', res.result.currentUser)
});
},
error: (err) => {
console.error('Join error:', err);
}
});
},
error: (err) => {
console.error('Init error:', err);
}
});
});
```
--------------------------------
### Get Share Status
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/windows/concepts/singleton-hierarchy.md
Retrieves the current status of a user's share (e.g., started, stopped).
```cpp
getShareStatus()
```
--------------------------------
### Complete Resilient Bot Initialization and Joining
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/linux/meeting-sdk-bot.md
This example demonstrates the complete lifecycle of a resilient bot, including loading configuration, initializing the SDK, authenticating with JWT, fetching meeting details, and joining the meeting with retry logic. Ensure SDK keys, secrets, and meeting details are correctly obtained.
```cpp
int main() {
// 1. Load configuration
BotConfig config = loadConfig();
// 2. Initialize Meeting SDK
InitParam initParam;
initParam.strWebDomain = "https://zoom.us";
initParam.emLanguageID = LANGUAGE_English;
initParam.enableLogByDefault = true;
SDKError err = InitSDK(initParam);
if (err != SDKERR_SUCCESS) {
cerr << "InitSDK failed: " << err << endl;
return 1;
}
// 3. Authenticate SDK with JWT
AuthContext authCtx;
authCtx.jwt_token = generateJWT(SDK_KEY, SDK_SECRET);
IAuthService* authService = CreateAuthService();
authService->SDKAuth(authCtx);
// Wait for auth callback...
// 4. Fetch meeting info + OBF token from REST API
MeetingInfo meetingInfo = fetchMeetingInfoFromAPI(MEETING_ID);
string obfToken = fetchOBFTokenFromAPI(USER_ID);
if (meetingInfo.empty() || obfToken.empty()) {
cerr << "ABORT: Failed to get meeting info or OBF token" << endl;
return 1;
}
// 5. Join meeting with retry
MeetingBot bot(config);
bool joined = bot.joinMeetingWithRetry(
meetingInfo.number,
meetingInfo.password,
obfToken,
"Transcription Bot"
);
if (!joined) {
cerr << "ABORT: Failed to join meeting" << endl;
return 1;
}
// 6. SDK callbacks handle: StartRawRecording, subscribe, reconnection
// 7. Keep running until meeting ends
bot.runEventLoop();
// 8. Cleanup
bot.cleanup();
CleanUPSDK();
return 0;
}
```
--------------------------------
### Install Zoom Video SDK and UI Dependencies
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/references/react.md
Install the core Zoom Video SDK, development tools like Biome, and shadcn/ui components. Initialize Biome for linting and formatting.
```bash
# Core dependencies
bun add @zoom/videosdk@latest
# Development tools
bun add -D @biomejs/biome@latest
# UI components (shadcn/ui)
bunx shadcn@latest init
bunx shadcn@latest add button card avatar badge dialog input scroll-area
# Initialize Biome for linting/formatting
bunx biome init
```
--------------------------------
### Install and Use @zoom/rtms SDK
Source: https://github.com/zoom/skills/blob/main/skills/rtms/references/quickstart.md
Install the @zoom/rtms SDK and express. This code snippet shows how to listen for RTMS start events and handle incoming audio, transcript, chat, and screen share data using the rtms.Client.
```bash
npm install @zoom/rtms express
```
```javascript
import rtms from "@zoom/rtms";
const RTMS_EVENTS = ["meeting.rtms_started", "webinar.rtms_started", "session.rtms_started"];
rtms.onWebhookEvent(({ event, payload }) => {
if (!RTMS_EVENTS.includes(event)) return;
const client = new rtms.Client();
client.onAudioData((data, timestamp, metadata) => {
console.log(`Audio from ${metadata.userName}`);
});
client.onTranscriptData((data, timestamp, metadata) => {
console.log(`${metadata.userName}: ${data}`);
});
client.onChatData((data, timestamp, metadata) => {
console.log(`[Chat] ${metadata.userName}: ${data}`);
});
client.onScreenShareData((data, timestamp, metadata) => {
console.log(`Screen share from ${metadata.userName}`);
});
// SDK accepts both meeting_uuid and session_id transparently
client.join(payload);
});
```
--------------------------------
### Basic Zoom App Instance Setup and Communication
Source: https://github.com/zoom/skills/blob/main/skills/zoom-apps-sdk/examples/app-communication.md
This snippet demonstrates the fundamental setup for app instance communication. It includes configuring capabilities, connecting instances, and setting up listeners for connection and message events. Ensure both instances call connect() independently.
```javascript
import zoomSdk from '@zoom/appssdk';
await zoomSdk.config({
capabilities: ['connect', 'postMessage', 'onConnect', 'onMessage'],
version: '0.16'
});
// Both instances must call connect()
await zoomSdk.connect();
// Know when the other instance connects
zoomSdk.addEventListener('onConnect', (event) => {
console.log('Other instance connected');
});
// Send a message
await zoomSdk.postMessage({
payload: JSON.stringify({ type: 'greeting', data: 'Hello from this instance!' })
});
// Receive messages
zoomSdk.addEventListener('onMessage', (event) => {
const message = JSON.parse(event.payload);
console.log('Received:', message.type, message.data);
});
```
--------------------------------
### Example .env Configuration for Rivet SDK
Source: https://github.com/zoom/skills/blob/main/skills/rivet-sdk/references/environment-variables.md
This example demonstrates a typical .env file setup for Rivet integrations, including core and port variables. Ensure sensitive values like secrets are replaced with actual credentials and stored securely.
```env
RIVET_CLIENT_ID="..."
RIVET_CLIENT_SECRET="..."
RIVET_WEBHOOK_SECRET_TOKEN="..."
RIVET_ACCOUNT_ID="..."
RIVET_REDIRECT_URI="http://YOUR_DEV_HOST:4002"
RIVET_STATE_STORE_SECRET="replace-me"
RIVET_CHATBOT_PORT=4001
RIVET_TEAMCHAT_PORT=4002
```
--------------------------------
### Get Zoom Meeting Details via REST API
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/linux/meeting-sdk-bot.md
Uses curl to make a GET request to the Zoom API to retrieve meeting details, including ID, topic, start time, and password. Requires an Authorization header with a Bearer token.
```bash
# Get meeting details
curl "https://api.zoom.us/v2/meetings/{meetingId}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
--------------------------------
### Complete Meeting Dashboard Integration Example
Source: https://github.com/zoom/skills/blob/main/skills/general/use-cases/meeting-details-with-events.md
This is a full example of integrating Zoom meeting data. It uses the zoom-rest-api skill to get meeting details and webhooks for real-time event updates. Ensure you have set up your Zoom API credentials and webhook secret.
```javascript
/**
* Complete example: Meeting Dashboard Integration
*
* Skills used:
* 1. zoom-rest-api - Get meeting details
* 2. webhooks - Real-time event updates
*/
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// In-memory store (use Redis/database in production)
const meetings = new Map();
// ============================================
// AUTHENTICATION HELPER
// ============================================
async function getAccessToken() {
const credentials = Buffer.from(
`${process.env.ZOOM_CLIENT_ID}:${process.env.ZOOM_CLIENT_SECRET}`
).toString('base64');
const response = await axios.post(
`https://zoom.us/oauth/token?grant_type=account_credentials&account_id=${process.env.ZOOM_ACCOUNT_ID}`,
null,
{ headers: { 'Authorization': `Basic ${credentials}` } }
);
return response.data.access_token;
}
// ============================================
// STEP 1: REST API - Get Meeting Details
// ============================================
async function getMeetingDetails(meetingId) {
const token = await getAccessToken();
const response = await axios.get(
`https://api.zoom.us/v2/meetings/${meetingId}`,
{ headers: { 'Authorization': `Bearer ${token}` } }
);
return response.data;
}
// API endpoint to fetch and track a meeting
app.get('/api/meetings/:meetingId', async (req, res) => {
try {
const { meetingId } = req.params;
// Get meeting details from Zoom API (zoom-rest-api skill)
const details = await getMeetingDetails(meetingId);
// Store for tracking (webhook events will update this)
meetings.set(meetingId, {
...details,
participants: [],
events: [],
tracking_status: 'active'
});
res.json({
success: true,
meeting: {
id: details.id,
topic: details.topic,
start_time: details.start_time,
join_url: details.join_url,
host_email: details.host_email
},
message: 'Meeting tracked. Events will be received via webhook.'
});
} catch (error) {
res.status(error.response?.status || 500).json({
success: false,
error: error.message
});
}
});
// ============================================
// STEP 2: WEBHOOKS - Receive Meeting Events
// ============================================
function verifyWebhook(req) {
const signature = req.headers['x-zm-signature'];
const timestamp = req.headers['x-zm-request-timestamp'];
const payload = `v0:${timestamp}:${JSON.stringify(req.body)}`;
const expected = `v0=${crypto
.createHmac('sha256', process.env.ZOOM_WEBHOOK_SECRET)
.update(payload)
.digest('hex')}`;
return signature === expected;
}
app.post('/webhooks/zoom', async (req, res) => {
// URL validation challenge
if (req.body.event === 'endpoint.url_validation') {
const hash = crypto
.createHmac('sha256', process.env.ZOOM_WEBHOOK_SECRET)
.update(req.body.payload.plainToken)
.digest('hex');
return res.json({
plainToken: req.body.payload.plainToken,
encryptedToken: hash
});
}
// Verify signature
if (!verifyWebhook(req)) {
return res.status(401).send('Invalid signature');
}
const { event, payload } = req.body;
const meetingId = String(payload.object.id);
// Get or create meeting record
let meeting = meetings.get(meetingId);
if (!meeting) {
// Meeting wasn't pre-fetched, create minimal record
meeting = {
id: meetingId,
topic: payload.object.topic,
participants: [],
events: [],
tracking_status: 'webhook_only'
};
meetings.set(meetingId, meeting);
}
// Log event
meeting.events.push({
type: event,
timestamp: new Date().toISOString(),
data: payload
});
// Update meeting state based on event
switch (event) {
case 'meeting.started':
meeting.status = 'in_progress';
meeting.actual_start_time = payload.object.start_time;
console.log(`ā Meeting started: ${meeting.topic}`);
break;
case 'meeting.ended':
meeting.status = 'ended';
meeting.end_time = payload.object.end_time;
meeting.actual_duration = payload.object.duration;
console.log(`š Meeting ended: ${meeting.topic} (${meeting.actual_duration} min)`);
break;
case 'meeting.participant_joined':
meeting.participants.push({
...payload.object.participant,
status: 'in_meeting'
});
console.log(`š ${payload.object.participant.user_name} joined`);
break;
case 'meeting.participant_left':
const p = meeting.participants.find(
p => p.user_id === payload.object.participant.user_id
);
if (p) {
p.status = 'left';
p.leave_time = payload.object.participant.leave_time;
}
```
--------------------------------
### Initialize and Authenticate SDK
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/windows/examples/authentication-pattern.md
This C++ code demonstrates the basic flow of initializing the SDK, authenticating with a JWT token, and waiting for the authentication callback. Ensure proper cleanup of resources.
```cpp
std::cerr << "ERROR: Authentication timeout after " << timeoutSeconds << " seconds" << std::endl;
return false;
}
// Small sleep to avoid CPU spinning
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
return g_authenticated;
}
// Main function
int main() {
// Your JWT token here
std::wstring jwt_token = L"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...";
// Step 1: Initialize SDK
if (!InitializeSDK()) {
return 1;
}
// Step 2: Authenticate
if (!AuthenticateSDK(jwt_token)) {
return 1;
}
// Step 3: Wait for callback
if (!WaitForAuthentication()) {
return 1;
}
std::cout << "\nā Authentication complete! Ready to join meeting." << std::endl;
// Now you can join meetings...
// Cleanup
if (g_authService) {
DestroyAuthService(g_authService);
}
CleanUPSDK();
return 0;
}
```
--------------------------------
### Add Flutter Zoom Video SDK Dependency
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/flutter/examples/setup-guide.md
Add the flutter_zoom_videosdk package to your pubspec.yaml file and run `flutter pub get` to install it.
```yaml
dependencies:
flutter_zoom_videosdk: ^
```
```bash
flutter pub get
```
--------------------------------
### Extracting and Setting Up Zoom SDK
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/linux/examples/session-join-pattern.md
Steps to extract the Zoom SDK archive, copy Qt5 libraries, and create necessary symbolic links before building.
```bash
# 1. Extract SDK
tar -xf zoom-video-sdk-linux_x86_64.tar.xz
cd zoom-video-sdk-linux_x86_64
# 2. Copy Qt5 libraries and create symlinks
cp -r samples/qt_libs/Qt/lib/* lib/
cd lib
for lib in libQt5*.so.5; do
ln -sf $lib ${lib%.5}
done
cd ..
```
--------------------------------
### Setup Whiteboard Client
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/references/advanced.md
Initialize the whiteboard client to enable collaborative drawing and annotation features. This client is required before starting or stopping the whiteboard.
```typescript
const whiteboard = client.getWhiteboardClient();
```
--------------------------------
### Get Media Stream from Zoom Video SDK
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/references/forum-top-questions.md
Retrieve the media stream object after successfully joining a session. This is required to start video or audio.
```javascript
stream = client.getMediaStream()
```
--------------------------------
### SDK Initialization and Cleanup
Source: https://github.com/zoom/skills/blob/main/skills/meeting-sdk/windows/examples/authentication-pattern.md
Demonstrates the essential pattern for initializing the SDK, performing authentication, and ensuring proper cleanup of resources regardless of success or failure. Always call Cleanup() to release resources.
```cpp
void Cleanup() {
if (g_authService) {
DestroyAuthService(g_authService);
g_authService = nullptr;
}
CleanUPSDK();
}
int main() {
if (!InitializeSDK()) {
return 1;
}
if (!AuthenticateSDK(jwt_token)) {
Cleanup(); // Always cleanup on failure
return 1;
}
if (!WaitForAuthentication()) {
Cleanup();
return 1;
}
// ... use SDK ...
Cleanup(); // Cleanup on success too
return 0;
}
```
--------------------------------
### Ask Claude about Zoom Development
Source: https://github.com/zoom/skills/blob/main/README.md
Once skills are installed, you can ask Claude questions about Zoom development. Examples include creating meetings, building bots, or understanding SDK differences.
```text
How do I create a meeting using the Zoom API?
```
```text
How do I build a meeting bot that joins and records?
```
```text
What's the difference between Meeting SDK and Video SDK?
```
--------------------------------
### Installation
Source: https://github.com/zoom/skills/blob/main/skills/video-sdk/web/examples/react-hooks.md
Install the Zoom Video SDK and the React SDK.
```APIDOC
## Installation
```bash
npm install @zoom/videosdk
npm install https://github.com/zoom/videosdk-react/releases/download/v0.0.1/zoom-videosdk-react-0.0.1.tgz
```
**Prerequisites:**
- React 18+
- Zoom Video SDK account and credentials
```