Files
Floke 3fd3c5acfa [31f88f42] Keine neuen Commits in dieser Session.
Keine neuen Commits in dieser Session.
2026-03-10 13:54:07 +00:00
..

Lead Engine: Multi-Source Automation v2.2 [31988f42]

🚀 Übersicht

Die Lead Engine ist ein spezialisiertes Modul zur autonomen Verarbeitung von B2B-Anfragen. Sie fungiert als Brücke zwischen dem E-Mail-Postfach und dem Company Explorer, um innerhalb von Minuten hochgradig personalisierte Antwort-Entwürfe auf "Human Expert Level" zu generieren.

🛠 Hauptfunktionen

1. Intelligenter E-Mail Ingest

  • Multi-Source: Überwacht das Postfach info@robo-planet.de via Microsoft Graph API.
  • Filter & Routing: Unterscheidet Anfragen von TradingTwins und dem Kontaktformular.
  • Parsing: Spezialisierte HTML-Parser extrahieren strukturierte Daten (Firma, Kontakt, Bedarf).

2. Contact Research (LinkedIn Lookup)

  • Automatisierung: Sucht via SerpAPI und Gemini 2.0 Flash nach der beruflichen Position.
  • Ergebnis: Identifiziert Rollen (z.B. "CFO"), um den Tonfall anzupassen.

3. Company Explorer Sync & Monitoring

  • Integration: Legt Accounts und Kontakte automatisch im CE an.
  • Monitor: Hintergrund-Prozess (monitor.py) überwacht den Analyse-Status.
  • Daten-Pull: Übernimmt Branche und Dossier in die lokale Lead-Datenbank.

4. Expert Response Generator

  • KI-Engine: Gemini 2.0 Flash erstellt E-Mail-Entwürfe.
  • Kontext: Kombiniert Lead-Daten + CE-Daten + Matrix-Argumente (Pains/Gains).

5. Trading Twins Autopilot (PRODUKTIV v2.2)

Der vollautomatische "Zero Touch" Workflow für Trading Twins Anfragen.

  • Human-in-the-Loop: Elizabeta Melcer erhält eine Teams-Nachricht ("Approve/Deny").
  • Feedback-Server: Ein integrierter FastAPI-Server (Port 8004) verarbeitet Klicks.
  • Direct Calendar Booking (Micro-Service):
    • Logik: Prüft den Kalender von e.melcer auf echte Verfügbarkeit.
    • Raster: Termine starten nur im 15-Minuten-Takt (:00, :15, :30, :45).
    • Abstand: Bietet zwei Termine an, mit ca. 3 Stunden Pause dazwischen.
    • Buchung: Klick auf Link -> Server erstellt Outlook-Termin von info@ mit e.melcer als Teilnehmer.

6. Smartlead Webhook Integration (NEU)

  • Zweck: Empfang von Echtzeit-Lead-Benachrichtigungen direkt aus der Smartlead-Plattform.
  • Event-basiert: Das System empfängt nur Daten für neue Ereignisse (z.B. "Lead als heiß markiert"), keine historischen Daten.

Endpunkte

Die folgenden Endpunkte werden für Smartlead bereitgestellt. Die Basis-URL ist flexibel und kann bei einem Serverumzug einfach angepasst werden. Der Platzhalter {IHRE_AKTUELLE_DOMAIN} sollte durch die aktuell aktive URL (z.B. floke-ai.duckdns.org oder die zukünftige neue Domain) ersetzt werden.

  • Hot Leads: https://{IHRE_AKTUELLE_DOMAIN}/public/smartlead/hot-lead
  • Follow-up Leads: https://{IHRE_AKTUELLE_DOMAIN}/public/smartlead/follow-up-lead

Inbetriebnahme & Test-Prozess

