instrument-data-to-all…
Convert laboratory instrument output files (PDF, CSV, Excel, TXT) to Allotrope Simple Model (ASM) JSON format or flattened 2D…
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.
Claude Code
$ npx -y skills add anthropics/knowledge-work-plugins --skill websockets --agent claude-code
Codex
$ npx skills add anthropics/knowledge-work-plugins --skill websockets -a codex -y
Cursor
$ npx skills add anthropics/knowledge-work-plugins --skill websockets -a cursor -y
Gemini CLI
$ npx skills add anthropics/knowledge-work-plugins --skill websockets -a gemini-cli -y
GitHub Copilot
$ npx skills add anthropics/knowledge-work-plugins --skill websockets -a github-copilot -y
OpenCode
$ npx skills add anthropics/knowledge-work-plugins --skill websockets -a opencode -y
Windsurf
$ npx skills add anthropics/knowledge-work-plugins --skill websockets -a windsurf -y
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"
Background reference for persistent Zoom event streams. Prefer workflow routing first, then use this file when WebSockets are plausibly better than webhooks.
| Aspect | WebSockets | Webhooks | |--------|------------|----------| | **Connection** | Persistent, bidirectional | One-time HTTP POST | | **Latency** | Lower (no HTTP overhead) | Higher (new connection per event) | | **Security** | Direct connection, no exposed endpoint | Requires endpoint validation, IP whitelisting | | **Model** | Pull (you connect to Zoom) | Push (Zoom connects to you) | | **State** | Stateful (maintains connection) | Stateless (each event independent) | | **Setup** | More complex (access token, connection) | Simpler (just endpoint URL) |
**Choose WebSockets when:**
**Choose Webhooks when:**
> **Need help with S2S OAuth?** See the **[zoom-oauth](../oauth/SKILL.md)** skill for complete authentication flows.
> **Start troubleshooting fast:** Use the **[5-Minute Runbook](RUNBOOK.md)** before deep debugging.
1. Go to [Zoom Marketplace](https://marketplace.zoom.us/develop/create) 2. Create a **Server-to-Server OAuth** app 3. Copy Account ID, Client ID, Client Secret
1. In your app, go to **Feature** → **Event 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
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();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"
}
}
}| Event | Description | |-------|-------------| | `meeting.created` | Meeting scheduled | | `meeting.updated` | Meeting settings changed | | `meeting.deleted` | Meeting deleted | | `meeting.started` | Meeting begins | | `meeting.ended` | Meeting ends | | `meeting.participant_joined` | Participant joins meeting | | `meeting.participant_left` | Participant leaves meeting | | `recording.completed` | Cloud recording ready | | `user.created` | New user added | | `user.updated` | User details changed |
WebSocket connections require periodic heartbeats. Zoom will close idle connections.
// Send ping every 30 seconds
setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
}
}, 30000);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;
}**Important:** Only ONE WebSocket connection can be open per subscript
Plugins that turn Claude into a specialist for your role, team, and company. Built for Claude Cowork, also compatible with Claude Code.
Convert laboratory instrument output files (PDF, CSV, Excel, TXT) to Allotrope Simple Model (ASM) JSON format or flattened 2D…
Run nf-core bioinformatics pipelines (rnaseq, sarek, atacseq) on sequencing data. Use when analyzing RNA-seq, WGS/WES, or…
This skill should be used when scientists need help with research problem selection, project ideation, troubleshooting stuck…
Deep learning for single-cell analysis using scvi-tools. This skill should be used when users need (1) data integration and batch…
Performs quality control on single-cell RNA-seq data (.h5ad or .h5 files) using scverse best practices with MAD-based filtering…
Set up your bio-research environment and explore available tools. Use when first getting oriented with the plugin, checking which…
Turn repeatable outputs of a one-person company into compounding assets. Use when Codex needs to explain asset-compounding…
dontbesilent 商业工具箱的技能调度台,根据当前问题和反馈选择下一步,在对话中直接执行、澄清、组合或对照尝试 Skill。用户不知道从哪里开始、需要调整处理方法、第一次使用…
Help define company values and culture for a minimalist business. Use when someone is setting up their company culture, preparing…