A production-ready Telegram bot for automated message forwarding between channels, with intelligent movie/series content classification, per-category rules, session-based routing, and a Cornix-style inline UI.
- Overview
- Architecture
- Features
- Project Structure
- Prerequisites
- Configuration
- Installation
- Deployment
- Usage Guide
- License
Multi-Forward-Bot consolidates multiple forwarding bots into a single, manageable application. It supports both bot-mode (using the Bot API) and session-mode (using a user's Pyrogram session string), allowing forwarding from channels where the bot may not have admin privileges.
Key design goals:
- Single-process architecture — one asyncio event loop manages the bot client and all user session clients.
- MongoDB persistence — categories, sessions, rules, deduplication records, and stats are stored in MongoDB via the async
motordriver. - Session encryption — all Pyrogram session strings are encrypted at rest using Fernet (AES-128-CBC).
- Approval gate — new users must be approved by an admin before accessing the bot.
main.py
|
+-- Pyrogram Bot Client (bot token)
| |
| +-- handlers/
| | start.py User onboarding, approval gate, main menu
| | sessions.py In-bot session wizard (phone -> OTP -> 2FA)
| | categories.py Category CRUD wizard (7 steps)
| | rules.py Inline toggle-based rules editor
| | auto_forward.py Start/stop per-category auto-forwarding
| | manual_forward.py Range-based manual forwarding
| | admin.py Admin stats and user management
| |
| +-- engine/
| classifier.py Movie/series regex detection
| dedup.py MongoDB-backed deduplication
| link_handler.py URL detection and policy enforcement
| forwarder.py Full forwarding pipeline
|
+-- Session Pool (per-user Pyrogram clients)
+-- MongoDB (motor async driver)
- Approval gate: new users send
/start, admins receive approve/reject buttons, and the user is notified of the outcome. - Admin stats panel: view approved/pending user counts, global forwarding statistics, and manage pending users.
- In-bot session generator: a multi-step wizard collects phone number, OTP code, and optional 2FA password, then exports and encrypts the Pyrogram session string.
- Session pool: lazily initializes and caches Pyrogram client instances with async locking to prevent concurrent startups.
- Encrypted storage: session strings are encrypted with Fernet before being written to MongoDB.
- Category wizard (7 steps): name, forwarding mode (bot or session), session selection, source channels, destination channels, movie/series split toggle, and series destination assignment.
- Cornix-style rules editor: each category has its own rule set, edited entirely through inline keyboard buttons:
- Toggle buttons (on/off) for forward replies, deduplication, series-separate dedup.
- Cycling controls for link policy (
forward/skip/remove), dedup mode (off/delete_old/skip_new), and dedup window (1h-24h). - Multi-select grid for allowed media types (video, document, photo, audio, animation, voice, sticker, video_note, text).
- List editors for allowlist and blacklist keywords with add, remove, and clear operations.
The forwarding pipeline processes each message through these stages:
- Media type filter — skip if message type is not in the allowed set.
- Blacklist check — skip if text, caption, or filename matches any blacklist keyword.
- Allowlist check — skip if an allowlist is defined and no keyword matches.
- Link policy —
forward(pass through),skip(drop messages containing URLs), orremove(strip URLs from caption/text). - Deduplication — compute a 4-level signature (file_unique_id > filename > caption > text) and check against MongoDB with a configurable TTL window. Supports
skip_newanddelete_oldmodes. - Movie/series classification — 9 regex patterns detect series content (S01E01, Season, Episode, etc.). When split is enabled, series and movie content route to separate destination channels.
- Copy with reply threading — messages are copied via
copy_message. Reply chains are preserved using a reply map stored in MongoDB. - Stats and dedup recording — forwarded message counts and dedup signatures are written back to the database.
- Registers Pyrogram
MessageHandlerinstances on the session (or bot) client, filtered to the source channels of each category. - All active categories are automatically restored on bot startup.
- Start and stop per-category via inline buttons.
- Forward a range of messages by providing the first and last Telegram message links and a destination channel.
- Supports both bot and session mode.
- Progress updates are sent during forwarding, with rate limiting to avoid FloodWait errors.
- Reply threading is maintained across the forwarded range.
.
├── main.py Entry point
├── requirements.txt Python dependencies
├── Procfile Heroku worker definition
├── runtime.txt Python version (3.11.7)
├── .env.example Environment variable template
├── .gitignore
└── bot/
├── __init__.py
├── config.py Environment variable loading and validation
├── encryption.py Fernet encryption/decryption for session strings
├── models.py Pydantic v2 models and enums
├── database.py Async MongoDB layer (7 collections, indexes, CRUD)
├── session_pool.py Pyrogram client cache with lazy initialization
├── keyboards.py Inline keyboard builders
├── texts.py All user-facing text templates
├── handlers/
│ ├── __init__.py
│ ├── start.py /start, /help, approval gate, main menu routing
│ ├── sessions.py Session wizard and session CRUD
│ ├── categories.py Category wizard and category CRUD
│ ├── rules.py Rules editor callbacks
│ ├── auto_forward.py Auto-forward lifecycle management
│ ├── manual_forward.py Manual forward wizard
│ └── admin.py Admin stats and pending user management
└── engine/
├── __init__.py
├── classifier.py Movie/series regex classifier
├── dedup.py Deduplication engine
├── link_handler.py URL detection and removal
└── forwarder.py Core forwarding pipeline
- Python 3.11+
- A MongoDB instance (local or hosted, e.g. MongoDB Atlas)
- A Telegram Bot Token (from @BotFather)
- Telegram API credentials (
API_IDandAPI_HASHfrom my.telegram.org)
Copy the environment template and fill in the values:
cp .env.example .env| Variable | Description | Required |
|---|---|---|
BOT_TOKEN |
Telegram Bot Token | Yes |
API_ID |
Telegram API ID (integer) | Yes |
API_HASH |
Telegram API Hash | Yes |
MONGO_URI |
MongoDB connection string | Yes |
DB_NAME |
MongoDB database name | Yes |
ADMIN_IDS |
Comma-separated admin Telegram user IDs | Yes |
ENCRYPTION_KEY |
Fernet key for session encryption | Yes |
LOG_LEVEL |
Logging level (DEBUG, INFO, WARNING) |
No (default: INFO) |
To generate an encryption key:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"git clone https://github.com/sahansbandara/Multi-Forward-Bot.git
cd Multi-Forward-Bot
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# Edit .env with your credentials
python main.pyheroku create your-app-name
heroku config:set BOT_TOKEN=... API_ID=... API_HASH=... MONGO_URI=... DB_NAME=... ADMIN_IDS=... ENCRYPTION_KEY=...
git push heroku main
heroku ps:scale worker=1The Procfile defines a single worker process. No web dyno is needed.
- Start the bot: send
/startin a private chat with the bot. - Admin approval: if you are listed in
ADMIN_IDS, you get immediate access. Other users must wait for admin approval. - Add a session: go to Sessions > Add Session. Follow the wizard to authenticate your Telegram account.
- Create a category: go to Categories > New Category. Define source channels, destination channels, forwarding mode, and optionally enable movie/series split.
- Configure rules: from the category detail view, tap "Edit Rules" to customize media types, link policy, deduplication, and keyword filters.
- Start auto-forwarding: from the category detail view, tap "Start Auto-Forward". Messages from source channels will be forwarded automatically.
- Manual forward: go to Manual Forward, select a mode, provide first and last message links, and a destination channel.
This project is provided as-is for personal use.