Fonctionnalité: Custo-manifest (Extensions Rainbow) — Extensions de l'interface graphique
Licence: licence Business au minimum
Cet article vous permettra de créer des extensions de l’interface graphique de Rainbow afin d’ajouter des boutons, des widgets et des applications Web intégrées à Rainbow. Vous découvrirez quels points d’extension sont disponibles et comment choisir l’emplacement le plus adapté à votre flux de travail.
Présentation
Les extensions de l’interface graphique vous permettent d’ajouter des boutons personnalisés, d’afficher des widgets et d’intégrer des applications web à l’interface de Rainbow. Ces extensions nécessitent au minimum une licence Business.
Ce que vous pouvez faire avec les extensions de l’interface graphique :
- Ajouter des boutons d’action cliquables dans les listes de contacts, le journal des appels, la fiche de communication et les Bulles
- Afficher automatiquement du contenu personnalisé (données CRM, tickets, Rapports) dans les fenêtres contextuelles d’appel et les panneaux de Contacts
- Intégrer une application Web tierce directement dans le panneau principal de Rainbow
Types de points d’extension
Un point d’extension (EP) est un emplacement nommé dans l’interface de Rainbow où une action personnalisée peut être associée. Chaque EP possède une clé unique (par exemple, « on-contact-list-actions »), un emplacement fixe dans l’interface utilisateur et des règles définissant les champs et variables disponibles. Le fichier « custo-manifest » déclare une ou plusieurs actions sous chaque clé EP.
Boutons — boutons cliquables
Un bouton-icône est inséré à un emplacement spécifique de l’interface utilisateur de Rainbow. Lorsqu’on clique dessus, une action est exécutée et, éventuellement, son résultat s’affiche dans une fenêtre contextuelle (Markdown ou Adaptive Card). Jusqu’à 3 boutons par point d’extension.
| Point d’extension | Emplacement du bouton |
|---|---|
| actions-des-boutons-lors-d’un-appel-entrant-vers-le-PBX | Fenêtre contextuelle d’appel entrant |
| actions-sur-la-liste-des-appels | Chaque ligne du journal des appels |
| actions-sur-la-liste-des-Contacts | Chaque ligne de la liste de contacts |
| Actions sur les détails des Contacts | Panneau des détails du Contact |
| actions sur la fiche de communication | Barre de gestion des appels |
| Actions sur la bulle | Menu des propriétés de la bulle |
| Actions de conférence sur la bulle | Menu de la conférence téléphonique |
| Actions du menu utilisateur | Menu utilisateur (BÊTA, Bureau / Web — hors Teams) |
Affichages — affichage automatique d’informations
Le contenu (Markdown ou Adaptive Card) est automatiquement inséré à un emplacement spécifique de l’interface utilisateur — sans aucune intervention de l’utilisateur. Le contenu est récupéré lorsque l’emplacement devient visible.
| Point d’extension | Emplacement d’affichage |
|---|---|
| on-incoming-pbx-call-display-actions | Dans la fenêtre contextuelle d’appel entrant |
| on-contact-card-display-actions | Dans le panneau de détails du Contact |
| actions-d'affichage-sur-le-widget-principal | Widget dans le panneau principal de Rainbow |
| actions d'affichage sur l'écran principal | Message dans l’application web Teams |
Affichage dans un cadre — application web tierce
Intègre une application Web tierce dans un cadre de l’interface utilisateur Rainbow. Lorsque l’option « Popup : true » est activée, l’application s’ouvre dans une fenêtre de navigateur au lieu d’être intégrée.
| Point d’extension | Emplacement |
|---|---|
| on-main-window-actions | Cadre dans la fenêtre principale de Rainbow |
Configuration d’une extension d’interface graphique
Le fichier custo-manifest est un objet JSON présentant la structure suivante :
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"<EXTENSION-POINT-KEY>": [
{
"name": "...",
"icon": "...",
"command": {
"url": "...",
"params": "...",
"commandType": "rest",
"method": "GET"
},
"responseType": "markdown"
}
]
}
}Règles générales :
- la version doit être « 2 ».
- jsonType doit être « Rainbow-custo-manifest ». Dans un fichier ZIP, ce champ identifie le fichier JSON qui sert de manifeste.
- Chaque clé sous « extension-points » est un tableau — avec un maximum de 3 actions par point d’extension.
- Chaque action doit contenir un objet « command » valide. Les champs « name » et « icon » sont obligatoires selon le point d’extension (voir §3.4).
Champs de l’action
| Champ | Position | Description |
|---|---|---|
| nom | racine | Texte affiché (libellé du bouton, titre du widget, libellé du menu). Obligatoire selon l’EP. |
| icône / iconId | racine | Icône du bouton (URL, ${custo.path}\... ou sprite intégré). Obligatoire pour les boutons avec icône. |
| tooltip | racine | Texte de l'info-bulle. Facultatif. |
| commande | racine | Objet « commande » (voir §3.2). Toujours obligatoire. |
| responseType | racine | « markdown » (par défaut), « json » ou « adaptiveCard ». Obligatoire pour les EP d’affichage ; facultatif pour les boutons. |
| displayJsonField | racine | Si responseType : « json », nom du champ JSON contenant le code Markdown à afficher. |
| adaptiveCardTemplate | racine | Modèle Adaptive Card avec JSON intégré. |
| adaptiveCardTemplateJsonField | racine | Nom du champ de la réponse REST contenant le modèle de carte adaptative. |
| adaptiveCardContentJsonField | racine | Nom du champ de la réponse REST contenant les données de la carte. |
| adaptiveCardSubmitUrl | root | URL REST appelée en POST lorsqu’une méthode Action.Submit est invoquée dans la carte. |
L'objet « command »
L’objet « command » est toujours obligatoire et contient au moins une URL. Selon le « commandType » choisi, des sous-champs supplémentaires sont autorisés.
"command" : {
"url" : "{{server}}/your-endpoint",
"params" : "user=${localUser.email}",
"commandType" : "rest",
"method" : "GET",
"header": ["Authorization: Bearer TOKEN"],
"bodyParameters": { "key": "value" }
}| Champ | Quand l’utiliser |
|---|---|
| url | Obligatoire. Chemin d’accès à l’application, URL Web, fichier ou API REST. |
| params | Facultatif. Ajouté après le signe « ? » pour les requêtes GET, ou sous forme de paramètres d’URL. Variables autorisées. |
| commandType | Facultatif. Valeur par défaut : « rest ». Valeurs possibles : « rest », « file » (selon l’EP). |
| method | Facultatif (uniquement si commandType = « rest »). Valeurs : « GET », « POST ». |
| header | Facultatif (si REST). Tableau de chaînes de caractères « Nom-d’en-tête : valeur » insérées en tant qu’en-têtes HTTP. |
| paramètres du corps | Obligatoire si la méthode est « POST ». Objet JSON envoyé en corps de requête. Les variables sont autorisées. |
Variables Rainbow
Les variables $ sont remplacées lors de l’exécution par leur valeur réelle. Elles peuvent apparaître dans command.url, command.params, command.bodyParameters, ainsi que dans le contenu renvoyé à l’extension pour affichage.
Syntaxe
${object.attribute}
${object.attribute.regex(pattern)}
${object.attribute.regex(pattern, replacement)}Objets et attributs disponibles
Utilisateur Rainbow (ME)
${localUser.firstName} ${localUser.lastName}
${localUser.email} ${localUser.canonicalNumber}
${localUser.phoneNumber} ${localUser.internalNumber}
${localUser.phonePbx} ${localUser.nickname}
${localUser.loginEmail} ${localUser.id}Contact (si identifié)
${contact.prénom} ${contact.nom}
${contact.numéroDeTéléphone} ${contact.e-mail}
${contact.compagnie} ${contact.numéroPro}
${contact.numéroMobile} ${contact.numéroPersonnel}
${contact.mobilePersonnel}
${contact.tags} (concaténés, séparés par des virgules)Appelant (EP du bouton d’appel uniquement)
${caller.firstName} ${caller.lastName} ${caller.phoneNumber}Appelé (uniquement pour les EP avec bouton d’appel)
${called.phoneNumber}Contexte de l’appel (EP avec bouton d’appel uniquement)
${call.callId}
${call.globalCallId} (OXE uniquement)
${call.correlator}Bulle (EP « bulle » uniquement)
${bubble.ownerEmail} ${bubble.name} ${bubble.shareLink}
${bubble.id}
${bubble.membres} (JSON — uniquement avec commandType : « rest »)Compatibilité par point d’extension
| Point d’extension | Objets variables autorisés |
|---|---|
| on-incoming-pbx-call-button-actions | localUser, caller, called, call, Contact |
| actions-sur-la-liste-des-appels | localUser, Contact |
| actions sur la liste des Contacts | utilisateur local, Contact |
| actions sur les détails des Contacts | utilisateur local, Contact |
| actions sur la fiche de communication | utilisateur local, appelant, appelé, appel, Contact |
| actions sur la bulle | utilisateur local, Bulle |
| actions sur la bulle de conférence | utilisateur local, Bulle |
| actions-sur-le-menu-de-l'utilisateur | localUser |
| actions-lors-de-l'affichage-d'un-appel-PBX-entrant | localUser, appelant, appelé, appel, Contact |
| actions-lors-de-l'affichage-de-la-fiche-de-contact | utilisateur local, Contact |
| actions d'affichage sur le widget principal | utilisateur local |
| actions-d'affichage-sur-l'écran-principal | utilisateur local |
| actions-de-la-fenêtre-principale | localUser |
modificateur d'expression régulière
Applique une expression régulière à la valeur de la variable avant la substitution:
// Normaliser un nombre — remplacer +33 ou +1 par 0
"params": "pbx=${localUser.phonePbx.regex(^\+33|^\+1, 0)}"
// Remplacer le domaine de l'adresse e-mail
"params": "byEmail=${localUser.email.regex(alcatel.com, al-enterprise.com)}"
// Extraire les 9 derniers chiffres (pas de remplacement = extraction)
"params": "${contact.phoneNumber.regex(.{0,9}$)}"Variable ${time}
Disponible sur tous les points d’extension — remplacée au moment de l’exécution de l’action.
| Variable | Valeur |
|---|---|
| ${time} | Date et heure complètes (ISO 8601, par exemple 2026-05-18T15:30:45.123Z) |
| ${time.year} | Année — 4 chiffres |
| ${time.month} | Mois — 01-12 |
| ${time.day} | Jour — 01-31 |
| ${time.hour} | Heure — 00-23 |
| ${time.minute} | Minute — 00-59 |
| ${time.second} | Seconde — 00-59 |
| ${time.millisec} | Millisecondes — 000-999 |
Ressources locales — ${custo.path}
Pour distribuer un manifeste contenant des fichiers locaux (icônes, contenu statique) :
- Référencez chaque ressource sous la forme ${custo.path}\\nom-de-fichier.ext
- Compressez le fichier custo-manifest.json et les fichiers de ressources dans un fichier ZIP (le manifeste à la racine)
{
"icon": "${custo.path}\\crm.png",
"command": {
"commandType": "file",
"url": "${custo.path}\\content.txt"
},
"responseType": "markdown"
}Champs spécifiques à l’extension
| Champ | Points d’extension concernés | Description |
|---|---|---|
| AnswerOnClick | actions-sur-le-bouton-d’appel-PBX-entrant | true → exécute l’action et répond à l’appel en un seul clic |
| Fenêtre contextuelle | actions-sur-la-fenêtre-principale | true → ouvre l’application Web dans une fenêtre de navigateur au lieu du cadre Rainbow |
| également pour les équipes | actions-sur-la-liste-des-appels, actions-sur-l'affichage-principal | Affiche également l’extension dans le module complémentaire Teams |
| urlConfig | actions-d'affichage-sur-le-widget-principal | URL HTTP/HTTPS pour la configuration du widget |
Inclusion de ressources locales (archive ZIP)
Si l’action fait référence à des fichiers locaux (icônes ou fichiers d’affichage), veuillez regrouper le fichier custo-manifest.json avec ces fichiers dans une archive .zip avant l’importation.
Structure ZIP requise — le fichier manifeste doit se trouver à la racine :
my-manifest.zip
├── custo-manifest.json
├── icon.png
└── display-content.txtDéploiement du manifeste
Une fois le manifeste configuré, déployez-le via la console d’administration Rainbow ou localement. Consultez la section « Déploiement d’un custo-manifest dans Rainbow ».
Exemples de configuration
Boutons
Pris en charge par Rainbow Desktop et Rainbow Web — nécessite CORS pour les appels REST.
Exemple 1 — « on-contact-list-actions » ajoute un bouton sur chaque ligne de Contact qui ouvre le Contact dans un CRM externe (pas de fenêtre contextuelle dans Rainbow) :
{
"version": "2",
"jsonType": "Rainbow-custo-manifest",
"extension-points": {
"on-contact-list-actions": [
{
"name": "Ouvrir dans le CRM",
"tooltip": "Afficher ce Contact dans notre CRM",
"icon": "${custo.path}\\crm.png",
"command": {
"url": "https://crm.example.com/contact",
"params": "email=${contact.email}&phone=${contact.phoneNumber}"
}
}
]
}
}Exemple 2 — on-incoming-pbx-call-button-actions ajoute un bouton dans la fenêtre contextuelle d’appel entrant qui permet de créer un ticket et de répondre à l’appel en un seul clic :
{
"version" : "2",
"jsonType" : "Rainbow-custo-manifest",
"extension-points" : {
"on-incoming-pbx-call-button-actions" : [
{
"name" : "Créer un ticket et répondre",
"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}"
}
}
}
]
}
}Affichage
Prise en charge par Rainbow Desktop et Rainbow Web — nécessite CORS pour les appels REST.
Exemple 1 — on-incoming-pbx-call-display-actions affiche automatiquement une fiche d’identification de l’appelant au format Markdown dans la fenêtre contextuelle d’appel entrant :
{
"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"
}
]
}
}Exemple 2 — « on-main-widget-display-actions » affiche un widget Adaptive Card dans le panneau principal de Rainbow, actualisé à chaque ouverture :
{
"version" : "2",
"jsonType" : "Rainbow-custo-manifest",
"extension-points" : {
"on-main-widget-display-actions" : [
{
"name": "Mes 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"
}
]
}
}Affichage du cadre
Prise en charge par Rainbow Desktop et Rainbow Web.
Exemple 1 — « on-main-window-actions » intègre un Tableau de bord CRM dans le panneau principal de Rainbow :
{
"version" : "2",
"jsonType" : "Rainbow-custo-manifest",
"extension-points" : {
"on-main-window-actions" : [
{
"name": "Mon CRM",
"icon": "${custo.path}\\crm.png",
"command": {
"url": "https://crm.example.com/dashboard",
"params": "user=${localUser.email}"
}
}
]
}
}Exemple 2 — identique, mais avec `Popup: true` pour ouvrir la page dans une fenêtre de navigateur (utile lorsque l’application refuse l’intégration via iframe) :
{
"version" : "2",
"jsonType" : "Rainbow-custo-manifest",
"extension-points" : {
"on-main-window-actions" : [
{
"name": "Rapports externes",
"icon": "${custo.path}\\report.png",
"Popup": true,
"command": {
"url": "https://reporting.example.com/",
"params": "user=${localUser.loginEmail}"
}
}
]
}
}