619 lines
16 KiB
Markdown
619 lines
16 KiB
Markdown
# n8n-nodes-librebooking
|
||
|
||
Ein vollständiger n8n Node für die Integration mit [LibreBooking](https://librebooking.org/) - einer Open-Source Ressourcen- und Raumbuchungslösung.
|
||
|
||
<!-- Badges -->
|
||
[](https://www.npmjs.com/package/n8n-nodes-librebooking)
|
||
[](https://opensource.org/licenses/MIT)
|
||
[](https://n8n.io)
|
||
[](https://librebooking.org)
|
||
[](https://nodejs.org)
|
||
[](https://www.typescriptlang.org)
|
||
|
||
---
|
||
|
||
## ⚡ Schnellstart
|
||
|
||
### Option 1: Mit Installations-Skript (empfohlen)
|
||
|
||
```bash
|
||
# Archiv entpacken
|
||
tar -xzf n8n-nodes-librebooking.tar.gz
|
||
cd n8n-nodes-librebooking
|
||
|
||
# Installieren (Linux/Mac)
|
||
./install.sh
|
||
|
||
# n8n starten
|
||
n8n start
|
||
```
|
||
|
||
### Option 2: Mit Docker
|
||
|
||
```bash
|
||
# Archiv entpacken und starten
|
||
tar -xzf n8n-nodes-librebooking.tar.gz
|
||
cd n8n-nodes-librebooking
|
||
docker-compose up -d
|
||
|
||
# Browser öffnen: http://localhost:5678
|
||
```
|
||
|
||
### Option 3: Manuell mit npm
|
||
|
||
```bash
|
||
cd n8n-nodes-librebooking
|
||
npm install && npm run build && npm link
|
||
n8n start
|
||
```
|
||
|
||
📖 **Detaillierte Anleitung:** Siehe [INSTALLATION.md](INSTALLATION.md)
|
||
|
||
---
|
||
|
||
## 📋 Inhaltsverzeichnis
|
||
|
||
- [Schnellstart](#-schnellstart)
|
||
- [Funktionen](#-funktionen)
|
||
- [Installation](#-installation)
|
||
- [Konfiguration](#️-konfiguration)
|
||
- [Operationen](#-operationen)
|
||
- [Beispiele](#-beispiele)
|
||
- [Trigger Node](#-trigger-node)
|
||
- [Troubleshooting](#-troubleshooting)
|
||
- [Entwicklung](#-entwicklung)
|
||
- [Lizenz](#-lizenz)
|
||
|
||
---
|
||
|
||
## 🚀 Funktionen
|
||
|
||
### Regular Node (LibreBooking)
|
||
- **Reservierungen**: Erstellen, Abrufen, Aktualisieren, Löschen, Genehmigen, Check-In/Check-Out
|
||
- **Ressourcen**: Verwalten von Räumen, Equipment und anderen buchbaren Ressourcen
|
||
- **Zeitpläne**: Abrufen von Zeitplänen und verfügbaren Slots
|
||
- **Benutzer**: Vollständige Benutzerverwaltung (Admin-Rechte erforderlich)
|
||
- **Konten**: Eigenes Konto verwalten
|
||
- **Gruppen**: Benutzergruppen mit Rollen und Berechtigungen verwalten
|
||
- **Zubehör**: Zubehörteile abrufen
|
||
- **Attribute**: Benutzerdefinierte Felder verwalten
|
||
|
||
### Trigger Node (LibreBooking Trigger)
|
||
- Polling-basierter Trigger für Reservierungs-Events
|
||
- Erkennung neuer Reservierungen
|
||
- Erkennung geänderter Reservierungen
|
||
- Konfigurierbare Filter (Ressource, Zeitplan, Benutzer)
|
||
- Deduplizierung von Events
|
||
|
||
---
|
||
|
||
## 📦 Installation
|
||
|
||
### Über npm (empfohlen)
|
||
|
||
```bash
|
||
npm install n8n-nodes-librebooking
|
||
```
|
||
|
||
### Manuelle Installation
|
||
|
||
1. Laden Sie das Paket herunter oder klonen Sie das Repository:
|
||
```bash
|
||
git clone https://github.com/your-org/n8n-nodes-librebooking.git
|
||
```
|
||
|
||
2. Wechseln Sie ins Verzeichnis und installieren Sie die Abhängigkeiten:
|
||
```bash
|
||
cd n8n-nodes-librebooking
|
||
npm install
|
||
```
|
||
|
||
3. Kompilieren Sie das Projekt:
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
4. Verlinken Sie das Paket für lokale Entwicklung:
|
||
```bash
|
||
npm link
|
||
```
|
||
|
||
5. Verlinken Sie es in Ihrem n8n Custom-Nodes-Verzeichnis:
|
||
```bash
|
||
cd ~/.n8n/custom
|
||
npm link n8n-nodes-librebooking
|
||
```
|
||
|
||
6. Starten Sie n8n neu:
|
||
```bash
|
||
n8n start
|
||
```
|
||
|
||
### Docker-Installation
|
||
|
||
Fügen Sie in Ihrem Docker-Compose oder Dockerfile hinzu:
|
||
|
||
```dockerfile
|
||
RUN npm install -g n8n-nodes-librebooking
|
||
```
|
||
|
||
Oder über Umgebungsvariable:
|
||
```yaml
|
||
environment:
|
||
- N8N_CUSTOM_EXTENSIONS=n8n-nodes-librebooking
|
||
```
|
||
|
||
### Integration in bestehende Docker-Installation
|
||
|
||
Für bestehende n8n Docker-Installationen gibt es mehrere Integrationsmethoden:
|
||
|
||
#### Schnellste Methode: Automatisches Skript
|
||
|
||
```bash
|
||
# Ins n8n Verzeichnis wechseln
|
||
cd /pfad/zu/ihrer/n8n/installation
|
||
|
||
# Skript ausführen
|
||
./install-docker.sh
|
||
```
|
||
|
||
#### Manuelle Methode
|
||
|
||
```bash
|
||
# 1. Custom Nodes kopieren
|
||
cp -r custom-nodes /pfad/zu/n8n/
|
||
cd /pfad/zu/n8n/custom-nodes && npm install && npm run build
|
||
|
||
# 2. docker-compose.override.yml erstellen
|
||
cat > docker-compose.override.yml << 'EOF'
|
||
version: '3.8'
|
||
services:
|
||
n8n:
|
||
volumes:
|
||
- ./custom-nodes:/home/node/.n8n/custom/n8n-nodes-librebooking:ro
|
||
environment:
|
||
- N8N_CUSTOM_EXTENSIONS=/home/node/.n8n/custom
|
||
- N8N_COMMUNITY_NODES_ENABLED=true
|
||
EOF
|
||
|
||
# 3. Container neustarten
|
||
docker-compose restart n8n
|
||
```
|
||
|
||
#### Eigenes Docker-Image bauen
|
||
|
||
```bash
|
||
docker build -f Dockerfile.custom-nodes -t n8n-librebooking .
|
||
docker run -d -p 5678:5678 n8n-librebooking
|
||
```
|
||
|
||
📖 **Ausführliche Docker-Anleitung:** Siehe [DOCKER-INTEGRATION.md](DOCKER-INTEGRATION.md)
|
||
|
||
🚀 **Docker-Schnellstart:** Siehe [SCHNELLSTART-DOCKER.md](SCHNELLSTART-DOCKER.md)
|
||
|
||
---
|
||
|
||
## ⚙️ Konfiguration
|
||
|
||
### Credentials einrichten
|
||
|
||
1. Öffnen Sie n8n und gehen Sie zu **Settings** → **Credentials**
|
||
2. Klicken Sie auf **Add Credential** und wählen Sie **LibreBooking API**
|
||
3. Füllen Sie die folgenden Felder aus:
|
||
|
||
| Feld | Beschreibung | Beispiel |
|
||
|------|-------------|----------|
|
||
| **LibreBooking URL** | Die Basis-URL Ihrer LibreBooking-Installation | `https://booking.example.com` |
|
||
| **Benutzername** | Ihr LibreBooking-Login (E-Mail oder Benutzername) | `admin@example.com` |
|
||
| **Passwort** | Ihr LibreBooking-Passwort | `•••••••••` |
|
||
|
||
> ⚠️ **Wichtig**: Die URL sollte **ohne** `/Web/Services` angegeben werden!
|
||
|
||
### API aktivieren
|
||
|
||
Stellen Sie sicher, dass die API in Ihrer LibreBooking-Installation aktiviert ist:
|
||
|
||
1. Öffnen Sie die `config.php` Ihrer LibreBooking-Installation
|
||
2. Suchen Sie nach `$conf['settings']['api']['enabled']`
|
||
3. Setzen Sie den Wert auf `true`
|
||
|
||
```php
|
||
$conf['settings']['api']['enabled'] = 'true';
|
||
```
|
||
|
||
### Credential-Test
|
||
|
||
Nach dem Speichern der Credentials können Sie diese testen:
|
||
- Klicken Sie auf **Test** um die Verbindung zu überprüfen
|
||
- Bei erfolgreicher Verbindung wird eine Bestätigung angezeigt
|
||
|
||
---
|
||
|
||
## 📖 Operationen
|
||
|
||
### Reservierungen
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Alle Abrufen** | Liste aller Reservierungen mit optionalen Filtern | ❌ |
|
||
| **Abrufen** | Einzelne Reservierung per Referenznummer | ❌ |
|
||
| **Erstellen** | Neue Reservierung anlegen | ❌ |
|
||
| **Aktualisieren** | Bestehende Reservierung ändern | ❌ |
|
||
| **Löschen** | Reservierung entfernen | ❌ |
|
||
| **Genehmigen** | Ausstehende Reservierung genehmigen | ❌* |
|
||
| **Check-In** | In Reservierung einchecken | ❌ |
|
||
| **Check-Out** | Aus Reservierung auschecken | ❌ |
|
||
|
||
*Erfordert Genehmigungsrechte
|
||
|
||
#### Filter für "Alle Abrufen"
|
||
- `userId` - Nach Benutzer filtern
|
||
- `resourceId` - Nach Ressource filtern
|
||
- `scheduleId` - Nach Zeitplan filtern
|
||
- `startDateTime` - Startzeit (ISO 8601)
|
||
- `endDateTime` - Endzeit (ISO 8601)
|
||
|
||
#### Zusätzliche Felder für "Erstellen/Aktualisieren"
|
||
- `description` - Beschreibung
|
||
- `participants` - Teilnehmer (Benutzer-IDs)
|
||
- `invitees` - Eingeladene (Benutzer-IDs)
|
||
- `resources` - Zusätzliche Ressourcen
|
||
- `allowParticipation` - Teilnahme erlauben
|
||
|
||
### Ressourcen
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Alle Abrufen** | Liste aller Ressourcen | ❌ |
|
||
| **Abrufen** | Einzelne Ressource per ID | ❌ |
|
||
| **Verfügbarkeit Prüfen** | Verfügbarkeit einer/aller Ressourcen | ❌ |
|
||
| **Gruppen Abrufen** | Ressourcen-Gruppenstruktur | ❌ |
|
||
| **Typen Abrufen** | Verfügbare Ressourcen-Typen | ❌ |
|
||
| **Status Abrufen** | Verfügbare Status-Werte | ❌ |
|
||
| **Erstellen** | Neue Ressource anlegen | ✅ |
|
||
| **Aktualisieren** | Ressource ändern | ✅ |
|
||
| **Löschen** | Ressource entfernen | ✅ |
|
||
|
||
#### Ressourcen-Optionen
|
||
- `location` - Standort
|
||
- `contact` - Kontaktinformation
|
||
- `description` - Beschreibung
|
||
- `maxParticipants` - Maximale Teilnehmerzahl
|
||
- `requiresApproval` - Genehmigung erforderlich
|
||
- `allowMultiday` - Mehrtägige Buchungen
|
||
- `requiresCheckIn` - Check-In erforderlich
|
||
- `autoReleaseMinutes` - Auto-Release nach X Minuten
|
||
- `color` - Anzeigefarbe (Hex)
|
||
- `statusId` - Status (0=Versteckt, 1=Verfügbar, 2=Nicht verfügbar)
|
||
|
||
### Zeitpläne
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Alle Abrufen** | Liste aller Zeitpläne | ❌ |
|
||
| **Abrufen** | Einzelner Zeitplan mit Perioden | ❌ |
|
||
| **Slots Abrufen** | Verfügbare Slots eines Zeitplans | ❌ |
|
||
|
||
### Benutzer (Admin)
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Alle Abrufen** | Liste aller Benutzer | ❌ |
|
||
| **Abrufen** | Einzelner Benutzer per ID | ❌ |
|
||
| **Erstellen** | Neuen Benutzer anlegen | ✅ |
|
||
| **Aktualisieren** | Benutzer ändern | ✅ |
|
||
| **Passwort Ändern** | Benutzer-Passwort setzen | ✅ |
|
||
| **Löschen** | Benutzer entfernen | ✅ |
|
||
|
||
### Konten
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Abrufen** | Eigene Kontoinformationen | ❌ |
|
||
| **Erstellen** | Neues Konto (Registrierung) | ❌ |
|
||
| **Aktualisieren** | Eigenes Konto ändern | ❌ |
|
||
| **Passwort Ändern** | Eigenes Passwort ändern | ❌ |
|
||
|
||
### Gruppen
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Alle Abrufen** | Liste aller Gruppen | ❌ |
|
||
| **Abrufen** | Einzelne Gruppe | ❌ |
|
||
| **Erstellen** | Neue Gruppe anlegen | ✅ |
|
||
| **Aktualisieren** | Gruppe ändern | ✅ |
|
||
| **Löschen** | Gruppe entfernen | ✅ |
|
||
| **Rollen Ändern** | Gruppenrollen setzen | ✅ |
|
||
| **Berechtigungen Ändern** | Ressourcen-Berechtigungen | ✅ |
|
||
| **Benutzer Ändern** | Gruppenmitglieder | ✅ |
|
||
|
||
#### Rollen-IDs
|
||
- `1` - Gruppenadministrator
|
||
- `2` - Anwendungsadministrator
|
||
- `3` - Ressourcenadministrator
|
||
- `4` - Zeitplanadministrator
|
||
|
||
### Zubehör
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Alle Abrufen** | Liste aller Zubehörteile | ❌ |
|
||
| **Abrufen** | Einzelnes Zubehörteil | ❌ |
|
||
|
||
### Attribute
|
||
|
||
| Operation | Beschreibung | Admin-Rechte |
|
||
|-----------|-------------|--------------|
|
||
| **Abrufen** | Einzelnes Attribut | ❌ |
|
||
| **Nach Kategorie Abrufen** | Alle Attribute einer Kategorie | ❌ |
|
||
| **Erstellen** | Neues Attribut anlegen | ✅ |
|
||
| **Aktualisieren** | Attribut ändern | ✅ |
|
||
| **Löschen** | Attribut entfernen | ✅ |
|
||
|
||
#### Attribut-Kategorien
|
||
- `1` - Reservierung
|
||
- `2` - Benutzer
|
||
- `4` - Ressource
|
||
- `5` - Ressourcen-Typ
|
||
|
||
#### Attribut-Typen
|
||
- `1` - Einzeilig (Text)
|
||
- `2` - Mehrzeilig (Textarea)
|
||
- `3` - Auswahlliste
|
||
- `4` - Checkbox
|
||
- `5` - Datum/Zeit
|
||
|
||
---
|
||
|
||
## 💡 Beispiele
|
||
|
||
### Beispiel 1: Alle Reservierungen der nächsten Woche abrufen
|
||
|
||
```json
|
||
{
|
||
"nodes": [
|
||
{
|
||
"parameters": {
|
||
"resource": "reservation",
|
||
"operation": "getAll",
|
||
"filters": {
|
||
"startDateTime": "={{ $now.toISO() }}",
|
||
"endDateTime": "={{ $now.plus({days: 7}).toISO() }}"
|
||
}
|
||
},
|
||
"name": "LibreBooking",
|
||
"type": "n8n-nodes-librebooking.libreBooking",
|
||
"typeVersion": 1,
|
||
"position": [250, 300],
|
||
"credentials": {
|
||
"libreBookingApi": {
|
||
"id": "1",
|
||
"name": "LibreBooking"
|
||
}
|
||
}
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
### Beispiel 2: Neue Reservierung erstellen
|
||
|
||
```json
|
||
{
|
||
"parameters": {
|
||
"resource": "reservation",
|
||
"operation": "create",
|
||
"resourceId": 1,
|
||
"startDateTime": "2026-01-26T10:00:00",
|
||
"endDateTime": "2026-01-26T11:00:00",
|
||
"title": "Team Meeting",
|
||
"additionalFields": {
|
||
"description": "Wöchentliches Team-Meeting",
|
||
"participants": "2,3,4"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### Beispiel 3: Verfügbarkeit prüfen
|
||
|
||
```json
|
||
{
|
||
"parameters": {
|
||
"resource": "resource",
|
||
"operation": "getAvailability",
|
||
"resourceIdOptional": 1,
|
||
"availabilityDateTime": "2026-01-26T14:00:00"
|
||
}
|
||
}
|
||
```
|
||
|
||
### Beispiel 4: Benutzer mit Filter suchen
|
||
|
||
```json
|
||
{
|
||
"parameters": {
|
||
"resource": "user",
|
||
"operation": "getAll",
|
||
"userFilters": {
|
||
"organization": "Marketing",
|
||
"lastName": "Müller"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## ⚡ Trigger Node
|
||
|
||
Der **LibreBooking Trigger** ist ein Polling-basierter Trigger, der auf neue oder geänderte Reservierungen reagiert.
|
||
|
||
### Konfiguration
|
||
|
||
| Parameter | Beschreibung |
|
||
|-----------|-------------|
|
||
| **Event** | Art des Events (Neue/Geänderte/Alle Reservierungen) |
|
||
| **Filter** | Optional: Ressource, Zeitplan, Benutzer |
|
||
| **Zeitfenster** | Überwachungszeitraum (7/14/30/90 Tage) |
|
||
| **Detaillierte Daten** | Vollständige Reservierungsdetails abrufen |
|
||
|
||
### Event-Typen
|
||
|
||
- **Neue Reservierung**: Wird nur bei neuen Reservierungen ausgelöst
|
||
- **Geänderte Reservierung**: Wird bei Änderungen an bestehenden Reservierungen ausgelöst
|
||
- **Alle Reservierungen**: Wird bei neuen und geänderten Reservierungen ausgelöst
|
||
|
||
### Beispiel-Workflow: Benachrichtigung bei neuer Reservierung
|
||
|
||
```
|
||
[LibreBooking Trigger] → [IF: Ressource = 1] → [Slack: Nachricht senden]
|
||
```
|
||
|
||
### Deduplizierung
|
||
|
||
Der Trigger speichert Informationen über bereits verarbeitete Reservierungen und verhindert so doppelte Ausführungen. Bei Änderungen (Titel, Zeit, etc.) wird eine Reservierung als "geändert" erkannt.
|
||
|
||
---
|
||
|
||
## 🔧 Troubleshooting
|
||
|
||
### Häufige Fehler
|
||
|
||
#### "Authentifizierung fehlgeschlagen"
|
||
- Überprüfen Sie die LibreBooking-URL (ohne `/Web/Services`)
|
||
- Stellen Sie sicher, dass Benutzername und Passwort korrekt sind
|
||
- Prüfen Sie, ob die API in LibreBooking aktiviert ist
|
||
|
||
#### "Zugriff verweigert" (403)
|
||
- Die Operation erfordert Administrator-Rechte
|
||
- Verwenden Sie einen Admin-Account oder wählen Sie eine andere Operation
|
||
|
||
#### "Nicht gefunden" (404)
|
||
- Die angegebene ID (Ressource, Benutzer, etc.) existiert nicht
|
||
- Überprüfen Sie die Referenznummer bei Reservierungen
|
||
|
||
#### "Session abgelaufen"
|
||
- Der Session-Token ist abgelaufen
|
||
- Führen Sie den Workflow erneut aus
|
||
|
||
### API-Limitierungen
|
||
|
||
- LibreBooking hat keine dokumentierten Rate-Limits
|
||
- Bei vielen Anfragen empfehlen wir Pausen zwischen den Operationen
|
||
- Der Node authentifiziert sich bei jeder Ausführung neu und meldet sich am Ende ab
|
||
|
||
### Debug-Tipps
|
||
|
||
1. Aktivieren Sie die n8n-Logs für detaillierte Fehlermeldungen:
|
||
```bash
|
||
export N8N_LOG_LEVEL=debug
|
||
n8n start
|
||
```
|
||
|
||
2. Testen Sie die API direkt im Browser:
|
||
```
|
||
https://your-librebooking.com/Web/Services/index.php
|
||
```
|
||
|
||
3. Überprüfen Sie die Zeitzonen-Einstellungen in LibreBooking und n8n
|
||
|
||
---
|
||
|
||
## 🛠 Entwicklung
|
||
|
||
### Voraussetzungen
|
||
|
||
- Node.js 18.17.0 oder höher
|
||
- npm 9.x oder höher
|
||
- n8n (für Tests)
|
||
|
||
### Setup
|
||
|
||
```bash
|
||
# Repository klonen
|
||
git clone https://github.com/your-org/n8n-nodes-librebooking.git
|
||
cd n8n-nodes-librebooking
|
||
|
||
# Abhängigkeiten installieren
|
||
npm install
|
||
|
||
# TypeScript kompilieren
|
||
npm run build
|
||
|
||
# Für Entwicklung (Watch-Modus)
|
||
npm run dev
|
||
```
|
||
|
||
### Projektstruktur
|
||
|
||
```
|
||
n8n-nodes-librebooking/
|
||
├── credentials/
|
||
│ └── LibreBookingApi.credentials.ts
|
||
├── nodes/
|
||
│ ├── LibreBooking/
|
||
│ │ ├── LibreBooking.node.ts
|
||
│ │ └── librebooking.svg
|
||
│ └── LibreBookingTrigger/
|
||
│ ├── LibreBookingTrigger.node.ts
|
||
│ └── librebooking.svg
|
||
├── workflows/
|
||
│ └── example-workflows.json
|
||
├── test/
|
||
│ └── test-api.ts
|
||
├── package.json
|
||
├── tsconfig.json
|
||
└── README.md
|
||
```
|
||
|
||
### Tests ausführen
|
||
|
||
```bash
|
||
# API-Test mit echten Credentials
|
||
npm test
|
||
```
|
||
|
||
### Linting
|
||
|
||
```bash
|
||
npm run lint
|
||
npm run lint:fix
|
||
```
|
||
|
||
### Build für Produktion
|
||
|
||
```bash
|
||
npm run build
|
||
```
|
||
|
||
---
|
||
|
||
## 📄 Lizenz
|
||
|
||
MIT License - siehe [LICENSE](LICENSE) Datei
|
||
|
||
---
|
||
|
||
## 🤝 Beitragen
|
||
|
||
Beiträge sind willkommen! Bitte öffnen Sie einen Issue oder Pull Request.
|
||
|
||
1. Fork des Repositories
|
||
2. Feature-Branch erstellen (`git checkout -b feature/AmazingFeature`)
|
||
3. Änderungen committen (`git commit -m 'Add AmazingFeature'`)
|
||
4. Branch pushen (`git push origin feature/AmazingFeature`)
|
||
5. Pull Request öffnen
|
||
|
||
---
|
||
|
||
## 📞 Support
|
||
|
||
- **Issues**: [GitHub Issues](https://github.com/your-org/n8n-nodes-librebooking/issues)
|
||
- **LibreBooking Dokumentation**: [https://librebooking.org/docs](https://librebooking.org/docs)
|
||
- **n8n Community**: [https://community.n8n.io](https://community.n8n.io)
|
||
|
||
---
|
||
|
||
**Erstellt mit ❤️ für die n8n und LibreBooking Community**
|