soakes/telegram-message-exporter

GitHub: soakes/telegram-message-exporter

专为 macOS 原生 Telegram 客户端设计的离线消息恢复与导出工具,解密本地 SQLCipher 数据库并将聊天记录输出为 HTML、Markdown 或 CSV 格式。

Stars: 18 | Forks: 0

# 💬 Telegram for macOS 消息导出工具 [![CI](https://img.shields.io/github/actions/workflow/status/soakes/telegram-message-exporter/ci.yml?branch=main&style=flat-square&label=ci)](https://github.com/soakes/telegram-message-exporter/actions/workflows/ci.yml) [![Python](https://img.shields.io/badge/Python-3.10%2B-3776AB.svg?style=flat-square&logo=python&logoColor=white)](https://www.python.org/downloads/) [![平台](https://img.shields.io/badge/platform-macOS-111111.svg?style=flat-square&logo=apple&logoColor=white)](#requirements) [![Telegram](https://img.shields.io/badge/Telegram-native%20macOS-2CA5E0.svg?style=flat-square&logo=telegram&logoColor=white)](https://macos.telegram.org/) [![许可证](https://img.shields.io/badge/License-MIT-2EA043.svg?style=flat-square)](LICENSE) [![Black](https://img.shields.io/badge/style-black-000000.svg?style=flat-square)](https://black.readthedocs.io/) [![Ruff](https://img.shields.io/badge/lint-ruff-46A3FF.svg?style=flat-square)](https://docs.astral.sh/ruff/) [![Pylint](https://img.shields.io/badge/lint-pylint-FFCD00.svg?style=flat-square)](https://pylint.readthedocs.io/) 专为以下恢复场景构建:当 Telegram 对话仅存的最后副本是 Mac 上的加密本地缓存时。该工具会解密本地 `db_sqlite`,充分解析 Telegram 的 Postbox 存储以查找对话者和消息,然后将可读的聊天记录输出为 HTML、Markdown 或 CSV 格式。 本项目针对的是来自 [macos.telegram.org](https://macos.telegram.org/) 或 Homebrew `telegram` cask 的**原生 Telegram for macOS 应用**。它**不**适用于跨平台的 Telegram Desktop/Qt 应用、iOS 备份、Android 备份、Mac App Store 版本或 Telegram 云端导出格式。 **快速链接:** [🚀 快速开始](#quick-start) · [🔄 工作原理](#how-it-works) · [🧪 用法](#usage) · [🧰 CLI 参考](#cli-reference) · [🩺 故障排除](#troubleshooting) · [🙏 致谢](#credits) ## 🧭 目录 - [📖 概述](#overview) - [✨ 功能特性](#capabilities) - [🔄 工作原理](#how-it-works) - [✅ 系统要求](#requirements) - [🚀 快速开始](#quick-start) - [🧪 用法](#usage) - [🧰 CLI 参考](#cli-reference) - [📄 输出格式](#output-formats) - [🗺️ 关键路径](#key-paths) - [🔐 安全与隐私](#safety-and-privacy) - [🩺 故障排除](#troubleshooting) - [⚠️ 限制](#limitations) - [❓ 常见问题](#faq) - [🔖 版本控制](#versioning) - [🧹 质量检查](#quality-checks) - [🗂️ 项目结构](#project-structure) - [🙏 致谢](#credits) - [🤝 贡献](#contributing) - [📄 许可证](#license) ## 📖 概述 Telegram for macOS 将本地消息数据存储在一个加密的 SQLite 数据库中。当聊天记录从 Telegram 的云端状态中被删除时,只要本地缓存仍然存在于磁盘上且未被覆盖或同步清除,它就可能成为最后有用的证据来源。 `telegram-message-exporter` 提供了一条专注的恢复路径: - 使用 `.tempkeyEncrypted` 解密本地 SQLCipher 数据库 - 检查解密后的纯文本 SQLite 副本 - 列出可能的对话者和联系人 - 将单个聊天或所有已解码的消息导出为整洁的聊天记录 该工具完全是离线的。它不会调用 Telegram API,不会将消息恢复回 Telegram,也不会将恢复的数据上传到任何地方。 ### 首次恢复检查清单 1. 尽快停止在 Mac 上使用 Telegram。 2. 如果您试图保留最近删除的聊天记录,请保持 Mac 处于离线状态。 3. 在进行实验之前,将 Telegram 密钥和数据库复制到一个单独的工作目录中。 4. 在虚拟环境中安装该工具。 5. 解密至 `plaintext.db`。 6. 运行 `list-peers` 以查找您关心的聊天。 7. 优先导出 HTML 以供阅读,如果您需要在电子表格中进行分析,则导出 CSV。 8. 安全地存储 `plaintext.db` 和聊天记录文件;它们包含私人消息内容。 ## ✨ 功能特性 - **离线解密**:从 Telegram 本地的 `.tempkeyEncrypted` 文件派生 SQLCipher 密钥 - **密码支持**:当启用 Telegram 密码锁时,接受 `--passcode` 或 `TG_LOCAL_PASSCODE` - **Postbox 解析**:处理原生 macOS 应用的键/值 Postbox 表 - **对话者发现**:搜索本地对话者记录,以便在导出时尽可能使用名称代替原始 ID - **定向导出**:按对话者 ID、联系人姓名、消息限制、开始日期和结束日期进行过滤 - **可读输出**:写入带有时间戳、发送者、消息方向和链接处理的带样式的 HTML、Markdown 或 CSV 文件 - **诊断功能**:当 Telegram 存储发生更改或缓存与预期结构不匹配时,对表和行进行采样 ## 🔄 工作原理 正常的恢复流程分为两个阶段:解密数据库,然后从纯文本副本中导出。 ``` flowchart TD A[Native Telegram for macOS data] --> B[.tempkeyEncrypted] A --> C[account-*/postbox/db/db_sqlite] B --> D[telegram-exporter decrypt] C --> D D --> E[plaintext.db] E --> F[list-peers] E --> G[diagnose] F --> H[export --peer-id or --contact] G --> H H --> I[HTML transcript] H --> J[Markdown transcript] H --> K[CSV dataset] ``` CLI 不需要 Telegram 网络访问权限。所有数据都来自 Mac 上已存在的本地文件。 ``` sequenceDiagram participant User participant CLI as telegram-exporter participant Key as .tempkeyEncrypted participant DB as db_sqlite participant Plain as plaintext.db participant Out as transcript file User->>CLI: decrypt --key --db --out plaintext.db CLI->>Key: derive local key candidates CLI->>DB: open encrypted SQLCipher database CLI->>Plain: write plaintext SQLite copy User->>CLI: list-peers --db plaintext.db CLI->>Plain: inspect peer records User->>CLI: export --db plaintext.db --peer-id ... CLI->>Plain: parse messages and peer map CLI->>Out: render HTML, Markdown, or CSV ``` ## ✅ 系统要求 - 存在原生 Telegram for macOS 数据的 macOS 系统 - Python 3.10 或更高版本 - 支持 `sqlcipher3` Python 包的 SQLCipher - Telegram 本地密码(如果启用了密码锁) - 用于本地安装的虚拟环境 在 macOS 上,如果 `sqlcipher3` 构建失败,请先安装 SQLCipher: ``` brew install sqlcipher ``` ## 🚀 快速开始 ### 1. 安装 通过克隆仓库安装: ``` git clone https://github.com/soakes/telegram-message-exporter.git cd telegram-message-exporter python3 -m venv .venv source .venv/bin/activate pip install -e . ``` 或直接从 GitHub 安装最新版本: ``` pip install -U "git+https://github.com/soakes/telegram-message-exporter.git" ``` ### 2. 定位 Telegram 数据库 原生 macOS 应用通常将其数据存储在以下路径下: ``` TELEGRAM_STABLE="$HOME/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable" ls -la "$TELEGRAM_STABLE" ls "$TELEGRAM_STABLE"/account-*/postbox/db/db_sqlite ``` 您需要: - `.tempkeyEncrypted`,因为它以 `.` 开头,所以在普通的 `ls` 命令下是隐藏的 - 匹配的 `account-*/postbox/db/db_sqlite` ### 3. 解密到工作副本 ``` telegram-exporter decrypt \ --key "$HOME/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/.tempkeyEncrypted" \ --db "$HOME/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/account-123456/postbox/db/db_sqlite" \ --out recovery/plaintext.db ``` 如果启用了 Telegram 密码锁: ``` TG_LOCAL_PASSCODE="your-passcode" \ telegram-exporter decrypt \ --key "$HOME/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/.tempkeyEncrypted" \ --db "$HOME/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/account-123456/postbox/db/db_sqlite" \ --out recovery/plaintext.db ``` ### 4. 查找对话者 ``` telegram-exporter list-peers --db recovery/plaintext.db --search "Alex" ``` ### 5. 导出聊天记录 ``` telegram-exporter export \ --db recovery/plaintext.db \ --peer-id 123456789 \ --me-name "Me" \ --format html \ --out recovery/alex.html ``` ## 🧪 用法 ### 导出单个聊天的 HTML ``` telegram-exporter export \ --db recovery/plaintext.db \ --peer-id 123456789 \ --format html \ --me-name "Me" \ --out recovery/chat.html ``` ### 按联系人姓名导出 ``` telegram-exporter export \ --db recovery/plaintext.db \ --contact "Alex" \ --format md \ --out recovery/alex.md ``` 如果匹配到多个对话者,命令将打印候选列表,并要求您使用 `--peer-id` 重新运行。 ### 导出日期范围 ``` telegram-exporter export \ --db recovery/plaintext.db \ --peer-id 123456789 \ --start-date 2024-01-01 \ --end-date 2024-12-31 \ --format html \ --out recovery/chat-2024.html ``` ### 导出所有已解码消息 ``` telegram-exporter export \ --db recovery/plaintext.db \ --format csv \ --out recovery/all-chats.csv ``` ### 检查未知数据库 ``` telegram-exporter diagnose --db recovery/plaintext.db ``` 采样特定表: ``` telegram-exporter diagnose --db recovery/plaintext.db --table t7 ``` ### 调试解密 ``` telegram-exporter decrypt \ --key /path/to/.tempkeyEncrypted \ --db /path/to/db_sqlite \ --out recovery/plaintext.db \ --debug ``` ## 🧰 CLI 参考 | 命令 | 用途 | | --- | --- | | `decrypt` | 将 Telegram 加密的 `db_sqlite` 解密为纯文本 SQLite 文件 | | `diagnose` | 列出纯文本数据库中的表、列和样本行 | | `list-peers` | 按名称片段查找可能的对话者 ID | | `export` | 将消息渲染为 HTML、Markdown 或 CSV | ### `decrypt` | 标志 | 必需 | 描述 | | --- | --- | --- | | `--key` | 是 | `.tempkeyEncrypted` 的路径 | | `--db` | 是 | 加密的 `db_sqlite` 的路径 | | `--out` | 否 | 输出的纯文本数据库路径,默认为 `plaintext.db` | | `--passcode` | 否 | Telegram 本地密码;也可使用 `TG_LOCAL_PASSCODE` | | `--debug` | 否 | 打印密钥/配置文件诊断信息 | ### `diagnose` | 标志 | 必需 | 描述 | | --- | --- | --- | | `--db` | 是 | 纯文本 SQLite 数据库的路径 | | `--table` | 否 | 要采样的表;存在时默认为 `t7` | ### `list-peers` | 标志 | 必需 | 描述 | | --- | --- | --- | | `--db` | 是 | 纯文本 SQLite 数据库的路径 | | `--search` | 否 | 用于过滤对话者的名称片段 | ### `export` | 标志 | 必需 | 描述 | | --- | --- | --- | | `--db` | 是 | 纯文本 SQLite 数据库的路径 | | `--contact` | 否 | 要解析为对话者的联系人姓名 | | `--peer-id` | 否 | 要导出的数字对话者 ID | | `--table` | 否 | 覆盖已检测到的消息表 | | `--limit` | 否 | 最大消息数 | | `--start-date` | 否 | 开始日期,`YYYY-MM-DD` 或 ISO 日期时间 | | `--end-date` | 否 | 结束日期,`YYYY-MM-DD` 或 ISO 日期时间 | | `--format` | 否 | `html`、`md` 或 `csv`;默认为 `md` | | `--out` | 否 | 输出路径;默认为 `chat_export.` | | `--me-name` | 否 | 发出消息的显示标签;默认为 `Me` | | `--show-direction` | 否 | 在 Markdown 中追加 `(in)` 或 `(out)` 标签 | ## 📄 输出格式 | 格式 | 最适合 | 备注 | | --- | --- | --- | | `html` | 阅读和分享精美的聊天记录 | 包括摘要卡片、日期跳转、返回顶部和链接处理 | | `md` | 归档文本、笔记、版本控制 | 紧凑、便携且易于比较 | | `csv` | 在电子表格或脚本中进行分析 | 包括日期、时间、Unix 时间戳、方向、发送者、文本、对话者 ID 和作者 ID | ### Markdown 片段 ``` # Telegram 聊天记录: Alex Example **Exported:** 2026-02-04 16:05:12 **Total Messages:** 418 --- ## 2026年2月4日 星期三 **14:13:09 — Me** 3h48 is good also ``` ### CSV 片段 ``` date,time,timestamp,direction,speaker,text,peer_id,author_id 2026-02-04,14:13:09,1770214389,out,Me,"3h48 is good also",123456789,123456789 ``` ## 🗺️ 关键路径 原生 Telegram for macOS 通常将恢复相关的文件存储在此处: ``` ~/Library/Group Containers/6N38VWS5BX.ru.keepcoder.Telegram/stable/ ├── .tempkeyEncrypted └── account-*/ └── postbox/ └── db/ └── db_sqlite ``` `account-*` 目录必须与您正在解密的数据库相匹配。如果有多个账户,请在解密每个账户后尝试 `list-peers`,并记录哪个纯文本数据库来自哪个账户目录。 ## 🔐 安全与隐私 - 尽可能使用 Telegram 文件的副本进行操作。 - 在时间紧迫的恢复过程中,保持 Mac 离线以避免同步更改。 - 将 `plaintext.db`、HTML、Markdown 和 CSV 输出视为敏感私人数据。 - 恢复工作完成后,删除或加密中间文件。 - 该工具只读取本地文件并写入本地输出;它不会联系 Telegram 或任何第三方恢复服务。 ## 🩺 故障排除 | 症状 | 检查内容 | | --- | --- | | `Key file not found` | 确认 `.tempkeyEncrypted` 路径,并为包含空格的路径加上引号 | | `Database file not found` | 确认所选的 `account-*` 目录中包含 `postbox/db/db_sqlite` | | `Failed to decrypt database` | 验证密钥和数据库是否属于同一个 Telegram 账户;如果启用了密码锁,请传入 `--passcode` | | `file is not a database` | 通常是密钥/数据库对不匹配或不受支持的 SQLCipher 配置文件 | | `No peer records found` | 运行 `diagnose` 并确认这是原生 macOS Telegram 数据库 | | `No messages found with the current filters` | 移除日期过滤器,确认 `--peer-id`,或尝试导出所有已解码消息 | | `sqlcipher3` 安装失败 | 使用 Homebrew 安装 SQLCipher,然后在干净的虚拟环境中重新安装该包 | 遇到解密问题时,请使用 `--debug` 重新运行: ``` telegram-exporter decrypt \ --key /path/to/.tempkeyEncrypted \ --db /path/to/db_sqlite \ --out recovery/plaintext.db \ --debug ``` ## ⚠️ 限制 - 不会将消息恢复到 Telegram 中。 - 不会绕过 Telegram 本地密码;您需要提供密码。 - 无法恢复本地缓存中已不存在的消息。 - 不会从 Telegram 服务器下载内容。 - 目前无法从 Telegram 的文件缓存中提取媒体文件。 - 某些较新或不常见的 Telegram 消息负载可能只能部分解码。 不支持 Telegram Desktop/Qt、Mac App Store 版本、移动设备备份或 Telegram 云端导出存档。 ## ❓ 常见问题 ### 这能恢复 Telegram 内已删除的聊天吗? 不能。它是从本地数据导出聊天记录;不会将消息写回 Telegram。 ### 我应该直接使用原始的 Telegram 数据库吗? 该命令可以读取它,但对于恢复工作来说,将密钥和数据库复制到单独的工作目录并从该副本解密会更安全。 ### 为什么这只支持 Telegram for macOS? 原生 macOS 应用使用与 Telegram Desktop/Qt 和移动客户端不同的存储布局。本项目是围绕原生应用的本地 Postbox/SQLCipher 数据构建的。 ### 它适用于 Mac App Store 版本吗? 不适用。本项目目前针对的是从 macos.telegram.org 直接下载/Homebrew 安装的版本。Mac App Store 版本使用不同的应用打包和存储设置,因此不在此工具支持的恢复范围内。 ### 它能恢复照片、视频或文档吗? 目前不能。导出工具侧重于已解码的消息文本和聊天记录元数据。 ## 🔖 版本控制 规范版本号存储在 [`VERSION`](VERSION) 中,并由 CLI 公开: ``` telegram-exporter --version ``` 在准备版本升级时使用辅助脚本: ``` .github/scripts/bump_version.py patch .github/scripts/bump_version.py minor .github/scripts/bump_version.py major .github/scripts/bump_version.py --set 1.2.3 ``` ## 🧹 质量检查 CI 工作流在 Python 3.10 到 3.13 的环境中运行 Black、Ruff 和 Pylint。 ``` pip install black ruff pylint black --check src/telegram_message_exporter telegram_exporter.py .github/scripts/bump_version.py ruff check src/telegram_message_exporter telegram_exporter.py .github/scripts/bump_version.py pylint src/telegram_message_exporter telegram_exporter.py ``` ## 🗂️ 项目结构 ``` telegram-message-exporter/ ├── .github/ │ ├── dependabot.yml # Dependency update schedule │ ├── scripts/ │ │ └── bump_version.py # Version helper │ └── workflows/ │ └── ci.yml # Python lint matrix ├── pyproject.toml # Packaging metadata and CLI entrypoint ├── telegram_exporter.py # Convenience wrapper for source checkouts ├── src/ │ └── telegram_message_exporter/ │ ├── __init__.py # Version metadata │ ├── __main__.py # python -m entrypoint │ ├── cli.py # Argument parsing and commands │ ├── crypto.py # SQLCipher and tempkey handling │ ├── db.py # DB heuristics and message extraction │ ├── exporters.py # HTML, Markdown, and CSV renderers │ ├── hashing.py # MurmurHash helper │ ├── models.py # Message data model │ ├── postbox.py # Postbox parsing utilities │ └── utils.py # Date parsing and link helpers ├── requirements.txt # Runtime dependencies ├── VERSION # Canonical package version ├── LICENSE └── README.md ``` ## 🙏 致谢 本项目建立在社区逆向工程工作的基础之上。特别感谢 **[@stek29](https://github.com/stek29)** 对 Telegram for macOS 本地密钥格式和 Postbox 结构的[最初研究和参考实现](https://gist.github.com/stek29/8a7ac0e673818917525ec4031d77a713)。 ## 🤝 贡献 欢迎提交 Issue 和 Pull Request,特别是关于以下方面: - 其他 Telegram for macOS 存储变体 - 更安全的恢复工作流 - 更好的 Postbox 解码 - 导出格式改进 - 针对真实缓存结构的测试 在分享示例时,请牢记恢复和隐私问题。请勿将私人 Telegram 数据库或聊天记录附加到公开的 Issue 中。 ## 📄 许可证 本项目采用 MIT 许可证授权。有关详细信息,请参阅 [`LICENSE`](LICENSE)。
标签:CSV, db_sqlite, HTML, HTTP工具, Markdown, Postbox, Python, SQLCipher, Telegram, Telegram for macOS, 二进制发布, 加密数据库, 即时通讯安全, 域渗透, 库, 应急响应, 开源工具, 数字取证, 数据导出, 数据库解析, 数据恢复, 数据泄露, 数据解密, 文档结构分析, 无后门, 本地缓存解密, 电子数据取证, 离线恢复, 聊天记录导出, 自动化脚本, 逆向工具, 通讯记录提取