Skip to main content

zoom-oauth

Reference skill for Zoom authentication. Use after routing to an auth workflow when choosing app credentials, grant types, scopes, token refresh behavior, or debugging Zoom OAuth failures.

설치로 이동

소스 정보

저장소
anthropics/knowledge-work-plugins
최근 소스 활동
2026년 4월 9일 23:28
감지된 SKILL.md 언어
영어
스타
25,764
포크
3,038

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
22 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
zoom-oauth
description
Reference skill for Zoom authentication. Use after routing to an auth workflow when choosing app credentials, grant types, scopes, token refresh behavior, or debugging Zoom OAuth failures.
user-invocable
false
triggers
["zoom oauth","zoom authentication","zoom authorization","server to server oauth","s2s oauth","zoom access token","zoom refresh token","authorization code flow","device authorization","pkce","zoom api authentication","oauth error 4709","oauth error 4733","oauth error 4735","redirect uri mismatch"]
# Zoom OAuth Background reference for Zoom auth and token lifecycle behavior. Prefer `setup-zoom-oauth` first, then use this skill for the exact flow, scope, and error details. # Zoom OAuth Authentication and authorization for Zoom APIs. ## 📖 Complete Documentation For comprehensive guides, production patterns, and troubleshooting, see **Integrated Index section below**. Quick navigation: - **[5-Minute Runbook](RUNBOOK.md)** - Preflight checks before deep debugging - **[OAuth Flows](concepts/oauth-flows.md)** - Which flow to use and how each works - **[Token Lifecycle](concepts/token-lifecycle.md)** - Expiration, refresh, and revocation - **[Production Examples](examples/s2s-oauth-redis.md)** - Redis caching, MySQL storage, auto-refresh - **[Troubleshooting](troubleshooting/common-errors.md)** - Error codes 4700-4741 ## Prerequisites - Zoom app created in [Marketplace](https://marketplace.zoom.us/) - Client ID and Client Secret - For S2S OAuth: Account ID ## Four Authorization Use Cases | Use Case | App Type | Grant Type | Industry Name | |----------|----------|------------|---------------| | **Account Authorization** | Server-to-Server | `account_credentials` | Client Credentials Grant, M2M, Two-legged OAuth | | **User Authorization** | General | `authorization_code` | Authorization Code Grant, Three-legged OAuth | | **Device Authorization** | General | `urn:ietf:params:oauth:grant-type:device_code` | Device Authorization Grant (RFC 8628) | | **Client Authorization** | General | `client_credentials` | Client Credentials Grant (chatbot-scoped) | ### Industry Terminology | Term | Meaning | |------|---------| | **Two-legged OAuth** | No user involved (client ↔ server) | | **Three-legged OAuth** | User involved (user ↔ client ↔ server) | | **M2M** | Machine-to-Machine (backend services) | | **Public client** | Can't keep secrets (mobile, SPA) → use PKCE | | **Confidential client** | Can keep secrets (backend servers) | | **PKCE** | Proof Key for Code Exchange (RFC 7636), pronounced "pixy" | ### Which Flow Should I Use? ``` ┌─────────────────────┐ │ What are you │ │ building? │ └──────────┬──────────┘ │ ┌────────────────────┼────────────────────┐ │ │ │ ▼ ▼ ▼ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ Backend │ │ App for other │ │ Chatbot only │ │ automation │ │ users/accounts │ │ (Team Chat) │ │ (your account) │ │ │ │ │ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │ │ │ ▼ │ ▼ ┌─────────────────┐ │ ┌─────────────────┐ │ ACCOUNT │ │ │ CLIENT │ │ (S2S OAuth) │ │ │ (Chatbot) │ └─────────────────┘ │ └─────────────────┘ │ ▼ ┌─────────────────────┐ │ Does device have │ │ a browser? │ └──────────┬──────────┘ │ ┌───────────────┴───────────────┐ │ NO YES│ ▼ ▼ ┌─────────────────────────┐ ┌─────────────────┐ │ DEVICE │ │ USER │ │ (Device Flow) │ │ (Auth Code) │ │ │ │ │ │ Examples: │ │ + PKCE if │ │ • Smart TV │ │ public client │ │ • Meeting SDK device │ │ │ └─────────────────────────┘ └─────────────────┘ ``` --- ## Account Authorization (Server-to-Server OAuth) For backend automation without user interaction. ### Request Access Token ```bash POST https://zoom.us/oauth/token?grant_type=account_credentials&account_id={ACCOUNT_ID} Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` ### Response ```json { "access_token": "eyJ...", "token_type": "bearer", "expires_in": 3600, "scope": "user:read:user:admin", "api_url": "https://api.zoom.us" } ``` ### Refresh Access tokens expire after **1 hour**. No separate refresh flow - just request a new token. --- ## User Authorization (Authorization Code Flow) For apps that act on behalf of users. ### Step 1: Redirect User to Authorize ``` https://zoom.us/oauth/authorize?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI} ``` Use `https://zoom.us/oauth/authorize` for consent, but `https://zoom.us/oauth/token` for token exchange. **Optional Parameters:** | Parameter | Description | |-----------|-------------| | `state` | CSRF protection, maintains state through flow | | `code_challenge` | For PKCE (see below) | | `code_challenge_method` | `S256` or `plain` (default: plain) | ### Step 2: User Authorizes - User signs in and grants permission - Redirects to `redirect_uri` with authorization code: ``` https://example.com/?code={AUTHORIZATION_CODE} ``` ### Step 3: Exchange Code for Token ```bash POST https://zoom.us/oauth/token?grant_type=authorization_code&code={CODE}&redirect_uri={REDIRECT_URI} Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` **With PKCE:** Add `code_verifier` parameter. ### Response ```json { "access_token": "eyJ...", "token_type": "bearer", "refresh_token": "eyJ...", "expires_in": 3600, "scope": "user:read:user", "api_url": "https://api.zoom.us" } ``` ### Refresh Token ```bash POST https://zoom.us/oauth/token?grant_type=refresh_token&refresh_token={REFRESH_TOKEN} Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` - Access tokens expire after **1 hour** - Refresh token lifetime can vary; ~90 days is common for some user-based flows. Treat it as configuration/behavior that can change and rely on runtime errors + re-auth fallback. - Always use the latest refresh token for the next request - If refresh token expires, redirect user to authorization URL to restart flow ### User-Level vs Account-Level Apps | Type | Who Can Authorize | Scope Access | |------|-------------------|--------------| | **User-level** | Any individual user | Scoped to themselves | | **Account-level** | User with admin permissions | Account-wide access (admin scopes) | --- ## Device Authorization (Device Flow) For devices without browsers (e.g., Meeting SDK apps). ### Prerequisites Enable "Use App on Device" in: Features > Embed > Enable Meeting SDK ### Step 1: Request Device Code ```bash POST https://zoom.us/oauth/devicecode?client_id={CLIENT_ID} Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` ### Response ```json { "device_code": "DEVICE_CODE", "user_code": "abcd1234", "verification_uri": "https://zoom.us/oauth_device", "verification_uri_complete": "https://zoom.us/oauth/device/complete/{CODE}", "expires_in": 900, "interval": 5 } ``` ### Step 2: User Authorization Direct user to: - `verification_uri` and display `user_code` for manual entry, OR - `verification_uri_complete` (user code prefilled) User signs in and allows the app. ### Step 3: Poll for Token Poll at the `interval` (5 seconds) until user authorizes: ```bash POST https://zoom.us/oauth/token?grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code={DEVICE_CODE} Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` ### Response ```json { "access_token": "eyJ...", "token_type": "bearer", "refresh_token": "eyJ...", "expires_in": 3599, "scope": "user:read:user user:read:token", "api_url": "https://api.zoom.us" } ``` ### Polling Responses | Response | Meaning | Action | |----------|---------|--------| | Token returned | User authorized | Store tokens, done | | `error: authorization_pending` | User hasn't authorized yet | Keep polling at interval | | `error: slow_down` | Polling too fast | Increase interval by 5 seconds | | `error: expired_token` | Device code expired (15 min) | Restart flow from Step 1 | | `error: access_denied` | User denied authorization | Handle denial, don't retry | ### Polling Implementation ```javascript async function pollForToken(deviceCode, interval) { while (true) { await sleep(interval * 1000); try { const response = await axios.post( `https://zoom.us/oauth/token?grant_type=urn:ietf:params:oauth:grant-type:device_code&device_code=${deviceCode}`, null, { headers: { 'Authorization': `Basic ${credentials}` } } ); return response.data; // Success - got tokens } catch (error) { const err = error.response?.data?.error; if (err === 'authorization_pending') continue; if (err === 'slow_down') { interval += 5; continue; } throw error; // expired_token or access_denied } } } ``` ### Refresh Same as User Authorization. If refresh token expires, restart device flow from Step 1. --- ## Client Authorization (Chatbot) For chatbot message operations only. ### Request Token ```bash POST https://zoom.us/oauth/token?grant_type=client_credentials Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` ### Response ```json { "access_token": "eyJ...", "token_type": "bearer", "expires_in": 3600, "scope": "imchat:bot", "api_url": "https://api.zoom.us" } ``` ### Refresh Tokens expire after **1 hour**. No refresh flow - just request a new token. --- ## Using Access Tokens ### Call API ```bash GET https://api.zoom.us/v2/users/me Headers: Authorization: Bearer {ACCESS_TOKEN} ``` ### Me Context Replace `userID` with `me` to target the token's associated user: | Endpoint | Methods | |----------|---------| | `/v2/users/me` | GET, PATCH | | `/v2/users/me/token` | GET | | `/v2/users/me/meetings` | GET, POST | --- ## Revoke Access Token Works for all authorization types. ```bash POST https://zoom.us/oauth/revoke?token={ACCESS_TOKEN} Headers: Authorization: Basic {Base64(ClientID:ClientSecret)} ``` ### Response ```json { "status": "success" } ``` --- ## PKCE (Proof Key for Code Exchange) For public clients that can't securely store secrets (mobile apps, SPAs, desktop apps). ### When to Use PKCE | Client Type | Use PKCE? | Why | |-------------|-----------|-----| | Mobile app | **Yes** | Can't securely store client secret | | Single Page App (SPA) | **Yes** | JavaScript is visible to users | | Desktop app | **Yes** | Binary can be decompiled | | Meeting SDK (client-side) | **Yes** | Runs on user's device | | Backend server | Optional | Can keep secrets, but PKCE adds security | ### How PKCE Works ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Client │ │ Zoom │ │ Zoom │ │ App │ │ Auth │ │ Token │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기