Language: English | 简体中文
TG Reader is a personal Telegram broadcast-channel reader. It refreshes the channel list from your logged-in Telegram account, syncs selected channels on demand, and provides a web UI for reading, filtering, image preview, and read/unread management.
- Refresh broadcast channels from the current Telegram account.
- Sync one selected channel on demand; page load does not auto-sync messages.
- Browse local messages by channel, keyword, unread state, and page size.
- Show the source channel when browsing all channels.
- Lazy-load Telegram images through
/images/{channel_id}/{message_id}.jpg. - Store messages by
(channel_id, message_id)to avoid multi-channel ID collisions.
Message list with channel sidebar, filters, read status, and image thumbnails:
Hover preview for long message content:
Image lightbox with gallery navigation:
Read-state actions and Telegram link shortcuts:
- Backend: FastAPI, SQLAlchemy async, Pydantic, Telethon
- Frontend: Vue 3, TypeScript, Vite, Element Plus
- Database: PostgreSQL
TG Reader uses the official Telegram API through Telethon and only reads channels that are accessible from the logged-in Telegram account. It is intended for personal reading, filtering, and local message management.
Do not use this project to redistribute channel content, bypass access restrictions, mirror Telegram channels, or collect Telegram data for AI training or other unauthorized purposes. Users are responsible for respecting Telegram's terms and the rights of channel owners.
The repository only commits one public environment template:
.env.example
Create your private Docker configuration from it:
cp .env.example .envThen edit .env and fill in your own values:
POSTGRES_USER=tg_reader
POSTGRES_PASSWORD=change_me
POSTGRES_DB=tg_reader
API_ID=
API_HASH=
SESSION_NAME=telegram_sessionGet API_ID and API_HASH from your Telegram developer account:
Docker Compose reads the root .env automatically, so Docker commands do not
need --env-file. Never commit .env, .env.local, backend/.env.local,
frontend/.env.local, or Telethon *.session files.
Build the backend image once, then create the Telegram session:
docker compose build backend
docker compose run --rm backend uv run python scripts/login_telegram.pyStart all services:
docker compose up -d --buildStop all services:
docker compose downReset the Docker database and volumes:
docker compose down -vDocker services:
db: PostgreSQLbackend: FastAPI API on host port8000frontend: nginx-served Vue app on host port80
The frontend container proxies /api/ and /images/ to the backend service.
Docker stores the Telegram session in the telegram_session volume and image
cache in the backend_images volume.
For local development, keep using the same root .env as the shared base
configuration. The backend also reads backend/.env.local if you want private
local overrides, and Vite reads frontend/.env.local if you want frontend-only
overrides.
Start PostgreSQL from the repository root:
docker compose up -d dbStart the backend:
cd backend
uv sync
uv run python main.pyStart the frontend in another terminal:
cd frontend
pnpm install
pnpm devDefault local URLs:
- Frontend:
http://localhost:5173 - Backend API:
http://localhost:8000 - Swagger UI:
http://localhost:8000/docs
To bind the Vite dev server to a specific LAN address, create or edit
frontend/.env.local:
VITE_DEV_HOST=0.0.0.0
VITE_DEV_PORT=5173
VITE_API_BASE=http://localhost:8000/api
VITE_IMAGE_BASE=http://localhost:8000- Open the frontend.
- Wait for the channel sidebar to load channels from the logged-in Telegram account.
- Select a channel.
- Click sync to import messages for the selected channel.
- Use channel, keyword, unread, and page-size filters to browse local messages.
Backend:
cd backend
uv run python -m compileall api config crud dao model service scripts main.pyFrontend:
cd frontend
pnpm type-check
pnpm build-only
pnpm lintDocker Compose:
docker compose config --quietMIT



