mcpField
Z
zoom-cobrowse-sdk

zoom-cobrowse-sdk

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

关于 zoom-cobrowse-sdk

zoom-cobrowse-sdk 是面向 Web 开发者的 Zoom Cobrowse SDK 集成参考技能,涵盖客户网站与坐席门户的配置、认证、会话流程和故障排查。

主要功能

  1. 01客户与坐席集成指南
  2. 02JWT 认证与会话生命周期
  3. 03批注工具与隐私遮罩
  4. 04远程协助与多标签页会话
  5. 05故障排查与 API 参考

适用场景

  1. 01实现客户与坐席协作浏览流程
  2. 02添加批注并遮罩敏感字段
  3. 03刷新页面后恢复会话
  4. 04排查浏览器、CORS 或 CSP 问题

安装

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

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

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

包含的文件

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

get-started.md
RUNBOOK.md
concepts/
distribution-methods.md
jwt-authentication.md
session-lifecycle.md
two-roles-pattern.md
examples/
agent-integration.md
annotations.md
auto-reconnection.md
byop-custom-pin.md
customer-integration.md
multi-tab-persistence.md
privacy-masking.md
remote-assist.md
session-events.md
references/
api-official.md
api-reference.md
api.md
authorization-official.md
authorization.md
environment-variables.md
error-codes.md
features-official.md
features.md
get-started-official.md
get-started.md
session-events.md
settings-reference.md
troubleshooting/
browser-compatibility.md
common-issues.md

详细介绍

Zoom Cobrowse SDK - Web 开发

Zoom Cobrowse SDK 网页协同浏览的背景参考资料。在支持流程已经明确、需要实现细节时再使用本文档。

官方文档: https://developers.zoom.us/docs/cobrowse-sdk/
API 参考: https://marketplacefront.zoom.us/sdk/cobrowse/
快速入门仓库: https://github.com/zoom/CobrowseSDK-Quickstart
认证端点示例: https://github.com/zoom/cobrowsesdk-auth-endpoint-sample

快速链接

初次使用 Cobrowse SDK?请按以下路径操作:

  1. 入门指南 - 从凭证到首次会话的完整设置
  2. 会话生命周期 - 了解客户与 Agent 的流程
  3. JWT 认证 - 令牌生成与安全
  4. 客户集成 - 将 SDK 集成到您的网站
  5. Agent 集成 - 设置 Agent 门户(iframe 或 npm)

核心概念:

功能:

故障排查:

参考:

  • API 参考 - 完整的 SDK 方法与事件
  • 设置参考 - 所有初始化设置
  • 集成索引 - 参见本文件below的章节

SDK 概览

Zoom Cobrowse SDK 是一个 JavaScript 库,提供以下功能:

  • 实时协同浏览:Agent 可实时看到客户的浏览器操作
  • 基于 PIN 的会话:用于客户与 Agent 连接的安全 6 位 PIN
  • 标注工具:绘制、高亮、消失笔、矩形、取色器
  • 隐私遮罩:基于 CSS 选择器对敏感表单字段进行遮罩
  • 远程协助:Agent 可滚动客户页面(需征得同意)
  • 多标签页持久化:客户打开新标签页时会话继续保持
  • 自动重连:页面刷新后会话可恢复(2 分钟窗口)
  • 会话事件:会话状态变化的实时事件
  • 要求 HTTPS:安全连接(HTTP 仅适用于 loopback/本地开发主机)
  • 无需插件:纯 JavaScript,无需浏览器扩展

双角色架构

Cobrowse 有两种不同的角色,各自采用不同的集成方式:

角色role_type集成方式需要 JWT用途
客户1网站集成(CDN 或 npm)是共享浏览器会话的用户
坐席2iframe(CDN)或 npm(仅 BYOP)是查看并协助客户的支持人员

关键点:客户与坐席使用不同的集成方式,但采用相同的 JWT 认证模式。

请先阅读(重要)

在客户/坐席演示中,应将客户 SDK 事件 pincode_updated 中的 PIN 视为唯一面向用户的 PIN。

  • 在 UI 中展示一个清晰标注的值(例如 Support PIN)。
  • 坐席加入时使用同一个 PIN。
  • 不要向用户暴露后端会话开始前生成的临时或调试 PIN。

如果忽略这些规则,坐席端通常会失败,并返回 Pincode is not found / 错误码 30308。

典型生产流程(最常见)

大多数团队会首先实现此流程,演示中用户通常也期望如此:

  1. 客户先开始会话(role_type=1)
    • 后端创建并记录会话
    • 后端返回客户 JWT
    • 客户 SDK 启动并接收 PIN
  2. 坐席随后加入(role_type=2)
    • 坐席输入客户 PIN
    • 后端校验 PIN 与会话状态
    • 后端返回坐席 JWT
    • 坐席打开由 Zoom 托管的工作台 iframe(或 BYOP 中自定义的 npm 坐席 UI)

如果演示中只有一个通用的"会话"用户,则无法体现真实的 Cobrowse 运营场景,是不完整的。

前置条件

平台要求
  • 支持的浏览器:

    • Chrome 80+ ✓
    • Firefox 78+ ✓
    • Safari 14+ ✓
    • Edge 80+ ✓
    • Internet Explorer ✗(不支持)
  • 网络要求:

    • 需要 HTTPS(HTTP 仅适用于回环地址或本地开发主机)
    • 允许跨域请求访问 *.zoom.us
    • CSP 响应头必须允许 Zoom 域名(参见 CORS 与 CSP 指南)
  • 第三方 Cookie:

    • 刷新重连需要启用第三方 Cookie
    • 隐私模式可能会限制部分功能
Zoom 账户要求
  1. 具备 SDK Universal Credit 的 Zoom Workplace 账户
  2. 在 Zoom Marketplace 中创建的 Video SDK 应用
  3. 来自应用 Cobrowse 标签页的 Cobrowse SDK 凭据

注意:Cobrowse SDK 是 Video SDK 的一项功能,而非独立产品。

凭据概览

你将从 Zoom Marketplace → Video SDK 应用 → Cobrowse 标签页获得 4 个凭据:

凭据类型用途是否可安全暴露?
SDK Key公开CDN URL、JWT 的 app_key 声明✓ 是(客户端可见)
SDK Secret私有签发 JWT✗ 否(仅服务端)
API Key私有REST API 调用(可选)✗ 否(仅服务端)
API Secret私有REST API 调用(可选)✗ 否(仅服务端)

重要:SDK Key 是公开的(嵌入在 CDN URL 中),但 SDK Secret 绝不能在客户端暴露。

快速开始

步骤 1:获取 SDK 凭据
  1. 前往 Zoom Marketplace
  2. 打开你的 Video SDK 应用(或创建一个)
  3. 进入 Cobrowse 标签页
  4. 复制你的凭据:
    • SDK Key
    • SDK Secret
    • API Key(可选)
    • API Secret(可选)
步骤 2:搭建 Token 服务

部署一个服务端端点用于生成 JWT。请使用官方示例:

git clone https://github.com/zoom/cobrowsesdk-auth-endpoint-sample.git
cd cobrowsesdk-auth-endpoint-sample
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

npm start

Token 端点:

// POST https://YOUR_TOKEN_SERVICE_BASE_URL
{
  "role": 1,           // 1 = customer, 2 = agent
  "userId": "user123",
  "userName": "John Doe"
}

// Response
{
  "token": "eyJhbGciOiJIUzI1NiIs..."
}
步骤 3:客户端集成(CDN)
<!DOCTYPE html>
<html>
<head>
  <title>Customer - Cobrowse Demo</title>
  <script type="module">
    const ZOOM_SDK_KEY = 'YOUR_SDK_KEY';
    
    // Load SDK from CDN
    (function(r, a, b, f, c, d) {
      r[f] = r[f] || { init: function() { r.ZoomCobrowseSDKInitArgs = arguments }};
      var fragment = a.createDocumentFragment();
      function loadJs(url) {
        c = a.createElement(b);
        d = a.getElementsByTagName(b)[0];
        c["async"] = false;
        c.src = url;
        fragment.appendChild(c);
      }
      loadJs(`https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js/2.13.2`);
      d.parentNode.insertBefore(fragment, d);
    })(window, document, "script", "ZoomCobrowseSDK");
  </script>
