跳到正文
DEV Community· MD. HABIBULLAH SHARIF·· 1 天前AI 評分60

MD. HABIBULLAH SHARIF 用一天推出 WAVault 免費開源 WhatsApp Web 資料匯出擴充功能

They Charge Me to Export My Own WhatsApp Contacts. I Shipped a Free Alternative in One Day 🔓

AI 導讀

MD. HABIBULLAH SHARIF 用一天推出免費開源瀏覽器擴充功能 WAVault,供 WhatsApp Web 和 WhatsApp Business 匯出資料。工具支援聯絡人、羣組成員、包含媒體的完整聊天記錄及狀態匯出。作者表示,資料在本機以唯讀方式處理,沒有伺服器、帳戶或自有網絡請求;工具把 957 條原始聯絡人記錄合併為 633 人。

正文

By Md. Habibullah Sharif — Full-Stack Engineer | CSE, Northern University Bangladesh


633 contacts in my WhatsApp Business account.
The "free" exporters let me take 10.
The other 623 had a price tag.

My own contacts. From my own account. Already loaded in my own browser tab.

And someone wanted a monthly subscription to hand them back to me.


The Paywall

My account had grown the way every long-lived WhatsApp account grows: years of phones, several synced devices, customers, suppliers, groups. 957 raw contact records for 633 actual people. I needed them in a spreadsheet.

WhatsApp has no export button. That part is well known.

So I checked the Chrome Web Store. Pages of exporters, polished icons, confident promises. I tried them one after another, and every one I tried followed the same script:

Free plan: 10 contacts. Some stretch it to 30.
Everything else: upgrade to Premium.

I build backends and data pipelines for a living. I know exactly what sits behind that "Premium" button: the data is already in the page's memory, and serialising it to CSV is a few dozen lines. There is no server cost to cover and no expensive API behind it. The paywall isn't covering a cost. It's a toll on your own data.

That was the part I refused to accept.

I closed the tab and started building. WAVault shipped the same day.


WAVault demo: filtering contacts, loading group members, backing up chats, saving statuses


What You Get, For Nothing

WAVault is a free, open-source browser extension for WhatsApp Web and WhatsApp Business.

No premium tier. No contact limit. No account. No server.

It adds a dashboard to WhatsApp Web with four sections.

1. Contacts, every one of them

One row per real person, merged from the address book, chats and groups. 15 one-click lists:

Saved · Unsaved · Invite list · Chatted · Unread · Read · With username · Without username · Business · Personal · Group members · Hidden number · Blocked

Combine them with Any/Yes/No filters, WhatsApp Business labels and group membership. Search works across scripts (Bangla, Arabic, Hindi, emoji) and across number formats: +44 7700 900123, 07700900123 and 447700900123 resolve to the same person.

Contacts filtered to Business, with filters open and rows selected

2. Group members

The member list of every group you belong to, with roles (Owner, Admin, Member). Excel output gives one sheet per group. This is the feature paid tools tend to lock hardest.

WhatsApp groups with member counts and roles

3. Full chat backup, with media

Whole conversations, loaded page by page, with photos, videos, voice notes and documents decrypted locally. The output is a ZIP with a folder per chat, an index page, and an HTML viewer that reads like WhatsApp itself: bubbles, replies, inline media, search. It opens offline, in any browser, on any machine.

A backed-up chat in the offline HTML viewer

4. Status downloader

Every current status, grouped by contact. Save one, or select many and get a ZIP with a gallery page.

Formats

Format Built for
Excel (.xlsx) Spreadsheets; numbers stored as text so + survives
CSV CRMs and tools; UTF-8 with BOM so non-Latin names render in Excel
Google Contacts CSV Direct import at contacts.google.com
Outlook CSV Outlook and Microsoft 365
vCard 3.0 / 4.0 iPhone, Android, iCloud
JSON Automation
Numbers list / HTML / PDF Quick lists, sharing, printing

The Architecture

WhatsApp Web exposes no public API for any of this. It doesn't need to: the data is already in the tab. The engineering problem is reading it safely, read-only, and without a single byte leaving the machine.

[Launcher tab / toolbar]
        │
        ▼
[Content script — React 19 dashboard inside a Shadow DOM]
        │   window.postMessage RPC (progress events, transferable ArrayBuffers)
        ▼
