Welchen Plan habe ich
Add-on AI Agents – Advanced

JSONata ist eine Open-Source-Sprache für Abfragen und Transformationen für JSON-Daten, mit deren Hilfe wir Daten in einem von der API zurückgegebenen JSON-Antworttext abrufen und analysieren.

Sie können Ihre Abfragen ganz einfach mit https://try.jsonata.org/ testen. Falls Sie ein anspruchsvolleres JavaScript-Format bevorzugen, können Sie dazu https://www.stedi.com/jsonata/playground verwenden. Bleiben wir für diese Einführung bei JSONatas Exerciser.

Starten Sie im Exerciser das Dummy-Objekt „Rechnung“, das wir als Bezugspunkt verwenden. Die unverarbeiteten Eingabedaten befinden sich links, die JSONata-Ausdrucksabfrage oben rechts und das Ergebnis dieses Ausdrucks unten rechts.

Um das JSON-Objekt neu auszurichten, verwenden Sie das kleine Einrückungswerkzeug ganz rechts beim Dummy-Objekt und speichern Sie den aktuellen Ausdruck mit der Teilen-Funktion oben rechts.

Das ist alles, was Sie im Augenblick über den Exerciser wissen müssen. Als Nächstes verwenden Sie eine Abfrage in der Standard-Rechnungsvorlage.

Falls Sie nach der Aktivierung nur nach den wichtigsten Erkenntnissen oder nach einem Bezugspunkt suchen, sehen Sie sich unser Cheat-Sheet an.

Datenzuordnung

Stammfeld: Konto
Verschachteltes Feld in Stammobjekt: Account.'Kontoname'
Falls eine andere JSON-Struktur gefunden wird, können Sie die folgenden Felder in Punktnotation eingeben.

Verschachteltes Feld in einem Root-Level-Array:

Erste Bestellung in diesem Konto:

Account.Order[0]

Erinnerung: Die Array-Indizierung beginnt bei [0] für das erste Element. Der Shortcut für das letzte Element in einem Array lautet [-1].

Die Farbe des ersten Produkts im selben Objekt:

Account.Order[0].Product[0].Description.Colour

Array von Elementen aus einem Array auf Stammebene abrufen:

Falls mehrere Werte mit einer Abfrage übereinstimmen, werden sie von JSONata automatisch aggregiert.

Prüfen Sie das gesamte Objekt „Account.Order“ und rufen Sie alle darin enthaltenen OrderIDs ab:

Account.Order.OrderID

Filtern von Daten

 

Definieren Sie das Ziel, auf das zugegriffen wird, beispielsweise:

Account.Order.OrderID

Fügen Sie nun die Bedingung an der entsprechenden Stelle hinzu. Für jeden Durchlauf durch ein Array fügen Sie ein Paar [] eckiger Klammern hinzu:

Beispiel: Beziehen Sie nur Bestellungen für Produkte mit einem Preis über 30 ein, die nur einmal bestellt wurden, und zeigen Sie den jeweiligen Produktnamen an:

Account.Order.Product[Price > 30 and Quantity = 1].'Product Name'

Beispiel: Beziehen Sie nur Bestellungen mit Produkten mit einer „Description.Weight“ größer als 1 ein zeigen Sie die entsprechende Order-ID an;

Account.Order[Product[Description.Weight > 1]].OrderID

Sie können auch nach einer zutreffenden Aussage suchen, z. B.:

Account.Order[Product["Purple" in Description.Colour]].OrderID

Dies kann auch mit Wildcard-Suchen kombiniert werden, wenn Sie mehrere Schlüssel prüfen möchten, z. B.:

Account.Order[Product["Purple" in Description.*]].OrderID

Andere Pfadoperatoren

