Vorschau-Feature — Apps befindet sich derzeit in der Vorschau-Phase. Funktionalität und API können sich
noch ändern. Wir freuen uns über Feedback!
Apps ermöglichen es, eigene HTML-Anwendungen direkt in Enneo zu erstellen und auszuführen.
Nutzen Sie Apps für individuelle Dashboards, Berichte, Formulare oder Tools — alles im vertrauten Enneo-Interface.
Überblick
Apps sind benutzerdefinierte Anwendungen, die HTML zurückgeben und direkt in Enneo als eigene Seite
angezeigt werden. Jede App wird in einer Sandbox ausgeführt und hat Zugriff auf die Enneo-API.
Typische Anwendungsfälle:
- Individuelle Dashboards — Echtzeitdaten aus dem ERP oder CRM visualisieren
- Berichte und Auswertungen — Maßgeschneiderte Reports mit eigener Logik
- Interne Tools — Formulare, Kalkulatoren oder Workflow-Helfer
- Datenabfragen — Vertragsdaten, Kundenstatus oder Statistiken anzeigen
Aufbau einer App
Jede App besteht aus:
| Bestandteil | Beschreibung |
|---|
| Name | Anzeigename in der Seitenleiste und in den Einstellungen |
| Slug | Eindeutiger technischer Bezeichner (z.B. mein-dashboard). Wird in der URL verwendet |
| Beschreibung | Optionale Beschreibung des Zwecks der App |
| Anbieter | Optional: Wer die App erstellt hat |
| Executor | Der Code, der bei Aufruf ausgeführt wird (Python, Node.js oder PHP) |
Executor
Der Executor verwendet das Standard-Executor-Format von Enneo (gleicher Aufbau wie bei Einstellungen und KI-Agenten).
Er unterstützt aktuell den Typ Quellcode mit den Sprachen Python 3.11, Node.js 20 und PHP 8.2.
Die Ausgabe auf stdout wird als HTML an den Browser zurückgegeben.
# Einfache App: Begrüßungsseite
print("<h1>Willkommen</h1>")
print("<p>Dies ist meine erste Enneo-App.</p>")
Eingabeparameter
Bei jedem Aufruf erhält der Code automatisch Metadaten als Parameter über STDIN:
{
"_metadata": {
"userId": 1,
"clientId": "1",
"appId": "a1b2c3d4-...",
"appRevision": 3,
"userAuthToken": "Bearer ..."
}
}
Zusätzliche GET- oder POST-Parameter werden automatisch übergeben und stehen im Code zur Verfügung.
Umgebungsvariablen
Folgende Umgebungsvariablen stehen im App-Code zur Verfügung:
| Variable | Beschreibung |
|---|
ENNEO_API_URL | Basis-URL der Enneo-API |
ENNEO_SESSION_TOKEN | Session-Token für API-Aufrufe |
ENNEO_USER_AUTH_HEADER | Auth-Header des aufrufenden Benutzers |
ENNEO_APP_ID | UUID der App |
ENNEO_APP_SLUG | Slug der App |
ENNEO_APP_VERSION | Version der App (z.B. 1.0.0) |
SDK | Pfad zur SDK-Datei |
Apps nutzen
Seitenleiste
Sobald mindestens eine App existiert und der Benutzer die Berechtigung readApps hat, erscheint
in der Seitenleiste der Menüpunkt Apps. Hier werden alle verfügbaren Apps als Tabs angezeigt.
Die App-URL im Browser verwendet den Slug der App:
App aufrufen
Jede App wird in einem iFrame innerhalb von Enneo ausgeführt. Die API-URL akzeptiert sowohl UUID als auch Slug:
/api/mind/app/{slug}/run
/api/mind/app/{appId}/run
GET-Parameter können direkt angehängt werden:
/api/mind/app/mein-dashboard/run?param1=wert1¶m2=wert2
App Storage
Apps können persistente Daten speichern und lesen. Der App Storage ist ein Key-Value-Store,
der pro App isoliert ist. Die Werte werden als JSON gespeichert.
SDK-Zugriff
# Wert speichern
sdk.AppStorage.save("counter", 42)
sdk.AppStorage.save("config", {"theme": "dark", "lang": "de"})
# Wert lesen
counter = sdk.AppStorage.get("counter") # → 42
config = sdk.AppStorage.get("config") # → {"theme": "dark", "lang": "de"}
# Wert mit Metadaten lesen
meta = sdk.AppStorage.get_meta("counter")
# → {"key": "counter", "value": 42, "createdAt": "...", "modifiedAt": "...", "lastAccessAt": "..."}
# Alle Schlüssel auflisten
keys = sdk.AppStorage.list_keys()
# → [{"key": "counter", "createdAt": "...", ...}, ...]
# Wert löschen
sdk.AppStorage.delete("counter")
App-Info
Über die Klasse AppInfo können App-Metadaten abgerufen werden:
app_id = sdk.AppInfo.get_id() # UUID der App
app_slug = sdk.AppInfo.get_slug() # Slug der App
app_version = sdk.AppInfo.get_version() # Version (z.B. "1.0.0")
Unterstützte Werttypen
| Typ | Beispiel |
|---|
| String | "hello world" |
| Zahl | 42, 3.14 |
| Boolean | true, false |
| Null | null |
| Objekt | {"key": "value"} |
| Array | [1, "two", 3.0] |
Apps verwalten
Die Verwaltung erfolgt unter Einstellungen → Erweiterte Einstellungen → Apps.
Neue App erstellen
- Navigieren Sie zu Einstellungen → Apps
- Klicken Sie auf App erstellen
- Geben Sie Name, Slug und optional Beschreibung ein
- Schreiben Sie den Executor-Code
- Nutzen Sie die Vorschau, um die Ausgabe zu prüfen
- Klicken Sie auf Speichern
App bearbeiten
Jede Änderung erstellt automatisch eine neue Revision. So können Sie jederzeit zu einer
früheren Version zurückkehren.
Ungespeicherte Änderungen werden durch ein Entwurf-Tag in der Seitenleiste angezeigt.
Beim Navigieren mit ungespeicherten Änderungen erscheint eine Warnung.
Export und Import
Apps können als JSON exportiert und importiert werden. Der Export-Button befindet sich
im Tab Spezifikationen. Dies ermöglicht den Transfer zwischen Umgebungen.
Revisionen und Rollback
Apps unterstützen Versionierung:
- Jede Speicherung erstellt eine neue Revision
- Über die Revisions-Übersicht können Sie zu jeder früheren Version zurückkehren
- Die aktive Revision wird den Benutzern angezeigt
Berechtigungen
| Berechtigung | Beschreibung | Standard-Rollen |
|---|
readApps | Apps ansehen und ausführen | Admin, Agent |
appCreator | Apps erstellen, bearbeiten und Vorschau | Admin |
manageApps | Apps importieren und löschen | Admin |
Beispiele
Dashboard mit Vertragsdaten
import importlib.util, os, json, sys
# SDK laden
file_path = os.getenv('SDK', 'sdk.py')
spec = importlib.util.spec_from_file_location('sdk', file_path)
sdk = importlib.util.module_from_spec(spec)
spec.loader.exec_module(sdk)
# Eingabedaten laden
input_data = sdk.load_input_data()
metadata = input_data.get('_metadata', {})
# Vertragsdaten laden (Beispiel)
contract_id = input_data.get('contractId', '715559')
try:
contract = sdk.ApiEnneo.get_contract(contract_id)
name = f"{contract.get('firstname', '')} {contract.get('lastname', '')}"
status = contract.get('status', 'Unbekannt')
except Exception:
name = "Nicht gefunden"
status = "-"
# HTML ausgeben
print(f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{ font-family: Arial, sans-serif; padding: 20px; }}
.card {{ background: #f5f5f5; padding: 16px; border-radius: 8px; margin: 8px 0; }}
h1 {{ color: #333; }}
</style>
</head>
<body>
<h1>Vertragsübersicht</h1>
<div class="card">
<strong>Name:</strong> {name}<br>
<strong>Status:</strong> {status}<br>
<strong>Vertragsnummer:</strong> {contract_id}
</div>
</body>
</html>
""")
App mit persistentem Zähler
import importlib.util, os, json, sys, html
file_path = os.getenv('SDK', 'sdk.py')
spec = importlib.util.spec_from_file_location('sdk', file_path)
sdk = importlib.util.module_from_spec(spec)
spec.loader.exec_module(sdk)
input_data = sdk.load_input_data()
# Zähler aus App Storage laden
try:
counter = sdk.AppStorage.get("page_views")
except Exception:
counter = 0
# Zähler erhöhen und speichern
counter += 1
sdk.AppStorage.save("page_views", counter)
print(f"""
<!DOCTYPE html>
<html>
<body style="font-family: Arial, sans-serif; padding: 20px;">
<h1>Besucherzähler</h1>
<p>Diese Seite wurde <strong>{counter}</strong> mal aufgerufen.</p>
<p><em>Der Wert wird im App Storage gespeichert und bleibt über Seitenaufrufe hinweg erhalten.</em></p>
</body>
</html>
""")
Statische Info-Seite
print("""
<!DOCTYPE html>
<html>
<head>
<style>
body { font-family: Arial, sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
.info { background: #e8f5e9; padding: 16px; border-radius: 8px;
border-left: 4px solid #4caf50; }
.warning { background: #fff3e0; padding: 16px; border-radius: 8px;
border-left: 4px solid #ff9800; }
</style>
</head>
<body>
<h1>Wichtige Informationen</h1>
<div class="info">
<strong>Servicezeiten:</strong> Mo-Fr, 8:00 - 18:00 Uhr
</div>
<br>
<div class="warning">
<strong>Hinweis:</strong> Wartungsarbeiten am Wochenende geplant.
</div>
</body>
</html>
""")
Apps haben Zugriff auf das gleiche Enneo SDK, das auch für regelbasierte KI-Agenten verwendet wird.
Damit können Sie Verträge abfragen, Tickets lesen, Einstellungen abrufen und externe APIs aufrufen.
Weitere Informationen finden Sie in der SDK-Dokumentation.
API-Referenz
App-Verwaltung
| Methode | Endpunkt | Beschreibung |
|---|
GET | /api/mind/app | Alle Apps auflisten |
POST | /api/mind/app | Neue App erstellen |
GET | /api/mind/app/{appId} | App-Details abrufen (UUID oder Slug) |
PATCH | /api/mind/app/{appId} | App aktualisieren (neue Revision) |
DELETE | /api/mind/app/{appId} | App löschen |
GET | /api/mind/app/{appId}/revisions | Alle Revisionen anzeigen |
POST | /api/mind/app/{appId}/rollback/{revision} | Auf Revision zurücksetzen |
POST | /api/mind/app/{appId}/preview | Vorschau ausführen |
POST | /api/mind/app/import | App importieren |
GET/POST | /api/mind/app/{appId}/run | App ausführen (HTML-Antwort) |
App Storage
| Methode | Endpunkt | Beschreibung |
|---|
GET | /api/mind/app/{appId}/data | Alle Schlüssel auflisten |
GET | /api/mind/app/{appId}/data/{key} | Wert lesen |
GET | /api/mind/app/{appId}/data/{key}/meta | Wert mit Metadaten lesen |
PUT | /api/mind/app/{appId}/data/{key} | Wert speichern/aktualisieren |
DELETE | /api/mind/app/{appId}/data/{key} | Schlüssel löschen |
Alle Endpunkte akzeptieren sowohl die App-UUID als auch den Slug als {appId}.
Das Executor-Objekt in data.executorUser folgt dem Standard-Executor-Format:
{
"id": 1,
"code": "print('<h1>Hello</h1>')",
"type": "sourceCode",
"language": "python311",
"packages": null,
"parameters": [],
"parameterDefinitions": []
}