Skip to content

Latest commit

 

History

History

manual_start_stop_using_js

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

readme.md

Zoom RTMS Realtime Media Streaming Service

This Node.js application demonstrates how to manually start and stop Zoom's Realtime Media Streaming (RTMS).

Project Overview

  • Listens for Zoom webhook events related to RTMS.
  • Connects to signaling and media WebSocket servers.
  • Captures and processes realtime transcript data.
  • Supports multiple media types: audio, video, transcript, and chat.
  • Includes automatic RTMS stop functionality after a configurable duration.

Environment Variables

Create a .env file with the following keys:

ZOOM_CLIENT_ID=your_zoom_client_id
ZOOM_CLIENT_SECRET=your_zoom_client_secret
WEBHOOK_PATH=/webhook
access_token=your_zoom_access_token
PORT=3000
# Optional: start/stop RTMS for a specific invitee already in the meeting.
# Omit to use the user represented by access_token.
RTMS_PARTICIPANT_USER_ID=zoom_user_id

Features

  • Validates Zoom webhook events for meeting lifecycle.
  • WebSocket handshakes secured with HMAC SHA256 signatures.
  • Realtime transcript stream capture from Zoom meetings.
  • Automatic RTMS stop scheduling after 10 seconds (configurable).
  • Handles keep-alive requests and maintains connection health.
  • Automatically cleans up connections when meetings end.
  • Optionally targets a specific joined invitee with RTMS_PARTICIPANT_USER_ID.

Endpoints

  • POST /webhook – Handles Zoom RTMS webhook events.

Webhook Events Handled

  • meeting.started – Initiates RTMS start and schedules automatic stop
  • meeting.rtms_started – Connects to signaling WebSocket
  • meeting.rtms_stopped – Logs meeting stop event

How It Works

Step 1: Webhook Receiver

The application listens for Zoom webhook events on /webhook endpoint.

Step 2: Meeting Started Event

When meeting.started is received:

  • Step 2a: Listen to meeting started event
  • Step 2b: Get access token from environment. To implement complete logicfor authorization, please visit here
  • Step 2c: Make API call to start RTMS using the meeting ID from the webhook.

If RTMS_PARTICIPANT_USER_ID is set, the request includes settings.participant_user_id. The participant must be an invitee who has already joined the meeting. Without it, Zoom uses the user represented by the access token.

Step 3: RTMS Started Event

When meeting.rtms_started is received, the application connects to Zoom's signaling WebSocket.

Step 4: Generate Signature

Creates HMAC SHA256 signature for authentication handshake using client ID, meeting UUID, and stream ID.

Step 5: WebSocket 1 - Signaling Connection

  • Connects to Zoom's signaling WebSocket server
  • Sends handshake request with meeting details and signature
  • Receives media server URL upon successful handshake

Step 6: WebSocket 2 - Media Connection

  • Connects to media WebSocket server
  • Sends media handshake requesting transcript stream
  • Receives and processes real-time transcript data

Step 7: Stop RTMS

Automatically stops RTMS after 10 seconds using Zoom API.

Message Types Handled

  • msg_type: 1 – HANDSHAKE_REQUEST
  • msg_type: 2 – HANDSHAKE_RESPONSE
  • msg_type: 3 – MEDIA_HANDSHAKE_REQUEST
  • msg_type: 4 – MEDIA_HANDSHAKE_RESPONSE
  • msg_type: 5 – TRANSCRIPT_DATA
  • msg_type: 7 – CLIENT_READY_ACK
  • msg_type: 12 – KEEP_ALIVE_REQUEST
  • msg_type: 13 – KEEP_ALIVE_RESPONSE

The REST start/stop request uses PATCH /live_meetings/{meetingId}/rtms_app/status. The access token needs the appropriate RTMS status scope, such as meeting:write or the corresponding admin/participant granular scope.

Prerequisites

  • Node.js v14 or higher
  • A valid Zoom App with webhook events and meeting and RTMS scopes.
  • Ngrok or another tunneling service for public webhook exposure

Installation

npm install

Running the Server

node rtms.js

The server will start on port 3000 and listen for webhook events.

Notes

  • RTMS is automatically stopped after 10 seconds to demo the stop action of the API
  • All WebSocket connections are properly closed when meetings end
  • Transcript data is logged to console for debugging

Webhook Delivery Authentication

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.