A production-ready Telegram bot for managing Outline VPN access keys with user approval workflow and automatic expiry management.
- 🔐 Two-tier user system: Admin approval required for new users
- 🖥️ Multi-server support: Manage multiple Outline VPN servers
- ⏰ Automatic expiry: Scheduled cleanup of expired keys
- 📊 Traffic quotas: 30GB, 50GB, or 100GB options
- 📅 Validity periods: 1 week or 1 month
- 📝 Comprehensive audit logging: Track all user and admin actions
- 🚀 Production ready: Docker support, health checks, proper error handling
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Telegram Bot │ │ Outline Servers │ │ Database │
│ │ │ │ │ │
│ • User mgmt │◄──►│ • Key creation │ │ • Users │
│ • Commands │ │ • Key deletion │ │ • Servers │
│ • Workflows │ │ • Data limits │ │ • Access Keys │
│ │ │ │ │ • Audit Logs │
└─────────────────┘ └─────────────────┘ └─────────────────┘
▲ ▲
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Scheduler │ │ Health Check │
│ │ │ │
│ • Auto expiry │ │ • Status API │
│ • Notifications│ │ • Statistics │
│ • Cleanup │ │ • Monitoring │
└─────────────────┘ └─────────────────┘
- Single admin user (configured via
ADMIN_TG_ID) - Approve/block users
- Add/remove Outline servers
- View server list and statistics
- Must be approved by admin before access
- Create VPN connections with custom settings
- View their active/expired connections
- Receive notifications about expiry
/start- Register and get started/new- Create a new VPN connection/mykeys- View your VPN connections/help- Show help information
/approve <user_id>- Approve a pending user/block <user_id>- Block a user/addserver- Add a new VPN server (interactive)/removeserver <server_id>- Remove a server/servers- List all servers
- Python 3.12+
- Telegram Bot Token (get one from @BotFather)
- Your Telegram User ID (get it from @userinfobot)
- Access to one or more Outline VPN servers
git clone <repository-url>
cd VPN_BOT
# Copy environment template
cp env.example .env
# Edit configuration
nano .envEdit .env file:
BOT_TOKEN=your_telegram_bot_token_here
ADMIN_TG_ID=your_telegram_user_id
DB_URL=sqlite+aiosqlite:///bot.db
TZ=UTC
LOG_LEVEL=INFO
HEALTH_CHECK_PORT=8000# Using pip
pip install -r requirements.txt
# Or using poetry (if you prefer)
poetry installpython run.py# Build and run with SQLite
docker-compose up --build- Update
.envfor PostgreSQL:
BOT_TOKEN=your_telegram_bot_token_here
ADMIN_TG_ID=your_telegram_user_id
DB_URL=postgresql+asyncpg://vpn_user:your_password@postgres:5432/vpn_bot
POSTGRES_PASSWORD=your_secure_password
TZ=UTC
LOG_LEVEL=INFO
HEALTH_CHECK_PORT=8000- Run with PostgreSQL:
docker-compose up --build| Variable | Description | Default | Required |
|---|---|---|---|
BOT_TOKEN |
Telegram bot token from @BotFather | - | ✅ |
ADMIN_TG_ID |
Telegram user ID of the admin | - | ✅ |
DB_URL |
Database connection URL | sqlite+aiosqlite:///bot.db |
❌ |
TZ |
Timezone for timestamps | UTC |
❌ |
LOG_LEVEL |
Logging level (DEBUG/INFO/WARNING/ERROR) | INFO |
❌ |
HEALTH_CHECK_PORT |
Port for health check API | 8000 |
❌ |
# SQLite (development)
DB_URL=sqlite+aiosqlite:///bot.db
# PostgreSQL (production)
DB_URL=postgresql+asyncpg://user:password@host:port/database
# PostgreSQL with Docker Compose
DB_URL=postgresql+asyncpg://vpn_user:password@postgres:5432/vpn_bot- Start the bot and verify admin access
- Add Outline servers using
/addserver - Provide server details:
- Name: Human-readable server name
- API URL: Outline server API endpoint
- Certificate SHA256: Server certificate fingerprint
- New users start with
/start - Bot automatically notifies admin with approve/block buttons
- Admin approves or blocks users
- Approved users can create VPN connections
- User runs
/newcommand - Interactive wizard:
- Choose server from available list
- Select validity period (1 week/1 month)
- Pick traffic quota (30GB/50GB/100GB)
- Bot creates Outline key and provides connection URL
- User copies URL to Outline app
- Users can view their keys with
/mykeys - Scheduler automatically disables expired keys
- Users receive notifications about expiry
- All actions are logged for audit purposes
The bot exposes a health check API on port 8000:
# Check bot health
curl http://localhost:8000/health
# Response
{
"status": "healthy",
"scheduler": "running",
"statistics": {
"users": {"total": 10, "pending": 2, "sales": 7, "blocked": 1},
"servers": {"total": 3, "active": 3, "inactive": 0},
"keys": {"total": 25, "active": 15, "expired": 5, "disabled": 5},
"recent_activity": 12,
"timestamp": "2024-01-01T12:00:00"
}
}# View logs in Docker
docker-compose logs -f vpn-bot
# Log files (if running locally)
tail -f bot.logid(BigInteger, PK) - Telegram user IDusername,first_name,last_name- User inforole- pending/sales/admin/blockedcreated_at,updated_at- Timestamps
id(Integer, PK) - Auto-increment IDname- Human-readable nameapi_url- Outline API endpointcert_sha256- Certificate fingerprintis_active- Boolean status
id(Integer, PK) - Auto-increment IDoutline_key_id- ID from Outline APIowner_id- Foreign key to Usersserver_id- Foreign key to Serversaccess_url- ss:// connection URLtraffic_quota- 30GB/50GB/100GBvalidity_period- 1week/1monthexpires_at- Expiration timestampdisabled_at- Disable timestamp (if disabled)disabled_reason- Reason for disabling
id(Integer, PK) - Auto-increment IDuser_id- Who performed the actionaction- What action was performedtarget_type,target_id- What was acted upondetails- Additional contextcreated_at- When the action occurred
- Environment Variables: Never commit
.envto version control - Certificate Verification: Implement proper cert pinning for production
- Database Access: Use strong passwords and restrict network access
- Audit Logging: All actions are logged for accountability
- User Validation: Admin approval required for all new users
-
Bot not responding
- Check bot token validity
- Verify network connectivity
- Check logs for errors
-
Database errors
- Ensure database is accessible
- Check connection string format
- Verify credentials
-
Outline API errors
- Verify server URLs are accessible
- Check certificate fingerprints
- Ensure API endpoints are correct
-
Scheduler not working
- Check scheduler logs
- Verify timezone configuration
- Ensure bot has notification permissions
Enable debug logging:
LOG_LEVEL=DEBUG# Connect to PostgreSQL
docker exec -it vpn-bot-postgres psql -U vpn_user -d vpn_bot
# View tables
\dt
# Check users
SELECT id, username, role, created_at FROM users;
# Check active keys
SELECT ak.id, u.username, s.name, ak.expires_at
FROM access_keys ak
JOIN users u ON ak.owner_id = u.id
JOIN servers s ON ak.server_id = s.id
WHERE ak.disabled_at IS NULL;VPN_BOT/
├── bot/
│ ├── __init__.py
│ ├── main.py # Entry point
│ ├── config.py # Configuration
│ ├── database.py # Database setup
│ ├── models.py # SQLAlchemy models
│ ├── outline.py # Outline API client
│ ├── scheduler.py # Background tasks
│ ├── utils.py # Utilities and decorators
│ ├── health.py # Health check API
│ └── handlers/
│ ├── __init__.py
│ ├── admin.py # Admin commands
│ └── sales.py # User commands
├── requirements.txt # Python dependencies
├── Dockerfile # Container definition
├── docker-compose.yml # Multi-container setup
├── run.py # Simple entry point
├── env.example # Environment template
├── README.md # This file
└── .gitignore # Git ignore rules
# Install dev dependencies
pip install pytest pytest-asyncio
# Run tests
pytest tests/
# Run with coverage
pytest --cov=bot tests/# Format code
black bot/
# Lint code
ruff check bot/
# Type checking
mypy bot/- Fork the repository
- Create a feature branch
- Make changes with proper tests
- Ensure code quality (black, ruff, mypy)
- Submit a pull request
[Add your license here]
For issues and questions:
- Check the troubleshooting section
- Review logs for error messages
- Open an issue with detailed information
Built with ❤️ for secure VPN management