A professional, offline recovery and export tool for the native Telegram for macOS app (not the cross‑platform Telegram Desktop/Qt app). It decrypts the local db_sqlite using .tempkeyEncrypted and produces a clean, readable transcript in HTML, Markdown, or CSV.
- Overview
- Motivation & Use Case
- Key Features
- What It Does
- Requirements
- Installation
- Quick Start
- Common Workflows
- CLI Reference
- Example Output
- Key Paths (macOS)
- Safety & Privacy
- Limitations
- FAQ
- Versioning
- Updating
- Quality Checks
- Project Structure
- Credits
- Contributing
- License
Telegram for macOS stores messages locally in an encrypted SQLite database. This tool decrypts the local database, parses Telegram’s Postbox structure, and exports a clean transcript that a non‑technical user can read.
It is designed for offline recovery on a Mac where the local cache still exists and has not yet synced a deletion.
Compatibility note: this targets the native Telegram for macOS app (macos.telegram.org / Homebrew cask telegram). The cross‑platform Telegram Desktop (Qt) app uses a different storage layout.
Telegram does not provide server‑side recovery for deleted chats. In scenarios like accidental deletion, device loss, or audit requirements, the only remaining source of truth can be the local encrypted cache on a macOS device.
This project was created after a family conversation was removed with no way to restore it via Telegram’s servers. The local Mac still had the encrypted cache, so this tool was built to recover what remained locally and convert it into a clean, shareable export.
- 🔐 Offline decryption using Telegram’s local key format (dbKey + dbSalt)
- 🧾 Human‑readable exports with names, timestamps, and link handling
- ✨ Modern HTML transcript with date jump + back‑to‑top
- 📊 CSV export for analysis or spreadsheets
- ⏱️ Date filters for targeted ranges
- 🧭 Best‑effort peer mapping for clean names
- Decrypts
db_sqliteusing.tempkeyEncrypted - Extracts messages from the Postbox store
- Outputs HTML, Markdown, or CSV transcripts
- Supports date filtering and peer‑specific exports
What it does not do:
- Restore chats back into Telegram
- Recover media that was never downloaded/cached locally
- Bypass Telegram passcode without the passcode
- macOS with Telegram for macOS data present (native app)
- Python 3.10 or higher (tested on 3.11–3.13)
- Virtual environment recommended
python3 -m venv .venv
source .venv/bin/activate
pip install -e .If you prefer a requirements file:
pip install -r requirements.txtInstall from GitHub (latest):
pip install -U "git+https://github.com/soakes/telegram-message-exporter.git"Clone from GitHub:
git clone https://github.com/soakes/telegram-message-exporter.git
cd telegram-message-exporter
pip install -e .telegram-exporter decrypt \
--key ~/Library/Group\ Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/.tempkeyEncrypted \
--db ~/Library/Group\ Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/account-*/postbox/db/db_sqlite \
--out plaintext.dbIf Passcode Lock is enabled:
TG_LOCAL_PASSCODE="your-passcode" \
telegram-exporter decrypt --key <key> --db <db> --out plaintext.dbtelegram-exporter list-peers --db plaintext.db --search "Alex"telegram-exporter export \
--db plaintext.db \
--peer-id 123456789 \
--me-name "Me" \
--format html \
--out chat_export.htmlExport HTML for a specific chat:
telegram-exporter export --db plaintext.db --peer-id 123456789 --format html --me-name "Me" --out chat_export.htmlExport a date range:
telegram-exporter export \
--db plaintext.db \
--peer-id 123456789 \
--start-date 2024-01-01 \
--end-date 2024-12-31 \
--format html \
--out chat_2024.htmlDebug decryption profile selection:
telegram-exporter decrypt --key <key> --db <db> --out plaintext.db --debugExport all chats (large output):
telegram-exporter export --db plaintext.db --format html --out all_chats.html| Command | Purpose |
|---|---|
decrypt |
Decrypt db_sqlite to a plaintext SQLite file |
diagnose |
Inspect tables and sample rows |
list-peers |
Find peer IDs by name fragment |
export |
Export messages to HTML/Markdown/CSV |
Common flags:
--dbPath to plaintext DB--keyPath to.tempkeyEncrypted--peer-idPeer to export--formathtml,md, orcsv--start-date/--end-dateDate filtering--me-nameLabel for outgoing messages--debugExtra diagnostics (decrypt)
<header class="glass header-panel">
<div class="brand">
<div class="logo">💬</div>
<div class="title-area">
<h1>Alex Example</h1>
<p class="subtitle">Recovery export for Telegram for macOS</p>
</div>
</div>
<div class="badge glass"><span class="dot"></span><span class="text">Ready</span></div>
</header># Telegram Chat History: Alex Example
**Exported:** 2026-02-04 16:05:12
**Total Messages:** 418
## Wednesday, February 04, 2026
**14:13:09 — Me**
3h48 is good alsodate,time,timestamp,direction,speaker,text,peer_id,author_id
2026-02-04,14:13:09,1770214389,out,Me,"3h48 is good also",123456789,123456789Telegram for macOS stores its data here:
~/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/.../account-*/postbox/db/db_sqlite.../stable/.tempkeyEncrypted
Media cache (if downloaded):
.../account-*/files/
- 🔌 Keep the Mac offline during recovery to avoid sync deletions
- 🧊 Media is only recoverable if it was cached locally
- 🧪 If decryption fails, retry with
--debugand verify key path
- 🔒 Requires the local passcode if Passcode Lock is enabled
- ☁️ Cannot restore or re‑upload chats to Telegram servers
- 🗂️ Attachments only appear if they were previously cached on the Mac
- 🧩 Some newer Telegram message types may not fully decode
Can this restore the chat inside Telegram?
No. This tool exports a transcript; it does not re‑insert messages back into Telegram.
Why do I only see some attachments?
Only files that were downloaded and cached locally can be recovered.
What if I get “file is not a database”?
The key and DB are mismatched, or Passcode Lock is enabled without the passcode.
Does it work with Telegram Desktop (Qt) or mobile backups?
No. This targets the native Telegram for macOS app and its local storage layout.
The canonical version is stored in VERSION and exposed via:
telegram-exporter --versionVersion bump helper:
./scripts/bump_version.py patch
./scripts/bump_version.py minor
./scripts/bump_version.py major
./scripts/bump_version.py --set 1.2.3If installed from GitHub:
pip install -U "git+https://github.com/soakes/telegram-message-exporter.git"If installed from a local clone:
git pull
pip install -e .black src/telegram_message_exporter telegram_exporter.py scripts/bump_version.py
ruff check src/telegram_message_exporter telegram_exporter.py scripts/bump_version.py
pylint src/telegram_message_exporter telegram_exporter.pytelegram-message-exporter/
├── pyproject.toml # Packaging metadata + CLI entrypoint
├── telegram_exporter.py # Convenience wrapper (no install)
├── scripts/
│ └── bump_version.py # Version helper
├── src/
│ └── telegram_message_exporter/
│ ├── __init__.py # Package entrypoint
│ ├── __main__.py # python -m entrypoint
│ ├── cli.py # Argument parsing + commands
│ ├── crypto.py # SQLCipher + tempkey handling
│ ├── db.py # DB heuristics + message extraction
│ ├── exporters.py # HTML / Markdown / CSV
│ ├── postbox.py # Postbox parsing utilities
│ ├── models.py # Message data model
│ ├── utils.py # Date + link helpers
│ └── hashing.py # Murmur3 helper
├── requirements.txt # Python dependencies
└── README.md
This project builds on community reverse‑engineering work. Special thanks to @stek29 for the original research and reference implementation of Telegram for macOS local key format and Postbox structure. This tool extends those ideas into a polished, end‑user‑friendly CLI and export workflow.
For enhancements or alternate export styles, feel free to open a PR (or fork and submit one). We’ll review and merge solid improvements—this repo is meant to be a good base to build on.
This project is licensed under the MIT License. See LICENSE for details.