System Architecture
Meet Transcriber is a single-server Node.js application that orchestrates multiple subsystems: browser automation, audio capture, transcription, and notification delivery.
Module Overview
| Module |
File |
Responsibility |
| Orchestrator |
src/index.js |
Entry point; coordinates all modules, manages PM2 lifecycle |
| Scheduler |
src/scheduler.js |
Browser-based Google Calendar polling via Puppeteer |
| Google Login |
src/google-login.js |
Google auth, session persistence, 2FA backup codes |
| Joiner |
src/joiner.js |
Joins Google Meet using headless Chrome |
| Recorder |
src/recorder.js |
Captures audio via PulseAudio virtual device + FFmpeg |
| Transcriber |
src/transcriber.js |
Sends audio file to OpenAI Whisper API |
| Notifier |
src/notifier.js |
Telegram bot + status API event logging |
| Database |
src/db.js |
SQLite state persistence (meetings, sessions) |
| Config |
src/config.js |
Environment config loader (reads .env) |
| Error Watcher |
src/error-watcher.js |
Monitors PM2 logs for crashes; triggers alerts |
Data Flow
┌─────────────────────────────────────────────────────────────────────────────┐
│ DigitalOcean Server (Ubuntu 24.04) │
│ 104.131.17.141 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────────────────┐ │
│ │ Scheduler │───▶│ Meeting Joiner │───▶│ Audio Recorder │ │
│ │ (Calendar │ │ (Puppeteer + │ │ (PulseAudio + FFmpeg) │ │
│ │ Poller) │ │ Headless Chrome│ │ │ │
│ └──────┬──────┘ └────────┬────────┘ └────────────┬────────────────┘ │
│ │ │ │ │
│ Google Calendar meet.google.com audio.mp3 │
│ (browser scrape) (browser join) (virtual sink) │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────────┐ ┌─────────────────────────────┐ │
│ │ SQLite DB │ │ Notifier │ │ Transcriber │ │
│ │ (state) │ │ (Telegram Bot) │ │ (OpenAI Whisper API) │ │
│ └─────────────┘ └─────────────────┘ └─────────────────────────────┘ │
│ │ │ │
│ └──────────────────────────┘ │
│ Transcript → Telegram │
└─────────────────────────────────────────────────────────────────────────────┘
Step-by-step Flow
- Calendar Poll —
scheduler.js uses Puppeteer to navigate meet.google.com/landing and scan for upcoming meeting cards
- Meeting Detected — when a meeting is found within the join window, the scheduler emits the meeting URL
- Browser Join —
joiner.js navigates to the Meet URL, mutes mic/camera, clicks the join button
- Audio Capture —
recorder.js spawns FFmpeg to record from the PulseAudio virtual sink (which captures Chrome audio output)
- Recording Saved — audio file written to
/root/meet-transcriber/recordings/ as MP3
- Transcription —
transcriber.js sends the MP3 to OpenAI Whisper API; receives transcript text
- Telegram Delivery —
notifier.js sends the transcript (and all status updates) to the configured Telegram bot
- Event Log — every notification is appended to the JSONL event log and visible on the status dashboard
PM2 Processes
| Process |
Description |
meet-transcriber |
Main bot — headless browser, scheduler, recorder, transcriber |
meet-status |
Status API server (port 3456) — dashboard + API |
error-watcher |
Watches PM2 logs for crash patterns; fires alerts |
Infrastructure
| Component |
Details |
| Web server |
Nginx (reverse proxy for status site) |
| SSL |
Let's Encrypt (auto-renews via certbot) |
| Process manager |
PM2 (ecosystem.config.cjs) |
| Storage |
Local filesystem + SQLite |