Files
Brancheneinstufung2/connector-superoffice/README.md

146 lines
6.6 KiB
Markdown

# SuperOffice Connector ("The Butler") - GTM Engine
Dies ist der Microservice zur Anbindung von **SuperOffice CRM** an die **GTM-Engine**.
Der Connector agiert als "Butler": Er bereitet im Hintergrund hyper-personalisierte Marketing-Texte vor und legt sie im CRM ab, damit der Vertrieb sie mit minimalem Aufwand versenden kann.
## 1. Architektur: Das "Butler-Modell"
Wir haben uns gegen eine komplexe Automatisierung *innerhalb* von SuperOffice (via CRMScript-Trigger) entschieden, da die DEV-Umgebung limitiert ist und die Logik extern flexibler ist.
**Der Datenfluss:**
1. **Master-Daten (Notion):** Pains & Gains werden pro Vertical in Notion gepflegt.
2. **Text-Matrix (Lokal):** Das Skript `build_matrix.py` "multipliziert" die Vertical-Daten mit den Rollen-Daten, generiert via Gemini die finalen Texte und speichert sie in einer lokalen SQLite DB (`marketing_matrix.db`).
3. **Polling & Injection (Daemon):** Das Skript `polling_daemon_final.py` läuft periodisch, prüft auf Änderungen an Kontakten in SuperOffice und "injiziert" die passenden Texte aus der lokalen Matrix-DB in die UDF-Felder.
```mermaid
graph TD
subgraph "A: Strategie & Content"
NotionDB["🏢 Notion DB<br/>(Industries & Roles)"]
end
subgraph "B: Lokale Engine (Python)"
MatrixBuilder["⚙️ build_matrix.py"]
GeminiAPI["🧠 Gemini API"]
MatrixDB[("💾 marketing_matrix.db")]
PollingDaemon["🤖 polling_daemon_final.py"]
end
subgraph "C: CRM-System"
SuperOfficeAPI["☁️ SuperOffice API"]
Contact["👤 Contact / Person<br/>(mit UDFs)"]
end
NotionDB -->|1. Liest Pains/Gains| MatrixBuilder
MatrixBuilder -->|2. Promptet| GeminiAPI
GeminiAPI -->|3. Generiert Texte| MatrixBuilder
MatrixBuilder -->|4. Speichert in DB| MatrixDB
PollingDaemon -->|5. Prüft Änderungen| SuperOfficeAPI
PollingDaemon -->|6. Holt passende Texte| MatrixDB
PollingDaemon -->|7. Schreibt in UDFs| SuperOfficeAPI
SuperOfficeAPI -->|8. Aktualisiert| Contact
```
## 2. Kern-Komponenten (Skripte)
* **`superoffice_client.py`:**
* Das Herzstück. Eine Python-Klasse, die die gesamte Kommunikation mit der SuperOffice API kapselt (Auth, GET, PUT, Search).
* Beherrscht Paginierung, um auch große Datensätze zu verarbeiten.
* **`build_matrix.py`:**
* Der "Content Generator".
* Liest Pains/Gains aus Notion.
* Iteriert über definierte Verticals und Rollen.
* Nutzt Gemini, um die spezifischen Textbausteine (`Subject`, `Intro`, `SocialProof`) zu erstellen.
* Speichert das Ergebnis in der `marketing_matrix.db`.
* **`polling_daemon_final.py`:**
* Der Automatisierungs-Motor.
* Läuft in einer Schleife (z.B. alle 15 Minuten) nur zu Geschäftszeiten (Mo-Fr, 7-18 Uhr).
* Fragt SuperOffice nach kürzlich geänderten Kontakten.
* Nutzt ein **Hash-System**, um zu prüfen, ob sich eine *relevante* Eigenschaft (Vertical oder Rolle) geändert hat, um unnötige API-Schreibvorgänge zu vermeiden.
* Wenn eine Änderung erkannt wird, stößt er den Update-Prozess an.
* **`normalize_persona.py`:**
* Ein Hilfs-Skript (Classifier), um Jobtitel auf unsere 4 Archetypen (Operativ, Infrastruktur, Wirtschaftlich, Innovation) zu mappen.
## 3. Setup & Konfiguration
### Installation
```bash
# In einer Python 3.11+ Umgebung:
pip install -r requirements.txt
```
### Konfiguration (`.env`)
Der Connector benötigt eine `.env` Datei im Root-Verzeichnis mit folgendem Inhalt:
```ini
# Gemini API Keys (DEV für Tests, PROD für Live-Tools)
GEMINI_API_KEY_DEV="AIza..."
GEMINI_API_KEY_PROD="AIza..."
GEMINI_API_KEY=${GEMINI_API_KEY_DEV} # Setzt den Default
# Notion
NOTION_API_KEY="secret_..."
# SuperOffice Client Configuration
SO_CLIENT_ID="<Client ID / App ID>"
SO_CLIENT_SECRET="<Client Secret>"
SO_CONTEXT_IDENTIFIER="CustXXXXX"
SO_REFRESH_TOKEN="<Refresh Token>"
SO_ENVIRONMENT="sod" # oder "online" für Produktion
```
## 4. SuperOffice Konfiguration (Admin)
Folgende **Benutzerdefinierte Felder (UDFs)** müssen angelegt sein. Die ProgIds sind umgebungs-spezifisch und müssen pro System (DEV/PROD) geprüft werden.
| Objekt | Feldname (Label) | Typ | ProgId (DEV) | ProgId (PROD) |
| :--- | :--- | :--- | :--- | :--- |
| Firma | Contact Vertical | Liste | `SuperOffice:5` | *tbd* |
| Firma | AI Challenge Satz | Text | `SuperOffice:6` | *tbd* |
| Person | Person Role | Liste | `SuperOffice:3` | *tbd* |
| Person | Marketing Subject | Text | `SuperOffice:5` | *tbd* |
| Person | Marketing Intro | Text | `SuperOffice:6` | *tbd* |
| Person | Marketing Proof | Text | `SuperOffice:7` | *tbd* |
| Person | AI Copy Hash | Text | `SuperOffice:8` | *tbd* |
### B. Listen-Werte & IDs (DEV Environment)
Folgende IDs werden in den Skripten als Referenz genutzt. Diese müssen für PROD neu validiert werden.
**MA Status (`x_ma_status`):**
* `Init`
* `Ready_to_Craft`
* `Ready_to_Send`
* `Sent_Week1`
* `...`
**Rollen (`x_person_role` / `SuperOffice:3`):**
| ID | Name |
| :--- | :--- |
| `19` | Operativer Entscheider |
| `20` | Infrastruktur-Verantwortlicher |
| `21` | Wirtschaftlicher Entscheider |
| `22` | Innovations-Treiber |
**Verticals (`x_contact_vertical` / `SuperOffice:5`):**
| ID | Name |
| :--- | :--- |
| `23` | Logistics - Warehouse |
| `24` | Healthcare - Hospital |
| `25` | Infrastructure - Transport |
| `26` | Leisure - Indoor Active |
| `...` | *tbd* |
## 5. "Gotchas" & Lessons Learned (Update Feb 16, 2026)
* **API-URL:** Der `sod` Tenant `Cust55774` ist nur über `https://app-sod.superoffice.com` erreichbar.
* **Listen-IDs:** Die API gibt IDs von Listenfeldern im Format `[I:26]` zurück. Der String muss vor der DB-Abfrage auf den Integer `26` geparst werden.
* **Write-Back (Stammfelder):**
* **UrlAddress & Phones:** Das einfache Root-Feld `UrlAddress` ist beim `PUT` oft schreibgeschützt. Um die Website oder Telefonnummern zu setzen, muss die entsprechende Liste (`Urls` oder `Phones`) als Array von Objekten gesendet werden (z.B. `{"Value": "...", "Description": "..."}`).
* **Mandatory Fields:** Beim Update eines `Contact` Objekts müssen Pflichtfelder wie `Name` und `Number2` (oder `Number1`) zwingend im Payload enthalten sein, sonst schlägt die Validierung serverseitig fehl.
* **Full Object PUT:** SuperOffice REST überschreibt das gesamte Objekt. Felder, die im `PUT`-Payload fehlen, werden im CRM geleert. Es empfiehlt sich, das Objekt erst per `GET` zu laden, die Änderungen vorzunehmen und dann das gesamte Objekt zurückzusenden.
* **Dev-System Limits:** Die Textfelder im DEV-System sind auf 40 Zeichen limitiert.
* **Y-Tabellen & Trigger:** Direkter Zugriff auf Zusatz-Tabellen und CRMScript-Trigger sind im SOD-DEV Mandanten blockiert.