tg-export
Экспорт данных из Telegram на локальный диск с гибкой настройкой.
Содержание
- Возможности
- Сценарии использования
- Установка
- Быстрый старт
- Структура конфигов
- Глобальные опции
- Документация
- Автодополнение командной строки
- Разработка
- Лицензия
Возможности
- Инкрементальный экспорт -- при повторном запуске скачиваются только новые сообщения и файлы, состояние хранится в SQLite
- Sibling-дедупликация -- при экспорте нескольких аккаунтов (семья, рабочий/личный) общие файлы не скачиваются повторно, а линкуются через hardlink
- Импорт из tdesktop -- файлы из стандартного экспорта Telegram Desktop копируются вместо повторного скачивания
- Takeout API -- использует официальный Takeout для обхода rate-limiting
- Гибкие правила экспорта -- настройка по чатам, папкам, типам (personal, groups, channels, bots), с фильтрами по датам, типам медиа и размеру файлов
- Логика архивных чатов -- чат считается архивным (
is_archived) только если он присутствует исключительно в архиве Telegram. Если чат есть в основном списке диалогов или в именованной папке, он не помечается как архивный, даже если одновременно находится в архиве - Проверка размера в runtime -- если реальный размер файла превышает лимит, скачивание прерывается и частичный файл удаляется
- HTML-рендеринг по месяцам -- каждый месяц в отдельном файле, с оглавлением (TOC) и навигацией prev/next
- Progress bars -- основной прогресс по сообщениям + sub-progress bars для каждого скачиваемого файла
- Контроль свободного места -- экспорт завершается ошибкой, если свободное место на диске падает ниже порога (
min_free_spaceвconfig.yaml, по умолчанию 20 GB); состояние при этом сохранено, и следующий запуск продолжает с той же точки - Корректный shutdown -- Ctrl+C сохраняет состояние; второй Ctrl+C в течение трёх секунд прерывает немедленно
- Поддержка прокси -- SOCKS5, SOCKS4, HTTP прокси для подключения к Telegram API
- Данные в SQLite -- все сообщения и метаданные хранятся в SQLite, что позволяет пересоздать HTML без обращения к Telegram API (
tg-export run --rerender), строить поисковые индексы, подключить веб-интерфейс или использовать данные в любых других целях - CLI для анализа -- команда
tg infoдля batch-запросов информации о чатах через API - Очистка данных чата -- команда
purgeдля удаления данных конкретного чата из БД и с диска
Сценарии использования
Личный архив -- экспорт всех личных переписок и групп с медиафайлами на локальный диск для долгосрочного хранения.
Семейный экспорт -- экспорт аккаунтов нескольких членов семьи. Общие группы и каналы содержат одинаковые файлы -- sibling-дедупликация экономит место на диске через hardlink.
Выборочный экспорт -- экспорт только нужных чатов/папок с правилами: рабочие чаты экспортируются, боты и публичные каналы пропускаются, для флудилок скачиваются только фото.
Миграция с tdesktop -- если уже есть экспорт из Telegram Desktop, файлы из него импортируются без повторного скачивания.
Установка
Требуется Python 3.11 или новее. Проверяется на Linux с версиями 3.11-3.14; на macOS
работа ожидается, но не проверяется. На Windows проект не проверяется: блокировка файла
сессии там вырождается в отсутствующую (нет fcntl), то есть от запуска второго процесса
на том же аккаунте ничто не защищает.
Из PyPI:
uv tool install tg-export
Тем же набором ставится и pip install tg-export. Поддержка прокси (python-socks)
входит в зависимости пакета: отдельного набора устанавливать не нужно, а прежнее
написание tg-export[proxy] продолжает работать и ничего не добавляет.
Из исходников:
git clone https://github.com/VitalyOstanin/tg-export.git
cd tg-export
uv sync
uv sync создаёт окружение .venv и ставит в него проект с зависимостями; команды
после этого запускаются как uv run tg-export ... из каталога проекта. Отдельная
uv pip install -e . окружения не создаёт и на свежем клоне завершается ошибкой
No virtual environment found -- ей нужен предварительный uv venv.
Инструменты разработки (pytest, ruff, pyright) объявлены группой dev и ставятся
uv sync по умолчанию -- отдельного флага для них не нужно, см. раздел
Разработка.
Быстрый старт
Примеры ниже записаны для пакета, установленного из PyPI: исполняемый файл tg-export
доступен в PATH. При работе из исходников те же команды запускаются с префиксом:
uv run tg-export ... из каталога проекта.
1. Получить API credentials
Зайти на my.telegram.org, создать приложение, получить api_id и api_hash.
tg-export auth credentials
Ввести api_id и api_hash. Они сохраняются в ~/.config/tg-export/api_credentials.yaml и используются для всех аккаунтов.
2. Настроить прокси (если нужен)
Создать файл ~/.config/tg-export/config.yaml:
proxy:
type: socks5 # socks5, socks4, http
host: 127.0.0.1
port: 1080
# username: user # опционально
# password: pass # опционально
3. Залогиниться в Telegram
tg-export auth add --name myaccount
Ввести номер телефона и код подтверждения. Сессия сохранится в ~/.config/tg-export/sessions/myaccount.session.
Для нескольких аккаунтов повторить с разными именами. Установить аккаунт по умолчанию:
tg-export account default myaccount
4. Анализ чатов и каталог
Получить каталог всех чатов аккаунта:
tg-export list --output-file catalog.yaml
tg-export list --json --output-file catalog.json
Посмотреть информацию о конкретных чатах (количество сообщений, последние сообщения):
tg-export tg info 123456789 987654321
tg-export tg info --from-catalog catalog.json --type personal -n 3
Посмотреть последние сообщения чата. Текст по умолчанию обрезается до 200 символов; --truncate N задаёт другую длину, --truncate 0 и --no-truncate печатают текст целиком:
tg-export tg messages 123456789 -n 5
tg-export tg messages 123456789 -n 5 --truncate 1000
tg-export tg messages 123456789 -n 5 --no-truncate
5. Настройка правил экспорта
Сгенерировать шаблон конфига:
tg-export init
Конфиг создается в ~/.config/tg-export/myaccount.yaml. Настроить правила: какие чаты экспортировать, какие пропускать, какие типы медиа скачивать.
AI-агенты (Claude Code, Cursor и т.д.) могут помочь с настройкой: показать список чатов по категориям, задать вопросы о каждом и сформировать конфиг интерактивно.
Пример конфига:
output:
path: ./export_output # экспорт аккаунта ляжет в ./export_output/<alias>/
defaults:
media:
types: [all]
max_file_size: 100MB
concurrent_downloads: 3
# Импорт файлов из существующего экспорта tdesktop
import_existing:
- path: ~/Downloads/Telegram Desktop/DataExport
type: tdesktop
# Правила по типам чатов
type_rules:
bots:
skip: true
public:
skip: true
personal: {} # экспортировать все личные чаты
self: {} # экспортировать Saved Messages
# Правила по папкам Telegram
folders:
Work: {}
Family:
media:
types: [photo, video]
# Правила по конкретным чатам
chats:
- id: 777000
name: Telegram
skip: true
- id: 123456789
name: "Important Chat"
media:
types: [] # без медиа
# Что делать с чатами, не попавшими ни в одно правило
unmatched:
action: skip # skip | export_with_defaults
6. Запустить экспорт
tg-export run
Для пробного запуска без скачивания:
tg-export run --dry-run
При повторном запуске скачиваются только новые сообщения (инкрементальный экспорт).
Экспорт идёт через Takeout API. Когда Takeout недоступен -- действует кулдаун
TAKEOUT_INIT_DELAY, запрос не подтверждён в клиенте Telegram или сервер
отказал, -- tg-export сообщает причину и продолжает через обычный API: результат
тот же, но медленнее и с обычными ограничениями частоты запросов. Использованный
режим печатается в итоговой сводке строкой API:. Чтобы отказ от Takeout был
ошибкой, а не переходом на обычный API:
tg-export run --require-takeout
Обратный случай -- когда Takeout не нужен и ждать кулдаун незачем: запрос не делается вовсе, экспорт сразу идёт через обычный API.
tg-export run --no-takeout
Takeout-сессия живёт между запусками: по окончании экспорта она не завершается,
а только отпускается, и следующий запуск переиспользует её идентификатор. Это
существенно, потому что на создание новой сессии Telegram отвечает кулдауном
TAKEOUT_INIT_DELAY длиной до 24 часов -- завершая сессию каждый раз, Takeout
удавалось бы использовать не чаще раза в сутки. Если сервер уже забыл сохранённый
идентификатор, tg-export это обнаруживает пробным запросом и создаёт новую сессию.
Завершить сессию явно:
tg-export takeout clear
7. Sibling-дедупликация
Каждый аккаунт экспортируется в свой подкаталог ./export_output/<alias>/. Соседние базы данных tg-export находит автоматически и использует уже скачанные файлы через hardlink:
export_output/
account1/ # первый аккаунт
account2/ # файлы из общих чатов линкуются из account1
Структура конфигов
~/.config/tg-export/
api_credentials.yaml # API ID и Hash (общие для всех аккаунтов)
config.yaml # Глобальные настройки (proxy, min_free_space)
default_account # Имя аккаунта по умолчанию
sessions/
myaccount.session # Telethon-сессия
myaccount.yaml # Конфиг экспорта для аккаунта
export_output/
myaccount/
.tg-export-state.db # SQLite: состояние экспорта, сообщения, файлы
index.html # Оглавление выгрузки
personal_info.html # Профиль (флаг personal_info)
contacts.html # Контакты (флаг contacts)
sessions.html # Активные сессии (флаг sessions)
userpics.html # Фото профиля (флаг userpics)
stories.html # Истории (флаг stories)
other_data.html # Сохранённые рингтоны (флаг profile_music)
profile_photos/ # Файлы фото профиля
stories/ # Файлы историй
ringtones/ # Файлы рингтонов
css/, js/, images/ # Оформление страниц
unfiled/ # Чаты вне папок
Chat_Name_123456/
messages.html # Redirect на первый месяц
messages_2024-01.html # Сообщения за январь 2024
messages_2024-02.html # Сообщения за февраль 2024
photos/ # Скачанные фото
videos/ # Скачанные видео
files/ # Скачанные документы
Channel_Name_222/ # Канал с монофорумом
Monoforum_Name_333/ # Монофорум вложен в каталог своего канала
folders/ # Чаты, разложенные по папкам Telegram
Work/
Chat_Name_444/
archived/ # Чаты только из архива Telegram
Chat_Name_555/
left/ # Покинутые каналы и группы
Channel_Name_666/
Подкаталог с медиа создаётся только при наличии соответствующих файлов; полный перечень подкаталогов по типам медиа -- в docs/configuration.md.
Глобальные опции
Опции указываются до подкоманды (tg-export <опция> <команда>):
| Опция | Назначение |
|---|---|
--debug |
Включить отладочное логирование (принудительно уровень DEBUG). |
--log-level LEVEL |
Уровень логирования: DEBUG/INFO/WARNING/ERROR/CRITICAL. Переопределяет TG_EXPORT_LOG_LEVEL и LOG_LEVEL. Суффикс :all (DEBUG:all) добавляет вывод telethon и aiosqlite. |
--quiet, -q |
Подавить прогресс и статусные строки; ошибки и итоговая сводка остаются. |
Приоритет уровня логирования (по убыванию): --debug > --log-level > переменная окружения TG_EXPORT_LOG_LEVEL > LOG_LEVEL > значение по умолчанию WARNING. Имя без префикса принимается ради совместимости и стоит ниже: оно не принадлежит ни одному инструменту.
Логи самих библиотек (telethon пишет каждый пакет MTProto, aiosqlite -- каждый запрос) держатся на уровне WARNING независимо от собственного: иначе --debug тонет в их выводе. Включаются суффиксом :all -- --log-level DEBUG:all или TG_EXPORT_LOG_LEVEL=DEBUG:all.
Потоки вывода: машиночитаемый вывод команд list, state show, tg info, tg messages идёт в stdout; прогресс, статусы, диагностика и ошибки — в stderr. Это позволяет безопасно использовать пайпинг, например tg-export list --json | jq ....
Флаг --json для машиночитаемого вывода поддерживают команды list, config, account list, account default, auth check, state show, tg info, tg messages и tg download. В этом режиме в stdout печатается только JSON.
Коды возврата
| № | Код | Когда возвращается |
|---|---|---|
| 1 | 0 |
Команда выполнена успешно. |
| 2 | 1 |
Команда сообщила об отказе: аккаунт не найден, сессия непригодна, сообщение не найдено, часть получателей не получила сообщение, экспорт завершился с ошибками, вопрос некому ответить (пустой stdin вместо терминала). |
| 3 | 2 |
Ошибка разбора аргументов (проверка Click). |
| 4 | 130 |
Прерывание по SIGINT (Ctrl+C), в том числе до старта экспорта. |
| 5 | 143 |
Завершение по SIGTERM во время экспорта. |
| 6 | 141 |
Закрытый конвейер: читатель на другом конце вышел раньше (`tg-export list |
Коды 130, 141 и 143 следуют соглашению 128 + номер сигнала. Запуск без терминала на входе (cron, systemd, CI, < /dev/null) на команде, задающей вопрос, получает код 1 и сообщение с именем флага, которым вопрос обходится (--yes у purge и state reset, --name/--api-id/--api-hash у команд auth): сигнала не было, и код 130 о нём лгал. Экспорт, завершившийся с ошибками при загрузке, возвращает 1, даже если часть чатов выгружена: число ошибок печатается в итоговой сводке строкой Errors:.
Документация
- docs/cli.md -- справочник команд: назначение, опции и коды возврата каждой команды.
- docs/configuration.md -- подробное описание YAML-конфигурации экспорта (правила, фильтры, типы медиа, настройки выгрузки).
- config.example.yaml -- рабочий пример конфигурации со всеми разделами; копируется в
~/.config/tg-export/<алиас>.yamlи правится под себя. - CHANGELOG.md -- список изменений между версиями.
- CONTRIBUTING.md -- руководство для контрибьюторов: карта модулей пакета («Устройство пакета»), установка dev-окружения, запуск тестов, формат коммитов.
- docs/adr/ -- архитектурные решения (ADR) в формате MADR.
- RELEASING.md -- процесс выпуска версий и конвенции тегов.
- SECURITY.md -- как сообщить об уязвимости приватно, минуя публичные issues.
Автодополнение командной строки
tg-export использует Click, который поддерживает автодополнение для bash/zsh/fish. Включить его можно через переменную окружения (добавьте строку в ~/.bashrc, ~/.zshrc или конфиг fish):
# bash
eval "$(_TG_EXPORT_COMPLETE=bash_source tg-export)"
# zsh
eval "$(_TG_EXPORT_COMPLETE=zsh_source tg-export)"
# fish
_TG_EXPORT_COMPLETE=fish_source tg-export | source
Разработка
Установка окружения вместе с инструментами разработки (группа dev входит в набор
по умолчанию):
uv sync
Весь набор проверок, который прогоняет CI -- синхронизация uv.lock, линтер, формат,
типы, тесты с покрытием и границы покрытия по модулям -- запускается одной командой;
она же приводит в порядок исправимое:
./scripts/check.sh
./scripts/check.sh --fix
Отдельный прогон тестов (порог покрытия применяется к полному прогону, поэтому для одного файла его снимают):
uv run python -m pytest
uv run python -m pytest tests/test_models.py --no-cov
Подробнее -- в CONTRIBUTING.md.
Лицензия
Metadata
Release files for tg-export 2.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tg_export-2.0.0.tar.gz | 346.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| tg_export-2.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 536.7 kB
Release files / tg_export-2.0.0.tar.gz
| Download URL | tg_export-2.0.0.tar.gz |
|---|---|
| Size | 346.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3a2ce9274dd2bf29ee5de50c832751f6c3c09e92e597449b46247a57073ed600
|
|
BLAKE2b-256 checksum How to use checksums |
d2f91787765cd54bf53e869b30035beaf0419a2c64608c73b4dd9dfffcdbc74c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency logRelease files / tg_export-2.0.0-py3-none-any.whl
| Download URL | tg_export-2.0.0-py3-none-any.whl |
|---|---|
| Size | 190.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f8233b24175c92516bdf3c62457564357a2f2fe60d2c5df846901a926a3a551e
|
|
BLAKE2b-256 checksum How to use checksums |
07998e9d2c95b82d5c46404ff3c0801644b94f92274236c626146cbc48626d9e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 24, 2026.
Transparency log