import time import threading import logging import datetime from .manager import TradingTwinsManager from .teams_notification import send_approval_card from .email_sender import send_email_via_graph import os logging.basicConfig(level=logging.INFO) logger = logging.getLogger("TradingTwinsOrchestrator") TIMEOUT_SECONDS = 300 # 5 Minuten SIGNATURE_FILE = "trading_twins/signature.html" BANNER_IMAGE = "trading_twins/RoboPlanetBannerWebinarEinladung.png" class TradingTwinsOrchestrator: def __init__(self): self.manager = TradingTwinsManager() def process_lead(self, customer_email, customer_name, customer_company): """ Startet den gesamten Prozess für einen Lead. """ logger.info(f"Neuer Lead eingegangen: {customer_email}") # 1. Job und Slots erstellen (mit Faktor-3 Logik) job_uuid, slots = self.manager.create_proposal_job( customer_email, customer_name, customer_company ) logger.info(f"Job erstellt: {job_uuid}. Slots: {slots}") # 2. Teams Benachrichtigung senden # Formatieren der Uhrzeit für die Teams-Nachricht send_time = (datetime.datetime.now() + datetime.timedelta(seconds=TIMEOUT_SECONDS)).strftime("%H:%M") success = send_approval_card(job_uuid, customer_name, send_time) if not success: logger.error("Konnte Teams-Benachrichtigung nicht senden!") # Fallback? Trotzdem Timer starten oder abbrechen? # Wir machen weiter, da E-Mail-Versand Priorität hat. # 3. Timer starten für automatischen Versand timer = threading.Timer(TIMEOUT_SECONDS, self._check_timeout, args=[job_uuid]) timer.start() return job_uuid def _check_timeout(self, job_uuid): """ Wird nach Ablauf des Timers aufgerufen. Prüft den Status und sendet ggf. automatisch. """ logger.info(f"Timer abgelaufen für Job {job_uuid}. Prüfe Status...") current_status = self.manager.get_job_status(job_uuid) if current_status == 'pending': logger.info(f"Job {job_uuid} ist noch 'pending'. Löse automatischen Versand aus.") self._trigger_email_send(job_uuid) elif current_status == 'approved': logger.info(f"Job {job_uuid} wurde bereits manuell genehmigt.") elif current_status == 'cancelled': logger.info(f"Job {job_uuid} wurde manuell abgebrochen.") else: logger.warning(f"Unbekannter Status für Job {job_uuid}: {current_status}") def _trigger_email_send(self, job_uuid): """ Hier wird der tatsächliche E-Mail-Versand angestoßen. """ # Job Details laden job_details = self.manager.get_job_details(job_uuid) if not job_details: logger.error(f"Konnte Job {job_uuid} nicht finden!") return # E-Mail Body zusammenbauen try: with open(SIGNATURE_FILE, "r") as f: signature_html = f.read() except FileNotFoundError: logger.warning("Signatur-Datei nicht gefunden!") signature_html = "
Viele Grüße
Ihr RoboPlanet Team" # Dynamische Terminvorschläge formatieren slots_text = "" for slot in job_details['slots']: # Format: "Morgen, 14:00 Uhr" oder Datum start = slot['start'] slots_text += f"
  • {start.strftime('%d.%m.%Y um %H:%M Uhr')}
  • " email_body = f"""

    Hallo {job_details['name']},

    vielen Dank für Ihr Interesse an Trading Twins.

    Gerne würde ich Ihnen in einem kurzen Gespräch (ca. 15-30 Min) zeigen, wie wir Sie unterstützen können.

    Hätten Sie an einem dieser Termine Zeit?

    Ich freue mich auf Ihre Rückmeldung.

    {signature_html} """ # Banner Check banner_path = BANNER_IMAGE if os.path.exists(BANNER_IMAGE) else None # Senden success = send_email_via_graph( to_email=job_details['email'], subject="Ihr Termin für Trading Twins", body_html=email_body, banner_path=banner_path ) if success: logger.info(f"🚀 E-MAIL WURDE VERSENDET für Job {job_uuid}") self.manager.update_job_status(job_uuid, 'sent') else: logger.error(f"❌ Fehler beim E-Mail-Versand für Job {job_uuid}") self.manager.update_job_status(job_uuid, 'failed') if __name__ == "__main__": # Test-Lauf orchestrator = TradingTwinsOrchestrator() orchestrator.process_lead("test@example.com", "Max Mustermann", "Musterfirma GmbH")