docs: rewrite Starface module guide as step-by-step new build
This commit is contained in:
parent
f89b9b4626
commit
b336bf3573
@ -1,130 +1,345 @@
|
|||||||
# Starface Modulcreator – Busylight Integration
|
# Starface Modul – Busylight Webhook (Neuaufbau)
|
||||||
|
|
||||||
## Übersicht
|
## Übersicht
|
||||||
|
|
||||||
Dieses Modul sendet bei jedem Anruf-Event einen HTTP-Request an den Busylight-Server,
|
Dieses Modul sendet bei jedem Anruf-Event einen HTTP-Request an den Busylight-Server.
|
||||||
damit die Türschilder automatisch den Telefonstatus anzeigen.
|
Damit zeigen die Türschilder automatisch den Telefonstatus an.
|
||||||
|
|
||||||
|
**Ablauf:** Anruf startet → Starface → HTTP GET → Busylight-Server → WLED wird rot
|
||||||
|
**Ablauf:** Anruf endet → Starface → HTTP GET → Busylight-Server → WLED zurück auf Normal
|
||||||
|
|
||||||
## Voraussetzungen
|
## Voraussetzungen
|
||||||
|
|
||||||
- Starface Telefonanlage mit Modulcreator-Lizenz
|
- Starface mit Modulcreator-Lizenz
|
||||||
- Busylight-Server erreichbar unter `http://BUSYLIGHT-IP:8081`
|
- Busylight-Server erreichbar unter `http://100.95.224.14:8081`
|
||||||
- Durchwahlen der Mitarbeiter im Busylight-Portal eingetragen
|
- Durchwahlen im Busylight-Portal bei den Benutzern eingetragen
|
||||||
|
|
||||||
## Modul im Modulcreator erstellen
|
---
|
||||||
|
|
||||||
### Schritt 1: Neues Modul anlegen
|
## Neues Modul erstellen
|
||||||
|
|
||||||
1. Starface Admin-Oberfläche öffnen
|
### Schritt 1: Modul anlegen
|
||||||
2. **Admin** → **Modulcreator** (oder **Module** → **Modulcreator**)
|
|
||||||
3. **Neues Modul erstellen**
|
1. Starface Admin → **Module** → **Modulcreator**
|
||||||
4. Modulinformationen:
|
2. **Neues Modul erstellen**
|
||||||
- **Name**: `Busylight`
|
3. Tab **Module Settings**:
|
||||||
- **Beschreibung**: `Sendet Telefonstatus an Busylight Türschilder`
|
- **Name**: `Busylight Webhook`
|
||||||
|
- **Version**: `1`
|
||||||
- **Vendor**: `cynfo GmbH`
|
- **Vendor**: `cynfo GmbH`
|
||||||
- **Version**: `1.0.0`
|
|
||||||
|
|
||||||
### Schritt 2: Modulkonfiguration (Instanz-Variablen)
|
---
|
||||||
|
|
||||||
Unter **Modulkonfiguration** folgende Variablen anlegen:
|
### Schritt 2: GUI-Tab – Einstellungen definieren
|
||||||
|
|
||||||
| Variable | Typ | Standardwert | Beschreibung |
|
1. Tab **GUI** öffnen
|
||||||
|----------|-----|-------------|-------------|
|
2. Ein neues Textfeld anlegen:
|
||||||
| `busylight_url` | String | `http://100.95.224.14:8081` | URL des Busylight Webhook-Servers |
|
- **Variable-Name**: `GUI_WEBHOOK_URL`
|
||||||
|
- **Typ**: String
|
||||||
|
- **Standardwert**: `http://100.95.224.14:8081`
|
||||||
|
- **Label/Beschreibung**: `Busylight Webhook URL`
|
||||||
|
|
||||||
### Schritt 3: Trigger konfigurieren
|
Das ist die einzige Einstellung die der Admin später pro Instanz konfiguriert.
|
||||||
|
|
||||||
1. **Trigger hinzufügen**: `Anruf-Trigger` (Call Trigger)
|
---
|
||||||
2. **Trigger-Typ**: `Bei jedem Anruf` oder `Call State Changed`
|
|
||||||
3. **Richtung**: Eingehend + Ausgehend (beide)
|
|
||||||
|
|
||||||
### Schritt 4: Funktionsablauf erstellen
|
### Schritt 3: Funktion "CallWebhook" erstellen
|
||||||
|
|
||||||
Der Ablauf hat zwei Zweige:
|
Diese Funktion baut die URL zusammen und sendet den HTTP-Request.
|
||||||
|
|
||||||
#### Zweig A: Anruf beginnt (callstart)
|
1. Tab **Development**
|
||||||
|
2. Links unter **Functions** auf **+** klicken → Name: `CallWebhook`
|
||||||
|
3. **Function Settings** klicken → **Input-Variablen** anlegen:
|
||||||
|
|
||||||
1. **Bedingung**: Anrufstatus = `CONNECTED` (Anruf angenommen)
|
| Name | Typ | Beschreibung |
|
||||||
2. **Aktion**: HTTP Request
|
|------|-----|-------------|
|
||||||
- **Methode**: GET
|
| `loginId` | String | Durchwahl des Benutzers |
|
||||||
- **URL**: `{busylight_url}/{called_number}/callstart`
|
| `action` | String | `callstart` oder `callend` |
|
||||||
- `{called_number}` = Die Durchwahl des angerufenen Benutzers
|
|
||||||
|
|
||||||
#### Zweig B: Anruf endet (callend)
|
4. Zurück zu **Edit** wechseln
|
||||||
|
|
||||||
1. **Bedingung**: Anrufstatus = `HANGUP` (Anruf beendet)
|
5. Folgende 4 Bausteine nacheinander aus der **Components**-Sidebar (rechts) in den Edit-Bereich ziehen:
|
||||||
2. **Aktion**: HTTP Request
|
|
||||||
- **Methode**: GET
|
|
||||||
- **URL**: `{busylight_url}/{called_number}/callend`
|
|
||||||
|
|
||||||
### Schritt 5: Variablen-Mapping
|
---
|
||||||
|
|
||||||
Die Starface-Variablen müssen auf die URL gemappt werden:
|
#### Baustein 1: Append (URL zusammenbauen)
|
||||||
|
|
||||||
| Starface-Variable | Beschreibung | Verwendung |
|
**Wo:** Components → **String** → **Append**
|
||||||
|-------------------|-------------|-----------|
|
|
||||||
| `${call.calledNumber}` | Durchwahl des Angerufenen | In URL als Durchwahl |
|
|
||||||
| `${call.callingNumber}` | Nummer des Anrufers | Optional für Logging |
|
|
||||||
| `${call.state}` | Aktueller Anrufstatus | Für Bedingung |
|
|
||||||
|
|
||||||
**Hinweis:** Die genauen Variablennamen können je nach Starface-Version variieren.
|
In den Edit-Bereich ziehen. Dann konfigurieren:
|
||||||
Im Modulcreator werden die verfügbaren Variablen als Dropdown angeboten.
|
|
||||||
|
|
||||||
### Schritt 6: Modul speichern und aktivieren
|
- Input **"Strings"** (Klick auf das Feld, dann mehrere Werte hinzufügen):
|
||||||
|
|
||||||
1. **Speichern** klicken
|
| Nr | Wert | By Reference |
|
||||||
2. **Modul exportieren** als `.sfm` Datei (für Backup)
|
|----|------|-------------|
|
||||||
3. Unter **Module** → **Modulinstanzen** eine neue Instanz anlegen
|
| 1 | `GUI_WEBHOOK_URL` | ✅ Ja (Referenz auf die Modul-Variable) |
|
||||||
4. `busylight_url` auf die IP des Busylight-Servers setzen: `http://100.95.224.14:8081`
|
| 2 | `/` | ❌ Nein (fester Text) |
|
||||||
5. **Aktivieren**
|
| 3 | `loginId` | ✅ Ja (Referenz auf Input-Variable) |
|
||||||
|
| 4 | `/` | ❌ Nein (fester Text) |
|
||||||
|
| 5 | `action` | ✅ Ja (Referenz auf Input-Variable) |
|
||||||
|
|
||||||
|
- Output **"result"** → wird automatisch erzeugt, z.B. `http://100.95.224.14:8081/222/callstart`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 2: CreateHttpUrlWithParams (URL-Objekt erstellen)
|
||||||
|
|
||||||
|
**Wo:** Components → **Net.HTTP** → **CreateHttpUrlWithParams**
|
||||||
|
|
||||||
|
In den Edit-Bereich ziehen (unter den Append). Konfigurieren:
|
||||||
|
|
||||||
|
- Input **"url"**: `result` → ✅ By Reference (Output vom Append-Baustein)
|
||||||
|
- Alle anderen Inputs leer lassen (keine Query-Parameter nötig)
|
||||||
|
- Output **"httpUrl"** → wird automatisch erzeugt
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 3: HttpRequest (HTTP-Request absenden)
|
||||||
|
|
||||||
|
**Wo:** Components → **Net.HTTP** → **HttpRequest**
|
||||||
|
|
||||||
|
In den Edit-Bereich ziehen (unter CreateHttpUrlWithParams). Konfigurieren:
|
||||||
|
|
||||||
|
- Input **"httpUrl"**: `httpUrl` → ✅ By Reference (Output von CreateHttpUrlWithParams)
|
||||||
|
- Input **"method"**: `GET` → ❌ Fester Text
|
||||||
|
- Alle anderen Inputs (body, headers, timeout) leer lassen
|
||||||
|
- Output brauchen wir nicht
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 4: Log (zum Debuggen)
|
||||||
|
|
||||||
|
**Wo:** Components → **System** → **Log**
|
||||||
|
|
||||||
|
In den Edit-Bereich ziehen (unter HttpRequest). Konfigurieren:
|
||||||
|
|
||||||
|
- Input **"Log level"**: `INFO` (fester Text)
|
||||||
|
- Input **"Message"** (mehrere Werte):
|
||||||
|
|
||||||
|
| Nr | Wert | By Reference |
|
||||||
|
|----|------|-------------|
|
||||||
|
| 1 | `Busylight: ` | ❌ Nein (fester Text) |
|
||||||
|
| 2 | `result` | ✅ Ja (die URL die aufgerufen wurde) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Die fertige CallWebhook-Funktion sieht im Editor so aus:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Append([GUI_WEBHOOK_URL, "/", loginId, "/", action]) → result
|
||||||
|
CreateHttpUrlWithParams(result) → httpUrl
|
||||||
|
HttpRequest(httpUrl, "GET")
|
||||||
|
Log("INFO", ["Busylight: ", result])
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 4: Funktion "Call" erstellen
|
||||||
|
|
||||||
|
Diese Funktion wird bei jedem Anruf-Event aufgerufen. Sie ermittelt die Durchwahl
|
||||||
|
und ruft je nach Status `CallWebhook` mit `callstart` oder `callend` auf.
|
||||||
|
|
||||||
|
1. Links unter **Functions** auf **+** klicken → Name: `Call`
|
||||||
|
2. **Function Settings** → **Input-Variablen** anlegen:
|
||||||
|
|
||||||
|
| Name | Typ | Beschreibung |
|
||||||
|
|------|-----|-------------|
|
||||||
|
| `UCI_CALL` | UCI_CALL | By Reference ✅ – Das Anruf-Objekt |
|
||||||
|
| `USER_ACCOUNT` | STARFACE_USER | By Reference ✅ – Der betroffene User |
|
||||||
|
|
||||||
|
3. Zurück zu **Edit** und folgende Bausteine einfügen:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 1: Call.getCallInformations
|
||||||
|
|
||||||
|
**Wo:** Components → **Call** → **Call.getCallInformations**
|
||||||
|
|
||||||
|
- Input **"call"**: `UCI_CALL` → ✅ By Reference
|
||||||
|
- Outputs die wir brauchen:
|
||||||
|
- `uciCallState` (String) – Der Anruf-Status
|
||||||
|
- `uciCalledNumber` (String) – Die angerufene Nummer
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 2: ResolveUserData (Benutzerdaten holen)
|
||||||
|
|
||||||
|
**Wo:** Components → **STARFACE** → **ResolveUserData**
|
||||||
|
|
||||||
|
- Input **"accountId"**: `USER_ACCOUNT` → ✅ By Reference
|
||||||
|
- Output den wir brauchen:
|
||||||
|
- `loginId` (String) – Die Login-ID / Durchwahl des Users
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 3: IsUser (Prüfen ob es ein echter User ist)
|
||||||
|
|
||||||
|
**Wo:** Components → **STARFACE** → **IsUser**
|
||||||
|
|
||||||
|
- Input **"accountId"**: `USER_ACCOUNT` → ✅ By Reference
|
||||||
|
- Output: `isUser` (Boolean)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 4: if(!isUser) → exit
|
||||||
|
|
||||||
|
Wenn es kein User ist (z.B. eine Gruppe oder Queue), abbrechen.
|
||||||
|
|
||||||
|
**Wo:** Components → **Basic Components** → **if**
|
||||||
|
|
||||||
|
- Bedingung: `isUser` → **is not true** (isNotTrueExpression)
|
||||||
|
- Innerhalb des if: **exit** einfügen (Components → Basic Components → exit)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### Baustein 5: switch(uciCallState) – Status-Weiche
|
||||||
|
|
||||||
|
**Wo:** Components → **Basic Components** → **switch**
|
||||||
|
|
||||||
|
- Variable: `uciCallState` → ✅ By Reference
|
||||||
|
|
||||||
|
Dann 3 **case**-Blöcke hinzufügen (Components → Basic Components → case):
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
##### case 'INCOMING'
|
||||||
|
|
||||||
|
- Condition: `INCOMING` (fester Text)
|
||||||
|
- Innerhalb: **CallWebhook** aufrufen
|
||||||
|
- **Wo:** Links unter Functions → `CallWebhook` in den case ziehen
|
||||||
|
- `loginId` = `loginId` → ✅ By Reference (Output von ResolveUserData)
|
||||||
|
- `action` = `callstart` → ❌ Fester Text
|
||||||
|
|
||||||
|
##### case 'OUTGOING'
|
||||||
|
|
||||||
|
- Condition: `OUTGOING` (fester Text)
|
||||||
|
- Innerhalb: **CallWebhook** aufrufen
|
||||||
|
- `loginId` = `loginId` → ✅ By Reference
|
||||||
|
- `action` = `callstart` → ❌ Fester Text
|
||||||
|
|
||||||
|
##### case 'HANGUP'
|
||||||
|
|
||||||
|
- Condition: `HANGUP` (fester Text)
|
||||||
|
- Innerhalb: **CallWebhook** aufrufen
|
||||||
|
- `loginId` = `loginId` → ✅ By Reference
|
||||||
|
- `action` = `callend` → ❌ Fester Text
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Die fertige Call-Funktion sieht im Editor so aus:**
|
||||||
|
|
||||||
|
```
|
||||||
|
Call.getCallInformations(UCI_CALL) → uciCallState, uciCalledNumber, ...
|
||||||
|
ResolveUserData(USER_ACCOUNT) → loginId, firstName, familyName, ...
|
||||||
|
IsUser(USER_ACCOUNT) → isUser
|
||||||
|
|
||||||
|
if(!isUser)
|
||||||
|
exit
|
||||||
|
|
||||||
|
switch(uciCallState)
|
||||||
|
case 'INCOMING':
|
||||||
|
CallWebhook(loginId, "callstart")
|
||||||
|
case 'OUTGOING':
|
||||||
|
CallWebhook(loginId, "callstart")
|
||||||
|
case 'HANGUP':
|
||||||
|
CallWebhook(loginId, "callend")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 5: Funktion "Register" erstellen
|
||||||
|
|
||||||
|
Diese Funktion registriert den Call-Event-Listener wenn das Modul aktiviert wird.
|
||||||
|
|
||||||
|
1. Links unter **Functions** auf **+** klicken → Name: `Register`
|
||||||
|
2. Einen Baustein einfügen:
|
||||||
|
|
||||||
|
**Wo:** Components → **Call** → **RegisterCallEventByUser** (oder ähnlich)
|
||||||
|
|
||||||
|
- Dieser registriert die `Call`-Funktion als Handler für alle Anruf-Events
|
||||||
|
- Target-Funktion: `Call`
|
||||||
|
|
||||||
|
**Hinweis:** Der genaue Baustein heißt je nach Starface-Version anders.
|
||||||
|
Im alten Modul steht er unter "Register" und verweist auf die "Call"-Funktion.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 6: Funktion "Unregister" erstellen
|
||||||
|
|
||||||
|
1. Links unter **Functions** auf **+** klicken → Name: `Unregister`
|
||||||
|
2. Einen Baustein einfügen der den Event-Listener wieder abmeldet
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 7: Entry Points setzen
|
||||||
|
|
||||||
|
1. Tab **Module Settings** (oder unten im Development-Tab)
|
||||||
|
2. **Entry Points** / **Lifecycle Events** konfigurieren:
|
||||||
|
- **InstanceActivated** → Funktion `Register` aufrufen
|
||||||
|
- **InstanceDeactivated** → Funktion `Unregister` aufrufen
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Schritt 8: Speichern und Installieren
|
||||||
|
|
||||||
|
1. **Save** klicken
|
||||||
|
2. **Apply** klicken
|
||||||
|
3. Modul als `.sfm` exportieren (für Backup)
|
||||||
|
4. Unter **Module** → **Modulinstanzen** → Neue Instanz anlegen
|
||||||
|
5. `GUI_WEBHOOK_URL` = `http://100.95.224.14:8081`
|
||||||
|
6. **Aktivieren**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Testen
|
## Testen
|
||||||
|
|
||||||
### Von der Kommandozeile testen
|
### Schnelltest von der Kommandozeile
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Anruf simulieren (Durchwahl 222 = Nicklas Janzen)
|
# Anruf simulieren (Durchwahl 222)
|
||||||
curl http://100.95.224.14:8081/222/callstart
|
curl http://100.95.224.14:8081/222/callstart
|
||||||
# → Türschild sollte rot werden
|
# → Dashboard zeigt "Telefoniert" bei Nicklas Janzen
|
||||||
|
|
||||||
# Anruf beenden
|
# Anruf beenden
|
||||||
curl http://100.95.224.14:8081/222/callend
|
curl http://100.95.224.14:8081/222/callend
|
||||||
# → Türschild sollte auf Zeiterfassungs-Status zurückspringen
|
# → Dashboard zeigt normalen Status
|
||||||
```
|
```
|
||||||
|
|
||||||
### Im Busylight-Portal prüfen
|
### Im Starface Modulcreator
|
||||||
|
|
||||||
- **Dashboard**: Telefon-Badge sollte "Telefoniert" anzeigen
|
- Tab **Log File** öffnen
|
||||||
- **Protokoll**: Einträge mit `phone_active` und `phone_end` sollten erscheinen
|
- Bei einem Testanruf sollte erscheinen:
|
||||||
|
```
|
||||||
|
INFO: Busylight: http://100.95.224.14:8081/222/callstart
|
||||||
|
```
|
||||||
|
|
||||||
## Alternative: Starface Rufnummernaktionen
|
### Im Busylight-Portal
|
||||||
|
|
||||||
Falls kein Modulcreator verfügbar ist, können auch **Rufnummernaktionen** verwendet werden:
|
- **Dashboard**: Telefon-Badge wechselt auf "Telefoniert" (rot)
|
||||||
|
- **Protokoll**: Einträge mit `phone_active` und `phone_end`
|
||||||
|
|
||||||
1. **Admin** → **Rufnummern** → Durchwahl auswählen
|
---
|
||||||
2. **Aktionen** → **Neue Aktion**
|
|
||||||
3. **Bei Anrufbeginn**: HTTP Request an `http://BUSYLIGHT:8081/{durchwahl}/callstart`
|
|
||||||
4. **Bei Anrufende**: HTTP Request an `http://BUSYLIGHT:8081/{durchwahl}/callend`
|
|
||||||
|
|
||||||
**Nachteil:** Muss pro Durchwahl einzeln eingerichtet werden.
|
## Zusammenfassung – Alle Funktionen
|
||||||
|
|
||||||
|
| Funktion | Zweck | Bausteine |
|
||||||
|
|----------|-------|-----------|
|
||||||
|
| `CallWebhook` | URL bauen + HTTP GET senden | Append → CreateHttpUrlWithParams → HttpRequest → Log |
|
||||||
|
| `Call` | Anruf-Event verarbeiten | getCallInformations → ResolveUserData → IsUser → if/exit → switch/case → CallWebhook |
|
||||||
|
| `Register` | Event-Listener anmelden | RegisterCallEventByUser |
|
||||||
|
| `Unregister` | Event-Listener abmelden | UnregisterCallEventByUser |
|
||||||
|
|
||||||
## Fehlerbehebung
|
## Fehlerbehebung
|
||||||
|
|
||||||
### Türschild reagiert nicht
|
### Webhook kommt nicht an
|
||||||
|
1. Starface Log File prüfen – steht die URL drin?
|
||||||
|
2. Firewall: Port 8081 vom Starface-Server (192.168.200.251) zum Busylight-Server (100.95.224.14) offen?
|
||||||
|
3. Test: `curl http://100.95.224.14:8081/` vom Starface-Server
|
||||||
|
|
||||||
1. Busylight-Server erreichbar? `curl http://100.95.224.14:8081/`
|
### Falscher User wird rot
|
||||||
2. Durchwahl im Busylight-Portal beim Benutzer eingetragen?
|
- `loginId` = Starface Login-ID = Durchwahl (z.B. 222)
|
||||||
3. Benutzer laut Zeiterfassung "anwesend" oder "homeoffice"?
|
- Diese muss im Busylight-Portal unter **Benutzer** → **Durchwahl** eingetragen sein
|
||||||
4. Starface-Modul aktiviert?
|
|
||||||
5. Firewall: Port 8081 von der Starface zum Busylight-Server offen?
|
|
||||||
|
|
||||||
### Falscher Benutzer wird rot
|
### Türschild bleibt rot
|
||||||
|
- HANGUP-case prüfen – wird `callend` gesendet?
|
||||||
- Prüfen ob die Durchwahl im Busylight-Portal dem richtigen Benutzer zugeordnet ist
|
- Manuell zurücksetzen: `curl http://100.95.224.14:8081/222/callend`
|
||||||
- Variable im Modulcreator: `${call.calledNumber}` (nicht `${call.callingNumber}`)
|
- Im Busylight-Protokoll prüfen ob `phone_end` ankommt
|
||||||
|
|
||||||
### Türschild bleibt nach Anrufende rot
|
|
||||||
|
|
||||||
- Prüfen ob das HANGUP-Event im Modul konfiguriert ist
|
|
||||||
- Im Busylight-Protokoll prüfen ob `callend` ankommt
|
|
||||||
- Manuell zurücksetzen: `curl http://100.95.224.14:8081/{durchwahl}/callend`
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user