本 Skill 通过 scripts/zoom-s2s.py 调用 Zoom Server-to-Server OAuth REST API,不实现"通用 REST 代理"。
Bash(python3:)(执行 scripts/zoom-s2s.py)、Bash(ls:) / Bash(cat:*)(查看脚本输出与缓存)、Read(读取凭证文件与文档)。https://zoom.us/oauth/token 与 https://api.zoom.us/v2/* 发起 HTTPS 请求,传输头包含 Authorization: Bearer 。~/.zoom-s2s-token.json 缓存访问令牌(已自动 chmod 600)。.env 读取 ZOOM_ACCOUNT_ID / ZOOM_CLIENT_ID / ZOOM_CLIENT_SECRET / ZOOM_USER_ID。list_meetings / get_meeting / create_meeting / delete_meetingget_user / list_usersrecordingsapi_call 给上层调用;不得通过修改脚本、注入参数、拼接 URL 等方式旁路调用白名单外的 Zoom 端点(如 DELETE /users/{id}、PATCH /accounts/{id} 等高风险端点)。create_meeting 与 delete_meeting 在执行前必须获得用户显式确认;delete_meeting 命令还需附加 --yes 参数。在 .env 文件中配置(仅 chmod 600,不要提交到任何 Git 仓库):
ZOOM_ACCOUNT_ID=你的AccountID
ZOOM_CLIENT_ID=你的ClientID
ZOOM_CLIENT_SECRET=你的ClientSecret
ZOOM_USER_ID=你的用户邮箱或user_id
> ⚠️ 完整的安全规范见下一节 ## 凭证安全。
Token 获取方式:Server-to-Server OAuth,机器对机器,无需用户交互授权。
.env 中的 ZOOM_CLIENT_SECRET 是长期有效的账户级凭据,等同于账户管理员口令。必须遵守:
.gitignore:本仓库 .gitignore 已包含 .env;同步确保 IDE、备份工具、文件同步(iCloud / Dropbox / OneDrive / 坚果云)不会自动上传该文件。chmod 600 .env;scripts/zoom-s2s.py 缓存的 ~/.zoom-s2s-token.json 同样敏感(已自动 chmod 600),不要复制到剪贴板、聊天窗口、终端截图、报错工单、AI 对话上下文或第三方日志服务。Account ID + Client ID + Client Secret 三元组可换得 1 小时有效的访问令牌。## 最小权限配置建议 表按需开启 Scope;不需要的 Action 不要勾选对应权限;delete_meeting 之外的写权限(meeting:write:update、user:write:、account:write:)默认不要开。ACCOUNT_ID / CLIENT_ID / CLIENT_SECRET / USER_ID 四项 → rm -f ~/.zoom-s2s-token.json 强制下次重新认证 → 复盘泄露路径。scripts/zoom-s2s.py — 纯 Python,无外部依赖,兼容 Python 3.7+。
cd ~/.agents/skills/zoom-meeting-admin/scripts
# 获取帮助
python3 zoom-s2s.py help
# 列出即将到来的会议
python3 zoom-s2s.py list_meetings <user> <page_size> upcoming
# 获取单个会议详情
python3 zoom-s2s.py get_meeting <meeting_id>
# 创建会议 (start_time: YYYY-MM-DDTHH:MM:SS)
python3 zoom-s2s.py create_meeting "<主题>" "<start_time>" <时长分钟> [时区] [密码]
python3 zoom-s2s.py create_meeting "煎饼果子讨论会" "2026-05-05T10:00:00" 60 Asia/Shanghai
# 删除会议
python3 zoom-s2s.py delete_meeting <meeting_id>
# 获取云录像
python3 zoom-s2s.py recordings <user> <page_size>
# 获取用户信息
python3 zoom-s2s.py get_user [user]
# 列出账户下所有用户
python3 zoom-s2s.py list_users [page_size]
脚本自动缓存 Token 到 ~/.zoom-s2s-token.json(有效期约 50 分钟),重复调用无需每次重新认证。
| 操作 | 命令 |
|---|---|
| ------ | ------ |
| 列出最近5个会议 | list_meetings |
| 列出最近10个历史会议 | list_meetings |
| 创建明天10点会议 | create_meeting "主题" "YYYY-MM-DDT10:00:00" 60 Asia/Shanghai |
| 获取会议详情 | get_meeting |
| 删除会议 | delete_meeting |
| 获取云录像 | recordings |
根据实际使用场景按需开通 scope,不需要的功能不要授权:
| 功能 | 所需 Scope | 建议 |
|---|---|---|
| ------ | ----------- | ------ |
| 列出会议 | meeting:read:list_meetings | ✅ 核心 |
| 查看会议详情 | meeting:read:meeting | ✅ 核心 |
| 创建会议 | meeting:write:create | 按需开启 |
| 删除会议 | meeting:write:delete | ⚠️ 谨慎开启 |
| 读取云录像 | cloud_recording:read:list_user_recordings | ⚠️ 谨慎开启 |
| 列出账户用户 | user:read:list_users | ⚠️ 谨慎开启 |
> 建议为此 Skill 单独创建一个 Zoom Server-to-Server App,不要复用已有 App 的凭证。
--yes 参数。创建 type=8(周期性会议)的 recurrence 参数说明:
| recurrence.type | 说明 | 可用字段 | 是否可用 |
|---|---|---|---|
| --- | --- | --- | --- |
| 1 | 每日循环(Daily) | end_date_time 或 count | ✅ |
| 2 | 每周循环(Weekly) | weekly_days(字符串), end_date_time 或 count | ✅ |
| 3 | 每月循环(Monthly) | monthly_day 或 monthly_weeks + weekly_days | ✅ |
⚠️ 关键避坑:weekly_days 必须是字符串,不是数组!
| 错误写法 | 正确写法 |
|---|---|
| --------- | --------- |
"weekly_days": [6] | "weekly_days": "6" |
"weekly_days": ["6"] | "weekly_days": "6"(单日) |
"weekly_days": "6,0"(多日,周六+周日) |
weekly_days 取值:1=周一 ~ 7=周日
示例:创建 5月23日-24日(周六日)的周期性会议:
payload = {
"topic": "CSM公开课",
"type": 8,
"start_time": "2026-05-23T08:00:00",
"duration": 540,
"timezone": "Asia/Shanghai",
"recurrence": {
"type": 2,
"repeat_interval": 1,
"weekly_days": "6,0", # 周六+周日,字符串!
"end_date_time": "2026-05-24T00:00:00Z"
},
"settings": {
"host_video": True,
"participant_video": True,
"join_before_host": False,
"mute_upon_entry": False
}
}
多日示例(周一+周三+周五):
"weekly_days": "1,3,5"
get_user)需要在 App 里开通对应 scope,又如 list_meetings 需要在 App 里开通 meeting:read:list_meetings 权限list_users 查 user_idweekly_days 必须为字符串:Zoom API 要求 weekly_days 是 "6" 这样的字符串,而非 [6] 数组,传数组会报 300 错误共 3 个版本