Skip to main content

tg-export

CI codecov PyPI version

Экспорт данных из 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.

Лицензия

MIT License

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)

Source distribution for tg-export 2.0.0
File Size Uploaded
tg_export-2.0.0.tar.gz 346.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for tg-export 2.0.0
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

2.1.1

2 release files

2.1.0

2 release files

This release

2.0.0 This release

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.7

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page