← All projects
SoftwareNode.jsSQLiteAutomationDockerCompleted

WhatsApp Logger — Headless Message Archiver

A headless Node.js service that connects to WhatsApp Web and logs message metadata, text, and media attachments to a local SQLite database, with a browser-based dashboard to search and browse everything.

March 5, 2026


Overview

I needed a reliable way to archive WhatsApp messages and media from specific chats — searchable, self-hosted, and running without a GUI. WhatsApp Logger connects to WhatsApp Web via a headless Chromium session, monitors the chats you select, and writes everything to a local SQLite database. Media attachments are downloaded automatically and served back through the web UI.

No raw protocol buffers are ever stored — only the fields that matter.

How It Works

On first run, a QR code appears in the terminal (or on a browser page if you're running it remotely). Scan it once with your phone and the session persists via LocalAuth. From there the service runs silently, logging every new message in the monitored chats.

You pick which chats to monitor through a two-column browser UI or via CLI commands — no need to touch the terminal once it's running.

What Gets Logged

For each message in a monitored chat:

  • Sender name and JID (including individual members in group chats)
  • Message body text
  • Timestamp, direction (inbound/outbound), delivery/read receipt status
  • Media attachments — images, audio, video, and documents are downloaded and stored locally; the dashboard shows thumbnails, audio players, and download links inline

Web UI

Three pages, all token-authenticated:

PagePurpose
/Dashboard — browse, filter, and search all logged messages with inline media previews
/monitor.htmlAdd or remove monitored chats from a two-column UI
/qr-scan.htmlPair or re-pair your phone remotely without terminal access

The dashboard is fully mobile-responsive — slide-in chat drawer, collapsible filter panel, card layout on small screens.

Filtering and Search

Messages are filterable by chat, direction, message type, date range, and full-text search across body and sender name. Pagination is built in (default 50 per page, max 500).

Reliability

  • Reconnect guard — exponential backoff, only one reconnect sequence at a time
  • Crash recovery — Chromium is properly destroyed on startup failure to prevent lock-file loops
  • Fire-and-forget media downloads — never block message processing; failures are logged at WARN and the row stays queryable
  • Auto-migrations — schema changes apply on startup, tracked in a _migrations table

Stack

ComponentTechnology
RuntimeNode.js 18+, TypeScript
WhatsAppwhatsapp-web.js (LocalAuth, Puppeteer/Chromium)
DatabaseSQLite via better-sqlite3
Web UIExpress + vanilla HTML/JS
Loggingpino (pretty in dev, JSON in production)
PackagingDocker Compose, PM2

Deployment

Runs anywhere Node.js does — bare metal, Docker, or PM2 on a VPS. The Docker image uses a system Chromium and mounts a single volume for the auth session, database, and all media files. Under PM2, --restart-delay=3000 gives Chromium enough time to exit cleanly between restarts.