JSONata est un langage de requête et de transformation en open source, conçu pour les données JSON, que nous utiliserons pour accéder aux données d’un corps de réponse JSON renvoyé par l’API et pour les analyser.
Vous pouvez facilement tester vos requêtes en utilisant https://try.jsonata.org/ ou, si vous préférez un format JavaScript-esque plus sophistiqué, https://www.stedi.com/jsonato/playfield. Nous n’utiliserons que la version d’exercice de JSONata pour cette introduction.
La machine lancera son objet fictif Facture, que nous utiliserons comme point de référence. Les données d’entrée brutes se trouvent sur la gauche, la requête d’expression JSON en haut à droite et le résultat trouvé par cette expression sera disponible en bas à droite.
Pour réaligner l’objet JSON, utilisez le petit outil de retrait tout à droite de l’objet fictif et enregistrez toute expression actuelle à l’aide de la fonctionnalité de partage en haut à droite.
C’est tout ce que vous devez savoir au sujet de l’utilisateur pour l’instant ! À présent, utilisez une requête dans le modèle de facture par défaut.
Si vous cherchez simplement les principaux enseignements ou un point de référence après l’activation, consultez notre aide-mémoire.
Données de mappage
Champ au niveau de la racine : Compte
Champ imbriqué dans l’objet racine : Compte. 'Nom du compte'
Si une autre structure JSON est trouvée, vous pouvez utiliser la notation par points pour saisir les champs ci-dessous.
Champ imbriqué dans un tableau au niveau de la racine :
Première commande dans ce compte :
Account.Order[0]
Rappel : L’indexation du tableau commence à [0] pour le premier élément. Le raccourci permettant d’accéder au dernier élément d’un tableau est [-1].
Couleur du premier produit dans le même objet :
Account.Order[0].Product[0].Description.Colour
Récupérer un tableau d’éléments à partir d’un tableau au niveau de la racine :
Si plusieurs valeurs correspondent à une requête, JSONata les agrégera automatiquement.
Vérifiez la totalité de l’objet Account.Order et récupérez tous les ID de commande qu’il contient :
Account.Order.OrderID
Filtrage des données
Définissez la cible à laquelle vous accédez, par ex.
Account.Order.OrderID
Maintenant, ajoutez la condition à l’endroit correspondant : pour chaque vérification d’un tableau, ajoutez une paire de crochets [] :
Par exemple, inclure uniquement les commandes avec des produits d’un prix supérieur à 30 qui n’ont été commandés qu’une seule fois et afficher le nom de produit respectif :
Account.Order.Product[Price > 30 and Quantity = 1].'Product Name'
Par exemple, inclure uniquement les Commandes avec les Produits avec une description. Pondération supérieure à 1 avec l’ID de commande respectif :
Account.Order[Product[Description.Weight > 1]].OrderID
Vous pouvez aussi vérifier que cette affirmation est vraie, par ex :
Account.Order[Product["Purple" in Description.Colour]].OrderID
En outre, cette opération peut être associée à des recherches par caractères génériques si vous souhaitez vérifier plusieurs clés, par ex :
Account.Order[Product["Purple" in Description.*]].OrderID
Autres opérateurs de protocole
(https://docs.jsonata.org/path-operators)
^( ... ) (Order-by)
Trier par ID de commande décroissant :
Account.Order^(>OrderID)
Trier du produit le moins cher au produit le plus cher :
Account.Order.Product^(Price)
* (Caractère générique)
Accédez à n'importe quelle référence, indépendamment du nom du parent :
Account.Order.*.SKU
Accédez à n’importe quel nom de produit, indépendamment du nom du parent :
**.'Product Name'
% (Parent)
Recherche à rebours dans la structure de données actuelle :
Account.Order.Product.{
'Account': %.%.`Account Name`,
'Order': %.OrderID,
'Product': `Product Name`
}
# (Liaison des variables positionnelles)
Crée un index, en commençant à 0 :
Account.Order#$i[Product.[Quantity > 0]].{
'Order ID': OrderID,
'Order Number': $i + 1
}
@ (Liaison des variables contextuelles)
Affecte temporairement une nouvelle structure de données, autorisant les mappages entre objets :
Account@$A.Account.Order@$O.{
"Account Name": $A.'Account Name',
"OrderID": $O.OrderID
}
Éléments conditionnels
À l'instar de l'opérateur ternaire en langage JS, vous pouvez utiliser « ? » pour les instructions « si » et « : » pour les instructions « sinon ». Les opérateurs booléens « et/ou » peuvent être utilisés pour créer des conditions de chaînes.
SI LA CONDITION EST VRAIE ? PRENEZ CES MESURES (SINON, NE RIEN FAIRE)
SI LA CONDITION EST VRAIE ? PRENEZ CES MESURES : SINON, PRENEZ CES MESURES
$count(Account.Order) > 1 ? "REPEAT CUSTOMER"
Account.Order[0].Product[0].Price <= 100 or Account.Order[0].Product[1].Price <= 100 ? "Bargain" : "VIP" = "Bargain"
Manipulation des données
Opérateurs pris en charge
Opérateur | Priority | Description |
Multiplier (*) | 5 | Multiplie deux nombres |
Diviser (/) | 5 | Divise deux nombres |
Moduler (%) | 5 | Renvoie le reste lors de la division de deux nombres |
Concaténer (&) | 4 | Concatène deux chaînes |
Additionner (+) | 4 | Ajoute deux numéros |
Soustraire (-) | 4 | Soustrait deux nombres |
Égal(e) à (=) | 3 | Teste si deux valeurs sont égales |
Pas égal(e) à (!=) | 3 | Teste si deux valeurs ne sont pas égales |
Supérieur à (>) | 3 | Renvoie Vrai si la valeur de gauche est supérieure à la valeur de droite |
Supérieur(e) ou égal(e) à (>=) | 3 | Renvoie Vrai si la valeur de gauche est supérieure ou égale à la valeur de droite |
Inférieur à (<) | 3 | Renvoie Vrai si la valeur de gauche est inférieure à la valeur de droite |
Inférieur(e) ou égal(e) à (<=) | 3 | Renvoie Vrai si la valeur de gauche est inférieure ou égale à la valeur de droite |
Logique ET (et) | 2 | Renvoie Vrai si les valeurs de gauche et de droite sont vraies |
Logique OU (ou) | 1 | Renvoie Vrai si la valeur de gauche est vraie ou si la valeur de droite est vraie |
Par exemple, en concaténant des chaînes :
Account.Order[0].Product[0].Description.Colour & " " & Account.Order[0].Product[0].'Product Name'
Fonctions intégrées
Veuillez noter que ces balises ont été fortement abrégées pour des raisons de lisibilité. Vous trouverez la documentation complète ici : https://docs.jsonata.org/overview.html
Remarque : une expression multiligne doit être entourée de ()
Type de chaîne de force : $string(Account.Order[0].Product[0].ProductID) : "858383"
Type de numéro de force : $number(Account.Order[0].Product[0].SKU) : 406654608
Chaîne en majuscules : $uppercase(Compte.Commande[0].ID de commande) : "ORDER103"
Chaîne en minuscules : $lowercase(Compte.Commande[0].Produit[0].Description.Couleur : « violet »
Sort un nombre aléatoire entre 0 et 1 : $random()
Nombre d'objets dans un tableau : $count(Compte.Commande)
Nombre d'objets dans un tableau qui correspondent à une condition : $count(Compte.Commande.Produit[Prix > 30])
Nombre de caractères dans une chaîne : $length(Compte.'Nom du compte')
Remplace / Supprime certains caractères d’une chaîne : $replace(Compte.Commande[0].Produit[0].'Nom du produit', « Bowler », "") : « Chapeau »
Réduction d’une chaîne sur un nombre de caractères spécifique : $substring($string(Compte.Commande[0].Produit[0].ID de produit), 1, 2)
Coupe une chaîne selon un modèle spécifique : $substringAfter(Compte.Commande[0].ID de commande, « commande »)
Résultat similaire en utilisant le diviser + joindre :
$join($split(Compte.Commande[0].Produit[0].'Nom du produit', " "), '_')
Peut aussi s’écrire comme une fonction ~> :
$split(Compte.Commande[0].Produit[0].'Nom du produit', " ") ~> $join('_')
Vérifiez si une chaîne contient un schéma spécifique. Le schéma peut être une chaîne exacte ou une expression rationnelle :
$contains(Compte.Commande[0].Produit[0].'Nom du produit', « Chapeau »)
Dates et heures
La plupart des dates seront transmises dans la norme internationale ISO 8601 et ressembleront à ceci 20-04-2023T13:09:39+00:00 (informations sur le fuseau horaire) ou 20-04-2023T13:09:39Z (en millisecondes par rapport à l'UTC). Elles sont agréablement lisibles par l'homme, mais ne peuvent pas être manipulées de manière native par JSONata.
Souvent, vous devrez donc les transformer en temps UNIX, qui est le nombre littéral de secondes qui se sont écoulées depuis 00:00:00 UTC le 1er janvier 1970 (Unix epoch), qui n'est plus humainement lisible, mais qui, en tant que nombre entier, peut être ajouté / soustrait / comparé à d'autres dates UNIX. JSONata travaille en mode natif avec Millis, qui sont les MILLISECONDES écoulées depuis Unix Epoch (soit donc UNIX * 1000).
$now() : « 20-04-2023T13:39:58.216Z »
$millis() : 1681998518175
Ces millisecondes peuvent désormais être retransformées dans un format de date de votre choix en définissant une image (votre schéma cible) dans une chaîne : https://www.w3.org/TR/xpath-functions-31/#date-picture-string
Exemples de schémas : https://www.w3.org/TR/xpath-functions-31/#date-time-examples
Spécificateur | Signification |
oui |
Année (valeur absolue) |
M | Mois de l’année |
D | Jour du mois |
F | Jour de la semaine |
H | Heure du jour (24 heures) |
h | Heure en demi-journée (12 heures) |
p | Marqueur AM/PM |
m | Minute dans l’heure |
s | Seconde dans la minute |
Z | Fuseau horaire |
Par exemple, $fromMillis($millis(), '[M]/[D]/[Y01]') renvoie « 20/04/23 »,
$fromMillis($millis(), '[J01].[M01].[A0001] [H#1]:[m01]') renvoie « 20.04.2023 13:51 ».
Supposons que vous ayez deux dates dans vos données de réponse et que vous vouliez vérifier le nombre de jours qui se sont écoulés depuis AUJOURD’HUI.
« 20-04-2023T00:00:00.000Z »
« 20.04.2023 »
Transformez-les toutes deux en Millisecondes : la deuxième date n’est pas dans le schéma ISO 8601 standard, vous devrez donc fournir l’image pour que JSONata sache quelle valeur correspond à votre jour, votre mois, votre année et toutes informations temporelles disponibles.
$toMillis('20-04-2023T00:00:00.000Z') : 1681948800000
$toMillis('20.04.2023', '[J01].[M01].[A0001]') : 1681948800000
Vous avez aussi l’heure actuelle en Millisecondes via la fonction standard $millis() : 1681999968402
Vous pouvez désormais simplement soustraire l’une de l’autre valeur et recevoir la différence entre les deux dates en millisecondes : 1681999968402 - 1681948800000 = 51296367
Utilisation de la conversion classique du temps :
1 000 millisecondes = 1 seconde
60 s = 1 minute
60 min = 1 heure
En arrondissant le résultat, vous recevez un total de 14 heures qui se sont écoulées entre aujourd’hui et votre horodatage fourni :
$round(51296367 / 1 000 / 60 / 60) = 14
En résumé, sur une seule ligne, vous voyez l’opération suivante :
$round(($millis() - $toMillis('20.04.2023', '[D01].[M01].[Y0001]')) / 1000 / 60 / 60)
Sorties spéciales
Ticket « En une fois »
Comme vous n’avez peut-être qu’une seule tentative de réponse, vous devez transférer autant d’informations que possible dans un seul paramètre. JSONata gère l’agrégation pour vous pour que vous puissiez jouer avec la copie de texte.
Supposons que vous vouliez afficher les références et les prix de tous les produits de votre commande :
Account.Order.Product
Comme vous voulez n’avoir qu’une seule ligne de texte avec tous les produits pris en compte, vous pouvez créer un tableau partagé avec toutes les informations nécessaires :
Account.Order.Product.(SKU & Price)
Il ne vous reste plus qu’à les combiner pour former une seule chaîne avec un saut de ligne comme séparateur :
$join(Account.Order.Product.("SKUs: " & SKU & ", " & "Price: " & Price), "\n")
Remarque : Réfléchissez aux limites de votre CRM : Zendesk Support fournit un formatage élémentaire, donc un \n se traduira par un saut de ligne lors du rendu d’un e-mail de réponse, mais ce n’est pas toujours le cas sur tous les systèmes.
Fiches et carrousels
Les fiches et les carrousels sont la véritable force de JSONata, car elle gère la requête et l’agrégation de données en mode natif, tant que votre réponse suit le même schéma. Les C&C se composent d’un tableau d’objets dans lequel chaque objet représente l’une de vos fiches. Un exemple très simple de structure C&C avec 2 cartes pourrait ressembler à ce qui suit :
[
{
"imageURL": data.url1,
"title": data.title1,
"description": data.description1
},
{
"imageURL": data.url2,
"title": data.title2,
"description": data.description2
}
]
Il est important que tous les objets du tableau suivent la même structure pour que vous puissiez y accéder via la même clé partagée. N’oubliez pas les limites de votre CRM .
Pour un exemple simple, créons à nouveau un nouveau C&C sur l’échantillon de données de facture. Commençons avec un tableau de départ : tout résultat de requête avec plus d’un objet de réponse sera automatiquement converti en tableau, mais cette sécurité est une bonne chose si votre résultat ne contient qu’un seul objet.
[Account.Order.Product.'Product Name']
[Account.Order.Product.SKU]
[Account.Order.Product.Description.Colour]
Voici quelques-uns des champs qui nous intéressent. Nous allons les combiner dans un seul objet. N’oubliez pas de donner un nom à chaque clé de votre objet cible :
[
Account.Order.Product.
{
"name": 'Product Name',
"sku": SKU,
"colour": Description.Colour
}
]
Si vous avez besoin d’une valeur d’un niveau supérieur, il vous suffit de commencer votre requête à un niveau supérieur. Si vous souhaitez aussi inclure [Compte.Commande.ID de commande] dans votre tableau :
[
Account.Order.
{
"orderId": OrderID,
"name": Product.'Product Name',
"sku": Product.SKU,
"Colour": Product.Description.Colour
}
]
Vous remarquerez qu’il n’y a plus de correspondance 1:1 directe, car chaque commande peut contenir plusieurs éléments. C’est la raison pour laquelle cette réponse crée des tableaux de chaînes qui semblent aléatoires. Vous pouvez résoudre ce problème en accédant indirectement à l’objet parent (consultez la liaison parent), en affectant temporairement une autre structure d’objet dans JSONata (consultez la liaison avec la variable contextuelle), en ajoutant un C&C secondaire qui parcourt les éléments dans l’ordre choisi, ou en transformant davantage les données, en fonction de l’expérience idéale. Voici un exemple de transformation :
[
Account.Order.
{
"orderId": OrderID,
"name": $join(Product.'Product Name', ", "),
"totalPrice": $sum(Product.Price)
}
]
Si vous voulez améliorer davantage votre requête, ajoutons des valeurs de sécurité au cas où vous n’avez pas les données de réponse attendues (pour couvrir par exemple un 404) et une butée si la réponse renvoie plus de résultats que ce que votre CRM peut prendre en charge (par ex. 10 pour les widgets SunCo) :
Account.Order ?
[Account.Order[[0..9]].
{
"orderId": OrderID,
"name": $join(Product.'Product Name', ", "),
"totalPrice": $sum(Product.Price)}]
: [{"orderId": "???", "name": "Cannot find your item?"}]
IMPORTANT : Assurez-vous que toutes les clés C&C suivent la convention camelCase, les noms de paramètres _ ne sont pas pris en charge.
Désormais, toutes ces clés, par exemple orderId, name, totalPrice, seront disponibles dans votre carrousel. Changez votre type de carrousel en dynamique dans l’interface utilisateur et ajoutez le nom du paramètre qui héberge votre requête au-dessus, par exemple orderList.
Vous pouvez désormais accéder à n’importe quelle clé des objets de votre tableau en ajoutant un raccourci %, ou en les sortant directement dans le chat sur vos fiches :
Ou en les stockant dans la session en remplissant votre carte de choix avec une action faisant référence à la clé de l’objet choisi dans un nom de paramètre de votre choix, par exemple :