Implement profile change detection and persistence

- Enhance topic detection with message_thread_id (primary) and reply_to_topic_id (fallback)
- Add DatabaseManager.get_user_profile() to load stored user profiles
- Add DatabaseManager.update_user_profile() for profile-only updates (without affecting message_count)
- Refactor handle_profile_update() to compare stored vs current profiles
- Automatically detect name and username changes in handle_message()
- Persist detected profile changes to user_stats and profile_history tables
- Log profile changes with before/after details in activity logging
This commit is contained in:
2026-06-09 20:32:35 +02:00
parent 4819bdb70e
commit 2af4603ba3
3 changed files with 183 additions and 33 deletions
+1
View File
@@ -1,5 +1,6 @@
config.yaml
venv
.venv
*.db
*.pyc
+72
View File
@@ -12,3 +12,75 @@
Хотелось бы ...'
[2026-06-09 18:28:43] | CHAT_ID=-1001465084814 | TOPIC=MAIN | TYPE=MESSAGE | USER=93813065 (chrisarnu) | DETAILS=Nachricht gesendet: '@admin...'
[2026-06-09 18:28:43] | CHAT_ID=-1001465084814 | TOPIC=MAIN | TYPE=MESSAGE | USER=93813065 (chrisarnu) | DETAILS=Nachricht gesendet: '@admin...'
[2026-06-09 19:36:03] | CHAT_ID=-1001465084814 | TOPIC=MAIN | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:36:03] | CHAT_ID=-1001465084814 | TOPIC=MAIN | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:38:04] | CHAT_ID=-1001465084814 | TOPIC=MAIN | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:38:04] | CHAT_ID=-1001465084814 | TOPIC=MAIN | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:47:37] | CHAT_ID=-1001465084814 | TOPIC=84696 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:47:37] | CHAT_ID=-1001465084814 | TOPIC=84696 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:49:05] | CHAT_ID=-1001465084814 | TOPIC=84696 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:49:05] | CHAT_ID=-1001465084814 | TOPIC=84696 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: '....'
[2026-06-09 19:54:35] | CHAT_ID=-1001202289941 | TOPIC=MAIN | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'hi...'
[2026-06-09 19:54:35] | CHAT_ID=-1001202289941 | TOPIC=MAIN | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'hi...'
[2026-06-09 19:54:55] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'test...'
[2026-06-09 19:54:55] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'test...'
[2026-06-09 19:55:53] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 19:55:53] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 19:56:20] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'b...'
[2026-06-09 19:56:20] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'b...'
[2026-06-09 19:56:50] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 's...'
[2026-06-09 19:56:50] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 's...'
[2026-06-09 19:57:21] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 19:57:21] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 19:58:47] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'b...'
[2026-06-09 19:58:47] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'b...'
[2026-06-09 20:14:31] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:31] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:38] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:38] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:52] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:52] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:59] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:14:59] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:15:36] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'ah ok...'
[2026-06-09 20:15:36] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'ah ok...'
[2026-06-09 20:16:36] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'hmm...'
[2026-06-09 20:16:36] | CHAT_ID=-1001202289941 | TOPIC=976 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'hmm...'
[2026-06-09 20:17:53] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:17:53] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:18:13] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'OK?...'
[2026-06-09 20:18:13] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'OK?...'
[2026-06-09 20:21:32] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:21:32] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:21:32] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:21:32] | CHAT_ID=-1001202289941 | TOPIC=757 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'a...'
[2026-06-09 20:22:38] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:22:38] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:22:38] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'geht das?...'
[2026-06-09 20:22:38] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'geht das?...'
[2026-06-09 20:23:31] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:23:31] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:23:31] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'aha...'
[2026-06-09 20:23:31] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'aha...'
[2026-06-09 20:24:05] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:24:05] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:24:05] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'aber...'
[2026-06-09 20:24:05] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'aber...'
[2026-06-09 20:24:57] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:24:57] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:24:57] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'nun?...'
[2026-06-09 20:24:57] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'nun?...'
[2026-06-09 20:25:14] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:25:14] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:25:14] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'grummel...'
[2026-06-09 20:25:14] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'grummel...'
[2026-06-09 20:27:30] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:27:30] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke 🌻' → 'Toke. 🌻'
[2026-06-09 20:27:30] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'asd...'
[2026-06-09 20:27:30] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'asd...'
[2026-06-09 20:27:34] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'sad...'
[2026-06-09 20:27:34] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'sad...'
[2026-06-09 20:28:04] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke. 🌻' → 'Toke 🌻'
[2026-06-09 20:28:04] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=PROFILE_CHANGE | USER=151261436 (tokelemma) | DETAILS=Profiländerung erkannt | Name: 'Toke. 🌻' → 'Toke 🌻'
[2026-06-09 20:28:04] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'Und back...'
[2026-06-09 20:28:04] | CHAT_ID=-1001202289941 | TOPIC=761 | TYPE=MESSAGE | USER=151261436 (tokelemma) | DETAILS=Nachricht gesendet: 'Und back...'
+110 -33
View File
@@ -140,6 +140,35 @@ class DatabaseManager:
except Exception as e:
logging.error(f"Fehler beim Aktualisieren der User Stats für {user_id}: {e}")
def get_user_profile(self, user_id: int) -> dict:
"""Lädt das gespeicherte Profil eines Benutzers aus der Datenbank."""
try:
self.cursor.execute("""
SELECT full_name, username FROM user_stats WHERE user_id = ?
""", (user_id,))
result = self.cursor.fetchone()
if result:
return {'full_name': result[0], 'username': result[1]}
return None
except Exception as e:
logging.error(f"Fehler beim Laden des Benutzerprofils {user_id}: {e}")
return None
def update_user_profile(self, user_id: int, full_name: str, username: str):
"""Aktualisiert nur die Profilinformationen (Name/Username) eines Benutzers.
Erstellt den Benutzer automatisch, falls er noch nicht existiert.
"""
try:
self.cursor.execute("""
INSERT INTO user_stats (user_id, full_name, username, message_count, last_message_timestamp)
VALUES (?, ?, ?, 0, NULL)
ON CONFLICT(user_id) DO UPDATE SET full_name = excluded.full_name, username = excluded.username
""", (user_id, full_name, username))
self.conn.commit()
except Exception as e:
logging.error(f"Fehler beim Aktualisieren des Benutzerprofils {user_id}: {e}")
def close(self):
"""Schließt die Datenbankverbindung."""
self.conn.close()
@@ -157,11 +186,25 @@ class MonitoringBot:
# --- HILFSFUNKTIONEN ZUR TOPIC-ERKENNUNG ---
def _get_topic_id(self, update: Update) -> str:
"""Extrahiert die Topic ID aus dem Update (Topic Aware)."""
if update.effective_chat and hasattr(update.message, 'reply_to_topic'):
# Dies ist ein sehr spezifischer API-Pfad und muss je nach PTB-Version/Update angepasst werden.
return str(update.message.reply_to_topic)
# Fallback: Hauptthema (MAIN).
"""Extrahiert die Topic ID aus dem Update (Topic Aware).
Versucht verschiedene Attribute je nach Telegram PTB-Version:
- message_thread_id: Für Nachrichten in Topics/Threads
- forum_topic_created: Wenn ein neues Topic erstellt wurde
- reply_to_topic_id: Fallback für explizite Topic-Antworten
"""
if not update.message:
return 'MAIN'
# Versuche message_thread_id (Standard für Topics)
if hasattr(update.message, 'message_thread_id') and update.message.message_thread_id:
return str(update.message.message_thread_id)
# Versuche reply_to_topic_id (Fallback)
if hasattr(update.message, 'reply_to_topic_id') and update.message.reply_to_topic_id:
return str(update.message.reply_to_topic_id)
# Fallback: Hauptthema (MAIN)
return 'MAIN'
# --- EVENT HANDLER 1: BEITRITT/AUSSTIEG ---
@@ -176,42 +219,76 @@ 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}")
# --- EVENT HANDLER 2: PROFILDÄNDERUNG (Jetzt History Loggend) ---
async def handle_profile_update(self, client: Update, context: ContextTypes.DEFAULT_TYPE):
"""Verarbeitet simulierte Profiländerungen und protokolliert sie."""
user = client.effective_user
chat_id = client.effective_chat.id
topic_id = self._get_topic_id(client.update)
# --- EVENT HANDLER 2: PROFILDÄNDERUNG (Profilvergleich mit DB) ---
async def handle_profile_update(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Erkennt Profiländerungen durch Vergleich des gespeicherten Profils mit dem aktuellen."""
#if not update or not update.effective_user or not update.effective_chat:
# return
# Da PTB keine direkten Profile-Update Events liefert, simulieren wir das Loggen eines
# gewünschten Change-Events basierend auf einem Trigger (z.B. /changename).
if context.args:
new_name = " ".join(context.args) # Annahme: Der User sendet den neuen Namen als Argument
# Hier müsste die Logik für alte vs neue Werte komplexer sein,
# aber wir loggen das gewünschte Ergebnis:
old_details = "N/A"
new_details = new_name
self._log_event(client, context, chat_id, topic_id, "PROFILE_CHANGE", user.id, user.full_name, f"Profiländerung: {old_details} -> {new_details}")
user = update.effective_user
chat_id = update.effective_chat.id
topic_id = self._get_topic_id(update)
current_full_name = user.full_name
current_username = getattr(user, 'username', None)
# Speichern der Änderung im dedizierten History Log
self.db.log_profile_change(
group_chat_id=chat_id,
user_id=user.id,
topic_id=topic_id,
old_name="Simulated Old Name",
new_name=new_details,
old_user="Simulated Old User",
new_user=getattr(user, 'username', 'N/A'),
details="Profil manuell via Bot-Befehl geändert."
)
# Lade das alte Profil aus der Datenbank
old_profile = self.db.get_user_profile(user.id)
# Vergleiche mit dem aktuellen Profil
if old_profile:
old_full_name = old_profile['full_name']
old_username = old_profile['username']
# Prüfe auf Änderungen
has_name_changed = old_full_name != current_full_name
has_username_changed = old_username != current_username
if has_name_changed or has_username_changed:
details = f"Profiländerung erkannt"
if has_name_changed:
details += f" | Name: '{old_full_name}''{current_full_name}'"
if has_username_changed:
details += f" | Username: '{old_username}''{current_username}'"
self._log_event(
client=update, context=context, chat_id=chat_id, topic_id=topic_id,
activity_type="PROFILE_CHANGE", user_id=user.id,
username=current_username or user.id, details=details
)
# Speichere die Änderung im History Log
self.db.log_profile_change(
group_chat_id=chat_id,
user_id=user.id,
topic_id=topic_id,
old_name=old_full_name or "N/A",
new_name=current_full_name,
old_user=old_username or "N/A",
new_user=current_username or "N/A",
details=details
)
# Persistiere die neuen Profilinformationen in user_stats
self.db.update_user_profile(
user_id=user.id,
full_name=current_full_name,
username=current_username
)
# --- EVENT HANDLER 3: MESSAGE (Statistik & Topic Aware) ---
# --- EVENT HANDLER 3: MESSAGE (Statistik & Topic Aware & Profiländerungserkennung) ---
async def handle_message(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
"""Verarbeitet jede Nachricht und aktualisiert die Statistiken des ABSENDERS."""
"""Verarbeitet jede Nachricht und aktualisiert die Statistiken des ABSENDERS.
Erkennt auch automatisch Profiländerungen durch Vergleich mit der Datenbank.
"""
if not update or not update.effective_chat or not update.effective_user:
return
# 0. Erkenne Profiländerungen BEVOR die Stats aktualisiert werden
await self.handle_profile_update(update, context)
# 1. TOPIC ID EXTRAHIEREN
topic_id = self._get_topic_id(update)