PluginBench
Skill
Official
Review
Audit score 70

setup-zoom-websockets

anthropics/knowledge-work-plugins

How to install setup-zoom-websockets

npx skills add https://github.com/anthropics/knowledge-work-plugins --skill setup-zoom-websockets
Claude Code
Cursor
Windsurf
Cline
Full instructions (SKILL.md)

Source of truth, from anthropics/knowledge-work-plugins.


name: setup-zoom-websockets description: Reference skill for Zoom WebSockets. Use after routing to a low-latency event workflow when persistent connections, faster event delivery, or security constraints make WebSockets preferable to webhooks. triggers:

  • "zoom websockets"
  • "websocket event subscription"
  • "persistent zoom events"
  • "low latency zoom events"
  • "zoom websocket connection"

/setup-zoom-websockets

Background reference for persistent Zoom event streams. Prefer workflow routing first, then use this file when WebSockets are plausibly better than webhooks.

WebSockets vs Webhooks

AspectWebSocketsWebhooks
ConnectionPersistent, bidirectionalOne-time HTTP POST
LatencyLower (no HTTP overhead)Higher (new connection per event)
SecurityDirect connection, no exposed endpointRequires endpoint validation, IP whitelisting
ModelPull (you connect to Zoom)Push (Zoom connects to you)
StateStateful (maintains connection)Stateless (each event independent)
SetupMore complex (access token, connection)Simpler (just endpoint URL)

Choose WebSockets when:

  • Real-time, low-latency updates are critical
  • Security is paramount (banking, healthcare, finance)
  • You don't want to expose a public endpoint
  • You need bidirectional communication

Choose Webhooks when:

  • Simpler setup is preferred
  • Small number of event notifications
  • Existing HTTP infrastructure

Prerequisites

  • Server-to-Server OAuth app in Zoom Marketplace
  • Account ID, Client ID, and Client Secret
  • WebSocket subscription with events enabled

Need help with S2S OAuth? See the zoom-oauth skill for complete authentication flows.

Start troubleshooting fast: Use the 5-Minute Runbook before deep debugging.

Quick Start

1. Create Server-to-Server OAuth App

  1. Go to Zoom Marketplace
  2. Create a Server-to-Server OAuth app
  3. Copy Account ID, Client ID, Client Secret

2. Enable WebSocket Subscription

  1. In your app, go to FeatureEvent Subscriptions
  2. Add an Event Subscription
  3. Select WebSockets as the method type
  4. Select events to subscribe to (e.g., meeting.created, meeting.started)
  5. Save - an endpoint URL will be generated

3. Connect via WebSocket

const WebSocket = require('ws');
const axios = require('axios');

// Step 1: Get access token
async function getAccessToken() {
  const credentials = Buffer.from(`${CLIENT_ID}:${CLIENT_SECRET}`).toString('base64');
  
  const response = await axios.post(
    'https://zoom.us/oauth/token',
    new URLSearchParams({
      grant_type: 'account_credentials',
      account_id: ACCOUNT_ID
    }),
    {
      headers: {
        'Authorization': `Basic ${credentials}`,
        'Content-Type': 'application/x-www-form-urlencoded'
      }
    }
  );
  
  return response.data.access_token;
}

// Step 2: Connect to WebSocket
async function connectWebSocket() {
  const accessToken = await getAccessToken();
  
  // WebSocket URL from your subscription settings
  const wsUrl = `wss://ws.zoom.us/ws?subscriptionId=${SUBSCRIPTION_ID}&access_token=${accessToken}`;
  
  const ws = new WebSocket(wsUrl);
  
  ws.on('open', () => {
    console.log('WebSocket connection established');
  });
  
  ws.on('message', (data) => {
    const event = JSON.parse(data);
    console.log('Event received:', event.event);
    
    // Handle different event types
    switch (event.event) {
      case 'meeting.started':
        console.log(`Meeting started: ${event.payload.object.topic}`);
        break;
      case 'meeting.ended':
        console.log(`Meeting ended: ${event.payload.object.uuid}`);
        break;
      case 'meeting.participant_joined':
        console.log(`Participant joined: ${event.payload.object.participant.user_name}`);
        break;
    }
  });
  
  ws.on('close', (code, reason) => {
    console.log(`Connection closed: ${code} - ${reason}`);
    // Implement reconnection logic
  });
  
  ws.on('error', (error) => {
    console.error('WebSocket error:', error);
  });
  
  return ws;
}

