One command. Bot + Mini App. Running together.
Built-in Mini App with dark theme rich editor served by Flask.
Auto-starts cloudflared tunnel for public Mini App URL.
No emojis. Unicode symbols. Stylish fonts. Banner image on /start.
Built with pyTelegramBotAPI + Flask + SQLite + Pillow.
Supports all 25 RichText types and 21 RichBlock types
from Telegram Bot API 10.2 (July 2026) Rich Messages.
git clone https://github.com/arpitrajjj/rich-editor-bot.git
cd rich-editor-bot
# Option 1: Interactive setup (asks for BOT_TOKEN + OWNER_ID, installs everything, starts in screen)
python setup.py
# Option 2: Manual start
export BOT_TOKEN="your_token"
export OWNER_ID="your_id"
python bot.py # Bot + Mini App + cloudflared all start togetherWhen you run python bot.py, it automatically:
- Starts a cloudflared tunnel for the Mini App public URL
- Serves the Mini App from Flask at
/app/ - Sets the Bot menu button with the Mini App URL
- Sets the webhook if WEBHOOK_URL is available
- Prints all URLs for BotFather configuration
When you run python setup.py, it additionally:
- Checks and installs all dependencies (pip + cloudflared + screen)
- Prompts for BOT_TOKEN and OWNER_ID if not set
- Starts everything in screen sessions (detach with Ctrl+A, D)
- Prints complete setup instructions
- Features
- Quick Start
- BotFather Setup
- Bot Commands
- API Endpoints
- Deploy on Render
- Deploy on Railway
- Deploy with Docker
- Architecture
- Environment Variables
- Troubleshooting
- License
- Self-contained — no separate Next.js project needed
- Served directly by Flask at
/app/— runs alongside the bot - Dark theme with stylish fonts (Inter + JetBrains Mono + Playfair Display)
- SVG icon toolbar — no emojis, clean Unicode symbols
- Full rich editor with format selector (HTML / Markdown / Blocks)
- Channel selector with real-time connect dialog
- Draft save/load system (localStorage)
- Live preview panel
- Telegram WebApp SDK integration (auto-expand, auto-close on publish)
- Auto-cloudflared — public URL generated automatically, no manual setup
- Dark-themed WYSIWYG editor with SVG icon toolbar
- Full Telegram markup support:
- Inline: Bold, italic, underline, strikethrough, code, marked, spoiler, subscript, superscript, custom emoji, date-time, math
- Blocks: Headings H1-H6, paragraphs, dividers, footers, ordered/unordered/checkbox lists, tables, block/pull quotes, collapsible details, photos, videos, audio, voice notes, animations, collages, slideshows, maps, footnotes/references, anchors, links
- 3 format styles: HTML, Markdown, Blocks
- Draft save/load with localStorage persistence
- Real-time preview with HTML rendering
- Interactive dialog-based connection (ForceReply — no broken
/connect) - Connect via username or numeric ID
- Stores channel even if bot can't verify access (pending verification)
- Disconnect channels with inline buttons
- Channel selector in Mini App with + CONNECT dialog
- Bot generates personalized dark-themed banner on
/start - Uses Pillow with stylish fonts (Tinos Bold / DejaVu Sans)
- Shows user's name, bot version, feature list
- Decorative accent bars and circles matching dark theme
/likecommand tracks likes per user- Duplicate prevention (one like per user)
- Inline button with real-time counter
- Owner can reset all likes from panel
/feedbacklets users send messages to owner- Owner gets real-time notification of new feedback
- Read/unread tracking with owner feedback panel
- Stats — Users, likes, channels, posts, maintenance, latency, Mini App URL, tunnel URL
- Broadcast — Message all users
- Set Welcome — Customize
/startmessage (HTML) - Maintenance — Toggle maintenance mode
- Users — List recent 20 users
- Channels — List all channels
- Reset Likes — Clear all likes
- Backup — Export entire database as JSON
- Set Webhook — Set webhook URL from chat (for Render/Railway)
- Read Feedback — View unread user feedback
/ping— Bot latency measurement/id— Telegram user/chat ID info/about— Bot version + stats/posthistory— Recent 10 published posts/disconnect— Remove channel link
- No emojis — all text uses Unicode mathematical alphanumeric symbols:
- Bold Fraktur for headers: \u271D\u271D\u271D \u271F\u2723\u271D \u271A\u271D\u271F
- Bold Script for subtitles: \u271C\u271D\u271D \u2721\u271E\u2723\u271D
- Double-struck for values: \u271A\u271D\u271F \u2724\u271E\u271E\u2723
- Sans-serif Bold for key-value keys
- All button labels use stylish Unicode fonts (Fraktur, Script, Double-struck)
- Stylish arrow bullets (\u27A1) instead of plain arrows
- Decorative separator bars (\u2550)
- Self-pings
/healthevery 6 minutes - Background thread keeps Render free tier alive
git clone https://github.com/arpitrajjj/rich-editor-bot.git
cd rich-editor-bot
python setup.pyThe setup script will:
- Install all Python dependencies
- Install cloudflared if not present
- Install screen if not present
- Ask for BOT_TOKEN and OWNER_ID
- Start cloudflared tunnel in screen
- Start bot in screen
- Print all URLs for BotFather
git clone https://github.com/arpitrajjj/rich-editor-bot.git
cd rich-editor-bot
pip install -r requirements.txt
export BOT_TOKEN="your_bot_token"
export OWNER_ID="your_telegram_id"
python bot.pyThe bot will:
- Auto-start cloudflared tunnel (if installed)
- Serve Mini App at the tunnel URL +
/app/ - Print all URLs you need for BotFather
Send /start to @userinfobot on Telegram.
After starting the bot, you'll see URLs printed in the console. Configure them in BotFather:
- Open @BotFather on Telegram
- Send
/mybotsand select your bot - Set Menu Button:
- Go to Bot Settings > Menu Button
- Set URL to your Mini App URL (e.g.
https://abc-xyz.trycloudflare.com/app/)
- Set Webhook (for production):
Or use the
https://api.telegram.org/bot<BOT_TOKEN>/setWebhook?url=https://your-service.onrender.com/webhook/setwebhookcommand from the owner panel
| Command | Description |
|---|---|
/start |
Main menu with banner image + Mini App button |
/connect |
Connect channel (interactive dialog) |
/connect @channel |
Connect by username |
/connect -1001234567890 |
Connect by numeric ID |
/channels |
List connected channels |
/disconnect |
Remove a channel link |
/like |
Like this bot |
/ping |
Check bot latency |
/id |
Get your Telegram IDs |
/about |
Bot info + version |
/feedback |
Send feedback to owner |
/posthistory |
View recent posts |
/help |
Full command reference |
| Command | Description |
|---|---|
/stats |
Full bot statistics |
/broadcast |
Message all users |
/setwelcome |
Custom welcome message |
/maintenance |
Toggle maintenance mode |
/setwebhook |
Set webhook URL |
/backup |
Export database |
/owner |
Owner panel menu |
| Endpoint | Method | Description |
|---|---|---|
/webhook |
POST | Telegram webhook receiver |
/app/ |
GET | Mini App (built-in) |
/api/publish |
POST | Publish rich message |
/api/channels |
GET | List user channels |
/api/channels/connect |
POST | Connect new channel |
/health |
GET | Health check + stats |
/ |
GET | Landing page with stats |
- Fork this repo
- Go to render.com > New Web Service
- Connect your repo
- Set env vars:
BOT_TOKEN,OWNER_ID,USE_CLOUDFLARED=0 - Set
WEBHOOK_URL=https://your-service.onrender.com - Set
MINI_APP_URL=https://your-service.onrender.com/app/ - Deploy!
- Set webhook:
https://api.telegram.org/bot<TOKEN>/setWebhook?url=https://your-service.onrender.com/webhook
Note: On Render, set USE_CLOUDFLARED=0 since Render provides its own public URL.
- Go to railway.app > New Project
- Deploy from GitHub
- Set env vars:
BOT_TOKEN,OWNER_ID,USE_CLOUDFLARED=0 - Set
WEBHOOK_URLandMINI_APP_URLfrom Railway domain
docker build -t rich-editor-bot .
docker run -d \
-e BOT_TOKEN="your_token" \
-e OWNER_ID="your_id" \
-e USE_CLOUDFLARED=0 \
-e WEBHOOK_URL="https://yourdomain.com" \
-p 5000:5000 \
rich-editor-botrich-editor-bot/
|-- bot.py # Main bot (telebot + Flask + Pillow + cloudflared)
|-- setup.py # One-click setup script (screen + deps + tunnel)
|-- requirements.txt # Python dependencies
|-- Dockerfile # Container config
|-- Procfile # Start command
|-- railway.yml # Railway deploy
|-- render.yaml # Render deploy
|-- .gitignore # Git rules
|-- README.md # This doc
|-- templates/
|-- mini_app.html # Built-in Mini App (dark theme rich editor)
|-- mini-app/
|-- README.md # Mini App docs
Tech Stack: pyTelegramBotAPI + Flask + SQLite + Pillow + cloudflared
One file starts everything: python bot.py starts bot + Mini App + tunnel.
| Variable | Required | Default | Description |
|---|---|---|---|
BOT_TOKEN |
Yes | -- | Bot token from @BotFather |
OWNER_ID |
Yes | 0 |
Your Telegram user ID |
USE_CLOUDFLARED |
No | 1 |
Auto-start cloudflared tunnel (set 0 on Render/Railway) |
MINI_APP_URL |
No | auto | Manual override for Mini App URL |
WEBHOOK_URL |
No | auto | Webhook base URL (auto-set from tunnel) |
WEBHOOK_PATH |
No | /webhook |
Webhook endpoint path |
KEEP_ALIVE_URL |
No | auto | Self-ping URL for Render |
PORT |
No | 5000 |
Server port |
DB_PATH |
No | bot_data.db |
SQLite database path |
- Install cloudflared:
python setup.py(auto-installs) - Or manually: https://developers.cloudflare.com/cloudflare-one/connections/network/applications/install-cloudflared/
- Set
USE_CLOUDFLARED=0and provideMINI_APP_URLmanually (for Render/Railway)
The Mini App is served at /app/ on the same Flask server as the bot. If cloudflared is running, the Mini App URL is https://tunnel-url.trycloudflare.com/app/. Check the console output for the exact URL.
The bot uses interactive dialog (ForceReply) for connecting. Just type /connect and it prompts you. Channels are stored even if bot can't verify access yet.
- Check BOT_TOKEN is correct
- For webhook mode: verify WEBHOOK_URL is set
- For polling mode: don't set WEBHOOK_URL
- Check logs:
screen -r rich-editor-bot
| Command | Description |
|---|---|
screen -r rich-editor-bot |
Reattach to bot session |
screen -r rich-editor-cf |
Reattach to tunnel session |
Ctrl+A, D |
Detach from screen |
screen -ls |
List all sessions |
MIT