A dependency-free Manifest V3 Chrome extension that exports your own Facebook / Messenger conversations to JSON, CSV, TXT, or HTML using DOM-only capture.
Install / Usage / Formats / Privacy / Development
Open Chat Archiver runs entirely inside your browser session. It reads only the conversation content already rendered in your own Messenger or Facebook tab, keeps settings in chrome.storage.local, and writes exports through Chrome's Downloads API.
This project is an independent clean-room implementation. It is not affiliated with, endorsed by, or derived from Meta Platforms, Inc. "Facebook" and "Messenger" are used only to describe the sites the extension can read from.
The popup shown mid-capture on messenger.com — 312 messages captured, JSON / CSV / TXT / HTML export ready.
| Surface | Value |
|---|---|
| Status | Pre-1.0 (manifest.json version 0.1.0) |
| Platform | Chrome extension, Manifest V3 |
| Capture model | DOM-only, rendered messages only |
| Export formats | JSON, CSV, TXT, HTML |
| Local storage | chrome.storage.local |
| Permissions | storage, downloads, activeTab, scoped Facebook / Messenger hosts |
| Release flow | Tag-driven GitHub Actions packaging |
| License | MIT |
- Export a captured conversation as JSON, CSV, TXT, or standalone HTML.
- Filter by date range before download without sending data anywhere.
- Use optional paced auto-scroll to load older messages more gently.
- Capture visible reactions and attachment URLs without downloading attachment bytes.
- Keep the extension fully local: no analytics, no feature flags, no remote endpoints, no runtime dependencies.
There is no build step. Load the extension source directly in Chrome.
git clone https://github.com/tyhallcsu/messages-saver-open-source.git
cd messages-saver-open-source- Open
chrome://extensions. - Enable Developer mode.
- Click Load unpacked.
- Select this repository folder.
The repository also includes a tag-driven release workflow in .github/workflows/release.yml. Once a v* tag is pushed, GitHub Actions packages a versioned ZIP and SHA256 checksum for the release page.
- Open a conversation on
https://www.messenger.com/t/<thread>or the full Facebook Messages page athttps://www.facebook.com/messages/t/<thread>. - Click the extension icon and choose Start capture.
- Scroll upward to load older messages, or enable paced auto-scroll in Options.
- Optionally set From and To dates in the popup.
- Choose an export format and click Download export.
The full end-user walkthrough lives in docs/USAGE.md.
| Format | Best for | Sample |
|---|---|---|
| JSON | Archival, scripting, schema-stable exports | sample-conversation.json |
| CSV | Spreadsheets, filtering, diffs | sample-conversation.csv |
| TXT | Readable transcripts | sample-conversation.txt |
| HTML | Standalone viewing and printing | sample-conversation.html |
JSON exports carry the schema string open-chat-archiver/1. The canonical shape is documented in docs/ARCHITECTURE.md and mirrored in sample-data/README.md.
The extension splits work across three contexts:
content.jsreads only the rendered conversation DOM, extracts messages, and maintains the in-tab capture buffer.popup.jslets you start capture, filter by date, and request an export from the active tab.background.jsserializes the filtered messages and hands the result tochrome.downloads.download()as a localdata:URL.
Popup capture flow (left) and an example export of the synthetic Weekend Camping Trip thread (right).
For the fuller data flow, see docs/ARCHITECTURE.md.
- No network egress. The extension does not call
fetch,XMLHttpRequest,WebSocket,navigator.sendBeacon, or any remote script source. - No private API scraping. The content script reads only the DOM already visible in your signed-in browser session.
- No broad permissions. Host permissions are limited to the Facebook / Messenger surfaces needed for capture.
- No attachment downloading. Exports record visible attachment URLs only.
The ground-truth policy lives in PRIVACY.md. Security reporting instructions live in SECURITY.md.
Edit the source files and reload the unpacked extension in Chrome. There is no bundler or build pipeline.
Regenerate icons after changing the icon script:
python3 scripts/generate_icons.pyThe generator uses only the Python standard library — no extra packages.
If you change content.js → extractMessageFromRow() or any serializer in
background.js, sanity-check the output against
sample-data/sample-conversation.json
to confirm the schema still parses.
.github/workflows/ci.yml runs on every push and
pull request to main and verifies:
manifest.jsonandsample-data/sample-conversation.jsonparse as JSON.node --checkpasses for every extension JS file.- Every path declared in
manifest.json(icons, scripts, popup, options, content scripts, web-accessible resources) exists on disk. - Icons on disk match the deterministic output of
scripts/generate_icons.py. - No disallowed network APIs are called from extension code.
host_permissionsdoes not include<all_urls>or wildcard schemes.
.github/workflows/release.yml has three
trigger paths and runs the _validate gate on every one. A failed gate
aborts the publish — you cannot ship an untested zip.
| Trigger | When it fires | What happens |
|---|---|---|
Version bump on main |
A push to main changes manifest.json version |
Auto: detects the bump, validates, creates the matching tag, publishes the release. |
| Tag push | You push a tag matching v*.*.* |
Validates the tag matches manifest.json, builds, publishes. |
| Manual UI | Run via Actions tab → release → Run workflow | Validates, tags (if needed), publishes from the chosen branch. |
The recommended flow is path 1: bump manifest.json version and add a
matching ## [<version>] section to CHANGELOG.md in the same PR. When
the PR merges, the release publishes itself.
# In a PR branch:
# 1. Bump manifest.json "version": "0.1.0" → "0.1.1"
# 2. Add a "## [0.1.1]" section to CHANGELOG.md
# 3. Open a PR, get CI green, squash-merge.
# That's it — release.yml takes over.The CI workflow validates the manifest, sample exports, icon generation, release bundle creation, forbidden network APIs, and host permission scope. See .github/workflows/ci.yml.
manifest.json MV3 manifest and extension metadata
background.js Service worker serializers and download handoff
content.js DOM capture, filtering, and tab-local buffer
popup.* Toolbar popup UI
options.* Options page UI
icons/ Generated extension icons
scripts/ Stdlib-only maintenance scripts
sample-data/ Synthetic example exports
docs/ Architecture and usage notes
Public contributions are welcome as long as they preserve the local-only, dependency-free design. Start with CONTRIBUTING.md.
Maintained by sharmanhall.
Released under the MIT License. See LICENSE.