A standalone web app for monitoring Telegram channels with auto-translation to English, media download, and a live log UI.
Built by @osintph
- 🌐 Auto-translates messages to English (Farsi, Russian, Chinese, Arabic, Korean, Ukrainian + more)
- 📸 Downloads photos and videos from channels
- 🔗 Preserves message formatting (bold, links, mentions, hashtags)
- 📊 Language breakdown stats per scan
- 💾 Exports results as a ZIP (HTML report + JSON + media files)
- 🖥️ Live log streaming in the browser
- ⚡ Multiple concurrent scan jobs
- 🗂️ Full job history — persists across restarts
- 🔁 Runs as a background systemd service
- 🔍 Keyword scan mode — only saves messages (and their media) that match your keywords
- 🗂️ In-app archive search — full-text search across all completed scans, original and translated
Before anything else, you need API credentials from Telegram:
- Go to https://my.telegram.org
- Log in with your phone number
- Click API development tools
- Create a new application
- Copy your
api_idandapi_hash
git clone https://github.com/osintph/channel-monitor-ui.git
cd channel-monitor-uiCopy the example env file and fill in your details before running the installer:
cp .env.example .env
nano .envFill in all three required fields:
TELEGRAM_API_ID=12345678
TELEGRAM_API_HASH=abcdef1234567890abcdef1234567890
TELEGRAM_PHONE=+15551234567Save and exit (Ctrl+X → Y → Enter).
⚠️ The installer will hard-stop if these are not filled in. You must complete this step before runninginstall.sh.
bash install.shThe installer will:
- Check Python version (3.10+ required)
- Create a virtual environment in
.venv/ - Install all Python dependencies
- Validate your
.envcredentials - Authenticate with Telegram — Telegram will send a login code to your phone or app, enter it when prompted
The session is saved to data/channel_monitor.session and reused on every future run — you will not need to authenticate again unless you delete the session file.
Option A — Run manually in the foreground:
bash run.shOption B — Install as a background service (recommended):
sudo bash install-service.shThe service starts automatically on boot and runs in the background using Gunicorn.
Then open your browser at:
sudo systemctl status channel-monitor # check if running
sudo systemctl restart channel-monitor # restart
sudo systemctl stop channel-monitor # stop
sudo systemctl start channel-monitor # start
sudo journalctl -u channel-monitor -f # live logsAll settings live in .env:
| Variable | Required | Default | Description |
|---|---|---|---|
TELEGRAM_API_ID |
✅ | — | From my.telegram.org |
TELEGRAM_API_HASH |
✅ | — | From my.telegram.org |
TELEGRAM_PHONE |
✅ | — | Your phone number e.g. +15551234567 |
PORT |
No | 5000 |
Web server port |
DATA_DIR |
No | data |
Where jobs and session files are stored |
SECRET_KEY |
No | random | Flask session secret |
The UI has three modes, selectable via the tab bar on the left panel.
Downloads all messages from a channel (up to your configured limit), translates them, and saves everything.
- Enter a channel username (e.g.
farsna) or full link (e.g.t.me/farsna) - Configure scan options:
- Message Limit — number of messages to fetch (0 = all)
- Days Back — only fetch messages from the last N days (leave blank for all)
- Force Language — skip auto-detect and force a specific source language
- Max Video Size (MB) — skip videos larger than this (0 = skip all videos)
- Min Free Disk (GB) — stop downloading if disk space drops below this
- Skip translation if already English — avoids unnecessary API calls
- Click ▶ Start Scan
- Watch the live log in real time
- Click ⬇ ZIP to download results when complete
Scans the full channel history but only saves messages — and their attached media — that contain at least one of your keywords. Non-matching messages are counted in the log but never written to disk, so the output ZIP contains only relevant content.
Keyword matching checks both the original text and the English translation, so you can search a Farsi or Russian channel using English keywords and still get matches.
- Enter a channel username or link
- Type keywords into the tag box and press Enter or , after each one — click × to remove
- Configure the same options as Full Scan (limit 0 = scan the entire channel history)
- Click 🔍 Start Keyword Scan
- The live log shows a summary at the end:
[i] Keyword filter: 1,243 messages skipped (did not match: missile, strike) [✓] 17 messages saved - Click ⬇ ZIP to download — the ZIP contains only the matching messages and their media
Completed keyword scan jobs show their keyword tags in the job history panel so you can tell them apart at a glance.
Searches across all completed scan archives without opening any ZIP files. Matches against both the original text and the English translation, so you can query foreign-language archives in English.
- Search is AND logic — all terms must appear in the message (
missile strikeonly matches messages containing both words) - Use the channel dropdown to narrow results to a specific channel
- Each result shows a highlighted excerpt, language, media type, and view count
- Click Show full message to expand the original text and full translation inline
- Direct links to download the job ZIP or view the job log are shown per result
| File | Description |
|---|---|
messages.html |
Self-contained report — original text, English translation, inline photos/videos |
messages.json |
Raw data with all fields |
media/ |
Downloaded photos and videos (keyword scan: only media from matching messages) |
If you need to log in again (e.g. session expired or phone changed):
rm data/channel_monitor.session
bash install.sh| Package | Purpose |
|---|---|
| Telethon | Telegram MTProto client |
| deep-translator | Google Translate wrapper |
| langdetect | Automatic language detection |
| Flask | Web framework |
| Gunicorn | Production WSGI server |
data/channel_monitor.sessiongrants access to your Telegram account — keep it private and never commit it to gitdata/is in.gitignoreand will never be committed- Job history persists across service restarts in
data/jobs_index.json - The service runs with a single Gunicorn worker to avoid Telegram session conflicts