</head>
<body>
  <h1>Customer Support</h1>
  <button id="cobrowse-btn" disabled>Loading...</button>
  
  
  <label>SSN: <input type="text" class="pii-mask" placeholder="XXX-XX-XXXX"></label>
  <label>Credit Card: <input type="text" class="pii-mask" placeholder="XXXX-XXXX-XXXX-XXXX"></label>
  
  <script type="module">
    let sessionRef = null;
    
    const settings = {
      allowAgentAnnotation: true,
      allowCustomerAnnotation: true,
      piiMask: {
        maskCssSelectors: ".pii-mask",
        maskType: "custom_input"
      }
    };
    
    ZoomCobrowseSDK.init(settings, function({ success, session, error }) {
      if (success) {
        sessionRef = session;
        
        // Listen for PIN code
        session.on("pincode_updated", (payload) => {
          console.log("PIN Code:", payload.pincode);
          // IMPORTANT: this is the PIN agent should use
          alert(`Share this PIN with agent: ${payload.pincode}`);
        });
        
        // Listen for session events
        session.on("session_started", () => console.log("Session started"));
        session.on("agent_joined", () => console.log("Agent joined"));
        session.on("agent_left", () => console.log("Agent left"));
        session.on("session_ended", () => console.log("Session ended"));
        
        document.getElementById("cobrowse-btn").disabled = false;
        document.getElementById("cobrowse-btn").innerText = "Start Cobrowse Session";
      } else {
        console.error("SDK init failed:", error);
      }
    });
    
    document.getElementById("cobrowse-btn").addEventListener("click", async () => {
      // Fetch JWT from your server
      const response = await fetch("https://YOUR_TOKEN_SERVICE_BASE_URL", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          role: 1,
          userId: "customer_" + Date.now(),
          userName: "Customer"
        })
      });
      const { token } = await response.json();
      
      // Start cobrowse session
      sessionRef.start({ sdkToken: token });
    });
  </script>
</body>
</html>
步骤 4:坐席端集成(iframe)
<!DOCTYPE html>
<html>
<head>
  <title>Agent Portal</title>
</head>
<body>
  <h1>Agent Portal</h1>
  <iframe 
    id="agent-iframe"
    width="1024" 
    height="768"
    allow="autoplay *; camera *; microphone *; display-capture *; geolocation *;"
  ></iframe>
  
  <script>
    async function connectAgent() {
      // Fetch JWT from your server
      const response = await fetch("https://YOUR_TOKEN_SERVICE_BASE_URL", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          role: 2,
          userId: "agent_" + Date.now(),
          userName: "Support Agent"
        })
      });
      const { token } = await response.json();
      
      // Load Zoom agent portal
      const iframe = document.getElementById("agent-iframe");
      iframe.src = `https://us01-zcb.zoom.us/sdkapi/zcb/frame-templates/desk?access_token=${token}`;
    }
    
    connectAgent();
  </script>
</body>
</html>
Step 5: 测试集成
  1. 打开两个独立的浏览器(或无痕窗口 + 普通窗口)
  2. 客户浏览器:打开客户页面,点击 "Start Cobrowse Session"
  3. 客户浏览器:记下显示的 6 位 PIN 码
  4. Agent 浏览器:打开 Agent 页面,输入 PIN 码
  5. 两个浏览器:会话建立,Agent 可以看到客户的页面
  6. 测试功能:标注、数据脱敏、远程协助

主要功能

1. 标注工具

客户和 Agent 都可以在共享屏幕上绘制:

const settings = {
  allowAgentAnnotation: true,      // Agent can draw
  allowCustomerAnnotation: true    // Customer can draw
};

可用工具:

  • 画笔(持久)
  • 消失画笔(4 秒后消失)
  • 矩形
  • 颜色选择器
  • 橡皮擦
  • 撤销/重做
2. 隐私遮罩

使用 CSS 选择器对 Agent 隐藏敏感字段:

const settings = {
  piiMask: {
    maskType: "custom_input",           // Mask specific fields
    maskCssSelectors: ".pii-mask, #ssn", // CSS selectors
    maskHTMLAttributes: "data-sensitive=true" // HTML attributes
  }
};

支持的遮罩类型:

  • 文本节点 ✓
  • 表单输入框 ✓
  • Select 元素 ✓
  • 图片 ✗(不支持)
  • 链接 ✗(不支持)
3. 远程协助

Agent 可以滚动客户的页面:

const settings = {
  remoteAssist: {
    enable: true,
    enableCustomerConsent: true,        // Customer must approve
    remoteAssistTypes: ['scroll_page'], // Only scroll supported
    requireStopConfirmation: false      // Confirmation when stopping
  }
};
4. 多标签页会话保持

客户打开新标签页时,会话继续保持:

const settings = {
  multiTabSessionPersistence: {
    enable: true,
    stateCookieKey: '$$ZCB_SESSION$$'  // Cookie key (base64 encoded)
  }
};

会话生命周期

客户流程
  1. 加载 SDK → CDN 脚本加载 ZoomCobrowseSDK
  2. 初始化 → ZoomCobrowseSDK.init(settings, callback)
  3. 获取 JWT → 向你的服务器请求令牌(role_type=1)
  4. 开始会话 → session.start({ sdkToken })
  5. 生成 PIN → 触发 pincode_updated 事件
  6. 分享 PIN → 客户将 6 位 PIN 码告知 Agent
  7. Agent 加入 → 触发 agent_joined 事件
  8. 会话进行中 → 实时同步开始
  9. 结束会话 → 调用 session.end() 或 Agent 离开
Agent 流程
  1. 获取 JWT → 向你的服务器请求令牌(role_type=2)
  2. 加载 Iframe → 使用令牌指向 Zoom Agent 门户
  3. 输入 PIN → Agent 输入客户的 6 位 PIN 码
  4. 连接 → 触发 session_joined 事件
  5. 查看会话 → Agent 查看客户的浏览器
  6. 使用工具 → 标注、远程协助、缩放
  7. 离开会话 → 点击 "Leave Cobrowse" 按钮
会话恢复(自动重连)

客户刷新页面时:

ZoomCobrowseSDK.init(settings, function({ success, session, error }) {
  if (success) {
    const sessionInfo = session.getSessionInfo();
    
    // Check if session is recoverable
    if (sessionInfo.sessionStatus === 'session_recoverable') {
      session.join();  // Auto-rejoin previous session
    } else {
      // Start new session
      session.start({ sdkToken });
    }
  }
});

恢复窗口:2 分钟。超过 2 分钟后,会话结束。

关键注意事项与最佳实践

⚠️ 重要:SDK Secret 必须保留在服务端

问题:开发者常常无意中将 SDK Secret 嵌入前端代码。

解决方案:

  • ✓ SDK Key → 可以公开(嵌入在 CDN URL 中)
  • ✗ SDK Secret → 切勿公开(仅用于服务端签名 JWT)
// ❌ WRONG - Secret exposed in frontend
const jwt = signJWT(payload, 'YOUR_SDK_SECRET');  // Security risk!

// ✅ CORRECT - Secret stays on server
const response = await fetch('/api/token', {
  method: 'POST',
  body: JSON.stringify({ role: 1, userId, userName })
});
const { token } = await response.json();
SDK Key 与 API Key(用途不同!)
凭据用途JWT 声明
SDK KeyCDN URL、JWT app_keyapp_key: "SDK_KEY"
API KeyREST API 调用(可选)JWT 中不使用

常见错误:在 JWT 的 app_key 声明中使用 API Key 而非 SDK Key。

会话限制
限制项数值触发结果
每个会话的客户数1错误 1012:SESSION_CUSTOMER_COUNT_LIMIT
每个会话的 Agent 数5错误 1013:SESSION_AGENT_COUNT_LIMIT
每个浏览器的活动会话数1错误 1004:SESSION_COUNT_LIMIT
PIN 码长度最多 10 个字符错误 1008:SESSION_PIN_INVALID_FORMAT
会话超时行为
事件超时时间触发结果
Agent 等待客户3 分钟会话自动结束
页面刷新重连2 分钟未重连则会话结束
重连尝试次数最多 2 次2 次失败后会话结束
HTTPS 要求

问题:SDK 无法在 HTTP 站点上加载。

解决方案:

  • 生产环境:使用 HTTPS ✓
  • 开发环境:使用 loopback 主机进行本地 HTTP 测试 ✓
  • 开发环境:如有需要,使用带受信任证书或自签名证书的本地 HTTPS 端点 ✓
需要启用第三方 Cookie

问题:刷新后重新连接失败。

解决方案:在浏览器设置中启用第三方 Cookie。

受影响的场景:

  • 浏览器隐私模式
  • 启用了“阻止跨站点跟踪”的 Safari
  • 启用了“阻止第三方 Cookie”的 Chrome
分发方式混淆
方式使用场景Agent 集成是否需要 BYOP
CDN大多数使用场景Zoom 托管的 iframe否(自动 PIN)
npm自定义 Agent UI,完全可控自定义 npm 集成是(必需)

关键提示:如果你想使用 npm 集成,你必须使用 BYOP(自带 PIN)模式。

跨域 iframe 处理

问题:Cobrowse 无法在跨域 iframe 中工作。

解决方案:将 SDK 代码片段注入跨域 iframe:

<script>
const ZOOM_SDK_KEY = "YOUR_SDK_KEY_HERE";

(function(r,a,b,f,c,d){r[f]=r[f]||{init:function(){r.ZoomCobrowseSDKInitArgs=arguments}};
var fragment=a.createDocumentFragment();function loadJs(url) {c=a.createElement(b);d=a.getElementsByTagName(b)[0];c.async=false;c.src=url;fragment.appendChild(c);};
loadJs('https://us01-zcb.zoom.us/static/resource/sdk/${ZOOM_SDK_KEY}/js');d.parentNode.insertBefore(fragment,d);})(window,document,'script','ZoomCobrowseSDK');
</script>

同源 iframe:无需额外设置。

已知限制

同步限制

不会同步:

  • HTML5 Canvas 元素
  • WebGL 内容
  • Audio 和 Video 元素
  • Shadow DOM
  • 使用 Canvas 渲染的 PDF
  • Web Components

部分同步:

  • 下拉框(仅同步所选结果)
  • 日期选择器(仅同步所选结果)
  • 颜色选择器(仅同步所选结果)
渲染限制
  • 高分辨率图片可能会被压缩
  • 不同屏幕尺寸可能导致 CSS 媒体查询结果不同
  • 跨域图片可能无法渲染(CORS 限制)
  • 跨域字体可能无法渲染(CORS 限制)
遮罩限制

支持:

  • 文本节点 ✓
  • 表单输入 ✓
  • Select 元素 ✓

不支持:

  • <img> 元素 ✗
  • 链接 ✗

完整文档库

本 Skill 按类别提供了全面的指南:

核心概念
示例
参考
故障排查

资源


需要帮助? 请从下方的集成索引部分开始,获取完整导航。


综合索引

本节从 SKILL.md 迁移而来。

Zoom Cobrowse SDK 全部文档的完整导航指南。

入门指南(从这里开始!)

如果你是 Zoom Cobrowse SDK 的新用户,请按以下学习路径操作:

  1. SKILL.md - 主要概述与快速入门
  2. 5 分钟运行手册 - 常见故障的预检查
  3. 入门指南 - 从凭据到首次会话的分步设置
  4. 会话生命周期 - 了解客户与 Agent 的完整流程
  5. 客户集成 - 将 SDK 集成到你的网站
  6. Agent 集成 - 设置 Agent 门户

核心概念

你需要理解的基础概念:

示例与模式

常见场景的完整可运行示例:

会话管理
功能

参考资料