(https://docs.jsonata.org/path-operators)

^( ... ) (Order-by)

Nach absteigender Bestell-ID sortieren:

Account.Order^(>OrderID)

Sortieren vom billigsten zum teuersten Produkt:

Account.Order.Product^(Price)

* (Wildcard)

Zugriff auf jede beliebige Artikelnummer, ungeachtet der Benennung des direkten übergeordneten Artikels:

Account.Order.*.SKU

Zugriff auf jede beliebige Produktnamen, unabhängig von den Benennungen des übergeordneten Kontos:

**.'Product Name'

% (Parent)

Sucht rückwärts in der aktuellen Datenstruktur:

Account.Order.Product.{
 'Account': %.%.`Account Name`,
 'Order': %.OrderID,
 'Product': `Product Name`
}

# (Positionsvariablenbindung)

Erstellt einen Index, beginnend bei 0:

Account.Order#$i[Product.[Quantity > 0]].{
 'Order ID': OrderID,
 'Order Number': $i + 1
}

@ (Kontextvariablenbindung)

Weist vorübergehend eine neue Datenstruktur zu, die objektübergreifende Zuordnungen ermöglicht:

Account@$A.Account.Order@$O.{ 
 "Account Name": $A.'Account Name',
"OrderID": $O.OrderID
}

Konditionale Logik

 

Ähnlich wie beim ternären Operator in JS können Sie auch ? for if- und : for else-Anweisungen verwenden. Boolesche Operatoren und/oder können zum Erstellen von Verkettungsbedingungen verwendet werden.

IF BEDINGUNG IST: WAHR? DIES TUN (ELSE: NICHTS TUN)

IF BEDINGUNG IST: WAHR? DIES TUN: ELSE: DIES TUN

$count(Account.Order) > 1 ? "REPEAT CUSTOMER"
Account.Order[0].Product[0].Price <= 100 or Account.Order[0].Product[1].Price <= 100 ? "Bargain" : "VIP" = "Bargain"

Manipulieren von Daten

Unterstützte Operatoren

Operator Priority Beschreibung
Multiplizieren (*) 5 Multipliziert zwei Zahlen.
Teilen (/) 5 Teilt zwei Zahlen.
Modulo (%) 5 Gibt den Rest einer Division zweier Zahlen zurück.
Verketten (&) 4 Verknüpft zwei Zeichenfolgen.
Hinzufügen (+) 4 Addiert zwei Zahlen.
Subtrahieren (-) 4 Subtrahiert zwei Zahlen.
Gleich (=) 3 Prüft, ob zwei Werte gleich sind.
Nicht Gleich (!=) 3 Prüft, ob zwei Werte ungleich sind.
Größer als (>) 3 Gibt „TRUE“ zurück, wenn der Wert auf der linken Seite größer als der Wert auf der rechten Seite ist.
Größer oder gleich (>=) 3 Gibt „TRUE“ zurück, wenn der Wert auf der linken Seite größer oder gleich dem Wert auf der rechten Seite ist.
Kleiner als (<) 3 Gibt „TRUE“ zurück, wenn der Wert auf der linken Seite kleiner als der Wert auf der rechten Seite ist.
Kleiner oder gleich (<=) 3 Gibt „TRUE“ zurück, wenn der Wert auf der linken Seite kleiner oder gleich dem Wert auf der rechten Seite ist.
Logisches UND (und) 2 Gibt „TRUE“ zurück, wenn sowohl der linke als auch der rechte Wert wahr sind.
Logisches ODER (oder) 1 Gibt „TRUE“ zurück, wenn entweder der linke Wert oder der rechte Wert wahr ist.

Beispiel: Verketten von Zeichenfolgen:

Account.Order[0].Product[0].Description.Colour & " " & Account.Order[0].Product[0].'Product Name'

Integrierte Funktionen

Dieser Abschnitt wurde aus Gründen der Übersichtlichkeit stark gekürzt. Die vollständige Dokumentation finden Sie hier: https://docs.jsonata.org/overview.html 

Hinweis: Ein mehrzeiliger Ausdruck muss in () eingeschlossen werden

