mcpField
Z
zoom-apps-sdk

zoom-apps-sdk

github.com/anthropics开发33.6k2.1k 次安装1 天前更新
代码仓库

关于 zoom-apps-sdk

供开发者构建运行在 Zoom 客户端内的 Web 应用的 JavaScript SDK。它提供会议上下文、应用间通信、客户端 OAuth、共享状态及沉浸式视频布局等接口。

主要功能

  1. 01读取会议、用户和参与者上下文
  2. 02客户端内 OAuth 授权
  3. 03会议操作与应用间消息传递
  4. 04参与者间共享应用状态
  5. 05通过 Layers API 自定义视频布局
  6. 06监听会议与参与者事件

适用场景

  1. 01构建 Zoom 会议或 Webinar 内应用
  2. 02在 Zoom 客户端中获取会议和用户信息
  3. 03为会议参与者创建共享状态体验
  4. 04制作自定义沉浸式视频布局或摄像头叠加层

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anthropics/knowledge-work-plugins --skill zoom-apps-sdk

安装后在 Claude Code 中输入/zoom-apps-sdk确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

RUNBOOK.md
concepts/
architecture.md
meeting-sdk-vs-zoom-apps.md
running-contexts.md
security.md
examples/
app-communication.md
breakout-rooms.md
collaborate-mode.md
guest-mode.md
in-client-oauth.md
layers-camera.md
layers-immersive.md
quick-start.md
references/
apis.md
environment-variables.md
events.md
layers-api.md
oauth.md
zmail-sdk.md
troubleshooting/
common-issues.md
debugging.md
forum-top-questions.md
migration.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?请按以下路径操作:

  1. 架构:前端/后端模式、嵌入式浏览器、深度链接
  2. 快速开始:完整可运行的 Express + SDK 应用
  3. 运行上下文:应用运行的位置(inMeeting、inMainClient 等)
  4. Zoom Apps 与 Meeting SDK 对比:避免混淆应用类型
  5. 客户端内 OAuth:借助 PKCE 实现无缝授权
  6. API 参考:100 多个 SDK 方法
  7. 集成索引:参见本文件下方的相应章节
  8. 5 分钟运行手册:在深入调试前进行预检

参考资料:

遇到问题?

构建沉浸式体验?

需要 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 中加载。

  1. 前往 Zoom Marketplace
  2. 打开您的应用 -> Feature 标签页
  3. 在 Zoom App 下找到 Add Allow List
  4. 添加您的域名(例如,生产环境使用 yourdomain.com,开发环境使用 xxxxx.ngrok.io)

如果未配置此项,Zoom 客户端会显示空白面板,且不会有任何错误提示。

OAuth 权限范围(必需)

各项功能需要在 Marketplace 中启用对应的 OAuth 权限范围:

功能所需权限范围
getMeetingContextzoomapp:inmeeting
getUserContextzoomapp:inmeeting
shareAppzoomapp:inmeeting
openUrlzoomapp:inmeeting
sendAppInvitationzoomapp:inmeeting
runRenderingContextzoomapp:inmeeting
authorizezoomapp:inmeeting
getMeetingParticipantszoomapp:inmeeting

添加权限范围: Marketplace -> 您的应用 -> Scopes 标签页 -> 添加所需权限范围。

缺少权限范围时,功能会静默失败或抛出错误。如果您新增了权限范围,用户必须重新授权。

运行上下文

您的应用会在 Zoom 内的不同界面中运行。configResponse.runningContext 会告诉您当前所在的位置:

上下文界面说明
inMeeting会议侧边栏最常见。可使用完整的会议 API
inMainClient主客户端面板主页标签。没有会议上下文 API
inWebinar网络研讨会侧边栏主持人/小组成员。可使用会议及网络研讨会 API
inImmersiveLayers API全屏自定义渲染
inCamera摄像头模式虚拟摄像头叠加层
inCollaborate协作模式共享状态上下文
inPhoneZoom Phone电话通话应用
inChatTeam 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
// }

规则:

  1. 必须先调用 config(),才能调用任何其他 SDK 方法
  2. 只有在 config() 中列出的功能才可用
  3. 功能必须与 Marketplace 中的 OAuth 权限范围相匹配
  4. 检查 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应用客户端 IDMarketplace -> 应用 -> App Credentials
ZOOM_APP_CLIENT_SECRET应用客户端密钥Marketplace -> 应用 -> App Credentials
ZOOM_APP_REDIRECT_URIOAuth 重定向 URL您的服务器 URL + /auth
SESSION_SECRETCookie 签名密钥生成随机字符串
ZOOM_HOSTZoom 主机 URLhttps://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、令牌存储
完整示例
故障排除
  • 常见问题 - 快速诊断与错误代码
  • 调试 - 本地开发、ngrok、浏览器预览
  • 迁移 - SDK 版本升级说明
参考

示例仓库

官方(由 Zoom 维护)
仓库类型最后更新状态SDK 版本
zoomapps-sample-jsHello World(原生 JS)2025 年 12 月活跃^0.16.26
zoomapps-advancedsample-react进阶(React + Redis)2025 年 10 月活跃0.16.0
zoomapps-customlayout-jsLayers API2023 年 11 月停止维护^0.16.8
zoomapps-texteditor-vuejs协作(Vue + Y.js)2023 年 10 月停止维护^0.16.7
zoomapps-serverless-vuejsServerless(Firebase)2024 年 8 月停止维护^0.16.21
zoomapps-cameramode-vuejs摄像头模式---
zoomapps-workshop-sample研讨会---

