Overview

Zoom to Google Drive Transfer

Automated pipeline that downloads Zoom recordings, converts VTT transcripts to Google Docs, and smart-names files using Google Calendar event matching. One command, all recordings transferred.

280
Recordings Transferred
92.9%
Calendar Match Rate
13 mo
Jan 2025 — Feb 2026

What It Does

  • Downloads all Zoom cloud recordings
  • Converts VTT transcripts to Google Docs
  • Smart-names files from Google Calendar
  • Organizes by year/month folders
  • Logs every transfer to a spreadsheet
  • Handles Zoom's 30-day API pagination

Key Files

File Structure
zoom_to_drive.pyMain orchestrator
zoom_client.pyZoom API wrapper
gdrive_client.pyGoogle Drive + Docs API
naming_engine.py3-tier smart naming
naming_rules.jsonTime-based naming rules
state_manager.pyTransfer state tracking
💡
Fully automated: Run python zoom_to_drive.py and it handles everything — API pagination, file downloads, naming, Google Drive upload, transcript conversion, and logging.
Pipeline

Transfer Pipeline

End-to-end flow from Zoom cloud storage to organized Google Drive folders. Each recording goes through naming, download, and upload stages.

Pipeline Flow

Zoom APIList recordings
Smart NameCalendar lookup
DownloadMP4 + VTT
UploadGoogle Drive
ConvertVTT → Google Doc
LogTransfer sheet

Per-Recording Steps

  1. Check state Skip if already transferred (state_manager tracks by meeting UUID + file type)
  2. Determine smart name 3-tier naming: Calendar match → Time rules → Zoom topic fallback
  3. Create folder structure Year/Month folders created on demand (e.g., Zoom Recordings/2026/02 - February)
  4. Download from Zoom MP4 video + VTT transcript (if available). Uses download_url with access_token.
  5. Upload to Google Drive Resumable upload for large files. Sets file name to smart name.
  6. Convert VTT transcript Parse VTT, strip timestamps, format as readable text, create Google Doc.
  7. Log transfer Append row to Transfer Log spreadsheet with date, name, source, status.
⚠️
Resumability: If the script is interrupted, re-running it skips already-transferred files. The state manager persists progress to a local JSON file.
Intelligence

Smart Naming (3 Tiers)

The naming engine uses a 3-tier fallback system to give each recording a meaningful name instead of Zoom's default UUID-based filenames.

Tier 1: Google Calendar Match (92.9%)

Looks up the recording's start time against Google Calendar events. If a calendar event overlaps the Zoom meeting time window, uses the event title as the file name.

Example: Zoom meeting at 2:00 PM → Calendar event "Client Call - GloboTech" at 2:00-2:30 PM → File named 2026-02-15 - Client Call - GloboTech.mp4

Tier 2: Time-Based Rules (4.8%)

When no calendar match is found, falls back to naming_rules.json. Rules map time windows and days to recurring meeting names.

{ "rules": [ { "name": "Morning Standup", "days": ["Monday", "Wednesday", "Friday"], "time_start": "09:00", "time_end": "09:30" }, { "name": "Weekly Team Sync", "days": ["Tuesday"], "time_start": "14:00", "time_end": "15:00" } ] }

Tier 3: Zoom Topic Fallback (2.3%)

Last resort: uses the Zoom meeting topic as the file name. This is Zoom's default meeting name (e.g., "Shane's Personal Meeting Room" or "Quick Sync").

⚠️
Common issue: Generic topics like "Zoom Meeting" or "Personal Meeting Room" are not descriptive. Consider adding a naming rule for recurring time slots to avoid this tier.

Naming Tier Stats (280 recordings)

Naming Source Distribution
Tier 1 — Calendar 260 recordings 92.9% Primary
Tier 2 — Time Rules 13 recordings 4.8% Fallback
Tier 3 — Zoom Topic 7 recordings 2.3% Last Resort
API

Zoom API Handling

Zoom's API limits recording list queries to 30-day windows. The pipeline chunks date ranges automatically and handles pagination, rate limits, and auth token refresh.

30-Day Chunking

Start DateJan 1, 2025
Chunk 1Jan 1-30
Chunk 2Jan 31 - Mar 1
...Auto-chunked
End DateFeb 28, 2026

13 months = ~14 API chunks, each ≤ 30 days

API Configuration

Zoom API Settings
AuthServer-to-Server OAuth (JWT deprecated)
Max range30 days per request
Page size300 recordings per page
Rate limit10 requests/second (heavy)
Download URLsRequire access_token param
Token TTL1 hour, auto-refreshed

