Files
ghostwire/docs/CLI.md
T

9.5 KiB

WhatsApp test suite

Portable single-file bundle

Copy whatsapp.py to another writable folder. That one Python file includes all tools, the native helpers and the regression fixtures. No adjacent source package, DLLs, C++ compiler or build script is needed to run it.

python whatsapp.py --help
python whatsapp.py test
python whatsapp.py live --suite history-read
python whatsapp.py contacts-export --output contacts.json
python whatsapp.py export-zip --output messages.zip
python whatsapp.py send-self

The bundle compresses the original modules and resources together with LZMA. It verifies its embedded payload and imports Python modules directly from memory. Only a native helper needed for a live command is materialized in a hash-verified cache beside the bundle. Keep the containing folder writable. Native helper bytes, native object checks, batch sizes and message read/send paths are unchanged.

Core WebView commands use the standard library. Python 3.11+, Windows x64, 64-bit Python are required for live Desktop operations. Other Desktop versions are attempted with a compatibility warning; only the recorded version was tested. Optional legacy CDP, Frida and QR tools retain the packages listed below. Node.js remains optional for JavaScript fixture tests.

The development package below remains the editable source. Rebuild the generated single-file distribution after changing it:

python build_whatsapp_bundle.py

The build is deterministic and records size and SHA-256 in analysis/whatsapp-suite/bundle-build.json. The build file is not needed on a machine running the bundle.

The WhatsApp scripts are consolidated in whatsapp_suite/, with one CLI and offline regression tests in tests/. Run commands from this workspace.

python -m whatsapp_suite
python -m whatsapp_suite --help
python -m whatsapp_suite test --output analysis/whatsapp-suite/results.json

python whatsapp_tests.py is an equivalent entry point. The default run uses fixtures and temporary files. It verifies saved-export parsing, Unicode search, chat filtering, text redaction, history pagination/decryption contracts, fixed probe responses, command dispatch, and bundled DLL hashes. Node.js runs the JavaScript history fixtures; that test is reported as skipped if Node is absent. Python 3.11 or newer is required.

To test an already running WhatsApp Desktop installation:

python -m whatsapp_suite test --live
python -m whatsapp_suite test --capabilities
python -m whatsapp_suite live --suite math
python -m whatsapp_suite live --suite capabilities
python -m whatsapp_suite live --suite history-read --output analysis/whatsapp-suite/js-history-read.json
python -m whatsapp_suite export-zip --output exports/whatsapp-messages.zip
python -m whatsapp_suite contacts-export --output exports/contacts.json
python -m whatsapp_suite send-self

Live WebView probes require Windows x64 and 64-bit Python. Desktop build 2.2639.100.0 and its recorded WebView2 Core DLL were tested. Other versions or DLL hashes produce a warning and are attempted. The helper discovers function and vtable locations from binary fingerprints and checks native objects and methods before executing JavaScript; changed layouts can cause failure or process instability. The JSON report includes detected/tested compatibility metadata and cleanup status. --pid selects a Desktop host.

Tools

Every command supports --help for its options.

Command Purpose
inventory List local Desktop storage files and sizes
stats EXPORT Summarize a saved JSON or JSONL export
search EXPORT QUERY Unicode-aware literal search of saved messages
desktop-search QUERY Bounded native app search through WebView2; metadata output
live --suite math|capabilities|all Fixed live WebView test suites
live --suite message-json|contacts Explicit fixed message search/contact sample; saves private data
live --suite history-read Read the five oldest local message records through the JS database getter and decoder, without CDP
webview-test Arithmetic check in a separate WebView2 host; may download its SDK
analyze Storage analysis, optionally using an existing loopback CDP endpoint
history-export Export local history through Desktop's own database decryption
export-zip Export all local message rows to ZIP through JavaScript on WebView, without CDP or UI automation
webhook Install/status/stop, direct HTTPS or loopback relay, ensure/auto-restore and optional watch/serve; see webhook guide
contacts-export Export all local contact rows to JSON through the app's JS database getter
send-self Send one fixed test message to the signed-in account itself and verify stored plaintext
ram-read Read loaded V8 message objects from process memory
ram-search QUERY Search RAM models with verified collection membership
native-search [QUERY] Experimental injected SQLite search, --oldest --limit 5, or --export-index
qr-memory Recover candidate Desktop pairing QR payloads from RAM
qr-window Save an already displayed Desktop linking QR
pairing Start an isolated browser and request an official linking QR
python -m whatsapp_suite search export.jsonl "keyword" --redact-text
python -m whatsapp_suite desktop-search "keyword" --limit 10
python -m whatsapp_suite history-export --help