新项目推荐: 使用 @zoom/appssdk 版本 ^0.16.26。

社区
类型仓库描述
库harvard-edtech/zacclZoom App Complete Connection Library

完整列表:请参阅 general/references/community-repos.md

学习路径
  1. 入门:zoomapps-sample-js,最简单,且最新
  2. 进阶:zoomapps-advancedsample-react,内容全面(In-Client OAuth、Guest Mode、Collaborate)
  3. 专项:根据功能选择(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,将其存储,并在回调时进行验证。

资源


需要帮助? 请从下方的综合索引部分开始,查看完整导航。


综合索引

本节内容迁移自 SKILL.md。

快速入门路径

如果你是 Zoom Apps 新手,请按以下顺序操作:

  1. 先运行预检查 -> RUNBOOK.md

  2. 阅读架构说明 -> concepts/architecture.md

    • 前后端模式、内嵌浏览器、深度链接
    • 了解 Zoom 如何加载并与你的应用通信
  3. 构建第一个应用 -> examples/quick-start.md

    • 完整的 Express + SDK Hello World
    • 本地开发的 ngrok 设置
  4. 了解运行上下文 -> concepts/running-contexts.md

    • 你的应用运行的位置(inMeeting、inMainClient、inWebinar 等)
    • 特定上下文的 API 与限制
  5. 实现 OAuth -> examples/in-client-oauth.md

    • 使用 PKCE 的 In-Client OAuth(最佳体验)
    • 令牌交换与存储
  6. 添加功能 -> references/apis.md

    • 按类别整理的 100 多个 SDK 方法
    • 每个方法的代码示例
  7. 故障排查 -> 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
  1. 架构 - 理解基本模式
  2. 快速开始 - 构建 Hello World
  3. 客户端内 OAuth - 添加授权
  4. 安全 - 必需的请求头
我想实现沉浸式视频布局(Layers API)
  1. Layers 沉浸式布局 - 自定义视频位置
  2. Layers API 参考 - 所有绘制方法
  3. 应用通信 - 在所有参与者之间同步布局
我想添加虚拟摄像头叠加层
  1. 摄像头模式 - 摄像头模式渲染
  2. Layers API 参考 - 绘制方法
我想实现实时协作
  1. 协作模式 - 共享状态 API
  2. 应用通信 - 实例消息传递
我想支持访客/匿名访问
  1. 访客模式 - 三种授权状态
  2. 客户端内 OAuth - promptAuthorize 流程
我想支持分组会议室
  1. 分组会议室 - 会议室检测与状态同步
我想在主客户端与会议之间同步
  1. 应用通信 - connect + postMessage
  2. 运行上下文 - 多实例行为
我想进行无服务器部署
  1. 快速开始 - 先理解基础模式
  2. 示例:zoomapps-serverless-vuejs - Firebase 模式
我想集成 Zoom Mail
  1. Zoom Mail 参考 - REST API + 邮件插件
我遇到了错误
  1. 常见问题 - 快速诊断表
  2. 调试 - 本地开发环境配置、DevTools
  3. 迁移 - 版本兼容性

最关键的文档

1. 架构(基础)

concepts/architecture.md

了解 Zoom App 的工作原理:前端运行在嵌入式浏览器中,后端负责 OAuth 和 API,SDK 充当桥梁。不理解这一点,其他内容都无从谈起。

2. 快速开始(第一个应用)

examples/quick-start.md

包含完整可运行的代码。在深入高级功能之前,先让程序跑起来。

3. 常见问题(最常见的问题)

troubleshooting/common-issues.md

90% 的 Zoom App 问题都源于:域名白名单、全局变量冲突,或缺少权限(capabilities)。


关键经验

关键发现:
  1. 全局变量冲突是头号陷阱

    • CDN 脚本会全局定义 window.zoomSdk
    • 在 Zoom 的浏览器中,let zoomSdk = ... 会导致 SyntaxError
    • 使用 let sdk = window.zoomSdk 或 NPM 导入
  2. 域名白名单不可省略

    • 如果域名未加入白名单,应用会显示空白面板,且没有任何错误提示
    • 必须同时包含你的域名、appssdk.zoom.us 以及所有 CDN 域名
    • ngrok 地址每次重启都会变化,因此每次都必须更新 Marketplace 配置
  3. config() 是一切的前提

    • 必须最先调用,且必须列出所有所需能力
    • 未列出的能力会抛出错误
    • 请检查 unsupportedApis,以确认客户端版本兼容性
  4. 就用户体验而言,客户端内 OAuth 优于网页 OAuth

    • authorize() 让用户留在 Zoom 内(无需浏览器跳转)
    • 只有在首次从 Marketplace 安装时才需要网页跳转
    • 务必实现 PKCE(code_verifier + code_challenge)
  5. 两个 App 实例可以同时运行

    • 主客户端实例与会议实例
    • 使用 connect() + postMessage() 在两者之间同步数据
    • 会前设置在主客户端完成,会议中使用
  6. Camera Mode 存在 CEF 相关的特殊问题

    • CEF 初始化需要一定时间
    • 如果调用过早,绘制调用可能失败
    • 使用带指数退避的重试机制
  7. 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+)


祝编码愉快!

先阅读 架构 以了解整体模式,然后参考 快速开始 构建你的第一个应用。

评论

支持 Markdown