关于 zoom-apps-sdk
供开发者构建运行在 Zoom 客户端内的 Web 应用的 JavaScript SDK。它提供会议上下文、应用间通信、客户端 OAuth、共享状态及沉浸式视频布局等接口。
主要功能
- 01读取会议、用户和参与者上下文
- 02客户端内 OAuth 授权
- 03会议操作与应用间消息传递
- 04参与者间共享应用状态
- 05通过 Layers API 自定义视频布局
- 06监听会议与参与者事件
适用场景
- 01构建 Zoom 会议或 Webinar 内应用
- 02在 Zoom 客户端中获取会议和用户信息
- 03为会议参与者创建共享状态体验
- 04制作自定义沉浸式视频布局或摄像头叠加层
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ anthropics/ knowledge-work-plugins --skill zoom-apps-sdk安装后在 Claude Code 中输入/zoom-apps-sdk确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
RUNBOOK.mdconcepts/architecture.mdmeeting-sdk-vs-zoom-apps.mdrunning-contexts.mdsecurity.mdexamples/app-communication.mdbreakout-rooms.mdcollaborate-mode.mdguest-mode.mdin-client-oauth.mdlayers-camera.mdlayers-immersive.mdquick-start.mdreferences/apis.mdenvironment-variables.mdevents.mdlayers-api.mdoauth.mdzmail-sdk.mdtroubleshooting/common-issues.mddebugging.mdforum-top-questions.mdmigration.md详细介绍
Zoom Apps SDK
面向在 Zoom 客户端内运行的 Web 应用的背景参考。请先使用 choose-zoom-approach,再转到此处了解 Layers API、Collaborate Mode、客户端内 OAuth 以及运行时约束。
Zoom Apps SDK
构建在 Zoom 客户端内运行的 Web 应用,支持会议、网络研讨会、主客户端和 Zoom Phone。
官方文档:https://developers.zoom.us/docs/zoom-apps/ SDK 参考:https://appssdk.zoom.us/ NPM 包:https://www.npmjs.com/package/@zoom/appssdk
快速链接
初次使用 Zoom Apps?请按以下路径操作:
- 架构:前端/后端模式、嵌入式浏览器、深度链接
- 快速开始:完整可运行的 Express + SDK 应用
- 运行上下文:应用运行的位置(inMeeting、inMainClient 等)
- Zoom Apps 与 Meeting SDK 对比:避免混淆应用类型
- 客户端内 OAuth:借助 PKCE 实现无缝授权
- API 参考:100 多个 SDK 方法
- 集成索引:参见本文件下方的相应章节
- 5 分钟运行手册:在深入调试前进行预检
参考资料:
- API 参考:按类别列出的全部 SDK 方法
- 事件参考:全部 SDK 事件监听器
- Layers API:沉浸式和摄像头模式渲染
- OAuth 参考:Zoom Apps 的 OAuth 流程
- Zoom Mail:邮件插件集成
遇到问题?
构建沉浸式体验?
- Layers 沉浸式模式:自定义视频布局
- 摄像头模式:虚拟摄像头叠加层
需要 OAuth 帮助? 请参阅 zoom-oauth Skill 了解认证流程。
SDK 概览
Zoom Apps SDK(@zoom/appssdk)为在 Zoom 嵌入式浏览器中运行的 Web 应用提供 JavaScript API:
- 上下文 API:获取会议、用户和参与者信息
- 会议操作:共享应用、邀请参与者、打开 URL
- 授权:基于 PKCE 的客户端内 OAuth(无需浏览器跳转)
- Layers API:沉浸式视频布局和摄像头模式叠加层
- Collaborate Mode:在参与者之间共享应用状态
- 应用通信:应用实例之间的消息传递(主客户端 <-> 会议)
- 媒体控制:虚拟背景、摄像头列表、录制控制
- UI 控件:展开应用、通知、弹出窗口
- 事件:响应会议状态、参与者、共享等变化
前提条件
- 在 Marketplace 中将应用配置为 "Zoom App" 类型
- 具有 Zoom Apps 权限范围的 OAuth 凭据(Client ID + Secret)
- Web 应用(推荐 Node.js + Express)
- 在 Marketplace 域名白名单中添加你的域名
- 本地开发需要 ngrok 或 HTTPS 隧道
- Node.js 18+(用于后端服务)
快速开始
方案 A:NPM(推荐用于框架)
npm install @zoom/appssdk
import zoomSdk from '@zoom/appssdk';
async function init() {
try {
const configResponse = await zoomSdk.config({
capabilities: [
'shareApp',
'getMeetingContext',
'getUserContext',
'openUrl'
],
version: '0.16'
});
console.log('Running context:', configResponse.runningContext);
// 'inMeeting' | 'inMainClient' | 'inWebinar' | 'inImmersive' | ...
const context = await zoomSdk.getMeetingContext();
console.log('Meeting ID:', context.meetingID);
} catch (error) {
console.error('Not running inside Zoom:', error.message);
showDemoMode();
}
}
方案 B:CDN(原生 JS)
<script src="https://appssdk.zoom.us/sdk.js"></script>
<script>
// CRITICAL: Do NOT declare "let zoomSdk" - the SDK defines window.zoomSdk globally
// Using "let zoomSdk = ..." causes: SyntaxError: redeclaration of non-configurable global property
let sdk = window.zoomSdk; // Use a different variable name
async function init() {
try {
const configResponse = await sdk.config({
capabilities: ['shareApp', 'getMeetingContext', 'getUserContext'],
version: '0.16'
});
console.log('Running context:', configResponse.runningContext);
} catch (error) {
console.error('Not running inside Zoom:', error.message);
showDemoMode();
}
}
function showDemoMode() {
document.body.innerHTML = '<h1>Preview Mode</h1><p>Open this app inside Zoom to use.</p>';
}
document.addEventListener('DOMContentLoaded', () => {
init();
setTimeout(() => { if (!sdk) showDemoMode(); }, 3000);
});
</script>
重要:全局变量冲突
CDN 脚本会全局定义 window.zoomSdk。请勿重复声明:
// WRONG - causes SyntaxError in Zoom's embedded browser
let zoomSdk = null;
zoomSdk = window.zoomSdk;
// CORRECT - use different variable name
let sdk = window.zoomSdk;
// ALSO CORRECT - NPM import (no conflict)
import zoomSdk from '@zoom/appssdk';
此规则仅适用于 CDN 方式。NPM 导入会创建模块作用域变量,不会产生冲突。
浏览器预览 / 演示模式
该 SDK 仅在 Zoom 客户端内运行。在普通浏览器中访问时:
window.zoomSdk存在,但sdk.config()会抛出错误- 始终使用 try/catch 并提供回退 UI
- 添加 3 秒超时,以防 SDK 挂起
URL 白名单(必需)
如果域名未加入白名单,您的应用将无法在 Zoom 中加载。
- 前往 Zoom Marketplace
- 打开您的应用 -> Feature 标签页
- 在 Zoom App 下找到 Add Allow List
- 添加您的域名(例如,生产环境使用
yourdomain.com,开发环境使用xxxxx.ngrok.io)
如果未配置此项,Zoom 客户端会显示空白面板,且不会有任何错误提示。
OAuth 权限范围(必需)
各项功能需要在 Marketplace 中启用对应的 OAuth 权限范围:
| 功能 | 所需权限范围 |
|---|---|
getMeetingContext | zoomapp:inmeeting |
getUserContext | zoomapp:inmeeting |
shareApp | zoomapp:inmeeting |
openUrl | zoomapp:inmeeting |
sendAppInvitation | zoomapp:inmeeting |
runRenderingContext | zoomapp:inmeeting |
authorize | zoomapp:inmeeting |
getMeetingParticipants | zoomapp:inmeeting |
添加权限范围: Marketplace -> 您的应用 -> Scopes 标签页 -> 添加所需权限范围。
缺少权限范围时,功能会静默失败或抛出错误。如果您新增了权限范围,用户必须重新授权。
运行上下文
您的应用会在 Zoom 内的不同界面中运行。configResponse.runningContext 会告诉您当前所在的位置:
| 上下文 | 界面 | 说明 |
|---|---|---|
inMeeting | 会议侧边栏 | 最常见。可使用完整的会议 API |
inMainClient | 主客户端面板 | 主页标签。没有会议上下文 API |
inWebinar | 网络研讨会侧边栏 | 主持人/小组成员。可使用会议及网络研讨会 API |
inImmersive | Layers API | 全屏自定义渲染 |
inCamera | 摄像头模式 | 虚拟摄像头叠加层 |
inCollaborate | 协作模式 | 共享状态上下文 |
inPhone | Zoom Phone | 电话通话应用 |
inChat | Team Chat | 聊天侧边栏 |
有关特定上下文的行为和 API,请参阅 运行上下文。
SDK 初始化模式
每个 Zoom App 都从 config() 开始:
import zoomSdk from '@zoom/appssdk';
const configResponse = await zoomSdk.config({
capabilities: [
// List ALL APIs you will use
'getMeetingContext',
'getUserContext',
'shareApp',
'openUrl',
'authorize',
'onAuthorized'
],
version: '0.16'
});
// configResponse contains:
// {
// runningContext: 'inMeeting',
// clientVersion: '5.x.x',
// unsupportedApis: [] // APIs not supported in this client version
// }
规则:
- 必须先调用
config(),才能调用任何其他 SDK 方法 - 只有在
config()中列出的功能才可用 - 功能必须与 Marketplace 中的 OAuth 权限范围相匹配
- 检查
unsupportedApis,以实现优雅降级
客户端内 OAuth(摘要)
无需浏览器跳转,是最佳的授权体验:
// 1. Get code challenge from your backend
const { codeChallenge, state } = await fetch('/api/auth/challenge').then(r => r.json());
// 2. Trigger in-client authorization
await zoomSdk.authorize({ codeChallenge, state });
// 3. Listen for authorization result
zoomSdk.addEventListener('onAuthorized', async (event) => {
const { code, state } = event;
// 4. Send code to backend for token exchange
await fetch('/api/auth/token', {
method: 'POST',
body: JSON.stringify({ code, state })
});
});
完整实现请参阅 客户端内 OAuth 指南。
Layers API(摘要)
用于构建沉浸式视频布局和摄像头叠加层:
// Start immersive mode - replaces gallery view
await zoomSdk.runRenderingContext({ view: 'immersive' });
// Position participant video feeds
await zoomSdk.drawParticipant({
participantUUID: 'user-uuid',
x: 0, y: 0, width: 640, height: 480, zIndex: 1
});
// Add overlay images
await zoomSdk.drawImage({
imageData: canvas.toDataURL(),
x: 0, y: 0, width: 1280, height: 720, zIndex: 0
});
// Exit immersive mode
await zoomSdk.closeRenderingContext();
请参阅 Layers 沉浸模式 和 摄像头模式。
环境变量
| 变量 | 说明 | 获取位置 |
|---|---|---|
ZOOM_APP_CLIENT_ID | 应用客户端 ID | Marketplace -> 应用 -> App Credentials |
ZOOM_APP_CLIENT_SECRET | 应用客户端密钥 | Marketplace -> 应用 -> App Credentials |
ZOOM_APP_REDIRECT_URI | OAuth 重定向 URL | 您的服务器 URL + /auth |
SESSION_SECRET | Cookie 签名密钥 | 生成随机字符串 |
ZOOM_HOST | Zoom 主机 URL | https://zoom.us(或 https://zoomgov.com) |
常用 API
| API | 描述 |
|---|---|
config() | 初始化 SDK,请求能力 |
getMeetingContext() | 获取会议 ID、主题、状态 |
getUserContext() | 获取用户名称、角色、参与者 ID |
getRunningContext() | 获取当前运行上下文 |
getMeetingParticipants() | 列出参与者 |
shareApp() | 与参与者共享应用屏幕 |
openUrl({ url }) | 在外部浏览器中打开 URL |
sendAppInvitation() | 邀请用户打开你的应用 |
authorize() | 触发客户端内 OAuth |
connect() | 连接到其他应用实例 |
postMessage() | 向已连接的实例发送消息 |
runRenderingContext() | 启动 Layers API(沉浸式/摄像头) |
expandApp({ action }) | 展开/收起应用面板 |
showNotification() | 在 Zoom 中显示通知 |
完整文档库
核心概念
- 架构 - 前后端模式、嵌入式浏览器、深度链接、X-Zoom-App-Context
- 运行上下文 - 所有上下文、上下文相关 API、多实例通信
- 安全 - OWASP 响应头、CSP、Cookie 安全、PKCE、令牌存储
完整示例
- 快速开始 - Hello World Express + SDK 应用
- 客户端内 OAuth - PKCE 授权流程
- Layers 沉浸式 - 自定义视频布局
- 摄像头模式 - 虚拟摄像头叠加层
- 协作模式 - 跨参与者共享状态
- 访客模式 - 未认证/已认证/已授权状态
- 分组会议室 - 房间检测与跨房间状态
- 应用通信 - 实例间的 connect + postMessage
故障排除
参考
- API 参考 - 所有 100 多个 SDK 方法
- 事件参考 - 所有 SDK 事件监听器
- Layers API 参考 - 绘制与渲染方法
- OAuth 参考 - Zoom Apps 的 OAuth 流程
- Zoom Mail - 邮件插件集成
示例仓库
官方(由 Zoom 维护)
| 仓库 | 类型 | 最后更新 | 状态 | SDK 版本 |
|---|---|---|---|---|
| zoomapps-sample-js | Hello World(原生 JS) | 2025 年 12 月 | 活跃 | ^0.16.26 |
| zoomapps-advancedsample-react | 进阶(React + Redis) | 2025 年 10 月 | 活跃 | 0.16.0 |
| zoomapps-customlayout-js | Layers API | 2023 年 11 月 | 停止维护 | ^0.16.8 |
| zoomapps-texteditor-vuejs | 协作(Vue + Y.js) | 2023 年 10 月 | 停止维护 | ^0.16.7 |
| zoomapps-serverless-vuejs | Serverless(Firebase) | 2024 年 8 月 | 停止维护 | ^0.16.21 |
| zoomapps-cameramode-vuejs | 摄像头模式 | - | - | - |
| zoomapps-workshop-sample | 研讨会 | - | - | - |
新项目推荐: 使用 @zoom/appssdk 版本 ^0.16.26。
社区
| 类型 | 仓库 | 描述 |
|---|---|---|
| 库 | harvard-edtech/zaccl | Zoom App Complete Connection Library |
完整列表:请参阅 general/references/community-repos.md
学习路径
- 入门:
zoomapps-sample-js,最简单,且最新 - 进阶:
zoomapps-advancedsample-react,内容全面(In-Client OAuth、Guest Mode、Collaborate) - 专项:根据功能选择(Layers、Serverless、Camera Mode)
关键注意事项(来自真实开发经验)
1. 全局变量冲突
CDN 脚本会定义 window.zoomSdk。在代码中声明 let zoomSdk 会导致 SyntaxError: redeclaration of non-configurable global property。请使用 let sdk = window.zoomSdk,或改用 NPM 导入。
2. 域名白名单
你的应用 URL 必须添加到 Marketplace 域名白名单中。否则,Zoom 会显示空白面板且不报任何错误。另外还需添加 appssdk.zoom.us 以及你所用的所有 CDN 域名。
3. 必须列出所需能力
只有在 config({ capabilities: [...] }) 中列出的 API 才可使用。调用未列出的 API 会抛出错误。事件监听器同样如此。
4. SDK 仅在 Zoom 内部有效
在 Zoom 客户端之外调用 zoomSdk.config() 会抛出错误。请始终使用 try/catch 包裹,并提供浏览器回退方案:
try { await zoomSdk.config({...}); } catch { showBrowserPreview(); }
5. ngrok URL 会变化
免费版 ngrok 的 URL 在重启后会改变。你必须在 Marketplace 中更新 4 处:Home URL、Redirect URL、OAuth Allow List、Domain Allow List。可考虑使用 ngrok 付费套餐以获得固定子域名。
6. In-Client OAuth 与 Web OAuth
为获得最佳用户体验,请使用 zoomSdk.authorize()(In-Client),无需浏览器跳转。仅在从 Marketplace 首次安装时才回退到 Web 重定向。
7. Camera Mode CEF 竞态条件
Camera Mode 使用 CEF,其初始化需要一定时间。如果调用过早,drawImage/drawWebView 可能失败。请实现带指数退避的重试机制。
8. Cookie 配置
Zoom 的内嵌浏览器要求 Cookie 同时设置 SameSite=None 和 Secure=true。否则会话会静默失效。
9. State 校验
务必校验 OAuth state 参数,以防止 CSRF 攻击。生成加密安全的随机 state,将其存储,并在回调时进行验证。
资源
- 官方文档:https://developers.zoom.us/docs/zoom-apps/
- SDK 参考:https://appssdk.zoom.us/
- NPM 包:https://www.npmjs.com/package/@zoom/appssdk
- 开发者论坛:https://devforum.zoom.us/
- GitHub SDK 源码:https://github.com/zoom/appssdk
需要帮助? 请从下方的综合索引部分开始,查看完整导航。
综合索引
本节内容迁移自 SKILL.md。
快速入门路径
如果你是 Zoom Apps 新手,请按以下顺序操作:
-
先运行预检查 -> RUNBOOK.md
-
阅读架构说明 -> concepts/architecture.md
- 前后端模式、内嵌浏览器、深度链接
- 了解 Zoom 如何加载并与你的应用通信
-
构建第一个应用 -> examples/quick-start.md
- 完整的 Express + SDK Hello World
- 本地开发的 ngrok 设置
-
了解运行上下文 -> concepts/running-contexts.md
- 你的应用运行的位置(inMeeting、inMainClient、inWebinar 等)
- 特定上下文的 API 与限制
-
实现 OAuth -> examples/in-client-oauth.md
- 使用 PKCE 的 In-Client OAuth(最佳体验)
- 令牌交换与存储
-
添加功能 -> references/apis.md
- 按类别整理的 100 多个 SDK 方法
- 每个方法的代码示例
-
故障排查 -> troubleshooting/common-issues.md
- 常见问题的快速诊断
文档结构
zoom-apps-sdk/
├── SKILL.md # Main skill overview
├── SKILL.md # This file - navigation guide
│
├── concepts/ # Core architectural patterns
│ ├── architecture.md # Frontend/backend, embedded browser, OAuth flow
│ ├── running-contexts.md # Where your app runs + context-specific APIs
│ └── security.md # OWASP headers, CSP, data access layers
│
├── examples/ # Complete working code
│ ├── quick-start.md # Hello World - minimal Express + SDK app
│ ├── in-client-oauth.md # In-Client OAuth with PKCE
│ ├── layers-immersive.md # Layers API - immersive mode (custom layouts)
│ ├── layers-camera.md # Layers API - camera mode (virtual camera)
│ ├── collaborate-mode.md # Collaborate mode (shared state)
│ ├── guest-mode.md # Guest mode (unauthenticated -> authorized)
│ ├── breakout-rooms.md # Breakout room integration
│ └── app-communication.md # connect + postMessage between instances
│
├── troubleshooting/ # Problem solving guides
│ ├── common-issues.md # Quick diagnostics, error codes
│ ├── debugging.md # Local dev setup, ngrok, browser preview
│ └── migration.md # SDK version migration notes
│
└── references/ # Reference documentation
├── apis.md # Complete API reference (100+ methods)
├── events.md # All SDK events
├── layers-api.md # Layers API detailed reference
├── oauth.md # OAuth flows for Zoom Apps
└── zmail-sdk.md # Zoom Mail integration
按使用场景
我想构建一个基础的 Zoom App
- 架构 - 理解基本模式
- 快速开始 - 构建 Hello World
- 客户端内 OAuth - 添加授权
- 安全 - 必需的请求头
我想实现沉浸式视频布局(Layers API)
- Layers 沉浸式布局 - 自定义视频位置
- Layers API 参考 - 所有绘制方法
- 应用通信 - 在所有参与者之间同步布局
我想添加虚拟摄像头叠加层
- 摄像头模式 - 摄像头模式渲染
- Layers API 参考 - 绘制方法
我想实现实时协作
我想支持访客/匿名访问
- 访客模式 - 三种授权状态
- 客户端内 OAuth - promptAuthorize 流程
我想支持分组会议室
- 分组会议室 - 会议室检测与状态同步
我想在主客户端与会议之间同步
我想进行无服务器部署
- 快速开始 - 先理解基础模式
- 示例:zoomapps-serverless-vuejs - Firebase 模式
我想集成 Zoom Mail
- Zoom Mail 参考 - REST API + 邮件插件
我遇到了错误
最关键的文档
1. 架构(基础)
了解 Zoom App 的工作原理:前端运行在嵌入式浏览器中,后端负责 OAuth 和 API,SDK 充当桥梁。不理解这一点,其他内容都无从谈起。
2. 快速开始(第一个应用)
包含完整可运行的代码。在深入高级功能之前,先让程序跑起来。
3. 常见问题(最常见的问题)
troubleshooting/common-issues.md
90% 的 Zoom App 问题都源于:域名白名单、全局变量冲突,或缺少权限(capabilities)。
关键经验
关键发现:
-
全局变量冲突是头号陷阱
- CDN 脚本会全局定义
window.zoomSdk - 在 Zoom 的浏览器中,
let zoomSdk = ...会导致 SyntaxError - 使用
let sdk = window.zoomSdk或 NPM 导入
- CDN 脚本会全局定义
-
域名白名单不可省略
- 如果域名未加入白名单,应用会显示空白面板,且没有任何错误提示
- 必须同时包含你的域名、
appssdk.zoom.us以及所有 CDN 域名 - ngrok 地址每次重启都会变化,因此每次都必须更新 Marketplace 配置
-
config() 是一切的前提
- 必须最先调用,且必须列出所有所需能力
- 未列出的能力会抛出错误
- 请检查
unsupportedApis,以确认客户端版本兼容性
-
就用户体验而言,客户端内 OAuth 优于网页 OAuth
authorize()让用户留在 Zoom 内(无需浏览器跳转)- 只有在首次从 Marketplace 安装时才需要网页跳转
- 务必实现 PKCE(code_verifier + code_challenge)
-
两个 App 实例可以同时运行
- 主客户端实例与会议实例
- 使用
connect()+postMessage()在两者之间同步数据 - 会前设置在主客户端完成,会议中使用
-
Camera Mode 存在 CEF 相关的特殊问题
- CEF 初始化需要一定时间
- 如果调用过早,绘制调用可能失败
- 使用带指数退避的重试机制
-
Cookie 设置很关键
- 必须同时设置
SameSite=None和Secure=true - 否则会话会在内嵌浏览器中静默失败
- 必须同时设置
快速参考
"App shows blank panel"(应用显示空白面板)
-> 域名白名单 - 在 Marketplace 中添加域名
"SyntaxError: redeclaration"(SyntaxError:重复声明)
-> 全局变量 - 使用 let sdk = window.zoomSdk
"config() throws error"(config() 抛出错误)
-> 浏览器预览 - SDK 只能在 Zoom 内部运行
"API call fails silently"(API 调用静默失败)
-> OAuth 权限范围 - 在 Marketplace 中添加所需的 scopes
"How do I implement [feature]?"(如何实现 [功能]?)
-> API 参考 - 查找对应方法,并确认所需能力
"How do I test locally?"(如何进行本地测试?)
-> 调试指南 - ngrok + Marketplace 配置
文档版本
基于 @zoom/appssdk v0.16.x(最新版本:0.16.26+)
祝编码愉快!