Ransomware.live integration, 48h window, CISA feeds, validation updates, README

This commit is contained in:
bot
2026-04-29 11:24:23 +03:00
parent 898909e061
commit ad69c6a266
6 changed files with 604 additions and 45 deletions
+31 -11
View File
@@ -24,8 +24,10 @@ from telegram.ext import (
from telegram.constants import ParseMode
from telegram.error import TelegramError
import aiohttp
from rss_manager import RSSFeedManager
from content_classifier import ContentClassifier
from ransomware_fetcher import RansomwareFetcher
# Configure logging
logging.basicConfig(
@@ -54,6 +56,8 @@ class ThreatIntelBot:
self.classifier = ContentClassifier()
self.application = None
self.monitoring_task = None
ransomware_key = os.getenv("RANSOMWARE_LIVE_API_KEY", "")
self.ransomware_fetcher = RansomwareFetcher(ransomware_key) if ransomware_key else None
self.load_subscribers()
def load_subscribers(self):
@@ -393,19 +397,23 @@ class ThreatIntelBot:
"""Background task to monitor RSS feeds by category."""
logger.info("Starting RSS feed monitoring for category feeds...")
# First run - just mark existing articles as seen, don't send alerts
# First run - mark existing articles and victims as seen, don't send alerts
try:
for category, cfg in CATEGORY_CONFIG.items():
async with RSSFeedManager(feeds_file=cfg["feeds_file"], feed_type=category) as manager:
logger.info(f"Initial {category.upper()} feed scan - marking existing articles as seen...")
existing_articles = await manager.fetch_all_feeds(initial_run=True)
logger.info(
f"Completed initial {category.upper()} scan. "
f"Found {len(existing_articles)} existing articles (no alerts sent)"
)
await manager.fetch_all_feeds(initial_run=True)
except Exception as e:
logger.error(f"Error in initial feed scan: {e}")
if self.ransomware_fetcher:
try:
async with aiohttp.ClientSession() as session:
await self.ransomware_fetcher.fetch_new_victims(session, initial_run=True)
logger.info("Initial ransomware scan complete — existing victims marked as seen")
except Exception as e:
logger.error(f"Error in initial ransomware scan: {e}")
while True:
try:
all_articles = []
@@ -417,7 +425,7 @@ class ThreatIntelBot:
if category_articles:
logger.info(f"Found {len(category_articles)} new {category.upper()} articles")
# Deduplicate within this polling batch (cross-feed/source duplicates).
# Deduplicate within this polling batch
unique_articles = []
batch_seen_url = set()
batch_seen_content = set()
@@ -425,16 +433,14 @@ class ThreatIntelBot:
fp = RSSFeedManager.get_article_fingerprints(article)
url_key = fp['url_key']
content_key = fp['content_key']
if (url_key and url_key in batch_seen_url) or (content_key in batch_seen_content):
continue
if url_key:
batch_seen_url.add(url_key)
batch_seen_content.add(content_key)
unique_articles.append(article)
# Classify and send all unique articles
# Classify and send RSS articles
sent_count = 0
for article in unique_articles:
classified = self.classifier.classify_article(article)
@@ -448,10 +454,24 @@ class ThreatIntelBot:
else:
logger.info("No new articles found")
# Poll ransomware.live for new victims
if self.ransomware_fetcher:
async with aiohttp.ClientSession() as session:
new_victims = await self.ransomware_fetcher.fetch_new_victims(session)
victim_count = 0
for victim in new_victims:
article = RansomwareFetcher.to_article(victim)
sent = await self.send_alert(article)
if sent:
self.ransomware_fetcher.mark_seen(victim.get("id", ""))
victim_count += 1
await asyncio.sleep(1)
if new_victims:
logger.info(f"Ransomware victims: {len(new_victims)} new, {victim_count} delivered")
except Exception as e:
logger.error(f"Error in feed monitoring: {e}")
# Wait 5 minutes before next check
await asyncio.sleep(300)
def build_application(self):