A small self-hosted admin panel for managing multiple Telegram user sessions and forwarding rules on one VPS.
Browser -> FastAPI Admin Panel -> SQLite -> TelegramManager -> Telethon session A -> rules -> Telethon session B -> rules -> Telethon session N -> rules
One VPS is enough for multiple light-use accounts. Each Telegram user gets a separate .session file.
- Admin login
- Add multiple Telegram accounts
- OTP login + Telegram 2FA support
- Separate Telethon session per user
- Multiple source -> target rules
- Enable/disable accounts and rules
- Restart accounts
- Text and common media copying
- Recent forwarding/error logs
- PM2 deployment
- Upload this folder:
scp -r telegram_forward_admin root@YOUR_VPS_IP:/root/ - SSH into VPS:
ssh root@YOUR_VPS_IP - Configure:
cd /root/telegram_forward_admincp .env.example .envnano .env - Set a strong
ADMIN_PASSWORDand randomSESSION_SECRET. - Run:
chmod +x deploy.sh run.sh./deploy.sh - Check:
pm2 logs tg-forward-adminpm2 list
Panel listens on port 8787.
Put the panel behind Nginx/Caddy with HTTPS and preferably IP allowlisting, Tailscale, or another VPN. Do not expose an admin panel carrying Telegram sessions and API credentials over plain HTTP.
- Friend creates/uses their own Telegram API ID/API hash.
- Admin -> Add Telegram Account.
- Click Send OTP.
- Friend provides the OTP directly while present/consenting; enter it immediately.
- If Telegram 2FA is enabled, enter it only for the login flow.
- Add rule:
- Source: bot username such as
moneygo_user_verification_bot, or numeric chat ID. - Target: private group numeric ID, or public username.
- Source: bot username such as
- Account status becomes
running.
- Never reuse your own
.sessionfor another person. - Treat
.session, API hash, OTP, and 2FA password as secrets. - Get explicit permission from every account owner.
- Back up sessions securely; never publish them to GitHub.
.envanddata/are ignored by git.- Telegram/third-party service terms may restrict automated access; use only where authorized.
- The sample stores API hashes in local SQLite. For a higher-security production service, move secrets to an encrypted secrets store and encrypt backups.
For safety this starter does not auto-import your old session. Add your own account through the panel first and test it. After successful testing, retire the old tg-forward process:
pm2 stop tg-forward
Do this only after confirming the new rule works.
- This is a ready-to-deploy starter, not a hardened multi-tenant SaaS.
- If many accounts are added, use PostgreSQL, encrypted secret storage, worker supervision, rate limiting, audit logs, and per-user RBAC.
- More reliable incoming source detection using username plus resolved Telegram entity ID.
- Debug log for every incoming chat, so source matching problems are visible.
- Find Groups button lists groups and exact numeric IDs.
- Test Send verifies target access before testing forwarding.
- Windows launcher
run_windows.batloads.envautomatically.
For a fresh test, extract the ZIP, configure .env, then double-click run_windows.bat.
If migrating an existing local V1 database/session, copy the old data folder into V2 while both servers are stopped.
- Super Admin and User roles
- Super Admin can create/disable users, reset passwords, see/manage all accounts/rules/logs
- Users only see/manage their own Telegram accounts and rules
- Guided setup instructions in dashboard
- Responsive mobile-friendly UI
- Existing V2 data can be migrated by copying
data/; old accounts may initially be unassigned and should be recreated/assigned for clean multi-user use.
- Verified accounts show OTP Verified / Login Complete instead of redundant OTP controls.
- 2FA password has Show/Hide.
- Find Chats / IDs lists groups, channels, bots and other dialogs with one-click Copy.
- Recent Logs collapsed by default.
- Redesigned responsive login page with password Show/Hide.
- Chats & IDs page now has instant search by chat name, @username, numeric ID, and type (Bot/Group/Channel/Chat).
- Live result count and Clear Search button.
- Setup Instructions are collapsed by default and expand on click.