Die Integration wird in einem kontrollierten Prozess ausgerollt, um die Datenstruktur sicher zu analysieren:

  1. URLs an Smartlead übergeben: Die oben genannten URLs werden an den Smartlead-Support oder in deren Admin-Oberfläche eingetragen.
  2. Test-Auslösung anfordern: Smartlead wird gebeten, für jeden der beiden Endpunkte einen einzelnen Test-Lead manuell auszulösen.
  3. Datenanalyse: Alle eingehenden Anfragen werden ungefiltert in die Log-Datei lead-engine/Log/smartlead_webhooks.log geschrieben. Dies ermöglicht eine genaue Analyse der von Smartlead gesendeten JSON-Struktur.
  4. Implementierung der Logik: Basierend auf den analysierten Test-Daten wird die eigentliche Geschäftslogik (z.B. Eintrag in die Datenbank, Teams-Benachrichtigung) implementiert.

Dieser Prozess stellt sicher, dass wir nicht "blind" entwickeln, sondern auf Basis der realen Datenstruktur von Smartlead aufbauen.

🏗 Architektur

/app/lead-engine/
├── app.py                   # Streamlit Web-Interface
├── trading_twins_ingest.py  # E-Mail Importer (Graph API)
├── monitor.py               # Monitor + Trigger für Orchestrator
├── trading_twins/           # Autopilot Modul
│   ├── manager.py           # Orchestrator, FastAPI, Graph API Logic
│   ├── test_calendar_logic.py # Interner Test für Kalender-Zugriff
│   └── signature.html       # HTML-Signatur (mit Bildern im selben Ordner)
└── db.py                    # Lokale SQLite Lead-Datenbank

🚨 Lessons Learned & Critical Fixes

1. Microsoft Graph API: Kalender-Zugriff

  • Problem: debug_calendar.py scheiterte oft mit TimeZoneNotSupportedException.
  • Ursache: Der API-Aufruf zur Abfrage der Verfügbarkeit (getSchedule) hat keine explizite Zeitzoneninformation erhalten.
  • Lösung: Die Zeitzone ("Europe/Berlin") wird nun explizit im payload des API-Aufrufs mitgegeben.

2. Exchange AppOnly AccessPolicy (Buchungs-Workaround)

  • Problem: Calendars.ReadWrite erlaubt einer App oft nicht, Termine in fremden Kalendern (e.melcer@) zu erstellen (403 Forbidden).
  • Lösung: Der Termin wird im eigenen Kalender des Service-Accounts (info@) erstellt. Der Mitarbeiter (e.melcer@) wird als Teilnehmer hinzugefügt. Das umgeht die Policy.

3. Dynamische HTML-Signatur mit Inline-Bildern

  • Problem: Eine statische Signatur in der Konfiguration war unflexibel und konnte keine Bilder enthalten.
  • Lösung: Ein Skript (scripts/extract_signature_assets.py) extrahiert die vollständige HTML-Signatur und alle eingebetteten Bilder aus einer .eml-Datei. Die send_email-Funktion wurde überarbeitet, um alle Bilder dynamisch als Inline-Anhänge zu versenden, was eine professionelle Darstellung sicherstellt.

4. Race-Condition-Schutz bei Überbuchung (Live-Check)

  • Problem: Wenn mehrere Leads E-Mails mit denselben Terminvorschlägen erhalten, konnten Doppelbuchungen entstehen.
  • Lösung: Implementierung eines "Live-Checks" im Feedback-Server. Bevor ein Termin gebucht wird, prüft das System in Echtzeit (is_slot_free), ob der Slot im Kalender von e.melcer@ noch verfügbar ist. Ist er belegt, wird die Buchung abgebrochen und ein Fallback-Szenario aktiviert.

