Files
Brancheneinstufung2/lead-engine/trading_twins/orchestrator.py

131 lines
4.8 KiB
Python

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 = "<br>Viele Grüße<br>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"<li>{start.strftime('%d.%m.%Y um %H:%M Uhr')}</li>"
email_body = f"""
<html>
<body>
<p>Hallo {job_details['name']},</p>
<p>vielen Dank für Ihr Interesse an Trading Twins.</p>
<p>Gerne würde ich Ihnen in einem kurzen Gespräch (ca. 15-30 Min) zeigen, wie wir Sie unterstützen können.</p>
<p>Hätten Sie an einem dieser Termine Zeit?</p>
<ul>
{slots_text}
</ul>
<p>Ich freue mich auf Ihre Rückmeldung.</p>
{signature_html}
</body>
</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")