Error Handling

  • 401 Unauthorized: Auto-refresh OAuth token and retry
  • 429 Rate Limited: Exponential backoff (1s, 2s, 4s, 8s)
  • 404 Not Found: Recording expired or deleted — skip and log
  • 500 Server Error: Retry up to 3 times with 5s delay
  • Download timeout: 5-minute timeout for large files, retry once
🚨
Zoom recording retention: Cloud recordings are auto-deleted after 30 days on free/pro plans. Run transfers regularly to avoid losing recordings. The pipeline tracks the last successful run date to start from there.
Integration

Google Drive Integration

Recordings are uploaded to an organized folder structure. VTT transcripts are converted to searchable Google Docs. Uses Google Drive API v3 and Google Docs API.

Folder Structure

Zoom Recordings/ 2025/ 01 - January/ 2025-01-15 - Client Onboarding Call.mp4 2025-01-15 - Client Onboarding Call (Transcript).gdoc 2025-01-22 - Team Planning Session.mp4 02 - February/ ... 2026/ 01 - January/ ... 02 - February/ 2026-02-15 - Client Call - GloboTech.mp4 2026-02-15 - Client Call - GloboTech (Transcript).gdoc

Upload Process

  1. Check/create year foldere.g., "2026"
  2. Check/create month foldere.g., "02 - February"
  3. Resumable uploadLarge files use resumable protocol
  4. Set metadataName, MIME type, parent folder

VTT Transcript Conversion

  1. Parse VTT fileExtract text, strip timestamps and metadata
  2. Format contentClean paragraphs with speaker labels
  3. Create Google DocUpload as Google Docs MIME type
  4. Name with "(Transcript)"Same smart name + suffix

Google API Authentication

Auth Configuration
credentials.jsonOAuth client credentials (from Google Cloud Console)
token.jsonAuto-generated refresh token (persisted between runs)
Scopesdrive.file + docs + calendar.readonly
Project ID851550492652 (shared with Accounting tools)
Tracking

Transfer Log

Every transfer is logged to a Google Sheets spreadsheet for auditing and tracking. Includes source details, naming tier used, and transfer status.

Log Columns

Transfer Log Spreadsheet
Transfer DateWhen the transfer was executedDate
Meeting DateOriginal Zoom meeting date/timeDate
Original NameZoom's default file name (UUID-based)Text
Smart NameFinal name assigned by naming engineText
Naming TierWhich tier was used: Calendar / Rules / TopicCategory
File TypeMP4, VTT, M4A (audio-only), etc.Text
File SizeSize in MBNumber
DurationMeeting duration in minutesNumber
Drive LinkDirect link to uploaded file in Google DriveURL
StatusSuccess, Skipped, or Error (with reason)Status
💡
State vs Log: The state_manager.py tracks which files have been processed (local JSON). The Transfer Log spreadsheet is the audit trail (cloud). Both are updated together, but the state file is what prevents duplicate transfers.
Quick Start

Quick Start Guide

Get up and running with the Zoom to Google Drive transfer pipeline.

Prerequisites

  • Python 3.10+
  • Zoom Server-to-Server OAuth app (in .env)
  • Google Cloud project with Drive, Docs, Calendar APIs enabled
  • credentials.json from Google Cloud Console

Setup Steps

  1. Install dependencies pip install -r requirements.txt
  2. Configure .env Set ZOOM_ACCOUNT_ID, ZOOM_CLIENT_ID, ZOOM_CLIENT_SECRET
  3. Place credentials.json Google OAuth client credentials in the project root
  4. First run (auth flow) python zoom_to_drive.py — opens browser for Google OAuth consent on first run
  5. Subsequent runs Same command. Picks up from last transfer, skips already-done files.

Common Commands

# Transfer all recordings (from last checkpoint) python zoom_to_drive.py # Transfer specific date range python zoom_to_drive.py --from 2026-01-01 --to 2026-02-28 # Dry run (list what would transfer, no downloads) python zoom_to_drive.py --dry-run # Force re-transfer (ignore state file) python zoom_to_drive.py --force

DO

  • Run transfers regularly (Zoom deletes cloud recordings)
  • Add naming rules for recurring meetings
  • Keep credentials.json and token.json gitignored
  • Use --dry-run before large batch transfers
  • Check the Transfer Log for any Error status rows

DON'T

  • Don't delete the state file unless you want full re-transfer
  • Don't share credentials.json or token.json
  • Don't run multiple instances simultaneously (state conflicts)
  • Don't exceed Zoom API rate limits (10 req/s)
  • Don't manually rename files in Drive (breaks dedup)
🎉
Walkthrough complete! You now understand the full Zoom to Google Drive pipeline — from API chunking and smart naming through upload, transcript conversion, and logging. 280 recordings and counting.