# 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
```text
/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.
```html
```
**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.
```nginx
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
```bash
# 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.
```env
# 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/
```