This example demonstrates how to receive audio, video, screen share, transcript, and chat from a Zoom meeting using RTMS. It logs the received media type without printing the raw media payload.
- Python 3.7 or higher
- A Zoom account with RTMS enabled
- Zoom App credentials (Client ID and Client Secret)
- Zoom Secret Token for webhook validation
- Install the required dependencies:
pip install -r requirements.txt- Create a
.envfile in the same directory with your Zoom credentials:
ZOOM_SECRET_TOKEN=your_secret_token
ZOOM_CLIENT_ID=your_client_id
ZOOM_CLIENT_SECRET=your_client_secret
RTMS_MEDIA_TYPES=audio,video,transcript
RTMS_MEDIA_TYPES accepts audio, video, screenshare, transcript, and
chat. Each selected name opens a separate data connection.
Unified media socket mode and
media_type: 32are deprecated. RTMS clients must open a separate data connection for each required media type and send one concrete media type per handshake.
- Start the server:
gunicorn index:app --bind 0.0.0.0:3000- The server will start on port 3000. You'll need to expose this port to the internet using a tool like ngrok:
ngrok http 3000-
Configure your Zoom App's webhook URL to point to your exposed endpoint (e.g.,
https://your-ngrok-url/webhook) -
Start a Zoom meeting and enable RTMS. The server will receive and print the incoming audio data.
- The server listens for webhook events from Zoom
- When RTMS starts, it establishes WebSocket connections to Zoom's signaling and media servers
- It opens one WebSocket for each selected media type
- The audio/video/transcript msg type is printed to the console
- This is a basic example that checks the msg type and prints the data type received. In a production environment, you would typically process or save this data.
- The server handles both signaling and media WebSocket connections
- Keep-alive messages are automatically responded to maintain the connection
The project runs the Python webhook-based RTMS boilerplate. Its multi-stage Dockerfile keeps build tooling out of the final runtime image and does not hard-code a CPU architecture.
Build and run it from the rtms-samples repository root:
docker build -f boilerplate/working_python/Dockerfile -t rtms-boilerplate-working_python .
docker run --rm --env-file boilerplate/working_python/.env -p 3000:3000 rtms-boilerplate-working_pythonRun the build from the repository root because the Dockerfile uses repository-relative paths. Runtime secrets are supplied with --env-file and are excluded from the image build context.
Normal Zoom webhook deliveries are verified against the exact raw request body using
x-zm-signature and x-zm-request-timestamp. Configure ZOOM_SECRET_TOKEN with the
Marketplace app's webhook Secret Token. Requests with missing, invalid, or stale
signatures are rejected; the default replay window is 300 seconds and can be changed
with WEBHOOK_TIMESTAMP_TOLERANCE_SECONDS.