Added automatic topic reopening and renaming last_message_timestamp to lastseen_timestamp

This commit is contained in:
2026-06-10 17:21:29 +02:00
parent 9006efcb8f
commit 5d82dfa289
3 changed files with 79 additions and 9 deletions
+72 -9
View File
@@ -38,6 +38,9 @@ WRITE_ACTIVITY_TO_FILE = config['logging']['write_to_file']
LOGGING_FILE = config['logging']['file_name'] LOGGING_FILE = config['logging']['file_name']
LOG_LEVEL = getattr(logging, config['logging']['level'], logging.INFO) LOG_LEVEL = getattr(logging, config['logging']['level'], logging.INFO)
# Forum Topics: Ausnahlmeliste (nicht zu reopening)
NOT_REOPEN_TOPICS = config.get('forum_topics', {}).get('not_reopen_topics', [])
# Logging konfigurieren # Logging konfigurieren
logging.basicConfig(level=LOG_LEVEL, format='%(asctime)s - %(levelname)s - %(message)s') logging.basicConfig(level=LOG_LEVEL, format='%(asctime)s - %(levelname)s - %(message)s')
@@ -76,7 +79,7 @@ class DatabaseManager:
last_name TEXT, last_name TEXT,
username TEXT, username TEXT,
is_bot INTEGER DEFAULT 0, is_bot INTEGER DEFAULT 0,
last_message_timestamp TEXT NULL lastseen_timestamp TEXT NULL
) )
""") """)
@@ -150,7 +153,7 @@ class DatabaseManager:
""" """
try: try:
self.cursor.execute(""" self.cursor.execute("""
INSERT INTO user_profile (user_id, first_name, last_name, username, is_bot, last_message_timestamp) INSERT INTO user_profile (user_id, first_name, last_name, username, is_bot, lastseen_timestamp)
VALUES (?, ?, ?, ?, ?, NULL) VALUES (?, ?, ?, ?, ?, NULL)
ON CONFLICT(user_id) DO UPDATE SET ON CONFLICT(user_id) DO UPDATE SET
first_name = excluded.first_name, first_name = excluded.first_name,
@@ -162,19 +165,19 @@ class DatabaseManager:
except Exception as e: except Exception as e:
logging.error(f"Fehler beim Aktualisieren des Benutzerprofils {user_id}: {e}") logging.error(f"Fehler beim Aktualisieren des Benutzerprofils {user_id}: {e}")
def update_user_stats(self, user_id: int, last_message_timestamp: str, first_name: str = None, last_name: str = None, username: str = None, is_bot: bool = False): def update_user_stats(self, user_id: int, lastseen_timestamp: str, first_name: str = None, last_name: str = None, username: str = None, is_bot: bool = False):
"""Aktualisiert die Statistiken und das letzte bekannte Profil des Benutzers.""" """Aktualisiert die Statistiken und das letzte bekannte Profil des Benutzers."""
try: try:
self.cursor.execute(""" self.cursor.execute("""
INSERT INTO user_profile (user_id, first_name, last_name, username, is_bot, last_message_timestamp) INSERT INTO user_profile (user_id, first_name, last_name, username, is_bot, lastseen_timestamp)
VALUES (?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(user_id) DO UPDATE SET ON CONFLICT(user_id) DO UPDATE SET
last_message_timestamp = excluded.last_message_timestamp, lastseen_timestamp = excluded.lastseen_timestamp,
first_name = COALESCE(excluded.first_name, user_profile.first_name), first_name = COALESCE(excluded.first_name, user_profile.first_name),
last_name = COALESCE(excluded.last_name, user_profile.last_name), last_name = COALESCE(excluded.last_name, user_profile.last_name),
username = COALESCE(excluded.username, user_profile.username), username = COALESCE(excluded.username, user_profile.username),
is_bot = COALESCE(NULLIF(excluded.is_bot, 0), user_profile.is_bot) is_bot = COALESCE(NULLIF(excluded.is_bot, 0), user_profile.is_bot)
""", (user_id, first_name, last_name, username, int(is_bot), last_message_timestamp)) """, (user_id, first_name, last_name, username, int(is_bot), lastseen_timestamp))
self.conn.commit() self.conn.commit()
except Exception as e: except Exception as e:
logging.error(f"Fehler beim Aktualisieren der User Stats für {user_id}: {e}") logging.error(f"Fehler beim Aktualisieren der User Stats für {user_id}: {e}")
@@ -228,6 +231,63 @@ class MonitoringBot:
self._log_event(client, context, chat_id, topic_id, "JOIN", new_member.id, new_member.full_name, f"Beitritt von {new_member.full_name}") self._log_event(client, context, chat_id, topic_id, "JOIN", new_member.id, new_member.full_name, f"Beitritt von {new_member.full_name}")
# --- EVENT HANDLER 1B: FORUM TOPIC GESCHLOSSEN ---
async def handle_forum_topic_closed(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Überwacht das Schließen von Forum-Topics und öffnet sie wieder (außer in der Ausnahlmeliste)."""
if not update or not update.message or not update.effective_chat:
return
chat_id = update.effective_chat.id
# Prüfe, ob ein Topic-Close-Event vorliegt
if hasattr(update.message, 'forum_topic_closed') and update.message.forum_topic_closed:
topic_id = self._get_topic_id(update)
details = f"Forum-Topic wurde geschlossen (Topic ID: {topic_id})"
self._log_event(
client=update, context=context, chat_id=chat_id, topic_id=topic_id,
activity_type="TOPIC_CLOSED", user_id=0, username="system",
details=details
)
# Prüfe, ob dieses Topic in der Ausnahlmeliste ist
should_skip = any(
item['group_id'] == chat_id and str(item['topic_id']) == topic_id
for item in NOT_REOPEN_TOPICS
)
if should_skip:
skip_details = f"Topic-Reopening übersprungen (in Ausnahmeliste)"
self._log_event(
client=update, context=context, chat_id=chat_id, topic_id=topic_id,
activity_type="TOPIC_REOPEN_SKIPPED", user_id=0, username="system",
details=skip_details
)
logging.info(f"⏭️ Topic {topic_id} in Chat {chat_id} wird nicht wiedereröffnet (Ausnahlmeliste)")
return
# Versuche das Topic wieder zu öffnen
try:
await context.bot.reopen_forum_topic(chat_id=chat_id, message_thread_id=int(topic_id))
reopen_details = f"Forum-Topic automatisch wiedereröffnet (Topic ID: {topic_id})"
self._log_event(
client=update, context=context, chat_id=chat_id, topic_id=topic_id,
activity_type="TOPIC_REOPENED", user_id=0, username="system",
details=reopen_details
)
logging.info(f"✅ Topic {topic_id} in Chat {chat_id} wurde wiedereröffnet")
except Exception as e:
error_details = f"Fehler beim Wiedereröffnen von Topic {topic_id}: {str(e)}"
self._log_event(
client=update, context=context, chat_id=chat_id, topic_id=topic_id,
activity_type="TOPIC_REOPEN_FAILED", user_id=0, username="system",
details=error_details
)
logging.error(f"{error_details}")
# --- EVENT HANDLER 2: PROFILDÄNDERUNG (Profilvergleich mit DB) --- # --- EVENT HANDLER 2: PROFILDÄNDERUNG (Profilvergleich mit DB) ---
async def handle_profile_update(self, update: Update, context: ContextTypes.DEFAULT_TYPE): async def handle_profile_update(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
@@ -308,6 +368,9 @@ class MonitoringBot:
if not update or not update.effective_chat or not update.effective_user: if not update or not update.effective_chat or not update.effective_user:
return return
# -1. Überwache Forum-Topic-Closes
await self.handle_forum_topic_closed(update, context)
# 0. Erkenne Profiländerungen BEVOR die Stats aktualisiert werden # 0. Erkenne Profiländerungen BEVOR die Stats aktualisiert werden
await self.handle_profile_update(update, context) await self.handle_profile_update(update, context)
@@ -322,7 +385,7 @@ class MonitoringBot:
# 2. Statistik-Update: Profildaten speichern und Timestamp aktualisieren # 2. Statistik-Update: Profildaten speichern und Timestamp aktualisieren
self._update_user_stats( self._update_user_stats(
user_id=user.id, user_id=user.id,
last_message_timestamp=timestamp_str, lastseen_timestamp=timestamp_str,
first_name=user.first_name, first_name=user.first_name,
last_name=user.last_name or None, last_name=user.last_name or None,
username=getattr(user, 'username', None), username=getattr(user, 'username', None),
@@ -353,9 +416,9 @@ class MonitoringBot:
with open(LOGGING_FILE, 'a', encoding='utf-8') as f: with open(LOGGING_FILE, 'a', encoding='utf-8') as f:
f.write(log_message) f.write(log_message)
def _update_user_stats(self, user_id: int, last_message_timestamp: str, first_name: str = None, last_name: str = None, username: str = None, is_bot: bool = False): def _update_user_stats(self, user_id: int, lastseen_timestamp: str, first_name: str = None, last_name: str = None, username: str = None, is_bot: bool = False):
"""Wrapper für DatabaseManager.update_user_stats().""" """Wrapper für DatabaseManager.update_user_stats()."""
self.db.update_user_stats(user_id, last_message_timestamp, first_name, last_name, username, is_bot) self.db.update_user_stats(user_id, lastseen_timestamp, first_name, last_name, username, is_bot)
# --- HAUPT-RUN FUNKTION (Bleibt gleich) --- # --- HAUPT-RUN FUNKTION (Bleibt gleich) ---
+7
View File
@@ -18,3 +18,10 @@ logging:
file_name: "activity_log.txt" file_name: "activity_log.txt"
# Python Logging Level (DEBUG, INFO, WARNING, ERROR, CRITICAL) # Python Logging Level (DEBUG, INFO, WARNING, ERROR, CRITICAL)
level: "INFO" level: "INFO"
# Forum-Topic Management
forum_topics:
# Topics, die NICHT automatisch wiedereröffnet werden sollen
# Format: [{"group_id": 123456, "topic_id": "1"}, {"group_id": 123456, "topic_id": "2"}]
not_reopen_topics: []
Regular → Executable
View File