346 lines
9.8 KiB
Markdown
346 lines
9.8 KiB
Markdown
# Starface Modul – Busylight Webhook (Neuaufbau)
|
||
|
||
## Übersicht
|
||
|
||
Dieses Modul sendet bei jedem Anruf-Event einen HTTP-Request an den Busylight-Server.
|
||
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
|
||
|
||
- Starface mit Modulcreator-Lizenz
|
||
- Busylight-Server erreichbar unter `http://100.95.224.14:8081`
|
||
- Durchwahlen im Busylight-Portal bei den Benutzern eingetragen
|
||
|
||
---
|
||
|
||
## Neues Modul erstellen
|
||
|
||
### Schritt 1: Modul anlegen
|
||
|
||
1. Starface Admin → **Module** → **Modulcreator**
|
||
2. **Neues Modul erstellen**
|
||
3. Tab **Module Settings**:
|
||
- **Name**: `Busylight Webhook`
|
||
- **Version**: `1`
|
||
- **Vendor**: `cynfo GmbH`
|
||
|
||
---
|
||
|
||
### Schritt 2: GUI-Tab – Einstellungen definieren
|
||
|
||
1. Tab **GUI** öffnen
|
||
2. Ein neues Textfeld anlegen:
|
||
- **Variable-Name**: `GUI_WEBHOOK_URL`
|
||
- **Typ**: String
|
||
- **Standardwert**: `http://100.95.224.14:8081`
|
||
- **Label/Beschreibung**: `Busylight Webhook URL`
|
||
|
||
Das ist die einzige Einstellung die der Admin später pro Instanz konfiguriert.
|
||
|
||
---
|
||
|
||
### Schritt 3: Funktion "CallWebhook" erstellen
|
||
|
||
Diese Funktion baut die URL zusammen und sendet den HTTP-Request.
|
||
|
||
1. Tab **Development**
|
||
2. Links unter **Functions** auf **+** klicken → Name: `CallWebhook`
|
||
3. **Function Settings** klicken → **Input-Variablen** anlegen:
|
||
|
||
| Name | Typ | Beschreibung |
|
||
|------|-----|-------------|
|
||
| `loginId` | String | Durchwahl des Benutzers |
|
||
| `action` | String | `callstart` oder `callend` |
|
||
|
||
4. Zurück zu **Edit** wechseln
|
||
|
||
5. Folgende 4 Bausteine nacheinander aus der **Components**-Sidebar (rechts) in den Edit-Bereich ziehen:
|
||
|
||
---
|
||
|
||
#### Baustein 1: Append (URL zusammenbauen)
|
||
|
||
**Wo:** Components → **String** → **Append**
|
||
|
||
In den Edit-Bereich ziehen. Dann konfigurieren:
|
||
|
||
- Input **"Strings"** (Klick auf das Feld, dann mehrere Werte hinzufügen):
|
||
|
||
| Nr | Wert | By Reference |
|
||
|----|------|-------------|
|
||
| 1 | `GUI_WEBHOOK_URL` | ✅ Ja (Referenz auf die Modul-Variable) |
|
||
| 2 | `/` | ❌ Nein (fester Text) |
|
||
| 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
|
||
|
||
### Schnelltest von der Kommandozeile
|
||
|
||
```bash
|
||
# Anruf simulieren (Durchwahl 222)
|
||
curl http://100.95.224.14:8081/222/callstart
|
||
# → Dashboard zeigt "Telefoniert" bei Nicklas Janzen
|
||
|
||
# Anruf beenden
|
||
curl http://100.95.224.14:8081/222/callend
|
||
# → Dashboard zeigt normalen Status
|
||
```
|
||
|
||
### Im Starface Modulcreator
|
||
|
||
- Tab **Log File** öffnen
|
||
- Bei einem Testanruf sollte erscheinen:
|
||
```
|
||
INFO: Busylight: http://100.95.224.14:8081/222/callstart
|
||
```
|
||
|
||
### Im Busylight-Portal
|
||
|
||
- **Dashboard**: Telefon-Badge wechselt auf "Telefoniert" (rot)
|
||
- **Protokoll**: Einträge mit `phone_active` und `phone_end`
|
||
|
||
---
|
||
|
||
## 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
|
||
|
||
### 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
|
||
|
||
### Falscher User wird rot
|
||
- `loginId` = Starface Login-ID = Durchwahl (z.B. 222)
|
||
- Diese muss im Busylight-Portal unter **Benutzer** → **Durchwahl** eingetragen sein
|
||
|
||
### Türschild bleibt rot
|
||
- HANGUP-case prüfen – wird `callend` gesendet?
|
||
- Manuell zurücksetzen: `curl http://100.95.224.14:8081/222/callend`
|
||
- Im Busylight-Protokoll prüfen ob `phone_end` ankommt
|