Problem bei X gelöst
Dieser Commit ist enthalten in:
@ -0,0 +1,291 @@
|
||||
# social_networks/facebook/facebook_verification.py
|
||||
|
||||
"""
|
||||
Facebook-Verifikation - Klasse für die Verifikationsfunktionalität bei Facebook
|
||||
Nutzt den gleichen EmailHandler wie Instagram.
|
||||
"""
|
||||
|
||||
import logging
|
||||
import time
|
||||
import re
|
||||
from typing import Optional, Dict, Any, List
|
||||
|
||||
from .facebook_selectors import FacebookSelectors
|
||||
from utils.logger import setup_logger
|
||||
|
||||
logger = setup_logger("facebook_verification")
|
||||
|
||||
class FacebookVerification:
|
||||
"""
|
||||
Klasse für die Verifikation bei Facebook (E-Mail, SMS, etc.).
|
||||
Nutzt den gleichen E-Mail-Service wie Instagram.
|
||||
"""
|
||||
|
||||
def __init__(self, automation):
|
||||
"""
|
||||
Initialisiert die Facebook-Verifikations-Funktionalität.
|
||||
|
||||
Args:
|
||||
automation: Referenz auf die Hauptautomatisierungsklasse
|
||||
"""
|
||||
self.automation = automation
|
||||
self.selectors = FacebookSelectors()
|
||||
|
||||
logger.debug("Facebook-Verifikation initialisiert")
|
||||
|
||||
def wait_for_email_code(self, email: str, timeout: int = 120) -> Optional[str]:
|
||||
"""
|
||||
Wartet auf den Verifikationscode aus der E-Mail.
|
||||
Nutzt den gleichen E-Mail-Service wie Instagram über EmailHandler.
|
||||
|
||||
Facebook-spezifisch:
|
||||
- Betreff: "Dein Bestätigungscode lautet FB-12345"
|
||||
- Code ist 5-stellig
|
||||
|
||||
Args:
|
||||
email: E-Mail-Adresse
|
||||
timeout: Maximale Wartezeit in Sekunden
|
||||
|
||||
Returns:
|
||||
Optional[str]: 5-stelliger Verifikationscode oder None
|
||||
"""
|
||||
logger.info(f"Warte auf Verifikationscode für {email}")
|
||||
|
||||
try:
|
||||
# Nutze den EmailHandler wie bei Instagram
|
||||
verification_code = self.automation.email_handler.get_verification_code(
|
||||
target_email=email,
|
||||
platform="facebook",
|
||||
max_attempts=timeout // 2, # 2 Sekunden pro Versuch
|
||||
delay_seconds=2
|
||||
)
|
||||
|
||||
if verification_code:
|
||||
logger.info(f"Verifikationscode erhalten: {verification_code}")
|
||||
return verification_code
|
||||
|
||||
logger.warning(f"Kein Verifikationscode nach {timeout} Sekunden erhalten")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Warten auf E-Mail-Code: {e}")
|
||||
return None
|
||||
|
||||
def extract_code_from_email(self, email_content: str) -> Optional[str]:
|
||||
"""
|
||||
Extrahiert den Verifikationscode aus dem E-Mail-Inhalt.
|
||||
Diese Methode wird vom EmailHandler aufgerufen.
|
||||
|
||||
Args:
|
||||
email_content: Inhalt der E-Mail
|
||||
|
||||
Returns:
|
||||
Optional[str]: 5-stelliger Code oder None
|
||||
"""
|
||||
try:
|
||||
# Facebook-spezifische Patterns für Verifikationscode
|
||||
# Betreff: "Dein Bestätigungscode lautet FB-12345"
|
||||
patterns = [
|
||||
r'FB-(\d{5})', # Format: FB-12345
|
||||
r'Bestätigungscode lautet (\d{5})', # Deutscher Text
|
||||
r'Bestätigungscode: (\d{5})', # Alternative
|
||||
r'confirmation code is (\d{5})', # Englisch
|
||||
r'verification code: (\d{5})', # Alternative Englisch
|
||||
r'Code: (\d{5})', # Kurz
|
||||
r'\b(\d{5})\b', # Jede 5-stellige Zahl als Fallback
|
||||
]
|
||||
|
||||
for pattern in patterns:
|
||||
match = re.search(pattern, email_content, re.IGNORECASE)
|
||||
if match:
|
||||
code = match.group(1) if '(' in pattern else match.group(0)
|
||||
logger.info(f"Verifikationscode gefunden: {code}")
|
||||
return code
|
||||
|
||||
logger.warning("Kein Verifikationscode im E-Mail-Inhalt gefunden")
|
||||
return None
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler beim Extrahieren des Codes: {e}")
|
||||
return None
|
||||
|
||||
def handle_sms_verification(self, phone_number: str, timeout: int = 120) -> Optional[str]:
|
||||
"""
|
||||
Behandelt SMS-Verifikation (für zukünftige Implementierung).
|
||||
|
||||
Args:
|
||||
phone_number: Telefonnummer
|
||||
timeout: Maximale Wartezeit
|
||||
|
||||
Returns:
|
||||
Optional[str]: SMS-Code oder None
|
||||
"""
|
||||
logger.info(f"SMS-Verifikation für {phone_number} angefordert")
|
||||
|
||||
# TODO: SMS-Service-Integration implementieren
|
||||
# Könnte später den gleichen Service wie Instagram nutzen
|
||||
|
||||
logger.warning("SMS-Verifikation noch nicht implementiert")
|
||||
return None
|
||||
|
||||
def handle_captcha(self) -> bool:
|
||||
"""
|
||||
Behandelt Captcha-Herausforderungen.
|
||||
|
||||
Returns:
|
||||
bool: True bei Erfolg
|
||||
"""
|
||||
try:
|
||||
logger.info("Prüfe auf Captcha")
|
||||
|
||||
# Captcha-Erkennung
|
||||
captcha_selectors = [
|
||||
"div[id*='captcha']",
|
||||
"div[class*='captcha']",
|
||||
"iframe[src*='recaptcha']",
|
||||
"div[class*='recaptcha']"
|
||||
]
|
||||
|
||||
captcha_found = False
|
||||
for selector in captcha_selectors:
|
||||
if self.automation.browser.is_element_visible(selector, timeout=1000):
|
||||
captcha_found = True
|
||||
logger.warning(f"Captcha erkannt: {selector}")
|
||||
break
|
||||
|
||||
if captcha_found:
|
||||
# Screenshot für manuelles Lösen
|
||||
self.automation._take_screenshot("captcha_challenge")
|
||||
|
||||
# TODO: Captcha-Lösung implementieren
|
||||
# Könnte die gleiche Strategie wie Instagram nutzen
|
||||
|
||||
logger.error("Captcha-Lösung noch nicht implementiert")
|
||||
return False
|
||||
|
||||
logger.debug("Kein Captcha gefunden")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler bei Captcha-Behandlung: {e}")
|
||||
return False
|
||||
|
||||
def handle_identity_verification(self) -> bool:
|
||||
"""
|
||||
Behandelt Identitäts-Verifikation (Ausweis-Upload, etc.).
|
||||
|
||||
Returns:
|
||||
bool: True bei Erfolg
|
||||
"""
|
||||
try:
|
||||
logger.info("Prüfe auf Identitäts-Verifikation")
|
||||
|
||||
# Prüfe auf Identitäts-Verifikations-Anforderung
|
||||
id_verification_keywords = [
|
||||
"identität bestätigen",
|
||||
"verify identity",
|
||||
"ausweis hochladen",
|
||||
"upload id",
|
||||
"foto hochladen",
|
||||
"upload photo"
|
||||
]
|
||||
|
||||
page_content = self.automation.browser.page.content().lower()
|
||||
|
||||
for keyword in id_verification_keywords:
|
||||
if keyword in page_content:
|
||||
logger.warning(f"Identitäts-Verifikation erforderlich: {keyword}")
|
||||
|
||||
# Screenshot
|
||||
self.automation._take_screenshot("identity_verification_required")
|
||||
|
||||
# Kann nicht automatisiert werden
|
||||
return False
|
||||
|
||||
logger.debug("Keine Identitäts-Verifikation erforderlich")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler bei Identitäts-Verifikations-Check: {e}")
|
||||
return False
|
||||
|
||||
def handle_suspicious_activity(self) -> bool:
|
||||
"""
|
||||
Behandelt "Verdächtige Aktivität" Warnungen.
|
||||
|
||||
Returns:
|
||||
bool: True wenn behandelt
|
||||
"""
|
||||
try:
|
||||
logger.info("Prüfe auf verdächtige Aktivitäts-Warnungen")
|
||||
|
||||
# Prüfe auf Warnungen
|
||||
suspicious_keywords = [
|
||||
"verdächtige aktivität",
|
||||
"suspicious activity",
|
||||
"ungewöhnliche aktivität",
|
||||
"unusual activity",
|
||||
"sicherheitsprüfung",
|
||||
"security check"
|
||||
]
|
||||
|
||||
page_content = self.automation.browser.page.content().lower()
|
||||
|
||||
for keyword in suspicious_keywords:
|
||||
if keyword in page_content:
|
||||
logger.warning(f"Verdächtige Aktivitäts-Warnung: {keyword}")
|
||||
|
||||
# Screenshot
|
||||
self.automation._take_screenshot("suspicious_activity")
|
||||
|
||||
# Versuche fortzufahren
|
||||
continue_buttons = [
|
||||
"button:has-text('Weiter')",
|
||||
"button:has-text('Continue')",
|
||||
"button:has-text('Fortfahren')"
|
||||
]
|
||||
|
||||
for button in continue_buttons:
|
||||
if self.automation.browser.click_element(button, timeout=2000):
|
||||
logger.info("Verdächtige Aktivitäts-Dialog behandelt")
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
logger.debug("Keine verdächtige Aktivitäts-Warnung gefunden")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler bei Behandlung verdächtiger Aktivität: {e}")
|
||||
return False
|
||||
|
||||
def bypass_checkpoint(self) -> bool:
|
||||
"""
|
||||
Versucht Facebook Checkpoints zu umgehen.
|
||||
|
||||
Returns:
|
||||
bool: True bei Erfolg
|
||||
"""
|
||||
try:
|
||||
logger.info("Prüfe auf Facebook Checkpoint")
|
||||
|
||||
# Prüfe URL
|
||||
current_url = self.automation.browser.page.url
|
||||
if "checkpoint" in current_url:
|
||||
logger.warning("Facebook Checkpoint erkannt")
|
||||
|
||||
# Screenshot
|
||||
self.automation._take_screenshot("checkpoint")
|
||||
|
||||
# Checkpoint-Typen behandeln
|
||||
# Diese könnten ähnlich wie bei Instagram behandelt werden
|
||||
|
||||
logger.error("Checkpoint-Umgehung noch nicht vollständig implementiert")
|
||||
return False
|
||||
|
||||
logger.debug("Kein Checkpoint erkannt")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Fehler bei Checkpoint-Umgehung: {e}")
|
||||
return False
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren