Self-host your Telegram history with a sync agent, searchable web UI, media storage, and change tracking for edits, deletions, and dialog updates.
Telegram is great for communication, but weak as a long-term personal archive. Search is limited, exports are clumsy, and historical changes are easy to lose. This project gives you your own searchable archive with structured storage, media retention, and an admin UI for browsing everything locally.
- Syncs Telegram chats, media, and metadata into your own storage
- Preserves history so edits, deletions, and dialog changes are inspectable
- Provides a web admin for browsing dialogs, searching messages, and reviewing timelines
- Stores structured data in MongoDB and media in MinIO-compatible object storage
- Supports both historical import and ongoing live sync
In practice, that means you get a self-hosted Telegram archive that is much easier to search, inspect, and keep long-term than Telegram's built-in tooling.
Browse archived dialogs, scan recent activity, and jump into the archive from a high-level overview.
Inspect a single conversation with participant context, metadata, and message-level navigation.
Find messages and conversations quickly with archive-wide search and targeted results.
Review edits, removals, and historical message states to understand how a conversation evolved.
Monitor sync state and background activity from the admin interface while imports and live updates run.
- Connects to Telegram using official APIs
- Archives messages, media, and conversation data
- Supports both historical sync and real-time updates
- Stores data in MongoDB and media files in MinIO
- Built with Bun runtime and Telegram API
- Web-based dashboard for viewing archived data
- Filters for users, groups, channels, and bots
- Detailed conversation and message views
- Media preview and download capabilities
- Built with Bun, Express, EJS, and Tailwind CSS
- Docker and Docker Compose
- Telegram API credentials from my.telegram.org
- Environment variables configuration
-
Clone the repository
-
Create a
.envfile in the root directory with the required credentials and storage settings:
TELEGRAM_API_ID=your_api_id
TELEGRAM_API_HASH=your_api_hash
TELEGRAM_PASSWORD=your_2fa_password_if_enabled
TELEGRAM_SESSION_STRING=your_session_string
ADMIN_PASSWORD=choose_a_strong_password
ADMIN_COOKIE_SECRET=choose_a_long_random_secret
MINIO_ROOT_USER=choose_a_minio_root_user
MINIO_ROOT_PASSWORD=choose_a_minio_root_passwordADMIN_PASSWORD enables the admin login screen. ADMIN_COOKIE_SECRET signs the login cookie and should be a long random string. MINIO_ROOT_USER and MINIO_ROOT_PASSWORD are required by the bundled MinIO service.
For local HTTP-only development, set ADMIN_COOKIE_SECURE=false. For any real deployment behind HTTPS, keep it true.
- Create the local MinIO data directory:
mkdir -p ./data/minio-data- Start the system using Docker Compose:
docker compose up -dBy default, the MinIO API and console bind to 127.0.0.1 only. If you need remote access, set MINIO_BIND_HOST explicitly.
This will start:
- Admin interface on http://localhost:3000
- Agent service for data collection
- MongoDB database
- MinIO object storage
- Text messages with formatting
- Photos and videos
- Documents and files
- Stickers and animations
- Voice messages
- Location sharing
- Service messages (calls, pins, etc.)
- Automatic media download and storage
- Thumbnail generation
- Content-type detection
- Deduplication using content hashing
- Streaming support for audio/video
- Version tracking for dialog changes
- Historical message syncing
- Real-time updates
- Message threading support
- Media file management
Each component can be developed independently. See the README.md files in their respective directories:
Use the dev override compose file to run backend + frontend + agent in watch mode:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d db minio admin agent admin-webUse:
http://localhost:5173for frontend development (Vite HMR)http://localhost:3000for admin backend/API/media
Notes:
- UI changes in
admin/web/srcreload instantly. - Backend changes in
admin/index.tsrestart automatically viabun --watch. - Agent changes in
agent/*.tsrestart automatically viabun --watch. - In dev mode, agent runs with
IMPORT_BEFORE_LIVE_SYNC=falseto keep restarts fast.
To keep local development separate from any deployed environment or shared storage, use the local-only env file and helper script:
cp .env.local.example .env.local
./scripts/dev-local.sh upThis local mode:
- uses
COMPOSE_PROJECT_NAME=tg-archive-local, so MongoDB uses separate local Docker volumes - stores MinIO data under
./.local-dev/minio-datainstead of your shared or deployed storage path - uses a separate MinIO bucket name (
tg-archive-local) - starts
db,minio,admin, andadmin-webonly by default - leaves the Telegram agent off unless you explicitly opt in
Useful commands:
./scripts/dev-local.sh up
./scripts/dev-local.sh up --with-agent
./scripts/dev-local.sh ps
./scripts/dev-local.sh downDefault local URLs:
http://localhost:5173- Vite frontendhttp://localhost:3000- admin backendhttp://localhost:19000- local MinIO APIhttp://localhost:19001- local MinIO console
Use these scripts to copy MongoDB data between the Docker volume and a backup directory:
- Export current MongoDB volume to a backup directory:
./scripts/mongo-sync-to-nas.sh
- Import MongoDB data from a backup directory into a local Docker volume:
./scripts/mongo-sync-from-nas.sh
Defaults:
- Backup path:
./backups/mongodb-data - Docker volume:
tg-archive_mongodb_data
Optional overrides:
MONGO_BACKUP_DIR=/custom/path ./scripts/mongo-sync-to-nas.shMONGO_VOLUME_NAME=custom_volume ./scripts/mongo-sync-from-nas.sh
The system uses a microservices architecture:
- Agent service for data collection
- Admin service for data visualization
- MongoDB for structured data storage
- MinIO for media file storage
- Docker for containerization and orchestration