完整的 API 与配置参考:

SDK 参考
  • API 参考 - 所有 SDK 方法与接口

    • ZoomCobrowseSDK.init()
    • session.start()
    • session.join()
    • session.end()
    • session.on()
    • session.getSessionInfo()
  • 设置参考 - 所有初始化设置

    • allowAgentAnnotation
    • allowCustomerAnnotation
    • piiMask
    • remoteAssist
    • multiTabSessionPersistence
  • 会话事件参考 - 所有事件类型

    • pincode_updated
    • session_started
    • session_ended
    • agent_joined
    • agent_left
    • session_error
    • session_reconnecting
    • remote_assist_started
    • remote_assist_stopped
错误参考
  • 错误代码 - 完整的错误代码参考
    • 1001-1017:会话错误
    • 2001:令牌错误
    • 9999:服务错误
官方文档
  • 入门指南 - 官方入门文档(已抓取)
  • 功能 - 官方功能文档(已抓取)
  • 授权 - 官方 JWT 授权文档(已抓取)
  • API 文档 - 已抓取的 API 参考文档

故障排查

快速诊断与常见问题解决:

  • 常见问题 - 常见问题的快速修复方法

    • SDK 无法加载
    • Token 生成失败
    • Agent 无法连接
    • 字段未被遮罩
    • 刷新后会话无法重新连接
  • 错误码 - 错误码查询与解决方案

    • 会话启动/加入失败(1001、1011、1016)
    • 会话数量限制错误(1002、1004、1012、1013、1015)
    • PIN 码错误(1006、1008、1009、1010)
    • Token 错误(2001)
  • CORS 与 CSP - 跨域与内容安全策略配置

    • Access-Control-Allow-Origin 响应头
    • Content-Security-Policy 响应头
    • 跨域 iframe 处理
    • 同源 iframe 处理
  • 浏览器兼容性 - 浏览器要求与限制

    • 支持的浏览器(Chrome 80+、Firefox 78+、Safari 14+、Edge 80+)
    • 不支持 Internet Explorer
    • 隐私模式限制
    • 第三方 Cookie 要求

按使用场景查找

根据您要完成的任务查找文档:

我想要...

首次设置 cobrowse:

添加标注工具:

对 Agent 隐藏敏感数据:

允许 Agent 控制客户页面:

使用自定义 PIN 码:

处理页面刷新:

通过 npm 集成(而非 CDN):

调试会话连接问题:

配置 CORS 与 CSP 响应头:

按错误码查找

快速查询错误码解决方案:

会话错误
PIN 错误
认证错误
服务错误

官方资源

外部文档与示例:

文档结构

cobrowse-sdk/
├── SKILL.md                    # Main skill entry point
├── SKILL.md                    # This file - complete navigation
├── get-started.md              # Step-by-step setup guide
│
├── concepts/                   # Core concepts
│   ├── two-roles-pattern.md
│   ├── session-lifecycle.md
│   ├── jwt-authentication.md
│   └── distribution-methods.md
│
├── examples/                   # Working examples
│   ├── customer-integration.md
│   ├── agent-integration.md
│   ├── annotations.md
│   ├── privacy-masking.md
│   ├── remote-assist.md
│   ├── multi-tab-persistence.md
│   ├── byop-custom-pin.md
│   ├── session-events.md
│   └── auto-reconnection.md
│
├── references/                 # API and config references
│   ├── api-reference.md        # SDK methods
│   ├── settings-reference.md   # Init settings
│   ├── session-events.md       # Event types
│   ├── error-codes.md          # Error reference
│   ├── get-started.md          # Official docs (crawled)
│   ├── features.md             # Official docs (crawled)
│   ├── authorization.md        # Official docs (crawled)
│   └── api.md                  # API docs (crawled)
│
└── troubleshooting/            # Problem resolution
    ├── common-issues.md
    ├── error-codes.md
    ├── cors-csp.md
    └── browser-compatibility.md

搜索提示

按关键词查找:


没有找到所需内容? 请查看官方文档或在开发者论坛提问。

环境变量

评论

支持 Markdown