history-read uses the native WebView bridge to execute JavaScript in the running app. It scans at most 100,000 local record timestamps in a read-only transaction, then calls WAWebSchemaMessage.getMessageTable().get and WAWebDBMessageSerialization.messageFromDbRow for the five oldest records. It saves decoded body/caption text when present, including messages absent from the loaded conversation models. System events and media-only records can have no text. The live result includes page-state and native bridge cleanup status. This command requires neither CDP nor optional Python packages.

export-zip uses the same native bridge and the app's JavaScript database getter and decoder. It paginates all local rows up to the initial upper primary key, streams them into messages.jsonl, and includes a manifest.json with row counts, decoding errors, scope, and bridge cleanup status. Rows include message IDs, chat IDs, timestamps, types, body and caption text; media files are not downloaded. This is a live scan, not an atomic database snapshot. Row decoding failures are preserved as error records and make the command return a failure status. --batch-size controls bounded reads (default 100); --redact-text omits body and caption text. Existing outputs are refused. Interrupted exports retain a .zip.partial file and a .zip.report.json diagnostic report. A completed ZIP is checked for CRC errors before publication.

contacts-export reads the local contact table rather than the five-contact loaded-model sample. It exports selected identity, name, phone and business fields. Local records can include separate PN/LID entries and contacts outside the phone address book; this is not a deduplicated phone address-book export.

send-self resolves the signed-in account and checks both the selected chat and outgoing message recipient before invoking the app's text-send action. It sends one identifiable test message and reads it back through the message database decoder, recording ACK and exact plaintext equality in a receipt. An existing receipt is refused and sending is never retried automatically. Unlike the offline test suite, this command actually sends a WhatsApp message.

The separate bulk history-export command requires an existing Desktop CDP endpoint. RAM tools only see loaded objects and cannot retrieve all history. Pairing commands are separate from the automated test run. The runtime module preserves the explicit temporary CDP context manager for research scripts; entering that context restarts Desktop and is never part of the default tests.

Optional dependencies

The default suite, saved-export tools, and native WebView probes need only the Python standard library (plus Node.js for the history fixture test).

Tools Additional Python packages
CDP analysis and history export websockets
Injected SQLite search frida
QR from RAM qrcode[pil]
QR from Desktop window Pillow, zxing-cpp
Isolated browser pairing websockets, qrcode[pil]; installed Chrome

Install all optional packages into a virtual environment with:

python -m pip install -r requirements-whatsapp-optional.txt

Layout and migration

  • whatsapp_suite/: canonical tool implementations, common normalization, storage paths, Desktop discovery, CLI, and test runner.
  • whatsapp_suite/assets/: verified native DLLs and the native SQLite agent.
  • tests/: synthetic Python regressions and the JavaScript history fixture.
  • analysis/whatsapp-suite/results.json: latest automated test result.

The former whatsapp_tool.py commands now use python -m whatsapp_suite; whatsapp-search is named desktop-search, and whatsapp-test is live --suite math. The former whatsapp_math.py options are available under live. Archived scripts have become package modules; the identical Desktop QR RAM scripts have one implementation (qr_memory). Research helpers now import these modules. Old script archive and portable script copies were removed. The clean Git project excludes research reports, extracted application code and browser profiles. The surrounding original workspace retains those local files.