Typ „Zeichenfolge“ erzwingen: $string(Account.Order[0].Product[0].ProductID): "858383"

Typ „Zahl“ erzwingen: $number(Account.Order[0].Product[0].SKU): 406654608

Zeichenfolge in Großbuchstaben: $uppercase(Account.Order[0].OrderID): "BESTELLUNG103"

Zeichenfolge in Kleinbuchstaben: $lowercase(Account.Order[0].Product[0].Description.Colour): "violett"

Zufällige Ausgabezahl zwischen 0 und 1: $random()

Anzahl der Objekte in einem Array: $count(Account.Order)

Anzahl der Objekte in einem Array, die eine Bedingung erfüllen:  $count(Account.Order.Product[Price > 30])

Anzahl der Zeichen in einer Zeichenfolge: $length(Account.'Kontoname')

Bestimmte Zeichen in einer Zeichenfolge ersetzen/entfernen: $replace(Account.Order[0].Product[0].'Product Name', "Bowler-", ""): "Hut"

Abschnitt zu einer bestimmten Anzahl von Zeichen: $substring($string(Account.Order[0].Product[0].ProductID), 1, 2)

Entfernen einer Zeichenfolge nach einem bestimmten Muster: $substringAfter(Account.Order[0].OrderID, "Bestellung")

Ähnliches Ergebnis mit Split + Join:

$join($split(Account.Order[0].Product[0].'Product Name', " "), '_')

Dies kann auch als „~“ > Funktion geschrieben werden:

$split(Account.Order[0].Product[0].'Product Name', " ") ~> $join('_')

Prüfen, ob eine Zeichenfolge ein bestimmtes Muster enthält. Das Muster kann eine exakte Zeichenfolge oder ein regulärer Ausdruck sein:

$contains(Account.Order[0].Product[0].'Product Name', "Hut")

Datum und Uhrzeit

Die meisten Datumswerte werden im internationalen Standard ISO 8601 übergeben und sehen wie folgt aus: 2023-04-20T13:09:39+00:00 (mit Zeitzoneninformationen) oder 2023-04-20T13:09:39Z (definiert mit Offset von UTC in Millisekunden.) Diese sind gut für Menschen lesbar, können aber von JSONata nicht nativ manipuliert werden. 

Daher müssen Sie sie häufig in UNIX-Zeit umwandeln, also in die Anzahl von Sekunden, die seit dem 1. Januar 1970 um 00:00:00 Uhr UTC verstrichen sind (Unix-Epoche), in Literalform. Dies ist nicht mehr für Menschen lesbar; da es sich jedoch um eine Ganzzahl handelt, kann dieser Wert zu anderen UNIX-Datumswerten addiert/von diesen subtrahiert/mit ihnen verglichen werden. JSONata verwendet nativ Millisekunden, die MILLISECONDS seit der Unix-Epoche (also UNIX * 1000).

$now(): "2023-04-20T13:39:58.216Z"

$millis(): 1681998518175

Diese Millisekunden können Sie dann in ein Datumsformat Ihrer Wahl umwandeln, indem Sie ein Bild (Ihr Zielmuster) in einer Zeichenfolge definieren: https://www.w3.org/TR/xpath-functions-31/#date-picture-string

Beispielmuster: https://www.w3.org/TR/xpath-functions-31/#date-time-examples

Bezeichnung Bedeutung
J

Jahr (absoluter Wert)

M Monat des Jahres
D Tag im Monat
F Tag in der Woche
H Stunde im Tag (24 Stunden)
h Stunde in einem halben Tag (12 Stunden)
P AM/PM-Markierung
m Minute in der Stunde
s Sekunde der Minute
Z Zeitzone

Beispiel. $fromMillis($millis(), '[M]/[D]/[Y01]') gibt "4/20/23" zurück. 

$fromMillis($millis(), '[D01].[M01].[Y0001] [H#1]:[m01]') gibt "20.04.2023 13:51" zurück.