[Bridge script — injected into the page's main world]
        │   read-only calls
        ▼
[WhatsApp Web's internal modules: contacts, chats, groups, messages, media]
Decision Reason
WXT One codebase, native builds for Chrome, Edge, Brave, Opera, Firefox and Safari
Shadow DOM Full style isolation in both directions
Main-world bridge Content scripts run in an isolated world and can't reach page objects
postMessage RPC Typed requests, streamed progress, cancellation, binary-safe media
Custom .xlsx writer (~130 lines) A spreadsheet library would outweigh the entire extension
fflate Streaming ZIP, so large chat backups don't need the whole archive in memory

Permissions: web.whatsapp.com and storage. Nothing else. No analytics, no telemetry, no remote code.


Five Problems the Paid Tools Don't Talk About

Exporting ten rows is easy. Exporting everything, correctly is where it gets interesting.

1. One person, two identities

WhatsApp now assigns every user a private LID alongside their phone number. The same person can appear as …@c.us and as …@lid, and in many groups members appear only as a LID with the number hidden.

A naive exporter gives you duplicates and calls it a feature. WAVault first builds the full LID ↔ phone map, then folds the address book, chats, group participants and block list into a single record per person.

957 raw records → 633 real people. That number is the difference between a list and a clean list.

2. WhatsApp changes its internals without notice

Mid-build, the function that pages through chat history changed its signature from (chat) to ({ chat, msgCollection, ... }). Users update WhatsApp Web at different times, so both shapes have to work. The resolver tries each and caches the winner:

let loadEarlierStyle = null; // 'object' | 'positional'

async function loadEarlier(loader, chat) {
  const styles = loadEarlierStyle ? [loadEarlierStyle] : ['object', 'positional'];
  let lastError;
  for (const style of styles) {
    try {
      const r = style === 'object'
        ? await loader.loadEarlierMsgs({ chat, msgCollection: chat.msgs })
        : await loader.loadEarlierMsgs(chat);
      loadEarlierStyle = style;
      return r;
    } catch (e) {
      lastError = e;
      if (!(e instanceof TypeError) || loadEarlierStyle) break;
    }
  }
  throw lastError;
}

Every internal access goes through one module with fallbacks. When WhatsApp moves something, WAVault reports which part is unavailable instead of failing silently. That design choice matters more than any single feature.

3. Media decryption expects instrumentation

WhatsApp's media pipeline now requires a performance-logging object on every download. WAVault logs nothing, so it passes a self-returning no-op that satisfies any call chain:

const noopLogger = new Proxy({}, {
  get: (_, key) => (key === 'then' ? undefined : () => noopLogger),
});

The then guard keeps it from being treated as a thenable. Verified against a live account: decrypted size matches the declared size byte for byte, JPEG header ff d8 ff e0.

4. Spreadsheets are hostile to phone numbers

Open a naive CSV in Excel and +447700900123 becomes 4.477E+11. Names in Bangla turn into রহিম. And a contact named =HYPERLINK("http://…") becomes a live formula on someone else's machine.

WAVault writes real .xlsx with numbers as text, adds a UTF-8 BOM to CSV, and neutralises formula injection while leaving genuine phone numbers untouched. Contact data is user-controlled input; it gets treated that way.

5. Your build artifacts can leak what git never saw

Firefox Add-ons requires a sources zip, and build tools zip the project folder by default, including local test output that .gitignore keeps out of the repo. A release built on a developer machine can quietly ship screenshots and logs from real accounts.

WAVault's build excludes every local artifact explicitly. Before release, every published file (git history and all four release zips) was scanned against the 1,111 real phone numbers in my own backup. Zero matches. Every screenshot here uses fictional data from number ranges reserved for film and TV.

💡 For anyone shipping a data tool: .gitignore protects the repo, not the artifact. Run unzip -l on every zip before it goes public.


Is It Safe?

  • Read-only. It never sends messages and never modifies chats, contacts or groups.
  • Local. No server, no account, no network requests of its own.
  • No automation. It reads what your tab has already loaded; it doesn't drive WhatsApp.
  • Auditable. MIT licensed, every line on GitHub.

It is an independent project, not affiliated with WhatsApp or Meta. Use it on your own account.


Install in Two Minutes

  1. Download the zip for your browser from the latest release and unzip it.
  2. Open chrome://extensions (or edge://, brave://), enable Developer mode, click Load unpacked, and select the folder. Firefox: about:debugging → Load Temporary Add-on.
  3. Open web.whatsapp.com and click the WAVault tab on the right edge.

Guides for every feature, including importing into Google Contacts, iPhone, Android and Outlook, are in the docs.

To run it without logging in, there's a demo mode with generated data:

git clone https://github.com/md8-habibullah/wavault-whatsapp-web-backup.git
cd wavault-whatsapp-web-backup
npm ci && npm run preview   # http://127.0.0.1:4789

Why It Stays Free

Your contacts were never a premium feature. They're yours.

Charging people to read data that already sits in their own browser is a business model built on the assumption that users can't see how simple the work behind the paywall is. Now there's a free, open alternative that does more than the paid ones, and anyone can verify every line of it.

WAVault will not get a premium tier. That is the one roadmap item that never changes.


Coming next: Chrome Web Store, Edge and Firefox Add-ons listings, incremental backups, and a Bangla interface. Issues and pull requests are open on GitHub.

If WAVault saved you a subscription, a ⭐ on the repo is how other people find it. And if you've hit the same 10-contact wall, tell me which tool in the comments.

This post was written with AI assistance and edited by me.

來源:DEV Community · dev.to