# Motia Advoware-EspoCRM Integration Dieses Projekt implementiert eine robuste Integration zwischen Advoware und EspoCRM über das Motia-Framework. Es bietet eine vollständige API-Proxy für Advoware und Webhook-Handler für EspoCRM, um Änderungen an Beteiligte-Entitäten zu synchronisieren. ## Übersicht Das System besteht aus drei Hauptkomponenten: 1. **Advoware API Proxy**: Vollständige REST-API-Proxy für alle HTTP-Methoden (GET, POST, PUT, DELETE) 2. **EspoCRM Webhook Receiver**: Empfängt Webhooks für CRUD-Operationen auf Beteiligte-Entitäten 3. **Event-Driven Sync**: Verarbeitet Synchronisationsereignisse mit Redis-basierter Deduplikation ## Architektur ### Komponenten - **Motia Framework**: Event-driven Backend-Orchestrierung - **Python Steps**: Asynchrone Verarbeitung mit aiohttp und redis-py - **Advoware API Client**: Authentifizierte API-Kommunikation mit Token-Management - **Redis**: Deduplikation von Webhook-Events und Caching - **EspoCRM Integration**: Webhook-Handler für create/update/delete Operationen ### Datenfluss ``` EspoCRM Webhook → VMH Webhook Receiver → Redis Deduplication → Event Emission → Sync Handler Advoware API → Proxy Steps → Response ``` ## Setup ### Voraussetzungen - Python 3.13+ - Node.js 18+ - Redis Server - Motia CLI ### Installation 1. **Repository klonen und Dependencies installieren:** ```bash cd /opt/motia-app/bitbylaw npm install pip install -r requirements.txt ``` 2. **Umgebungsvariablen konfigurieren:** Erstellen Sie eine `.env`-Datei mit folgenden Variablen: ```env ADVOWARE_BASE_URL=https://api.advoware.com ADVOWARE_USERNAME=your_username ADVOWARE_PASSWORD=your_password REDIS_URL=redis://localhost:6379 ESPOCRM_WEBHOOK_SECRET=your_webhook_secret ``` 3. **Redis starten:** ```bash redis-server ``` 4. **Motia starten:** ```bash motia start ``` ## Verwendung ### Advoware API Proxy Die Proxy-Endpunkte spiegeln die Advoware-API wider: - `GET /api/advoware/*` - Daten abrufen - `POST /api/advoware/*` - Neue Ressourcen erstellen - `PUT /api/advoware/*` - Ressourcen aktualisieren - `DELETE /api/advoware/*` - Ressourcen löschen **Beispiel:** ```bash curl -X GET "http://localhost:3000/api/advoware/employees" ``` Für detaillierte Informationen zu den Proxy-Steps siehe [steps/advoware_proxy/README.md](steps/advoware_proxy/README.md). ### EspoCRM Webhooks Webhooks werden automatisch von EspoCRM gesendet für Änderungen an Beteiligte-Entitäten: - **Create**: `/webhooks/vmh/beteiligte/create` - **Update**: `/webhooks/vmh/beteiligte/update` - **Delete**: `/webhooks/vmh/beteiligte/delete` Für detaillierte Informationen zu den Webhook- und Sync-Steps siehe [steps/vmh/README.md](steps/vmh/README.md). ### Synchronisation Die Synchronisation läuft event-driven ab: 1. Webhook-Events werden in Redis-Queues dedupliziert 2. Events werden an den Sync-Handler emittiert 3. Sync-Handler verarbeitet die Änderungen (aktuell Placeholder) ## Konfiguration ### Motia Workbench Die Flows sind in `motia-workbench.json` definiert: - `advoware-proxy`: API-Proxy-Flows - `vmh-webhook`: Webhook-Receiver-Flows - `beteiligte-sync`: Synchronisations-Flow ### Redis Keys - `vmh:webhook:create`: Create-Event Queue - `vmh:webhook:update`: Update-Event Queue - `vmh:webhook:delete`: Delete-Event Queue ## Entwicklung ### Projektstruktur ``` bitbylaw/ ├── steps/ │ ├── advoware_proxy/ # API Proxy Steps - siehe [README](steps/advoware_proxy/README.md) │ │ ├── advoware_api_proxy_get_step.py │ │ ├── advoware_api_proxy_post_step.py │ │ ├── advoware_api_proxy_put_step.py │ │ └── advoware_api_proxy_delete_step.py │ └── vmh/ # VMH Webhook & Sync Steps - siehe [README](steps/vmh/README.md) │ ├── webhook/ # Webhook Receiver Steps │ │ ├── beteiligte_create_api_step.py │ │ ├── beteiligte_update_api_step.py │ │ └── beteiligte_delete_api_step.py │ └── beteiligte_sync_event_step.py # Sync Handler ├── services/ │ └── advoware.py # API Client ├── config.py # Configuration ├── motia-workbench.json # Flow Definitions ├── package.json ├── requirements.txt └── tsconfig.json ``` ### Testing **API Proxy testen:** ```bash curl -X GET "http://localhost:3000/api/advoware/employees" ``` **Webhook simulieren:** ```bash curl -X POST "http://localhost:3000/webhooks/vmh/beteiligte/create" \ -H "Content-Type: application/json" \ -d '{"id": "123", "name": "Test Beteiligte"}' ``` ### Logging Alle Steps enthalten detaillierte Logging-Ausgaben für Debugging: - API-Requests/Responses - Redis-Operationen - Event-Emission - Fehlerbehandlung ## Deployment ### Docker ```dockerfile FROM python:3.13-slim WORKDIR /app COPY requirements.txt . RUN pip install -r requirements.txt COPY . . EXPOSE 3000 CMD ["motia", "start"] ``` ### Production Setup 1. Redis Cluster für Hochverfügbarkeit 2. Load Balancer für API-Endpunkte 3. Monitoring für Sync-Operationen 4. Backup-Strategie für Redis-Daten ## Fehlerbehebung ### Häufige Probleme 1. **Context Attribute Error**: Verwenden Sie `Config` statt `context.config` 2. **Redis Connection Failed**: Überprüfen Sie Redis-URL und Netzwerkverbindung 3. **Webhook Duplikate**: Redis-Deduplikation verhindert Mehrfachverarbeitung ### Logs überprüfen ```bash motia logs ``` ## Calendar Sync Das System enthält auch eine bidirektionale Kalender-Synchronisation zwischen Advoware und Google Calendar. ### Architektur - **PostgreSQL Hub**: Speichert Sync-Zustand und verhindert Datenverlust - **Event-Driven Sync**: 4-Phasen-Sync (Neu, Gelöscht, Aktualisiert) - **Safe Wrappers**: Globale Write-Protection für Advoware-Schreiboperationen - **Rate Limiting**: Backoff-Handling für Google Calendar API-Limits ### Dauertermine (Recurring Appointments) Advoware verwendet `dauertermin=1` für wiederkehrende Termine mit folgenden Feldern: - `turnus`: Intervall (z.B. 1 = jeden, 3 = jeden 3.) - `turnusArt`: Frequenz-Einheit - `1` = Täglich (DAILY) - `2` = Wöchentlich (WEEKLY) - `3` = Monatlich (MONTHLY) - `4` = Jährlich (YEARLY) - `datumBis`: Enddatum der Wiederholung **RRULE-Generierung:** ``` RRULE:FREQ={FREQ};INTERVAL={turnus};UNTIL={datumBis} ``` Beispiel: `turnus=3, turnusArt=1` → `RRULE:FREQ=DAILY;INTERVAL=3;UNTIL=20251224` ### Setup 1. **Google Service Account**: `service-account.json` im Projektroot 2. **Umgebungsvariablen**: ```env ADVOWARE_WRITE_PROTECTION=false # Global write protection POSTGRES_HOST=localhost GOOGLE_CALENDAR_SERVICE_ACCOUNT_PATH=service-account.json ``` 3. **Trigger Sync**: ```bash curl -X POST "http://localhost:3000/advoware/calendar/sync" -H "Content-Type: application/json" -d '{"full_content": true}' ``` ### Rate Limiting & Backoff - **Google Calendar API**: 403-Fehler bei Rate-Limits werden mit exponentiellem Backoff (max. 60s) wiederholt - **Delays**: 100ms zwischen API-Calls zur Vermeidung von Limits - **Retry-Logic**: Max. 4 Versuche mit base=4 ### Sicherheit - **Write Protection**: `ADVOWARE_WRITE_PROTECTION=true` deaktiviert alle Advoware-Schreiboperationen - **Per-User Calendars**: Automatische Erstellung und Freigabe von Google-Calendars pro Mitarbeiter ### Troubleshooting - **Rate Limit Errors**: Logs zeigen Backoff-Retries; warten oder Limits erhöhen - **Sync Failures**: `ADVOWARE_WRITE_PROTECTION=false` setzen für Debugging - **Calendar Access**: Service Account muss Owner-Rechte haben ## Lizenz [License Information] ## Beitrag Bitte erstellen Sie Issues für Bugs oder Feature-Requests. Pull-Requests sind willkommen!