- Fix Python syntax error: change 'true' to 'True' in config.py - Limit recurring events to max 2 years to avoid Google Calendar API limits - Add share_google_calendar function for manual calendar sharing - Update README with calendar sync documentation - Debug mode: limit sync to user AI only
275 lines
7.7 KiB
Markdown
275 lines
7.7 KiB
Markdown
# 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! |