{"skill":{"slug":"zoom-meeting-admin","displayName":"ZOOM Meeting Admin","summary":"Manage Zoom meetings, cloud recordings, and account users via a Server-to-Server OAuth REST script. Use this skill when the user wants to list, view, create,...","description":"---\nname: zoom-meeting-admin\nallowed-tools: Bash(python3:*) Bash(ls:*) Bash(cat:*) Read\ncompatibility: Requires Python 3.7+, network access to zoom.us and api.zoom.us, and a local .env with Zoom Server-to-Server OAuth credentials.\ndescription: Manage Zoom meetings, cloud recordings, and account users via a Server-to-Server OAuth REST script. Use this skill when the user wants to list, view, create, or delete a scheduled Zoom meeting; query cloud recordings for a user; or look up account users. Actions are restricted to a fixed list (list/get/create/delete meeting, get/list user, list recordings) — the script does not perform arbitrary Zoom API calls. create_meeting and delete_meeting require explicit user confirmation before execution. Requires a Zoom Server-to-Server OAuth app and a local .env with ACCOUNT_ID, CLIENT_ID, CLIENT_SECRET, USER_ID.\n---\n\n# Zoom Server-to-Server OAuth REST API\n\n## 权限与约束\n\n本 Skill 通过 `scripts/zoom-s2s.py` 调用 Zoom Server-to-Server OAuth REST API，不实现\"通用 REST 代理\"。\n\n- **声明的工具**：`Bash(python3:*)`（执行 `scripts/zoom-s2s.py`）、`Bash(ls:*)` / `Bash(cat:*)`（查看脚本输出与缓存）、`Read`（读取凭证文件与文档）。\n- **网络访问**：向 `https://zoom.us/oauth/token` 与 `https://api.zoom.us/v2/*` 发起 HTTPS 请求，传输头包含 `Authorization: Bearer <token>`。\n- **文件写入**：在 `~/.zoom-s2s-token.json` 缓存访问令牌（已自动 `chmod 600`）。\n- **凭证读取**：从仓库根目录的 `.env` 读取 `ZOOM_ACCOUNT_ID` / `ZOOM_CLIENT_ID` / `ZOOM_CLIENT_SECRET` / `ZOOM_USER_ID`。\n- **允许的 Action（白名单）**——禁止构造任意 Zoom REST 请求或调用未列出的端点：\n  - 会议：`list_meetings` / `get_meeting` / `create_meeting` / `delete_meeting`\n  - 用户：`get_user` / `list_users`\n  - 录像：`recordings`\n- **越权防护**：脚本未导出 `api_call` 给上层调用；不得通过修改脚本、注入参数、拼接 URL 等方式旁路调用白名单外的 Zoom 端点（如 `DELETE /users/{id}`、`PATCH /accounts/{id}` 等高风险端点）。\n- **强人类确认**：`create_meeting` 与 `delete_meeting` 在执行前必须获得用户显式确认；`delete_meeting` 命令还需附加 `--yes` 参数。\n\n## 凭证配置\n\n在 `.env` 文件中配置（**仅 chmod 600，不要提交到任何 Git 仓库**）：\n\n```env\nZOOM_ACCOUNT_ID=你的AccountID\nZOOM_CLIENT_ID=你的ClientID\nZOOM_CLIENT_SECRET=你的ClientSecret\nZOOM_USER_ID=你的用户邮箱或user_id\n```\n\n> ⚠️ 完整的安全规范见下一节 `## 凭证安全`。\n\n**Token 获取方式**：Server-to-Server OAuth，机器对机器，无需用户交互授权。\n\n## 凭证安全\n\n`.env` 中的 `ZOOM_CLIENT_SECRET` 是长期有效的账户级凭据，等同于账户管理员口令。**必须**遵守：\n\n- **加入 `.gitignore`**：本仓库 `.gitignore` 已包含 `.env`；同步确保 IDE、备份工具、文件同步（iCloud / Dropbox / OneDrive / 坚果云）不会自动上传该文件。\n- **限制文件权限**：`chmod 600 .env`；`scripts/zoom-s2s.py` 缓存的 `~/.zoom-s2s-token.json` 同样敏感（已自动 `chmod 600`），**不要**复制到剪贴板、聊天窗口、终端截图、报错工单、AI 对话上下文或第三方日志服务。\n- **不要在共享环境复用**：CI runner、公用跳板机、容器镜像、共享开发机中复用同一份凭据 ≈ 凭据公开。`Account ID + Client ID + Client Secret` 三元组可换得 1 小时有效的访问令牌。\n- **最小权限**：按 `## 最小权限配置建议` 表按需开启 Scope；不需要的 Action 不要勾选对应权限；`delete_meeting` 之外的写权限（`meeting:write:update`、`user:write:*`、`account:write:*`）默认不要开。\n- **独立 App**：为此 Skill 单独创建一个 Zoom Server-to-Server App，**不要**复用其他业务 App 的凭据；一旦泄露，旋转该 App 的凭据即可，不影响其他业务。\n- **凭据泄露应急**：在 Zoom Marketplace 删除该 App → 重新创建并轮换 `ACCOUNT_ID` / `CLIENT_ID` / `CLIENT_SECRET` / `USER_ID` 四项 → `rm -f ~/.zoom-s2s-token.json` 强制下次重新认证 → 复盘泄露路径。\n\n## 核心脚本\n\n`scripts/zoom-s2s.py` — 纯 Python，无外部依赖，兼容 Python 3.7+。\n\n```bash\ncd ~/.agents/skills/zoom-meeting-admin/scripts\n\n# 获取帮助\npython3 zoom-s2s.py help\n\n# 列出即将到来的会议\npython3 zoom-s2s.py list_meetings <user> <page_size> upcoming\n\n# 获取单个会议详情\npython3 zoom-s2s.py get_meeting <meeting_id>\n\n# 创建会议 (start_time: YYYY-MM-DDTHH:MM:SS)\npython3 zoom-s2s.py create_meeting \"<主题>\" \"<start_time>\" <时长分钟> [时区] [密码]\npython3 zoom-s2s.py create_meeting \"煎饼果子讨论会\" \"2026-05-05T10:00:00\" 60 Asia/Shanghai\n\n# 删除会议\npython3 zoom-s2s.py delete_meeting <meeting_id>\n\n# 获取云录像\npython3 zoom-s2s.py recordings <user> <page_size>\n\n# 获取用户信息\npython3 zoom-s2s.py get_user [user]\n\n# 列出账户下所有用户\npython3 zoom-s2s.py list_users [page_size]\n```\n\n## Token 缓存\n\n脚本自动缓存 Token 到 `~/.zoom-s2s-token.json`（有效期约 50 分钟），重复调用无需每次重新认证。\n\n## 常用操作快速参考\n\n| 操作 | 命令 |\n|------|------|\n| 列出最近5个会议 | `list_meetings <user> 5 upcoming` |\n| 列出最近10个历史会议 | `list_meetings <user> 10 past` |\n| 创建明天10点会议 | `create_meeting \"主题\" \"YYYY-MM-DDT10:00:00\" 60 Asia/Shanghai` |\n| 获取会议详情 | `get_meeting <id>` |\n| 删除会议 | `delete_meeting <id> --yes` |\n| 获取云录像 | `recordings <user> 10` |\n\n## 最小权限配置建议\n\n根据实际使用场景按需开通 scope，不需要的功能不要授权：\n\n| 功能 | 所需 Scope | 建议 |\n|------|-----------|------|\n| 列出会议 | `meeting:read:list_meetings` | ✅ 核心 |\n| 查看会议详情 | `meeting:read:meeting` | ✅ 核心 |\n| 创建会议 | `meeting:write:create` | 按需开启 |\n| **删除会议** | `meeting:write:delete` | ⚠️ 谨慎开启 |\n| **读取云录像** | `cloud_recording:read:list_user_recordings` | ⚠️ 谨慎开启 |\n| **列出账户用户** | `user:read:list_users` | ⚠️ 谨慎开启 |\n\n> 建议为此 Skill 单独创建一个 Zoom Server-to-Server App，不要复用已有 App 的凭证。\n\n## Agent 调用规范\n\n- **创建会议前**：向用户确认主题、时间、时长，再执行。\n- **删除会议前**：必须向用户明确展示会议信息并获得确认，命令需附加 `--yes` 参数。\n- **禁止超范围调用**：仅允许文档中列出的 Action，不得构造任意 Zoom REST API 请求。\n\n## 创建周期性会议\n\n创建 `type=8`（周期性会议）的 `recurrence` 参数说明：\n\n| recurrence.type | 说明 | 可用字段 | 是否可用 |\n|---|---|---|---|\n| 1 | 每日循环（Daily） | `end_date_time` 或 `count` | ✅ |\n| 2 | 每周循环（Weekly） | `weekly_days`（字符串）, `end_date_time` 或 `count` | ✅ |\n| 3 | 每月循环（Monthly） | `monthly_day` 或 `monthly_weeks` + `weekly_days` | ✅ |\n\n**⚠️ 关键避坑：`weekly_days` 必须是字符串，不是数组！**\n\n| 错误写法 | 正确写法 |\n|---------|---------|\n| `\"weekly_days\": [6]` | `\"weekly_days\": \"6\"` |\n| `\"weekly_days\": [\"6\"]` | `\"weekly_days\": \"6\"`（单日） |\n|  | `\"weekly_days\": \"6,0\"`（多日，周六+周日） |\n\n**weekly_days 取值**：1=周一 ~ 7=周日\n\n**示例**：创建 5月23日-24日（周六日）的周期性会议：\n```python\npayload = {\n    \"topic\": \"CSM公开课\",\n    \"type\": 8,\n    \"start_time\": \"2026-05-23T08:00:00\",\n    \"duration\": 540,\n    \"timezone\": \"Asia/Shanghai\",\n    \"recurrence\": {\n        \"type\": 2,\n        \"repeat_interval\": 1,\n        \"weekly_days\": \"6,0\",   # 周六+周日，字符串！\n        \"end_date_time\": \"2026-05-24T00:00:00Z\"\n    },\n    \"settings\": {\n        \"host_video\": True,\n        \"participant_video\": True,\n        \"join_before_host\": False,\n        \"mute_upon_entry\": False\n    }\n}\n```\n\n**多日示例**（周一+周三+周五）：\n```python\n\"weekly_days\": \"1,3,5\"\n```\n\n## 踩坑记录\n\n1. **scope 错误 (4711)**：某些 API（如 `get_user`）需要在 App 里开通对应 scope，又如 `list_meetings` 需要在 App 里开通 `meeting:read:list_meetings` 权限\n2. **Token 有效期**：Server-to-Server Token 有效期 1 小时，脚本自动刷新并缓存\n3. **用户 ID**：可用邮箱，也可用 `list_users` 查 user_id\n4. **`weekly_days` 必须为字符串**：Zoom API 要求 `weekly_days` 是 `\"6\"` 这样的字符串，而非 `[6]` 数组，传数组会报 300 错误","tags":{"latest":"1.0.3"},"stats":{"comments":0,"downloads":538,"installsAllTime":0,"installsCurrent":0,"stars":1,"versions":4},"createdAt":1777903059575,"updatedAt":1780668660160},"latestVersion":{"version":"1.0.3","createdAt":1780668660160,"changelog":"- Renamed skill to \"zoom-meeting-admin\" and updated all naming for clarity and consistency.\n- Added a detailed Permissions & Security section, clarifying tool usage, credential storage, scope limits, and explicit action whitelisting.\n- Strengthened documentation on credential security practices and recommended standalone OAuth app usage.\n- Clarified that only a fixed set of meeting/user/recording operations are supported; arbitrary API calls are now explicitly forbidden.\n- Removed the redundant \"skill-card.md\" file.","license":"MIT-0"},"metadata":null,"owner":{"handle":"mebusw","userId":"s17fqnnawywqwp37410y5w9r1h83pwab","displayName":"Jacky Shen","image":"https://avatars.githubusercontent.com/u/760587?v=4"},"moderation":null}