In der Praxis bedeutet dies: Angenommen, Ihre Antwortdaten enthalten zwei Datumswerte und Sie möchten prüfen, wie viele Tage seit HEUTE vergangen sind.

"2023-04-20T00:00:00.000Z"

"20.04.2023"

Verwandeln Sie beide in Milis. Das zweite Datum entspricht nicht dem Standardmuster nach ISO 8601. Sie müssen also das Bild bereitstellen, damit JSONata weiß, welcher Wert Ihr Tag, Ihr Monat, Ihr Jahr sowie jede Zeitangabe ist die Sie zur Verfügung haben.

$tomillis('2023-04-20T00:00:00.000Z'): 1681948800000

$tomillis('20.04.2023', '[D01].[M01].[Y0001]'): 1681948800000

Über die Standardfunktion $millis() erhalten Sie außerdem die aktuelle Zeit in Millisekunden: 1681999968402.

Jetzt können Sie einfach einen Wert vom anderen subtrahieren, um den Unterschied zwischen den beiden Datumswerten in Millisekunden zu erhalten: 1681999968402 – 1681948800000 = 51296367

Verwenden der gemeinsamen Zeitumrechnung:

1000 Millisekunden = 1 Sekunde

60 Sek. = 1 Minute

60 Min. = 1 Stunde

Wenn Sie das Ergebnis abrunden, erhalten Sie insgesamt 14 Stunden, die zwischen dem aktuellen Zeitpunkt und dem angegebenen Zeitstempel vergangen sind:

$round(51296367 / 1000 / 60 / 60) = 14

In einer Zeile zusammengefasst erhalten Sie Folgendes:

$round(($millis() - $toMillis('20.04.2023', '[D01].[M01].[Y0001]')) / 1000 / 60 / 60)

Besondere Ausgaben

„Einzeilige“ Tickets

Da Sie möglicherweise nur eine Gelegenheit für eine Antwort haben, sollten Sie möglichst viele Informationen in einem einzigen Parameter übergeben. JSONata übernimmt die Aggregation für Sie, sodass Sie frei mit dem Text experimentieren können.

Nehmen wir an, Sie möchten die Artikelnummern und Preise aller Produkte in Ihrer Bestellung darstellen:

Account.Order.Product

Da Sie letztendlich nur eine große Textzeile haben möchten, in der alle Produkte berücksichtigt werden, können Sie einfach ein gemeinsames Array mit allen erforderlichen Informationen erstellen:

Account.Order.Product.(SKU & Price)

Jetzt brauchen Sie sie nur noch zu einer langen Zeichenfolge mit einem Zeilenumbruch als Trennzeichen zusammenzufassen:

$join(Account.Order.Product.("SKUs: " & SKU & ", " & "Price: " & Price), "\n")

Hinweis: Beachten Sie die Einschränkungen Ihres CRM-Systems: Zendesk Support bietet einige grundlegende Formatierung, d. h., ein „\n“ in einer Antwort-E-Mail wird korrekt in einen Zeilenumbruch umgewandelt. Dies ist jedoch nicht bei allen Systemen der Fall.

Karten und Karussells

Karten und Karussells sind die wahre Stärke von JSONata, da dies die Datenabfrage und -aggregation nativ übernimmt, solange Ihre Antwort dem gleichen Schema folgt. Ein C&C besteht aus einem Array von Objekten, wobei jedes Objekt eine Ihrer Karten repräsentiert. Ein sehr einfaches Beispiel für eine C&C-Struktur mit 2 Karten könnte ungefähr so aussehen:

[
{
   "imageURL": data.url1,
   "title": data.title1,
   "description": data.description1
},
{
   "imageURL": data.url2,
   "title": data.title2,
   "description": data.description2
}
]

Wichtig ist, dass alle Objekte im Array derselben Struktur folgen, damit über denselben Shared Key zugegriffen werden kann. Beachten Sie auch die Einschränkungen Ihres CRM.

