feat: implement backend-controlled zoom RTMS start endpoint#16
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (14)
📝 WalkthroughWalkthroughThis PR adds Zoom RTMS (Real-Time Messaging Service) support to the SDK by implementing OAuth token management, RTMS control operations, data persistence, and corresponding API endpoints. Configuration variables and database models are established, OAuth code exchange and token refresh logic is implemented, the RTMS control client is added, and tests and documentation are updated. ChangesZoom RTMS OAuth and Control Integration
Sequence Diagram(s)sequenceDiagram
participant Client
participant OAuthCallback as OAuth Callback Handler
participant OAuthClient as ZoomOAuthClient
participant ZoomOAuth as Zoom OAuth Endpoint
participant Repository as SDKRepository
participant Database as Database
Client->>OAuthCallback: GET /oauth/callback?code=AUTH_CODE
OAuthCallback->>OAuthClient: exchange_code(AUTH_CODE)
OAuthClient->>ZoomOAuth: POST /oauth/token (code grant)
ZoomOAuth-->>OAuthClient: token_payload (access/refresh/expires)
OAuthClient->>Repository: save_zoom_oauth_token(payload)
Repository->>Database: INSERT SDKZoomOAuthToken
Database-->>Repository: token record
Repository-->>OAuthClient: saved token
OAuthClient-->>OAuthCallback: token JSON
OAuthCallback-->>Client: OAuthCallbackResponse (token_stored=true)
sequenceDiagram
participant Client
participant SDKEndpoint as SDK API Endpoint
participant SDK as MeetMindSDK
participant ControlClient as ZoomRTMSControlClient
participant OAuthClient as ZoomOAuthClient
participant ZoomRTMS as Zoom RTMS Endpoint
participant Repository as SDKRepository
Client->>SDKEndpoint: POST /sessions/{id}/rtms/start (participant_user_id?)
SDKEndpoint->>SDKEndpoint: Load session, validate Zoom
SDKEndpoint->>SDK: start_zoom_rtms(session, participant_user_id)
SDK->>ControlClient: start(meeting_id, participant_user_id)
ControlClient->>OAuthClient: get_access_token()
OAuthClient-->>ControlClient: access_token
ControlClient->>ZoomRTMS: POST /status (action, client_id, participant_user_id)
ControlClient->>ControlClient: Authorization Bearer token
ZoomRTMS-->>ControlClient: response (status_code, payload)
ControlClient-->>SDK: result dict (action, meeting_id, code, response)
SDK->>Repository: update_session(rtms_start_requested)
Repository-->>SDK: session updated
SDK-->>SDKEndpoint: control result
SDKEndpoint-->>Client: session + zoom start result
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…to feat/zoom-sdk-integration
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@app/api/v1/routes/zoom_sdk.py`:
- Around line 39-47: The callback handler currently calls
ZoomOAuthClient(db).exchange_code(code) without validating the incoming state;
before calling exchange_code (in the same function handling code: str | None and
state: str | None), fetch the server-stored nonce for this user/session from the
DB (or session store) and compare it to the incoming state, and if they do not
match raise/return an HTTPException (403/400) or otherwise abort the request;
only proceed to call ZoomOAuthClient(db).exchange_code(code) when the state
matches, and ensure any ZoomOAuthError handling remains after this validation.
In `@sdk/models.py`:
- Around line 134-136: The access_token and refresh_token columns are stored
plaintext; change them to store encrypted blobs and perform transparent
encryption/decryption around persistence: replace direct use of
access_token/refresh_token mapped_columns with encrypted storage columns (e.g.,
access_token_encrypted, refresh_token_encrypted) and expose plaintext via
properties or ORM event hooks on the model class (the class containing
access_token/access_refresh_token mapped_columns in sdk/models.py). Implement
and call a central encrypt_token(value) and decrypt_token(value) utility that
uses your KMS/app envelope key before insert/update and after load, and ensure
token_type and any index/unique constraints are preserved; update
create/update/read paths to use the plaintext properties so callers are
unchanged. Ensure null handling for refresh_token and add tests for round-trip
encryption/decryption.
In `@sdk/providers/zoom_rtms/control.py`:
- Around line 61-70: The httpx.post call in Zoom RTMS control (around the block
using self.settings.zoom_api_base_url, meeting_id, access_token and
parse_zoom_response) can raise httpx.RequestError on network failures and is not
currently caught; wrap the httpx.post invocation in a try/except that catches
httpx.RequestError as e and re-raises a ZoomRTMSControlError with the error
details (e.g., raise ZoomRTMSControlError(str(e)) from e) so network errors are
mapped to the same domain error type before you continue to use response and
response_payload.
In `@sdk/providers/zoom_rtms/oauth.py`:
- Around line 24-35: The httpx.post() calls that build OAuth token and revoke
requests (the blocks creating response = httpx.post(...) using
self.settings.zoom_oauth_token_url and the later httpx.post(...) for revoke)
must be wrapped in try/except that catches httpx.RequestError (and subclasses)
and raises ZoomOAuthError with the original exception message; keep the existing
HTTP status_code check after a successful request. Locate the two response =
httpx.post(...) occurrences in oauth.py and surround each with a try: ... except
httpx.RequestError as exc: raise ZoomOAuthError(f"Zoom HTTP transport error:
{exc}") to convert transport-level failures into ZoomOAuthError for consistent
error handling.
In `@sdk/repositories.py`:
- Around line 203-204: The current early-return returns a token when
token.expires_at is None which treats unknown-expiry tokens as usable; change
the conditional around the token variable so that if token is None or
token.expires_at is None the function returns None (not token) so the
caller/refresh logic will treat missing expiry as non-usable and force a
refresh; update the if block that checks "if token is None or token.expires_at
is None:" to return None.
In `@tests/sdk/test_zoom_rtms_control.py`:
- Around line 68-70: The assertion currently hard-codes a specific client_id in
the raw bytes from requests[0].read(), which is brittle; instead, decode and
parse the request body from requests[0].read(), then assert the JSON structure
and that settings.client_id equals the test's actual client id (e.g., the client
id variable used to construct the RTMS control request) or compare against the
value extracted from the request/fixture rather than the literal
"3iMvy78ESDa9JkWUgH3oXg". Locate the assertion on requests[0].read(), replace
the byte-string equality with parsing the body (JSON), assert action=="start"
and settings exists, and assert settings["client_id"] matches the dynamic client
id variable or extracted expected value.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 76aa17b3-c9f1-49db-8694-d2ab466837b9
📒 Files selected for processing (12)
.env.exampleapp/api/v1/routes/sdk.pyapp/api/v1/routes/zoom_sdk.pydocs/sdk/zoom-rtms-sdk-prototype.mdsdk/config.pysdk/models.pysdk/providers/zoom_rtms/control.pysdk/providers/zoom_rtms/oauth.pysdk/repositories.pysdk/schemas.pysdk/sdk.pytests/sdk/test_zoom_rtms_control.py
Description
Adds backend-controlled Zoom RTMS start support so the SDK can request RTMS manually instead of depending only on Zoom auto-start. This includes Zoom OAuth token exchange/storage, RTMS control API integration, and a new session endpoint for starting RTMS on an active Zoom meeting.
Type of Change
feat— New featurefix— Bug fixrefactor— Code refactoring (no functional change)docs— Documentation updatetest— Adding or updating testschore— Maintenance (dependencies, CI, tooling)Related Issue
Closes #
Changes Made
/api/v1/zoom/oauth/callback.sdk_zoom_oauth_tokenstable for storing Zoom access/refresh tokens and expiry metadata.POST /api/v1/sdk/sessions/{session_id}/rtms/startto manually request RTMS start for an active Zoom meeting.Proof of Work
API Response / Screenshots
Test Cases
Test output
make lint # All checks passed!Checklist
Summary by CodeRabbit
New Features
Documentation
Tests