Funzionalità: Custo-manifest (Rainbow Extensions) — Estensioni dell’interfaccia grafica
Licenza: Licenza Business come requisito minimo
Potrà utilizzare questo articolo per creare estensioni dell’interfaccia grafica di Rainbow che aggiungono pulsanti, widget e applicazioni web incorporate a Rainbow. Scoprirà quali punti di estensione sono disponibili e come scegliere la posizione più adatta al Suo flusso di lavoro.
Panoramica
Le estensioni dell’interfaccia grafica consentono di aggiungere pulsanti personalizzati, visualizzare widget e applicazioni web incorporate nell’interfaccia di Rainbow. Queste estensioni richiedono almeno una licenza Business.
Cosa è possibile fare con le estensioni dell’interfaccia grafica:
- Aggiungere pulsanti di azione cliccabili negli elenchi dei contatti, nel registro delle chiamate, nella scheda di comunicazione e negli Spazi
- Visualizzare automaticamente contenuti personalizzati (dati CRM, ticket, Report) nei pop-up delle chiamate e nei pannelli dei Contatti
- Incorporare un’applicazione web di terze parti direttamente nel pannello principale di Rainbow
Tipi di punti di estensione
Un punto di estensione (EP) è uno slot denominato nell’interfaccia di Rainbow a cui è possibile associare un’azione personalizzata. Ogni EP possiede una chiave univoca (ad es. on-contact-list-actions), una posizione fissa nell’interfaccia utente e regole che stabiliscono quali campi e variabili sono disponibili. Il file custo-manifest dichiara una o più azioni per ciascuna chiave EP.
Pulsanti — pulsanti cliccabili
Un pulsante con icona viene inserito in una posizione specifica dell’interfaccia utente di Rainbow. Al clic, viene eseguita un’azione e, facoltativamente, il suo risultato viene visualizzato in un popup (Markdown o Adaptive Card). Sono consentiti fino a 3 pulsanti per ogni punto di estensione.
| Punto di estensione | Posizionamento del pulsante |
|---|---|
| azioni-dei-pulsanti-per-le-chiamate-in-entrate-dal-pbx | Finestra a comparsa per le chiamate in arrivo |
| azioni-nell'elenco-del-registro-delle-chiamate | Ogni riga del registro delle chiamate |
| azioni-nell'elenco-dei-Contatti | Ogni riga dell'elenco dei contatti |
| Azioni relative ai dettagli dei contatti | Pannello dei dettagli del contatto |
| Azioni sulla scheda di comunicazione | Barra di gestione delle chiamate |
| Azioni sulla bolla | Menu delle proprietà del fumetto dello Spazio |
| Azioni relative alla conferenza nel fumetto | Menu della conferenza telefonica |
| Azioni nel menu utente | Menu utente (BETA, Desktop / Web — non Teams) |
Visualizzazioni — visualizzazione automatica delle informazioni
Il contenuto (Markdown o Adaptive Card) viene inserito automaticamente in una posizione specifica dell’interfaccia utente — senza alcuna interazione da parte dell’utente. Il contenuto viene recuperato quando la posizione diventa visibile.
| Punto di estensione | Posizionamento della visualizzazione |
|---|---|
| on-incoming-pbx-call-display-actions | Nel pop-up della chiamata in arrivo |
| on-contact-card-display-actions | Nel pannello dei dettagli del contatto |
| azioni-di-visualizzazione-nel-widget-principale | Widget nel pannello principale di Rainbow |
| azioni-di-visualizzazione-sul-pannello-principale | Messaggio nell’app web Teams |
Visualizzazione in frame — applicazione web di terze parti
Incorpora un’applicazione web di terze parti all’interno di un frame dell’interfaccia utente di Rainbow. Con Popup: true, l’applicazione si apre in una finestra del browser anziché essere incorporata.
| Punto di estensione | Posizionamento |
|---|---|
| azioni-nella-finestra-principale | Frame nella finestra principale di Rainbow |
Configurazione di un’estensione GUI
Il custo-manifest è un oggetto JSON con la seguente struttura:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"<EXTENSION-POINT-KEY>": [
{
"name": "...",
"icon": "...",
"command": {
"url": "...",
"params": "...",
"commandType": "rest",
"method": "GET"
},
"responseType": "markdown"
}
]
}
}Regole generali:
- la versione deve essere "2".
- jsonType deve essere "Rainbow-custo-manifest". All’interno di un file ZIP, questo campo identifica quale file JSON costituisce il manifesto.
- Ogni chiave presente in `extension-points` è un array — con un massimo di 3 azioni per ciascun punto di estensione.
- Ogni azione deve contenere un oggetto comando valido. I campi "name" e "icon" sono obbligatori a seconda del punto di estensione (vedere §3.4).
Campi dell’azione
| Campo | Posizione | Descrizione |
|---|---|---|
| nome | radice | Testo visualizzato (etichetta del pulsante, titolo del widget, etichetta del menu). Obbligatorio a seconda dell’EP. |
| icona / iconId | root | Icona del pulsante (URL, ${custo.path}\... o sprite integrato). Obbligatorio per i pulsanti con icona. |
| tooltip | root | Testo del tooltip. Facoltativo. |
| comando | root | Oggetto comando (vedere §3.2). Sempre obbligatorio. |
| responseType | root | "markdown" (impostazione predefinita), "json" o "adaptiveCard". Obbligatorio per gli EP di visualizzazione; facoltativo per i pulsanti. |
| displayJsonField | root | Se responseType è impostato su "json", nome del campo JSON contenente il codice Markdown da visualizzare. |
| adaptiveCardTemplate | root | Modello Adaptive Card con JSON incorporato. |
| adaptiveCardTemplateJsonField | root | Nome del campo della risposta REST contenente il modello Adaptive Card. |
| adaptiveCardContentJsonField | root | Nome del campo della risposta REST contenente i dati della scheda. |
| adaptiveCardSubmitUrl | root | URL REST a cui viene inviato un richiesta POST quando viene richiamato Action.Submit nella scheda. |
L’oggetto command
L’oggetto comando è sempre obbligatorio e contiene almeno un URL. A seconda del commandType scelto, sono validi ulteriori sottocampi.
"command": {
"url": "{{server}}/your-endpoint",
"params": "user=${localUser.email}",
"commandType": "rest",
"method": "GET",
"header": ["Authorization: Bearer TOKEN"],
"bodyParameters": { "key": "value" }
}| Campo | Quando utilizzarlo |
|---|---|
| url | Obbligatorio. Percorso dell’applicazione, URL Web, file o API REST. |
| params | Facoltativo. Aggiunti dopo il simbolo “?” per i richieste GET, oppure come parametri URL. Sono ammesse variabili. |
| commandType | Facoltativo. Impostazione predefinita "rest". Valori: "rest", "file" (a seconda dell’EP). |
| method | Facoltativo (solo se commandType: "rest"). Valori: "GET", "POST". |
| header | Opzionale (se REST). Array di stringhe del tipo "Nome-intestazione: valore" inserite come intestazioni HTTP. |
| parametri del corpo | Obbligatorio se method: "POST". Oggetto JSON inviato come corpo della richiesta. Sono ammesse variabili. |
Variabili Rainbow
Le variabili $ vengono sostituite in fase di esecuzione con il loro valore effettivo. Possono comparire in command.url, command.params, command.bodyParameters e nel contenuto restituito all’estensione per la visualizzazione.
Sintassi
${object.attribute}
${object.attribute.regex(pattern)}
${object.attribute.regex(pattern, replacement)}Oggetti e attributi disponibili
Utente Rainbow (ME)
${localUser.firstName} ${localUser.lastName}
${localUser.email} ${localUser.canonicalNumber}
${localUser.phoneNumber} ${localUser.internalNumber}
${localUser.phonePbx} ${localUser.nickname}
${localUser.loginEmail} ${localUser.id}Contatto (se identificato)
${contact.firstName} ${contact.lastName}
${contact.phoneNumber} ${contact.email}
${contact.azienda} ${contact.numeroAzienda}
${contact.numeroCellulare} ${contact.numeroPersonale}
${contact.cellularePersonale}
${contact.tag} (concatenati, separati da virgola)Chiamante (solo per gli EP con pulsante di chiamata)
${caller.firstName} ${caller.lastName} ${caller.phoneNumber}Chiamato (solo per EP con pulsante di chiamata)
${chiamato.numeroDiTelefono}Contesto della chiamata (solo per EP con pulsante di chiamata)
${call.callId}
${call.globalCallId} (solo OXE)
${call.correlator}Spazio (solo EP con funzione "spazio")
${bubble.ownerEmail} ${bubble.name} ${bubble.shareLink}
${bubble.id}
${bubble.membri} (JSON — solo con commandType: "rest")Compatibilità per punto di estensione
| Punto di estensione | Oggetti variabili consentiti |
|---|---|
| on-incoming-pbx-call-button-actions | localUser, caller, called, call, Contatto |
| azioni-relative-all'elenco-del-registro-delle-chiamate | localUser, Contatto |
| azioni relative all'elenco dei contatti | utente locale, Contatto |
| azioni relative ai dettagli dei contatti | utente locale, Contatto |
| azioni sulla scheda di comunicazione | utente locale, chiamante, chiamato, chiamata, Contatto |
| azioni relative agli Spazi | utente locale, Spazio |
| azioni-sulla-bolla-di-conferenza | utente locale, Spazio |
| azioni nel menu utente | utente locale |
| azioni-di-visualizzazione-chiamata-in-entrante-pbx | utente locale, chiamante, chiamato, chiamata, Contatto |
| azioni-di-visualizzazione-scheda-Contatto | utente locale, Contatto |
| azioni di visualizzazione sul widget principale | utente locale |
| azioni-di-visualizzazione-sul-display-principale | utente locale |
| azioni-nella-finestra-principale | utente locale |
modificatore regex
Applica un'espressione regolare al valore della variabile prima della sostituzione:
// Normalizza un numero — sostituisca +33 o +1 con 0
"params": "pbx=${localUser.phonePbx.regex(^\+33|^\+1, 0)}"
// Sostituisca il dominio dell’indirizzo e-mail
"params": "byEmail=${localUser.email.regex(alcatel.com, al-enterprise.com)}"
// Estragga le ultime 9 cifre (nessuna sostituzione = estrazione)
"params": "${contact.phoneNumber.regex(.{0,9}$)}"Variabile ${time}
Disponibile su tutti i punti di estensione — sostituita nel momento in cui l’azione viene eseguita.
| Variabile | Valore |
|---|---|
| ${time} | Data e ora complete (ISO 8601, ad es. 2026-05-18T15:30:45.123Z) |
| ${time.year} | Anno — 4 cifre |
| ${time.month} | Mese — da 01 a 12 |
| ${time.day} | Giorno — 01-31 |
| ${time.hour} | Ora — 00-23 |
| ${time.minute} | Minuto — 00-59 |
| ${time.second} | Secondo — 00-59 |
| ${time.millisec} | Millisecondi — 000-999 |
Risorse locali — ${custo.path}
Per distribuire un manifesto con file locali (icone, contenuti statici):
- Fare riferimento a ciascuna risorsa come ${custo.path}\\nome-file.ext
- Comprimere il file custo-manifest.json e i file delle risorse in un archivio ZIP (con il manifesto nella directory principale)
{
"icon": "${custo.path}\\crm.png",
"command": {
"commandType": "file",
"url": "${custo.path}\\content.txt"
},
"responseType": "markdown"
}Campi specifici dell’estensione
| Campo | Punti di estensione interessati | Descrizione |
|---|---|---|
| AnswerOnClick | azioni-pulsante-chiamata-in-entrante-pbx | true → esegue l’azione e risponde alla chiamata con un solo clic |
| Popup | azioni-nella-finestra-principale | true → apre l’app WEB in una finestra del browser anziché nel frame di Rainbow |
| anche per i team | azioni-nell'elenco-del-registro-delle-chiamate, azioni-nella-schermata-principale | Mostra inoltre l’estensione nel componente aggiuntivo di Teams |
| urlConfig | azioni-di-visualizzazione-sul-widget-principale | URL HTTP/HTTPS per la configurazione del widget |
Inclusione di risorse locali (archivio ZIP)
Se l’azione fa riferimento a file locali (icone o file di visualizzazione), si prega di includere il file custo-manifest.json insieme a tali file in un archivio .zip prima dell’importazione.
Struttura ZIP richiesta — il manifesto deve trovarsi nella directory principale:
my-manifest.zip
├── custo-manifest.json
├── icon.png
└── display-content.txtDistribuzione del manifesto
Una volta configurato il manifesto, lo si distribuisce tramite la console di amministrazione di Rainbow o localmente. Si veda Distribuzione di un custo-manifest in Rainbow.
Esempi di configurazione
Pulsanti
Supportati da Rainbow Desktop e Rainbow Web — richiedono CORS per le chiamate REST.
Esempio 1 — on-contact-list-actions aggiunge un pulsante su ogni riga di contatto che apre il contatto in un CRM esterno (senza finestra pop-up all’interno di Rainbow):
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-contact-list-actions": [
{
"name": "Apri nel CRM",
"tooltip": "Visualizza questo Contatto nel nostro CRM",
"icon": "${custo.path}\\crm.png",
"command": {
"url": "https://crm.example.com/contact",
"params": "email=${contact.email}&phone=${contact.phoneNumber}"
}
}
]
}
}Esempio 2 — on-incoming-pbx-call-button-actions aggiunge un pulsante nella finestra pop-up delle chiamate in arrivo che consente di creare un ticket e rispondere alla chiamata con un solo clic:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-incoming-pbx-call-button-actions": [
{
"name": "Crea ticket e rispondi",
"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}"
}
}
}
]
}
}Visualizza
Supportato da Rainbow Desktop e Rainbow Web — richiede CORS per le chiamate REST.
Esempio 1 — on-incoming-pbx-call-display-actions mostra automaticamente una scheda Markdown con l’ID del chiamante nel pop-up della chiamata in arrivo:
{
"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"
}
]
}
}Esempio 2 — on-main-widget-display-actions mostra un widget Adaptive Card nel pannello principale di Rainbow, aggiornato ogni volta che viene aperto:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-main-widget-display-actions": [
{
"name": "I miei biglietti",
"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"
}
]
}
}Visualizzazione del riquadro
Supportato da Rainbow Desktop e Rainbow Web.
Esempio 1 — on-main-window-actions incorpora una Dashboard CRM nel pannello principale di Rainbow:
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-main-window-actions": [
{
"name": "My CRM",
"icon": "${custo.path}\\crm.png",
"command": {
"url": "https://crm.example.com/dashboard",
"params": "user=${localUser.email}"
}
}
]
}
}Esempio 2 — identico al precedente, ma con Popup: true per l’apertura in una finestra del browser (utile quando l’app non consente l’incorporamento tramite iframe):
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-main-window-actions": [
{
"name": "Reportistica esterna",
"icon": "${custo.path}\\report.png",
"Popup": true,
"command": {
"url": "https://reporting.example.com/",
"params": "user=${localUser.loginEmail}"
}
}
]
}
}