Skip to content

painhardcore/tgbacky

Repository files navigation

tgbacky

tgbacky saves media from Telegram chats to local folders.

It uses your normal Telegram account. It keeps a small local SQLite DB so it can resume later instead of starting from zero.

It can save:

  • photos
  • image documents
  • videos
  • animations
  • audio
  • voice notes
  • normal documents

Files sent as files stay files. tgbacky does not convert PNG to JPG, WebP to PNG, video to MP4, or anything like that. It saves Telegram bytes as-is.

Not here yet: bot tokens, invite links, stickers, profile photos, contacts, and multi-chat batch export.

Installation

Most users should install a release binary. You do not need Rust or Cargo for this.

  1. Open GitHub Releases.
  2. Download the archive for your system:
Linux:               tgbacky-v0.1.0-linux-x86_64.tar.gz
macOS Apple Silicon: tgbacky-v0.1.0-macos-aarch64.tar.gz
macOS Intel:         tgbacky-v0.1.0-macos-x86_64.tar.gz
Windows:             tgbacky-v0.1.0-windows-x86_64.zip
  1. Optional but recommended: verify the download if SHA256SUMS.txt is attached to the release. You can't trust anyone online.
  2. Extract the archive.
  3. Move the binary somewhere in your PATH.

Linux:

tar -xzf tgbacky-v0.1.0-linux-x86_64.tar.gz
cd tgbacky-v0.1.0-linux-x86_64
chmod +x tgbacky
sudo mv tgbacky /usr/local/bin/tgbacky
tgbacky --version

macOS Apple Silicon:

tar -xzf tgbacky-v0.1.0-macos-aarch64.tar.gz
cd tgbacky-v0.1.0-macos-aarch64
chmod +x tgbacky
xattr -d com.apple.quarantine ./tgbacky
sudo mv tgbacky /usr/local/bin/tgbacky
tgbacky --version

For Intel Macs, replace macos-aarch64 with macos-x86_64. If macOS blocks the downloaded binary, allow it from System Settings > Privacy & Security, or run this before moving it to /usr/local/bin:

Windows PowerShell:

Expand-Archive .\tgbacky-v0.1.0-windows-x86_64.zip
cd .\tgbacky-v0.1.0-windows-x86_64\tgbacky-v0.1.0-windows-x86_64
.\tgbacky.exe --version

For regular use on Windows, move tgbacky.exe to a folder that is already in your Path, or add the extracted folder to your user Path.

Release archives contain the tgbacky binary, README.md, LICENSE, and env.example.

Build from Source

Use this only if there is no release binary for your system, or if you want to test local changes. Install Rust 1.85 or newer first.

From this checkout:

cargo install --path .
tgbacky --version

Or build without installing:

cargo build --release
./target/release/tgbacky --version

First Use

Login once:

tgbacky auth

First run asks for API ID and API hash once. They are app/client credentials, not Telegram user credentials. All Telegram account profiles can reuse same API credentials.

Get API ID and API hash from my.telegram.org:

  1. Sign in.
  2. Open API development tools.
  3. Create an app.
  4. Copy api_id and api_hash.

List chats:

tgbacky chats list

Pick a chat id, username, or exact title. Numeric id is safest.

Export one chat:

tgbacky export --chat -1001234567890 --out ./downloads

Run same command again later. It resumes.

Common Commands

Use another profile:

tgbacky auth --profile work
tgbacky chats list --profile work
tgbacky export --profile work --chat @example --out ./downloads/work

Show profiles:

tgbacky profiles list
tgbacky profiles current
tgbacky profiles use work

Manage API credentials:

tgbacky api list
tgbacky api add --name default
tgbacky api add --name backup --api-id 123456 --api-hash abcdef
tgbacky api use backup
tgbacky api delete backup --yes

Use one API profile for one command:

tgbacky auth --profile work --api-profile backup

Export only some media:

tgbacky export --chat @example --out ./downloads --only photo,video
tgbacky export --chat @example --out ./downloads --skip document,audio,voice

Force rescan:

tgbacky export --chat @example --out ./downloads --rescan

Plan first, download later:

tgbacky export plan --chat @example --out ./downloads --save-queue
tgbacky export --chat @example --out ./downloads

Verify files:

tgbacky verify --chat @example --out ./downloads
tgbacky verify --chat @example --out ./downloads --deep
tgbacky verify --chat -1001234567890 --out ./downloads --deep --json

