Added automatic topic reopening and renaming last_message_timestamp to lastseen_timestamp
This commit is contained in:
@@ -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) ---
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user