5. Seamless Website Integration (WordPress iFrame)

  • Problem: Die API-Endpoints gaben nackten Text zurück, was für Kunden unprofessionell wirkte.
  • Lösung: Der Server liefert nun saubere HTML-Snippets zurück. Durch Setzen der WORDPRESS_BOOKING_URL in der .env führen die Links in der Kunden-E-Mail direkt auf die Kunden-Website. Dort wird das HTML-Ergebnis (Erfolg inkl. Teams-Link ODER Fallback zum Microsoft Bookings Kalender bei Doppelbuchung) unsichtbar in einem iFrame geladen.

5.1 Troubleshooting der iFrame-Integration

Um sicherzustellen, dass die Buchungs-Landingpage auf WordPress immer korrekt funktioniert sowohl mit spezifischen Terminvorschlägen als auch als Fallback zu einer allgemeinen Buchungsseite sind mehrere Konfigurationsschritte und Fehlerbehebungen notwendig:

1. Robuster iFrame-Code für Ihre WordPress-Seite Der folgende JavaScript-Code sollte in Ihre WordPress-Seite integriert werden, die als Landingpage für Terminbuchungen dient (z.B. robo-planet.de/terminbestaetigung). Er prüft, ob spezifische Termindaten (Job-UUID und Timestamp) über die URL übergeben werden, und lädt entsprechend entweder den spezifischen Termin-Slot oder die allgemeine Microsoft Bookings URL als Fallback.

<iframe id="booking-iframe" width="100%" height="800px" style="border:none;" scrolling="no"></iframe>
<script>
   const urlParams = new URLSearchParams(window.location.search);
   const jobUuid = urlParams.get('job_uuid');
   const timestamp = urlParams.get('ts');

   let iframeSrc = "";

   if (jobUuid && timestamp) {
      // Wenn beide Parameter vorhanden sind, den spezifischen Buchungslink verwenden
      iframeSrc = "https://floke-ai.duckdns.org/feedback/book_slot/" + jobUuid + "/" + timestamp;
   } else {
      // Andernfalls auf die allgemeine MS Bookings URL verweisen
      iframeSrc = "https://outlook.office.com/book/KennenlernenmitRoboplanet@wackler-group.de/?ismsaljsauthenabled";
   }

   document.getElementById('booking-iframe').src = iframeSrc;
</script>

2. Nginx-Konfiguration für korrekte Pfad-Weiterleitung Das Laden der spezifischen /feedback/book_slot/...-URL im iFrame scheiterte initial, da der Nginx-Proxy die verschachtelten Pfade nicht korrekt an den lead-engine-Container weiterleitete. Dies führte zur "Synology-Fehlerseite".

  • Problem: Die location-Regel in nginx-proxy-clean.conf für /feedback/ war zu starr.

  • Lösung: Die Konfiguration wurde mit einer rewrite-Regel angepasst, um sicherzustellen, dass der gesamte Pfad korrekt an den lead-engine-Dienst weitergegeben wird und die notwendigen Proxy-Header für moderne Webanwendungen gesetzt sind.

            location /feedback/ {
                auth_basic off;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "upgrade";
                rewrite ^/feedback/(.*)$ /$1 break;
                proxy_pass http://lead-engine:8004;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
            }
    
    • Aktion nach Änderung: Nach dem Anpassen von nginx-proxy-clean.conf muss der Nginx-Container neu gestartet werden: docker-compose restart nginx

3. Behebung des lead-engine Service-Absturzes (SyntaxError) Der lead-engine-Dienst selbst stürzte aufgrund eines Python SyntaxError ab, der durch einen ungültigen Import-Pfad verursacht wurde, der Bindestriche enthielt. Dies verhinderte, dass der Dienst überhaupt eine Antwort senden konnte, was ebenfalls zu einer leeren iFrame-Anzeige beitrug.

  • Problem: Eine Zeile from connector-superoffice.superoffice_client import SuperOfficeClient in manager.py verursachte einen SyntaxError, da Bindestriche in Python-Modulnamen nicht erlaubt sind.

  • Lösung: Die fehlerhafte sys.path.append-Anweisung und die ungültige import-Zeile wurden aus lead-engine/trading_twins/manager.py entfernt, da sie Teil eines verschobenen Tasks waren.

    • Aktion nach Änderung: Nach der Korrektur in manager.py muss der lead-engine-Container neu gebaut und neu gestartet werden: docker-compose up -d --build --force-recreate lead-engine

Durch diese Maßnahmen wird die iFrame-Integration nun robust funktionieren und immer eine sinnvolle Ansicht auf der WordPress-Landingpage bieten.

🚀 Inbetriebnahme & Test

Inbetriebnahme

# Neustart des Dienstes
docker-compose up -d --build --force-recreate lead-engine

Test & Debugging

  • Allgemeiner Test: Die URL https://floke-ai.duckdns.org/feedback/test_lead löst einen generischen Test-Lead aus.
  • Spezifischer Test pro Lead: Im Lead-Tool (/lead/) kann für jeden Lead mit einem generierten E-Mail-Entwurf der Button "🧪 Test-Versand (an floke.com@gmail.com)" geklickt werden. Dies startet den gesamten End-to-End-Prozess (Teams-Nachricht & E-Mail-Versand) für den ausgewählten Lead, sendet die E-Mail aber sicher an die Test-Adresse.

Zugriff: https://floke-ai.duckdns.org/lead/ (Passwortgeschützt)

📝 Zukünftige Erweiterungen & Todos

Task: Automatisches Nachfassen (Follow-up)

  • Problem: Wenn ein Lead nicht auf die E-Mail antwortet und auch keinen Termin bucht, geht der Kontakt verloren.
  • Lösung: Einbindung eines Follow-up-Mechanismus nach 5 Tagen. Dies könnte entweder durch ein Flag im CRM-System oder durch eine geplante E-Mail direkt über die Lead-Engine realisiert werden.

Task: Erfolgsmessung & Tracking (Microsoft Bookings Auswertung)

  • Ziel: Übersicht gewinnen, wie viele Meetings tatsächlich über diesen neuen Kanal (Trading Twins / E-Mail) final gebucht wurden.
  • Lösungsweg (Pragmatischer Ansatz):
    1. Die E-Mail-Adresse der geteilten Bookings-Seite (KennenlernenmitRoboplanet@wackler-group.de) muss von der IT zur bestehenden Exchange ApplicationAccessPolicy der CAL_APPID hinzugefügt werden.
    2. Dadurch kann unsere bestehende "Lese-App" auch die Termine dieses zentralen Postfachs über die MS Graph API (GET /users/{bookings-email}/calendar/events) auslesen.
    3. Ein geplanter Job (z.B. täglich oder wöchentlich) zählt die neu hinzugekommenen Termine und erstellt einen kurzen KPI-Report.

Task: CRM-Synchronisierung der gebuchten Termine (SuperOffice)

  • Ziel: Die über Bookings generierten Termine müssen für die Historie und Dokumentation im CRM-System (SuperOffice) landen.
  • Lösung: Die im vorherigen Task ausgelesenen Termine werden über den connector-superoffice an das CRM übergeben und dort als "Termin" oder "Aktivität" direkt beim entsprechenden Kontakt (gematcht über die E-Mail-Adresse) abgelegt.
# Info-Postfach (App 1 - Schreiben)
INFO_Application_ID=...
INFO_Tenant_ID=...
INFO_Secret=...

# E.Melcer Kalender (App 2 - Lesen)
CAL_APPID=...
CAL_TENNANT_ID=...
CAL_SECRET=...

# URLs
TEAMS_WEBHOOK_URL=...
FEEDBACK_SERVER_BASE_URL=https://floke-ai.duckdns.org/feedback
WORDPRESS_BOOKING_URL=https://www.robo-planet.de/terminbestaetigung
MS_BOOKINGS_URL=https://outlook.office365.com/book/KennenlernenmitRoboplanet@wackler-group.de/