bot 63f0ac74bc Add bot_config.py: single source of truth for category/feed config
Category labels, feed-file mappings, and emoji were copy-pasted across
threat_intel_bot.py, check_feeds.py, and validation/run_validation.py,
which is how the ransomware category split almost missed one of them.
check_feeds.py now imports from bot_config.py instead of keeping its
own copy.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-25 12:19:37 +03:00

telegram-rss-bot

Telegram bot that monitors cybersecurity RSS feeds and ransomware.live victim data, delivering real-time alerts to Telegram topics. Articles are enriched with CVEs, threat actors, and malware families extracted from content.

Project Structure

rss_telegram_bot/
├── threat_intel_bot.py       # Main bot — commands, subscriptions, alert dispatch
├── rss_manager.py            # Feed fetching, dedup, message formatting
├── content_classifier.py     # CVE/actor/malware extraction
├── ransomware_fetcher.py     # ransomware.live PRO API — victim feed
├── check_feeds.py            # CLI utility to check feed health
├── feeds/
│   ├── news_feeds.json
│   ├── malware_feeds.json
│   ├── threat_intel_feeds.json   # includes CISA Advisories, Alerts, ICS
│   ├── osint_feeds.json
│   └── research_feeds.json
├── validation/
│   ├── run_validation.py     # continuous validation monitor (saves to results.jsonl)
│   └── review.py             # pretty-print and filter results.jsonl
├── .env                      # not committed — see Setup
├── subscribers.json          # auto-managed — chat/topic subscriptions
├── seen_articles.db          # SQLite — tracks sent RSS articles (7-day retention)
└── seen_victims.db           # SQLite — tracks sent ransomware victims (7-day retention)

Setup

pip install python-telegram-bot feedparser aiohttp beautifulsoup4

Create .env:

BOT_TOKEN=your_token_here
RANSOMWARE_LIVE_API_KEY=your_key_here   # optional — register at api-pro.ransomware.live

Run:

python3 threat_intel_bot.py

Bot Commands

Command Action
/on_<category> Subscribe this chat/topic to a category
/off_<category> Unsubscribe
/stats Check feed health and subscriber count
/help Show commands

Categories: news, malware, threat_intel, osint, research

Telegram Topics: Run /on_<category> inside each topic to route categories to separate threads.

Message Format

RSS articles:

{emoji} Title

Description

📡 Source  ·  Published (UTC)
🆔 CVE-2024-1234, CVE-2024-5678      (only if CVEs detected)
👤 APT28, Fancy Bear                  (only if threat actors detected)
🦠 LockBit, Cobalt Strike             (only if malware families detected)

🔗 Read Full Article

Ransomware victims (posted to the malware topic):

🦠 company.com claimed by LockBit

Sector: Finance | Country: US
Data description from leak post

📡 ransomware.live  ·  Published (UTC)
🦠 Lockbit

🔗 View on ransomware.live

Enrichment lines only appear when the classifier finds something — clean articles stay minimal.

Data Sources

RSS Feeds (64 feeds across 5 categories)

Category Sources
news Krebs, Bleeping Computer, The Hacker News, Security Week, Dark Reading, The Record, Cyberscoop, NCSC UK, and others
threat_intel CISA Advisories, CISA Alerts, CISA ICS, SANS ISC, Unit42, Mandiant, Cisco Talos, Microsoft MSRC, and others
malware Malware Traffic Analysis, Kaspersky Securelist, Security Affairs, Sekoia, and others
osint DataBreaches.net, Have I Been Pwned, UpGuard, Vulmon Research
research Google Project Zero, watchTowr Labs, SpecterOps, Synacktiv, Doyensec, NCC Group, and others

Add or remove feeds by editing the relevant feeds/*.json file, then restart the bot. Run python3 check_feeds.py to verify health before deploying.

ransomware.live PRO API

When RANSOMWARE_LIVE_API_KEY is set, the bot polls the PRO API every 5 minutes for newly discovered ransomware victims. New entries are posted to the malware topic. Victims are tracked in seen_victims.db with 7-day retention.

Classification

content_classifier.py extracts the following from article title + description:

CVEsCVE-YYYY-NNNNN regex pattern.

Threat actors — APT groups and named adversaries including APT28/29/40/41, Lazarus, Sandworm, Volt Typhoon, Scattered Spider, FIN7, and others. Full list in THREAT_ACTORS.

Malware families — ransomware, C2 frameworks, loaders, stealers, APT tooling: LockBit, Cobalt Strike, Emotet, QakBot, Sliver, PlugX, and others. Full list in MALWARE_FAMILIES. Matching is case-insensitive with word-boundary checking. To add a family, append its display name to the set.

Severity and quality scoring are intentionally absent — the enrichment fields give enough context for the reader to judge importance.

Validation

A separate monitor for testing without affecting the production bot:

# runs continuously, same poll cycle as the bot
python3 validation/run_validation.py

# review collected results
python3 validation/review.py                      # all results
python3 validation/review.py --category research  # filter by category
python3 validation/review.py --has cves           # only articles with CVEs
python3 validation/review.py --has malware        # only articles with malware hits
python3 validation/review.py --today              # only today's run

Results are saved to validation/results.jsonl. Each line is a JSON object with a type field (article or victim) so RSS articles and ransomware victims can be filtered separately.

Systemd Service (VPS)

/etc/systemd/system/rss-bot.service:

[Unit]
Description=Threat Intel RSS Telegram Bot
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/root/tele-bots/rss_splited_bot
EnvironmentFile=/root/tele-bots/rss_splited_bot/.env
ExecStart=/root/tele-bots/rss_splited_bot/venv/bin/python3 threat_intel_bot.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now rss-bot
sudo journalctl -u rss-bot -f

Deploying Updates

From the local project directory:

rsync -avz ransomware_fetcher.py threat_intel_bot.py rss_manager.py content_classifier.py feeds/threat_intel_feeds.json feeds/news_feeds.json feeds/research_feeds.json root@deployer:/root/tele-bots/rss_splited_bot/
ssh root@deployer "systemctl restart rss-bot"

Notes

  • First run marks all current articles and victims as seen — no flood on startup
  • Polling interval: 5 minutes
  • Articles published within the last 48 hours are processed (rolling window, not calendar day)
  • seen_articles.db and seen_victims.db auto-purge entries older than 7 days
S
Description
No description provided
Readme 153 KiB
Languages
Python 100%