Verify defaults to a fast local check: tracked status, missing files, unreadable paths, and file sizes. Add --deep to also read file bytes and check SHA-256 hashes when available. Add --json for script-friendly output.

Check local setup:

tgbacky doctor
tgbacky doctor --live

See previous runs:

tgbacky runs list --limit 20
tgbacky runs list --failed-only

Find old .part files:

tgbacky recover stale-parts --out ./downloads
tgbacky recover stale-parts --out ./downloads --delete

Reset one chat in local DB:

tgbacky chats reset --chat @example --keep-files --yes

Remove --keep-files if you also want to delete tracked files.

Useful Export Flags

--chat <CHAT>                      username, exact title, or numeric chat id
--out <DIR>                        where files go
--only <KINDS>                     save only these media kinds
--skip <KINDS>                     skip these media kinds
--workers <N>                      download workers
--rescan                           scan history again
--verbose-progress                 show more live details
--json-report                      print JSON report after run

Media kinds:

photo,image_doc,video,animation,audio,voice,document

Runtime flags:

--delay-ms <MS>
--flood-sleep-threshold-secs <SECS>
--jitter-ms <MS>
--retry-count <N>
--retry-backoff-ms <MS>
--download-stall-timeout-secs <SECS>

Example for gentle but not too slow export:

tgbacky export \
  --chat @example \
  --out ./downloads \
  --workers 4 \
  --delay-ms 700 \
  --retry-count 5 \
  --download-stall-timeout-secs 120 \
  --verbose-progress

Large Downloads and Telegram Rate Limits

Telegram can rate limit very large exports. This is normal, especially when one chat contains tens or hundreds of gigabytes of media.

For example, downloading about 120G from one conversation can trigger Telegram RPC errors such as FLOOD_PREMIUM_WAIT_X. X is the number of seconds Telegram asks the client to wait before continuing. tgbacky treats these like normal flood waits, respects the delay, and continues the download afterward. This protects the account and avoids corrupting partial files, but very large exports can take a while.

Where Files Go

Files go under output dir, then chat folder, then media type and date:

downloads/
  my_chat/
    photos/2026/04/...
    videos/2026/04/...
    audio/2026/04/...
    files/2026/04/...
    animations/2026/04/...

State DB is separate from media files.

Default profile data lives under your OS app-data folder. You can override paths:

tgbacky auth \
  --profile work \
  --session ./data/work.session.db \
  --db ./data/work.state.db \
  --download-dir ./downloads/work \
  --artifacts-dir ./data/work-artifacts

Important paths:

tgbacky_API_PROFILE          default API credential set name
tgbacky_SESSION_PATH        Telegram login/session DB
tgbacky_DB_PATH             chat state, checkpoints, media records, run history
tgbacky_DOWNLOAD_DIR        default output folder
tgbacky_RUN_ARTIFACT_DIR    JSON run artifacts

Most people can skip .env and use CLI flags.

Config order:

  1. CLI flags
  2. environment variables
  3. profile defaults

See env.example for all env vars.

Secrets

Keep these private:

  • Telegram session DB
  • local API credential fallback file
  • .env with API ID/API hash
  • downloaded private media
  • state DB if chat names or file paths are private

tgbacky tries OS keychain first for API credentials. If keychain fails, it asks before writing local plaintext credentials. API credentials are global, not stored inside each Telegram account profile.

On macOS, Keychain may ask whether tgbacky can read saved API credentials. Choose Always Allow if you trust this tgbacky binary. If you rebuild or run an unsigned/dev binary, macOS may ask again because it sees a changed tool. This is normal macOS behavior, not data loss.

Do not commit session files, state DBs, .env, or downloads.

More notes: SECURITY.md.

If Things Feel Stuck

Use:

tgbacky export --chat @example --out ./downloads --verbose-progress

Look at:

  • active=0: no download running
  • active=1: one download running or stuck
  • cooldown=yes: Telegram asked tool to wait
  • pending=N: queued downloads waiting
  • failed=N: files failed after retries

If a download stalls, default timeout is 120 seconds. Change it:

tgbacky export --chat @example --out ./downloads --download-stall-timeout-secs 60

Development

cargo fmt --all
cargo clippy --all-targets --all-features -- -D warnings
cargo test
cargo build --release

Release notes live in CHANGELOG.md.

License: MIT.

About

Thing to get your media backed from telegram

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages