Funktion: Custo-manifest (Rainbow-Erweiterungen) – GUI-Erweiterungen
Lizenz: Mindestens Business-Lizenz
Anhand dieses Artikels können Sie Rainbow-GUI-Erweiterungen erstellen, die Rainbow um Schaltflächen, Widgets und eingebettete Webanwendungen ergänzen. Sie erfahren, welche Erweiterungspunkte verfügbar sind und wie Sie die richtige Platzierung für Ihren Arbeitsablauf auswählen.
Übersicht
Mit GUI-Erweiterungen können Sie der Rainbow-Benutzeroberfläche benutzerdefinierte Schaltflächen, Widgets und eingebettete Webanwendungen hinzufügen. Für diese Erweiterungen ist mindestens eine Business-Lizenz erforderlich.
Was Sie mit GUI-Erweiterungen tun können:
- Fügen Sie anklickbare Aktionsschaltflächen in Kontaktlisten, im Anrufprotokoll, auf der Kommunikationskarte und in Bubbles hinzu
- Benutzerdefinierte Inhalte (CRM-Daten, Tickets, Berichte) automatisch in Anruf-Popups und Kontaktfenstern anzeigen
- Eine Webanwendung eines Drittanbieters direkt in das Rainbow-Hauptfenster einbetten
Arten von Erweiterungspunkten
Ein Erweiterungspunkt (EP) ist ein benannter Platzhalter in der Rainbow-Oberfläche, an den eine benutzerdefinierte Aktion angehängt werden kann. Jeder EP verfügt über einen eindeutigen Schlüssel (z. B. „on-contact-list-actions“), eine feste Position in der Benutzeroberfläche sowie Regeln, die festlegen, welche Felder und Variablen verfügbar sind. Das „custo-manifest“ deklariert unter jedem EP-Schlüssel eine oder mehrere Aktionen.
Schaltflächen – anklickbare Schaltflächen
Eine Symbolschaltfläche wird an einer bestimmten Stelle der Rainbow-Benutzeroberfläche eingefügt. Beim Klicken wird eine Aktion ausgeführt und optional das Ergebnis in einem Popup (Markdown oder Adaptive Card) angezeigt. Pro Erweiterungspunkt sind bis zu 3 Schaltflächen zulässig.
| Erweiterungspunkt | Platzierung der Schaltflächen |
|---|---|
| on-incoming-pbx-call-button-actions | Popup bei eingehendem Anruf |
| on-call-log-list-actions | Jede Zeile des Anrufprotokolls |
| Aktionen in der Kontaktliste | Jede Zeile der Kontaktliste |
| Aktionen in den Kontaktdetails | Fenster „Kontaktdetails“ |
| Aktionen auf der Kommunikationskarte | Leiste des Anrufmanagers |
| Aktionen in der Bubble | Eigenschaftenmenü der Bubble |
| Aktionen bei Konferenz-Sprechblasen | Menü „Konferenz“ |
| Aktionen im Benutzermenü | Benutzermenü (BETA, Desktop / Web – nicht Teams) |
Anzeigen – automatische Informationsanzeige
Inhalte (Markdown oder Adaptive Card) werden automatisch an einer bestimmten Stelle der Benutzeroberfläche eingefügt – ohne Benutzereingriff. Der Inhalt wird abgerufen, sobald die Platzierung sichtbar wird.
| Erweiterungspunkt | Anzeigeplatzierung |
|---|---|
| on-incoming-pbx-call-display-actions | Im Popup-Fenster für eingehende Anrufe |
| on-contact-card-display-actions | Im Kontaktdetail-Fenster |
| Aktionen zur Anzeige im Haupt-Widget | Widget im Hauptbereich von Rainbow |
| Aktionen bei der Anzeige im Hauptbereich | Nachricht in der Teams-Web-App |
Frame-Anzeige – Webanwendung eines Drittanbieters
Bettet eine Webanwendung eines Drittanbieters in einen Rainbow-UI-Frame ein. Bei „Popup: true“ wird die Anwendung in einem Browserfenster geöffnet, anstatt eingebettet zu werden.
| Erweiterungspunkt | Platzierung |
|---|---|
| on-main-window-actions | Rahmen im Rainbow-Hauptfenster |
Konfiguration einer GUI-Erweiterung
Das „custo-manifest“ ist ein JSON-Objekt mit folgender Struktur:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"<EXTENSION-POINT-KEY>": [
{
"name": "...",
"icon": "...",
"command": {
"url": "...",
"params": "...",
"commandType": "rest",
"method": "GET"
},
"responseType": "markdown"
}
]
}
}Globale Regeln:
- Die Version muss „2“ lauten.
- „jsonType“ muss „Rainbow-custo-manifest“ lauten. Innerhalb einer ZIP-Datei gibt dieses Feld an, welche JSON-Datei das Manifest ist.
- Jeder Schlüssel unter „extension-points“ ist ein Array – maximal 3 Aktionen pro Erweiterungspunkt.
- Jede Aktion muss ein gültiges Befehlsobjekt enthalten. „name“ und „icon“ sind je nach Erweiterungspunkt obligatorisch (siehe §3.4).
Aktionsfelder
| Feld | Position | Beschreibung |
|---|---|---|
| name | root | Angezeigter Text (Schaltflächenbeschriftung, Widget-Titel, Menübezeichnung). Je nach EP obligatorisch. |
| Symbol / Symbol-ID | root | Schaltflächensymbol (URL, ${custo.path}\... oder integriertes Sprite). Obligatorisch für Symbolschaltflächen. |
| Tooltip | root | Tooltip-Text. Optional. |
| Befehl | root | Befehlsobjekt (siehe §3.2). Immer obligatorisch. |
| responseType | root | „markdown“ (Standard), „json“ oder „adaptiveCard“. Erforderlich für Anzeige-EPs; optional für Schaltflächen. |
| displayJsonField | root | Wenn responseType: „json“ ist, der Name des JSON-Feldes, das den anzuzeigenden Markdown-Code enthält. |
| adaptiveCardTemplate | root | Inline-JSON-Vorlage für Adaptive Cards. |
| adaptiveCardTemplateJsonField | root | Name des REST-Antwortfeldes, das die Adaptive-Card-Vorlage enthält. |
| adaptiveCardContentJsonField | root | Name des REST-Antwortfeldes, das die Kartendaten enthält. |
| adaptiveCardSubmitUrl | root | REST-URL, die per POST aufgerufen wird, wenn in der Karte „Action.Submit“ ausgelöst wird. |
Das Befehlsobjekt
Das Befehlsobjekt ist stets obligatorisch und enthält mindestens eine URL. Je nach gewähltem `commandType` sind zusätzliche Unterfelder zulässig.
"command": {
"url": "{{server}}/your-endpoint",
"params": "user=${localUser.email}",
"commandType": "rest",
"method": "GET",
"header": ["Authorization: Bearer TOKEN"],
"bodyParameters": { "key": "value" }
}| Feld | Wann es verwendet wird |
|---|---|
| url | Obligatorisch. Anwendungspfad, Web-URL, Datei oder REST-API. |
| params | Optional. Wird bei GET hinter dem „?“ angehängt oder als URL-Parameter angegeben. Variablen sind zulässig. |
| commandType | Optional. Standardwert „rest“. Werte: „rest“, „file“ (abhängig vom EP). |
| method | Optional (nur wenn commandType: „rest“). Werte: „GET“, „POST“. |
| header | Optional (bei REST). Array aus Zeichenfolgen im Format „Header-Name: Wert“, die als HTTP-Header eingefügt werden. |
| bodyParameters | Erforderlich, wenn method: „POST“. Als Body gesendetes JSON-Objekt. Variablen sind zulässig. |
Rainbow-Variablen
$Variablen werden zur Laufzeit durch ihren tatsächlichen Wert ersetzt. Sie können in „command.url“, „command.params“, „command.bodyParameters“ sowie in den an die Erweiterung zur Anzeige zurückgegebenen Inhalten vorkommen.
Syntax
${object.attribute}
${object.attribute.regex(pattern)}
${object.attribute.regex(pattern, replacement)}Verfügbare Objekte und Attribute
Rainbow-Benutzer (ME)
${localUser.firstName} ${localUser.lastName}
${localUser.email} ${localUser.canonicalNumber}
${localUser.phoneNumber} ${localUser.internalNumber}
${localUser.phonePbx} ${localUser.nickname}
${localUser.loginEmail} ${localUser.id}Kontakt (sofern identifiziert)
${kontakt.firstName} ${kontakt.lastName}
${kontakt.phoneNumber} ${kontakt.email}
${contact.company} ${contact.workNumber}
${contact.mobileNumber} ${contact.personalNumber}
${contact.personalMobile}
${contact.tags} (verkettet, durch Kommas getrennt)Anrufer (nur bei EPs mit Anrufschaltfläche)
${caller.firstName} ${caller.lastName} ${caller.phoneNumber}Angerufener (nur bei EPs mit Anrufschaltfläche)
${called.phoneNumber}Anrufkontext (nur bei EP mit Anrufschaltfläche)
${call.callId}
${call.globalCallId} (nur OXE)
${call.correlator}Bubble (nur bei Bubble-EPs)
${bubble.ownerEmail} ${bubble.name} ${bubble.shareLink}
${bubble.id}
${bubble.mitglieder} (JSON – nur bei commandType: „rest“)Kompatibilität pro Erweiterungspunkt
| Erweiterungspunkt | Zulässige Variablenobjekte |
|---|---|
| on-incoming-pbx-call-button-actions | localUser, caller, called, call, Kontakt |
| on-call-log-list-actions | localUser, Kontakt |
| Aktionen in der Kontaktliste | localUser, Kontakt |
| Aktionen in der Kontaktdetailansicht | lokaler Benutzer, Kontakt |
| Aktionen auf der Kommunikationskarte | lokaler Benutzer, Anrufer, Angerufener, Anruf, Kontakt |
| Aktionen bei Sprechblasen | lokaler Benutzer, Bubble |
| Aktionen bei Sprechblasen in Konferenzen | localUser, Bubble |
| Aktionen im Benutzermenü | localUser |
| Aktionen bei der Anzeige eingehender PBX-Anrufe | localUser, Anrufer, Angerufener, Anruf, Kontakt |
| Aktionen bei der Anzeige der Kontaktkarte | localUser, Kontakt |
| Aktionen bei der Anzeige im Haupt-Widget | localUser |
| Aktionen bei Anzeige auf dem Hauptbildschirm | localUser |
| Aktionen im Hauptfenster | localUser |
Regex-Modifikator
Wendet vor der Ersetzung einen Regex-Modifikator auf den Wert der Variablen an:
// Eine Zahl normalisieren – +33 oder +1 durch 0 ersetzen
"params": "pbx=${localUser.phonePbx.regex(^\+33|^\+1, 0)}"
// E-Mail-Domäne ersetzen
"params": "byEmail=${localUser.email.regex(alcatel.com, al-enterprise.com)}"
// Die letzten 9 Ziffern extrahieren (kein Ersetzen = Extrahieren)
"params": "${kontakt.phoneNumber.regex(.{0,9}$)}"Variable ${time}
Verfügbar an allen Erweiterungspunkten – wird zum Zeitpunkt der Ausführung der Aktion ersetzt.
| Variable | Wert |
|---|---|
| ${time} | Vollständiges Datums- und Zeitformat (ISO 8601, z. B. 2026-05-18T15:30:45.123Z) |
| ${time.year} | Jahr – 4 Ziffern |
| ${time.month} | Monat – 01–12 |
| ${time.day} | Tag – 01–31 |
| ${time.hour} | Stunde — 00–23 |
| ${time.minute} | Minute – 00–59 |
| ${time.second} | Sekunde – 00–59 |
| ${time.millisec} | Millisekunden – 000–999 |
Lokale Ressourcen — ${custo.path}
So verteilen Sie ein Manifest mit lokalen Dateien (Symbole, statische Inhalte):
- Verweisen Sie auf jede Ressource als ${custo.path}\\Dateiname.ext
- Packen Sie die Datei „custo-manifest.json“ und die Ressourcendateien in eine ZIP-Datei (das Manifest im Stammverzeichnis)
{
"icon": "${custo.path}\\crm.png",
"command": {
"commandType": "file",
"url": "${custo.path}\\content.txt"
},
"responseType": "markdown"
}Erweiterungsspezifische Felder
| Feld | Betroffene Erweiterungspunkte | Beschreibung |
|---|---|---|
| AnswerOnClick | on-incoming-pbx-call-button-actions | true → führt die Aktion aus und nimmt den Anruf mit einem Klick entgegen |
| Popup | Aktionen im Hauptfenster | true → öffnet die Web-App in einem Browserfenster anstelle des Rainbow-Frames |
| auchFürTeams | Aktionen in der Anrufprotokoll-Liste, Aktionen auf dem Hauptbildschirm | Zeigt die Erweiterung auch im Teams-Add-in an |
| urlConfig | Aktionen auf dem Haupt-Widget-Display | HTTP/HTTPS-URL für die Widget-Konfiguration |
Einbinden lokaler Ressourcen (ZIP-Archiv)
Falls die Aktion auf lokale Dateien (Symbole oder Anzeigedateien) verweist, packen Sie die Datei „custo-manifest.json“ zusammen mit diesen Dateien vor dem Import in ein ZIP-Archiv.
Erforderliche ZIP-Struktur – die Manifestdatei muss sich im Stammverzeichnis befinden:
my-manifest.zip
├── custo-manifest.json
├── icon.png
└── display-content.txtBereitstellung des Manifests
Sobald das Manifest konfiguriert ist, stellen Sie es über die Rainbow-Verwaltungskonsole oder lokal bereit. Siehe „Bereitstellen eines custo-manifest in Rainbow“.
Beispiele für die Konfiguration
Schaltflächen
Unterstützt von Rainbow Desktop und Rainbow Web – erfordert CORS für REST-Aufrufe.
Beispiel 1 – „on-contact-list-actions“ fügt in jeder Kontaktzeile eine Schaltfläche hinzu, die den Kontakt in einem externen CRM öffnet (kein Popup innerhalb von Rainbow):
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-contact-list-actions": [
{
"name": "In CRM öffnen",
"tooltip": "Diesen Kontakt in unserem CRM anzeigen",
"icon": "${custo.path}\\crm.png",
"command": {
"url": "https://crm.example.com/contact",
"params": "email=${contact.email}&phone=${contact.phoneNumber}"
}
}
]
}
}Beispiel 2 – „on-incoming-pbx-call-button-actions“ fügt dem Popup-Fenster für eingehende Anrufe eine Schaltfläche hinzu, mit der Sie mit einem Klick ein Ticket erstellen und den Anruf annehmen können:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-incoming-pbx-call-button-actions": [
{
"name": "Ticket erstellen & annehmen",
"AnswerOnClick": true,
"command": {
"commandType": "rest",
"method": "POST",
"url": "https://tickets.example.com/api/tickets",
"header": [
„Authorization: Bearer TOKEN“,
"Content-Type: application/json"
],
"bodyParameters": {
"caller": "${caller.phoneNumber}",
"callId": "${call.callId}",
"createdBy": "${localUser.loginEmail}"
}
}
}
]
}
}Anzeigen
Unterstützt von Rainbow Desktop und Rainbow Web – erfordert CORS für REST-Aufrufe.
Beispiel 1 – „on-incoming-pbx-call-display-actions“ zeigt automatisch eine Markdown-Karte mit der Anrufer-ID im Popup-Fenster für eingehende Anrufe an:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-incoming-pbx-call-display-actions": [
{
"command": {
"commandType": "rest",
"method": "GET",
"url": "https://api.example.com/lookup",
"params": "phone=${caller.phoneNumber}",
"header": ["Authorization: Bearer TOKEN"]
},
"responseType": "markdown"
}
]
}
}Beispiel 2 – „on-main-widget-display-actions“ zeigt ein Adaptive-Card-Widget im Rainbow-Hauptbereich an, das bei jedem Öffnen aktualisiert wird:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-main-widget-display-actions": [
{
"name": "Meine Tickets",
"command": {
"commandType": "rest",
"method": "GET",
"url": "https://api.example.com/tickets/me",
"header": ["Authorization: Bearer TOKEN"]
},
"responseType": "adaptiveCard",
"adaptiveCardTemplateJsonField": "card",
„adaptiveCardContentJsonField“: „data“,
„adaptiveCardSubmitUrl“: „https://api.example.com/tickets/submit“
}
]
}
}Anzeige im Frame
Unterstützt von Rainbow Desktop und Rainbow Web.
Beispiel 1 – „on-main-window-actions“ bettet ein CRM-Dashboard in das Rainbow-Hauptfenster ein:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-main-window-actions": [
{
"name": "Mein CRM",
"icon": "${custo.path}\\crm.png",
"command": {
"url": "https://crm.example.com/dashboard",
"params": "user=${localUser.email}"
}
}
]
}
}Beispiel 2 – identisch, jedoch mit „Popup: true“, um das Fenster in einem Browserfenster zu öffnen (nützlich, wenn die App die Einbettung in Iframes nicht zulässt):
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-main-window-actions": [
{
"name": "Externe Berichterstellung",
"icon": "${custo.path}\\report.png",
"Popup": true,
"command": {
"url": "https://reporting.example.com/",
"params": "user=${localUser.loginEmail}"
}
}
]
}
}