Um ein einfaches Beispiel zu sehen, erstellen wir erneut ein C&C anhand der Rechnungsbeispieldaten. Fangen wir gleich mit einem Array an: Jedes Query-Ergebnis mit mehr als einem Antwortobjekt wird automatisch in ein Array umgewandelt. Aber es ist sinnvoll, sich für den Fall abzusichern, dass das Ergebnis nur ein Objekt enthält. 

[Account.Order.Product.'Product Name']
[Account.Order.Product.SKU]
[Account.Order.Product.Description.Colour]

Hier sind einige der Felder, die uns interessieren. Führen wir sie in ein und demselben Objekt zusammen. Geben Sie dabei jedem Schlüssel im Zielobjekt einen Namen:

[
Account.Order.Product.
{
"name": 'Product Name',
"sku": SKU,
"colour"
: Description.Colour
}
]

Wenn Sie einen Wert benötigen, der eine Ebene höher ist, können Sie Ihre Query einfach eine Ebene höher beginnen. Wenn Sie auch [Account.Order.OrderID] in Ihr Array aufnehmen möchten:

[
Account.Order.
{
"orderId": OrderID,
"name": Product.'Product Name',
"sku": Product.SKU,
"Colour"
: Product.Description.Colour
}
]

Sie sehen, dass es keine direkte 1:1-Übereinstimmung mehr gibt, da jede Bestellung mehrere Artikel enthalten kann, weshalb diese Antwort scheinbar zufällige Arrays von Zeichenfolgen erzeugt. Sie können dieses Problem lösen, indem Sie indirekt auf das übergeordnete Objekt zugreifen (siehe Bindung übergeordneter Objekte), vorübergehend eine andere Objektstruktur in JSONata zuweisen (siehe Kontextvariablenbindung), ein sekundäres C&C hinzufügen, das die Elemente in der gewählten Reihenfolge durchläuft, oder Daten weiter transformieren. Dies hängt vom idealen Benutzererlebnis ab. Hier zeigen wir ein Beispiel für eine Transformation:

[
Account.Order.
{
"orderId": OrderID,
"name": $join(Product.'Product Name', ", "),
"totalPrice"
: $sum(Product.Price)
}
]

Wenn Sie Ihre Query noch besser absichern möchten, fügen wir einige Fail-Safes für den Fall, dass die erwarteten Antwortdaten nicht verfügbar sind (z. B. für 404-Fehler), und eine Sperre für den Fall hinzu, dass die Antwort mehr Ergebnisse zurückgibt als Ihr CRM unterstützen kann (z. B. 10 für SunCo-Widgets):

Account.Order ? 
[Account.Order[[0..9]].
{
"orderId": OrderID,
"name": $join(Product.'Product Name', ", "),
"totalPrice": $sum(Product.Price)}]
: [{"orderId": "???", "name": "Cannot find your item?"
}]

WICHTIG: Stellen Sie sicher, dass alle C&C-Schlüssel der camelCase-Konvention folgen. Parameternamen mit _ werden nicht unterstützt.

Jetzt stehen alle diese Schlüssel, z. B. orderId, name und totalPrice, für Ihr Karussell zur Verfügung. Ändern Sie in der Benutzeroberfläche den Typ des Karussells in „dynamisch“ und fügen Sie den Namen des Parameters hinzu, unter dem Ihre obige Query gehostet wird, z. B. orderList.

Sie können jetzt auf einen beliebigen Schlüssel in den Objekten Ihres Arrays zugreifen, indem Sie einen % shorthand-Code hinzufügen. Dazu haben Sie zwei Möglichkeiten: Sie können sie direkt im Chat auf Ihren Karten ausgeben:

Oder speichern Sie sie in der Sitzung, indem Sie eine Karte mit einer Aktion ausfüllen, die den Schlüssel des ausgewählten Objekts in einem beliebigen Parameternamen referenziert, z. B.:

Powered by Zendesk