connectWebSocket();

Event Format

Events received via WebSocket have the same format as webhook events:

{
  "event": "meeting.started",
  "event_ts": 1706123456789,
  "payload": {
    "account_id": "abcD3ojkdbjfg",
    "object": {
      "id": 1234567890,
      "uuid": "abcdefgh-1234-5678-abcd-1234567890ab",
      "host_id": "xyz789",
      "topic": "Team Standup",
      "type": 2,
      "start_time": "2024-01-25T10:00:00Z",
      "timezone": "America/Los_Angeles"
    }
  }
}

Common Events

EventDescription
meeting.createdMeeting scheduled
meeting.updatedMeeting settings changed
meeting.deletedMeeting deleted
meeting.startedMeeting begins
meeting.endedMeeting ends
meeting.participant_joinedParticipant joins meeting
meeting.participant_leftParticipant leaves meeting
recording.completedCloud recording ready
user.createdNew user added
user.updatedUser details changed

Connection Management

Keep-Alive

WebSocket connections require periodic heartbeats. Zoom will close idle connections.

// Send ping every 30 seconds
setInterval(() => {
  if (ws.readyState === WebSocket.OPEN) {
    ws.ping();
  }
}, 30000);

Reconnection

Implement automatic reconnection for reliability:

function connectWithReconnect() {
  const ws = connectWebSocket();
  
  ws.on('close', () => {
    console.log('Connection lost. Reconnecting in 5 seconds...');
    setTimeout(connectWithReconnect, 5000);
  });
  
  return ws;
}

Single Connection Limit

Important: Only ONE WebSocket connection can be open per subscription at a time. Opening a new connection will close the existing one.

Detailed References

Troubleshooting

Sample Repositories

Official / Community

TypeRepositoryDescription
Node.jsjust-zoomit/zoom-websocketsWebSocket sample with S2S OAuth

WebSockets vs RTMS

Don't confuse WebSockets with RTMS (Realtime Media Streams):

FeatureWebSocketsRTMS
PurposeEvent notificationsMedia streams
DataMeeting events, user eventsAudio, video, transcripts
Use caseReact to Zoom eventsAI/ML, live transcription
SkillThis skillrtms

For real-time audio/video/transcript data, use the rtms skill instead.

Resources

Environment Variables

Related skills

More from anthropics/knowledge-work-plugins and the wider catalog.

DA

data-visualization

Official
anthropics/knowledge-work-plugins

Pick the right chart and generate publication-quality Python visualizations with built-in design and accessibility best practices.

8.8k installsAudited
CO

code-review

Official
anthropics/knowledge-work-plugins

Review code changes for security, performance, and correctness. Trigger with a PR URL or diff, "review this before I merge", "is this code safe?", or when checking a change for N+1 queries, injection risks, missing edge cases, or error handling gaps.

6.3k installsAudited
DO

documentation

Official
anthropics/knowledge-work-plugins

Write and maintain technical documentation. Trigger with "write docs for", "document this", "create a README", "write a runbook", "onboarding guide", or when the user needs help with any form of technical writing — API docs, architecture docs, or operational runbooks.

6.2k installs
BU

build-dashboard

Official
anthropics/knowledge-work-plugins

Build an interactive HTML dashboard with charts, filters, and tables. Use when creating an executive overview with KPI cards, turning query results into a shareable self-contained report, building a team monitoring snapshot, or needing multiple charts with filters in one browser-openable file.

5.3k installs
TA

task-management

Official
anthropics/knowledge-work-plugins

Simple task management using a shared TASKS.md file. Reference this when the user asks about their tasks, wants to add/complete tasks, or needs help tracking commitments.

5.1k installsAudited
ME

memory-management

Official
anthropics/knowledge-work-plugins

Two-tier memory system that makes Claude a true workplace collaborator. Decodes shorthand, acronyms, nicknames, and internal language so Claude understands requests like a colleague would. CLAUDE.md for working memory, memory/ directory for the full knowledge base.

5.0k installsAudited