ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Zoom REST API 云录制流水线实战:Webhook 触发自动下载与归档

Zoom REST API 云录制流水线实战:Webhook 触发自动下载与归档 Zoom REST API 云录制流水线实战Webhook 触发自动下载与归档【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins本指南围绕 Zoom 云录制的自动化摄取场景讲解如何从订阅recording.completedWebhook 事件开始到调用录制接口获取文件元数据、以带认证的方式安全下载录制文件再到落地存储S3/GCS 等并维护状态的全链路实现。读者将掌握一套可直接复制的Webhook → 下载 → 存储流水线架构并学会规避下载鉴权、重定向与录制就绪延迟等高频坑点。流水线概览四个环节缺一不可云录制自动归档的本质是一条事件驱动的数据管道。在知识工作类插件如会议纪要归档、培训内容沉淀、合规留痕中最常见的做法是让后端服务监听 Zoom 的录制事件在会议结束、云端处理完成后自动把录制文件拉取回自己的存储系统。从本仓库的 recording-pipeline.md 出发完整流水线由四个高层步骤构成订阅录制相关的 Webhook 事件例如recording.completed收到 Webhook 后通过录制接口获取录制文件信息文件名、文件类型、download_url等使用带认证的请求下载文件关键点download_url通常要求携带Authorization头将文件存储进自己的系统S3/GCS 等并持续追踪每条录制记录的处理状态。下面逐环节展开并给出可运行的代码与可验证的仓库依据。环节一订阅recording.completedWebhook 事件Zoom 会在云录制就绪后推送recording.completed事件这是流水线的触发源。相比每分钟轮询GET /users/{userId}/recordings的写法事件驱动方式几乎不消耗 API 配额是官方与仓库文档共同推荐的做法参见 rate-limits.md 中的Use Webhooks Instead of Polling最佳实践。事件结构recording.completed的 payload 核心位于payload.object包含会议信息与recording_files数组每个文件对象至少带有file_type文件类型与download_url下载地址。仓库中的 webhook-server.md 给出了对应的处理器写法function handleRecordingCompleted(payload) { const { id, uuid, topic, recording_files } payload.object; console.log(Recording ready: ${topic}); // Download recordings (see recording-pipeline.md) recording_files.forEach(file { console.log(- ${file.file_type}: ${file.download_url}); // downloadRecording(file.download_url, file.id); }); }接收端的安全三件套Webhook 接收端不能裸奔。根据 webhook-server.md上线前必须实现三项安全机制CRC 校验Challenge-Response CheckZoom 在配置或变更 Webhook URL 时会发送endpoint.url_validation事件服务端须在 3 秒内用 HMAC-SHA256 对plainToken加密并回传plainToken与encryptedTokenfunction handleCRC(req, res) { const { plainToken } req.body.payload; const encryptedToken crypto .createHmac(sha256, WEBHOOK_SECRET_TOKEN) .update(plainToken) .digest(hex); res.status(200).json({ plainToken, encryptedToken }); }签名验证提取x-zm-signature与x-zm-request-timestamp请求头构造消息v0:{timestamp}:{body}用 Webhook Secret 做 HMAC-SHA256 后前置v0与签名头比对防止伪造请求。幂等去重Zoom 对失败 Webhook 会以指数退避重试 3 次5 分钟 / 20 分钟 / 60 分钟。可在服务端用event-event_ts-object.id作为事件唯一键去重确保重试不会触发重复下载。订阅配置事件订阅通过 Zoom App 的 Feature/Event 配置页完成每个应用最多 10 个事件订阅每个订阅内的事件数量不限见 rate-limits.md。除了recording.completed同族事件还有recording.transcript_completed转写就绪可一并订阅用于后续字幕/纪要处理。环节二通过录制接口拉取文件元数据Webhook 通知到达后通常需要回查录制接口获取完整的文件列表与最新状态。录制相关端点集中在 recordings.md端点用途GET /users/{userId}/recordings列出用户某时间段的录制需from、to查询参数格式YYYY-MM-DDGET /meetings/{meetingId}/recordings获取单场会议的全部录制文件DELETE /meetings/{meetingId}/recordings删除会议的全部录制DELETE /meetings/{meetingId}/recordings/{recordingId}删除单个录制文件其中列表接口按日期查询例如GET /v2/users/me/recordings?from2025-01-01to2025-01-31需要留意接口路径中userId的取值规则来自 api-architecture.mdUser-level OAuth 应用必须使用me而Server-to-Server OAuth 应用必须提供真实 userId 或邮箱混用会分别触发 4700无效 token/缺 scope或 1001用户不存在类错误。录制文件的类型体系响应中的recording_files可能同时包含多种文件仓库文档以表格形式列出它们是自动化归档时按需筛选的依据类型说明shared_screen_with_speaker_view共享屏幕 演讲者视图shared_screen_with_gallery_view共享屏幕 画廊视图active_speaker仅演讲者视图gallery_view仅画廊视图audio_only音频文件M4Achat_file聊天记录timeline会议时间线audio_transcriptVTT 转写文本归档策略可据此只下载需要的类型例如仅保留audio_only与audio_transcript避免重复的多个视频视图占用存储。所需 OAuth Scopes访问与下载录制需要以下 scoperecordings.mdrecording:read查看/下载录制recording:write删除录制若调用报 4700Invalid access token, does not contain scopes需要回到 Marketplace 应用配置中补齐 scope 并重新换取 tokencommon-errors.md。环节三带认证的下载本流水线最关键的环节下载是整个流水线中事故率最高的地方。download_url是动态生成的临时地址不能裸请求。两种认证方式仓库的 api-architecture.md 记录了两种可用凭证Bearer token 放入Authorization请求头推荐curl -L -H Authorization: Bearer ACCESS_TOKEN \ https://zoom.us/rec/archive/download/xyz使用 Webhook payload 中的download_access_token适用于 Webhook 触发的即时下载curl -L -H Authorization: Bearer DOWNLOAD_ACCESS_TOKEN \ https://zoom.us/rec/archive/download/xyz记录在 recordings.md 中的另一旧式写法GET {download_url}?access_token{token}也应尽量替换为请求头方式避免 token 出现在 URL 日志中。必须跟随重定向download_url可能返回 301/302 重定向客户端必须允许自动跳转否则会拿到空响应或错误内容// Node.js — fetch 默认跟随重定向 const response await fetch(downloadUrl, { headers: { Authorization: Bearer ${accessToken} }, redirect: follow }); const fileBuffer await response.arrayBuffer();# Python — requests 默认跟随重定向流式写盘 import requests response requests.get( download_url, headers{Authorization: fBearer {access_token}}, allow_redirectsTrue, streamTrue ) with open(recording.mp4, wb) as f: for chunk in response.iter_content(chunk_size8192): f.write(chunk)curl 命令行同理务必加-L参数。完整流水线下载示例Node.js结合上述要点一个健壮的下载函数应同时处理 token、重定向与状态码async function downloadRecording(downloadUrl, accessToken) { const response await fetch(downloadUrl, { headers: { Authorization: Bearer ${accessToken} }, redirect: follow }); if (!response.ok) { throw new Error(Download failed: ${response.status} ${response.statusText}); } return Buffer.from(await response.arrayBuffer()); }身份验证令牌的获取后端自动化场景推荐 Server-to-Server OAuthauthentication.md在 Marketplace 创建 Server-to-Server OAuth 应用获得 Account ID / Client ID / Client Secret然后换取一小时有效的 access tokencurl -X POST https://zoom.us/oauth/token \ -H Authorization: Basic $(echo -n {clientId}:{clientSecret} | base64) \ -H Content-Type: application/x-www-form-urlencoded \ -d grant_typeaccount_credentialsaccount_id{accountId}响应中的access_token、expires_in3600 秒以及按用户区域返回的api_url字段都可用于后续请求本地缓存 token 并在过期前刷新可避免每次下载前都重新换取。环节四存储与状态追踪下载完成后将文件写入 S3/GCS 等对象存储并为每条录制维护一条状态记录。建议状态机包含以下阶段PENDING收到 webhook → FETCHING正在回查接口/下载 → STORED已归档 → FAILED失败待重试落库时应同时保存会议级元数据meetingId、uuid、topic、start_time与文件级元数据file_type、recording_id、大小、存储 key便于后续检索与合规审计。对于大批量历史录制回填场景可结合GET /users/{userId}/recordings?from...to...按日期窗口分页拉取配合 rate-limits.md 中的请求队列与退避策略控制速率——注意录制接口属于Light 类别Free 4/秒Pro 30/秒Business 80/秒而配额是按账号共享的一个重应用会影响同账号下的其他应用务必监控X-RateLimit-Remaining响应头。高频陷阱排查手册原文档专门列出三个实战中最常见的坑结合仓库资料逐一给出定位与解法陷阱 1直接跟随download_url而不附加 Bearer token现象返回 401 或下载到错误内容。原因download_url是动态签发的地址必须携带认证信息。解决在请求头附上Authorization: Bearer access_token或 Webhook payload 中的download_access_token参考上文环节三。陷阱 2不处理download_url的重定向响应现象fetch/curl拿到 3xx 响应后即终止文件为空。原因录制下载地址会跳转到实际的存储位置。解决客户端开启自动跟随重定向Node 的redirect: follow、Python 的allow_redirectsTrue、curl 的-L。陷阱 3认为会议结束后录制立即可用现象recording.completed尚未推送或接口返回空列表/处理中状态。原因云端录制需要一定处理时间包含转码、生成各视图文件与转写等步骤。解决不要把会议结束当作录制就绪。依赖recording.completed事件而非meeting.ended收到事件后若接口仍未就绪使用带退避的轮询或重试队列等文件真正可下载后再进入下载环节。进一步阅读recording-pipeline.md本流水线的原始指南recordings.md录制端点、文件类型与 scope 速查webhook-server.md含 CRC 校验、签名验证与事件去重的完整服务端实现api-architecture.mdme关键字规则、UUID 双重编码、下载 URL 认证authentication.mdServer-to-Server OAuth 与 User OAuth 完整流程rate-limits.md配额分级与重试策略common-errors.mdHTTP 状态码与 Zoom 错误码对照【免费下载链接】knowledge-work-pluginsOpen source repository of plugins primarily intended for knowledge workers to use in Claude Cowork项目地址: https://gitcode.com/GitHub_Trending/kn/knowledge-work-plugins创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表