299 lines
6.9 KiB
Markdown
299 lines
6.9 KiB
Markdown

|
||

|
||

|
||

|
||

|
||

|
||
|
||
# 📎 Telegram File Link Bot
|
||
|
||
A self-hosted **Telegram bot** that generates **secure, rate-limited download links** for uploaded files, with **time-based expiration (TTL)**, an **optional admin dashboard**, and **automatic cleanup**.
|
||
|
||
The project can run **locally**, on a **VPS**, or on any cloud platform.
|
||
For the easiest setup, **Railway is recommended**.
|
||
|
||
---
|
||
|
||
## 🚀 Deployment (Railway – Recommended)
|
||
|
||
[](https://railway.com/deploy/telegram-file-to-link-bot?referralCode=nIQTyp&utm_medium=integration&utm_source=template&utm_campaign=generic)
|
||
|
||
This repository is designed to be deployed **directly as a Railway template**.
|
||
|
||
### Why Railway?
|
||
- **Free public domain** (`*.railway.app`) included
|
||
- **Automatic HTTPS** (no SSL setup needed)
|
||
- **One-click PostgreSQL & Redis**
|
||
- **Easy environment variable management**
|
||
- **No server maintenance** or manual provisioning
|
||
|
||
### Steps
|
||
1. Click **Deploy on Railway**
|
||
2. Railway will create a new project from this template
|
||
3. Add PostgreSQL and Redis plugins
|
||
4. Set the required environment variables
|
||
5. Optional: Enable Persistent Storage (Railway Buckets)
|
||
6. Deploy
|
||
|
||
Your bot and download API will be live within minutes.
|
||
|
||
> You can still deploy this project locally or on any VPS.
|
||
|
||
---
|
||
|
||
## ✨ Features
|
||
|
||
### 🤖 Telegram Bot
|
||
- Upload files via Telegram and receive a public download link
|
||
- Supports documents, videos, audio, photos, animations, voice, and video notes
|
||
- Preserves original file quality
|
||
- Optional private bot mode (allowed user IDs)
|
||
- Built with Pyrogram / Pyrofork
|
||
|
||
---
|
||
|
||
### 🔗 File Links
|
||
- Unique file IDs
|
||
- Direct downloads via FastAPI
|
||
- Correct filenames and headers
|
||
- Supports HTTP range requests (206 Partial Content)
|
||
|
||
---
|
||
|
||
### ⏳ Expiration (TTL Only)
|
||
- Optional expiration per file
|
||
- Time-based expiration only (no download limits)
|
||
- Unlimited downloads are always allowed
|
||
- Files expire automatically when TTL is reached
|
||
|
||
---
|
||
|
||
### 🔄 Upload Concurrency Control
|
||
- Limits how many file uploads are processed at the same time
|
||
- Prevents server overload and Telegram flood limits
|
||
- Extra uploads are automatically queued
|
||
- Fully configurable via environment variables
|
||
|
||
---
|
||
|
||
### ⚙️ Mode System (TTL Control)
|
||
|
||
TTL is controlled **per user** via Telegram commands.
|
||
|
||
Examples:
|
||
- `/mode ttl 30` → 30 minutes
|
||
- `/mode ttl 2h` → 2 hours
|
||
- `/mode ttl 1d` → 1 day
|
||
- `/mode ttl 0` or `/mode reset` → Never expire
|
||
|
||
TTL is stored internally in **seconds**.
|
||
|
||
---
|
||
|
||
### 📊 Admin Dashboard (Optional)
|
||
|
||
Enabled only if `ADMIN_ENABLED=true`.
|
||
|
||
Features:
|
||
- Secure session-based login
|
||
- View total files, downloads, and active files
|
||
- Search files by name
|
||
- Disable files (expire immediately)
|
||
- Delete files
|
||
- View top downloads, recent uploads, and expiring files
|
||
- Light / Dark mode toggle
|
||
|
||
When enabled, the admin dashboard is available at:
|
||
|
||
```
|
||
https://your-domain.com/admin
|
||
```
|
||
|
||
> If `ADMIN_ENABLED=false`, the admin dashboard routes are not registered and the bot still works normally.
|
||
|
||
---
|
||
|
||
## 📸 Screenshots
|
||
|
||
### Admin Dashboard
|
||

|
||
|
||
### Telegram Upload
|
||

|
||
|
||
---
|
||
|
||
### 🧹 Automatic Cleanup
|
||
- Background task removes expired files
|
||
- Cleans database records and Redis cache
|
||
- Deletes expired objects from S3-compatible storage automatically
|
||
- Safe against partial failures
|
||
|
||
---
|
||
|
||
### 🚦 Rate Limiting
|
||
- Global per-IP rate limiting
|
||
- Redis-backed
|
||
- Proper `Retry-After` headers
|
||
|
||
---
|
||
|
||
## 🗄️ Storage Backends
|
||
|
||
This project supports **two storage backends**, selectable via environment variables.
|
||
|
||
### Local Filesystem (default)
|
||
- Files are stored in the `uploads/` directory
|
||
- Suitable for local development and small deployments
|
||
- Files are removed automatically when TTL expires
|
||
|
||
### S3-Compatible Object Storage (Recommended for Production)
|
||
- Files are stored in an S3-compatible bucket
|
||
- Supports **Railway Storage Buckets**, AWS S3, Cloudflare R2, and similar services
|
||
- Files are served via **presigned URLs**
|
||
- No service egress for downloads
|
||
- Files persist across deployments
|
||
- Automatic cleanup when TTL expires
|
||
|
||
On Railway, S3 credentials are injected automatically when you connect a Storage Bucket.
|
||
|
||
Enable S3 storage by setting:
|
||
```
|
||
STORAGE_BACKEND=s3
|
||
```
|
||
|
||
---
|
||
|
||
### S3-Compatible Storage (Advanced / Non-Railway)
|
||
|
||
If you are using S3-compatible storage **outside of Railway**
|
||
(e.g. AWS S3, Cloudflare R2, MinIO, Backblaze B2),
|
||
you must provide the following environment variables:
|
||
|
||
```env
|
||
AWS_ENDPOINT_URL=https://storage.example.com
|
||
AWS_S3_BUCKET_NAME=your-bucket-name
|
||
AWS_DEFAULT_REGION=auto
|
||
AWS_ACCESS_KEY_ID=your-access-key
|
||
AWS_SECRET_ACCESS_KEY=your-secret-key
|
||
```
|
||
|
||
---
|
||
|
||
## 🧱 Tech Stack
|
||
- Python **3.11+** (tested on 3.13)
|
||
- FastAPI
|
||
- Pyrogram / Pyrofork
|
||
- PostgreSQL (asyncpg)
|
||
- Redis
|
||
- Jinja2
|
||
- Vanilla HTML / CSS / JS
|
||
- S3-compatible object storage
|
||
|
||
---
|
||
|
||
## ⚠️ Database Schema Management
|
||
|
||
This project automatically creates and maintains its database schema at startup.
|
||
|
||
Migrations are intentionally omitted to keep the template simple and easy to deploy.
|
||
For larger or multi-tenant deployments, adding a migration system is recommended.
|
||
|
||
---
|
||
|
||
## ⚙️ Environment Variables
|
||
|
||
Create a `.env` file in the project root.
|
||
> Tip: Rename `.env.example` to `.env` and fill in your values.
|
||
|
||
### Telegram Bot
|
||
```
|
||
API_ID=your_api_id
|
||
API_HASH=your_api_hash
|
||
BOT_TOKEN=your_bot_token
|
||
```
|
||
|
||
### Upload Concurrency
|
||
```
|
||
MAX_CONCURRENT_TRANSFERS=3
|
||
```
|
||
|
||
### Database & Cache
|
||
```
|
||
DATABASE_URL=postgresql://user:password@localhost:5432/filelink
|
||
REDIS_URL=redis://localhost:6379
|
||
```
|
||
|
||
### Storage Backend
|
||
Choose where uploaded files are stored.
|
||
|
||
Local filesystem (default):
|
||
```
|
||
STORAGE_BACKEND=local
|
||
```
|
||
|
||
S3-compatible storage:
|
||
```
|
||
STORAGE_BACKEND=s3
|
||
```
|
||
> If not set, the bot defaults to local filesystem storage.
|
||
|
||
### Public URL
|
||
Local development:
|
||
```
|
||
BASE_URL=http://localhost:8000
|
||
```
|
||
|
||
Railway:
|
||
```
|
||
BASE_URL=${RAILWAY_PUBLIC_DOMAIN}
|
||
```
|
||
|
||
Custom domain:
|
||
```
|
||
BASE_URL=https://files.example.com
|
||
```
|
||
|
||
### Rate Limiting
|
||
```
|
||
GLOBAL_RATE_LIMIT_REQUESTS=60
|
||
GLOBAL_RATE_LIMIT_WINDOW=10
|
||
```
|
||
|
||
### Access Control (Optional)
|
||
```
|
||
ALLOWED_USER_IDS=123456789
|
||
```
|
||
|
||
### Admin Dashboard (Optional)
|
||
```
|
||
ADMIN_ENABLED=true
|
||
ADMIN_EMAIL=admin@example.com
|
||
ADMIN_PASSWORD=change-me-now
|
||
SESSION_SECRET=change-me
|
||
```
|
||
|
||
---
|
||
|
||
## ▶️ Running Locally
|
||
|
||
```
|
||
pip install -r requirements.txt
|
||
uvicorn app.main:app --reload --log-level warning
|
||
```
|
||
|
||
---
|
||
|
||
## 🐳 Running with Docker
|
||
|
||
```
|
||
docker build -t telegram-file-link-bot .
|
||
docker run -d --env-file .env -p 8000:8000 telegram-file-link-bot
|
||
```
|
||
|
||
---
|
||
|
||
## 📜 License
|
||
|
||
Apache License 2.0
|