291 Zeilen
10 KiB
Python
291 Zeilen
10 KiB
Python
# 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 |