Production-grade Telegram bot for Cloudflare R2 object storage management
Upload, organize, and manage files directly from Telegram without a web interface.
Radian is a secure, feature-complete Telegram bot that provides full object storage management capabilities through an intuitive chat interface. Built for production environments with comprehensive security controls, multi-bucket support, and enterprise-grade reliability.
- Upload Send any file, photo, video, audio, or document to your R2 bucket
- Custom Naming Rename files before upload (extensions preserved automatically)
- Clipboard Links Auto-generated markdown links after every upload
- Browse List all files with size and modification date
- View Generate presigned or custom-domain URLs for any file
- Metadata Inspect complete file information (size, MIME type, ETag, timestamps)
- Rename In-place file renaming (atomic copy-delete operation)
- Move Transfer files between buckets seamlessly
- Search Case-insensitive substring matching across filenames
- Single Delete File removal with confirmation prompt
- Batch Delete Multi-select interface for bulk deletion with parallel processing
- Bucket Wipe Complete bucket emptying with pagination (handles large buckets)
- Per-Bucket Statistics File count, total size, average size, top 5 largest files
- Global Overview Aggregate stats across all configured buckets
- Default Bucket Skip selection screen for frequently used buckets
- Multi-Bucket Unlimited bucket configuration with inline keyboard selection
- Session Management Cancel any operation and clear state instantly
- Command Menu All commands registered in Telegram's native menu
- Access Control Whitelist-based user authentication
- Path Sanitization Traversal attack prevention on all user inputs
- Size Limits Enforced upload restrictions
- Session TTL Automatic cleanup of stale sessions (10 minutes)
- Bucket Validation Whitelist verification on every callback
- Startup Validation Bot refuses to start with missing or invalid configuration
- Persistent Sessions Sessions survive process restarts via filesystem storage
- Rate Limiting Per-user rate limiting prevents API abuse
- Audit Logging Complete audit trail of all user actions with daily log rotation
- Parallel Processing Bulk operations execute in parallel for optimal performance
- Bun runtime
- Cloudflare account with R2 enabled
- Telegram bot token from @BotFather
git clone https://github.com/pimatis/radian.git
cd radian
bun installcp .env.example .envEdit .env with your credentials:
TELEGRAM_BOT_TOKEN=your_bot_token_here
CF_ACCOUNT_ID=your_cloudflare_account_id
CF_ACCESS_KEY_ID=your_r2_access_key_id
CF_SECRET_ACCESS_KEY=your_r2_secret_access_key
CF_BUCKET_NAMES=my-bucket,my-other-bucket
ALLOWED_TELEGRAM_USER_IDS=123456789Finding Your Telegram User ID: Message @userinfobot
Creating R2 API Keys: Cloudflare Dashboard → R2 → Manage R2 API Tokens → Create API Token (Object Read & Write permissions required)
bun startDevelopment mode with auto-reload:
bun devConfigure public domains for bucket URLs:
CF_BUCKET_DOMAINS=my-bucket=https://files.example.com,other-bucket=https://media.example.comWhen configured, all generated links use public URLs instead of expiring presigned URLs.
Sessions are persisted to disk by default in ./data/sessions/. You can customize the storage location:
SESSIONS_DIR=/path/to/custom/sessionsSessions survive process restarts and are automatically cleaned up after the 10-minute TTL expires.
Prevent API abuse with per-user rate limiting:
RATE_LIMIT_WINDOW_MS=60000 # Time window in milliseconds (default: 1 minute)
RATE_LIMIT_MAX_REQUESTS=30 # Max requests per window (default: 30)All user actions are logged for compliance and security monitoring:
AUDIT_ENABLED=true # Enable/disable audit logging (default: true)
AUDIT_LOGS_DIR=./data/audit # Directory for audit logsLogs are rotated daily with format: audit-YYYY-MM-DD.log. Each entry includes:
- User ID and username
- Action performed (upload, delete, rename, etc.)
- Target bucket and file key
- Timestamp and status
MAX_FILE_SIZE_BYTES=52428800 # Maximum upload size (default: 50MB)
PRESIGNED_URL_EXPIRY=3600 # Presigned URL validity in seconds (default: 1 hour)Use PM2 or similar process manager for production:
# Install PM2 globally
npm install -g pm2
# Start with PM2
pm2 start index.ts --name radian --interpreter bun
# Enable auto-restart on crash
pm2 startup
pm2 saveFROM oven/bun:latest
WORKDIR /app
COPY . .
RUN bun install
CMD ["bun", "start"]Build and run:
docker build -t radian .
docker run -d --env-file .env -v ./data:/app/data radianThe bot stores three types of data in the ./data/ directory:
sessions/- Active user sessions (survives restarts)ratelimits/- Rate limit trackingaudit/- Daily audit logs
Important: Mount a persistent volume for the ./data directory when using Docker or cloud deployments to preserve sessions and logs across restarts.
MIT License. See the LICENSE file for details.
