¿Qué plan tengo?
Complemento Agentes IA - Avanzado

JSONata es un lenguaje de consulta y transformación de código abierto, diseñado para acceder y analizar datos de un cuerpo de respuestas JSON que devuelve una API.

Las consultas se pueden probar fácilmente usando https://try.jsonata.org/, o si prefiere un formato más sofisticado similar a Javascript, https://www.stedi.com/jsonata/playground. Nos ceñiremos a la herramienta Exerciser de JSONata para esta introducción.

La herramienta lanzará su objeto simulado Invoice, que usaremos como punto de referencia. Los datos de entrada sin procesar se encuentran a la izquierda, la consulta de la expresión de JSONata está en la parte superior derecha y el resultado que encontró esa expresión se representará en la parte inferior derecha.

Para volver a alinear el objeto JSON, use la herramienta de sangría pequeña a la derecha del objeto simulado y guarde cualquier expresión actual usando la funcionalidad de compartir en la parte superior derecha.

Eso es todo lo que necesita saber sobre la herramienta Exerciser por ahora. A continuación, use una consulta dentro de la plantilla predeterminada de Invoice.

Si solo busca los hallazgos clave o un punto de referencia después de la activación, consulte nuestra hoja de referencia.

Mapeo de datos

Campo de nivel raíz: Cuenta
Campo anidado en objeto raíz: Account.'Account Name'
Si encuentra otra estructura JSON, puede usar la notación de puntos para ingresar los siguientes campos.

Campo anidado en una matriz de nivel raíz:

Primer pedido en esta cuenta:

Account.Order[0]

Recordatorio: La indización de matrices comienza en [0] para el primer elemento. El método abreviado para el último elemento de una matriz es [-1].

Color del primer producto en este mismo objeto:

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

Recupere una matriz de elementos de una matriz de nivel raíz:

Si varios valores coinciden con una consulta, JSONata los agregará automáticamente.

Verifique todo el objeto Account.Order y recupere todos los OrderID que contiene:

Account.Order.OrderID

Filtrar datos

 

Defina el destino al que se está accediendo, p. ej.

Account.Order.OrderID

Ahora agregue la condición en el lugar correspondiente: para cada ejecución a lo largo de una matriz, agregue un par de corchetes []:

Por ejemplo, incluya solo los pedidos con productos cuyo precio sea superior a 30, fueron ordenados una sola vez y muestran el Nombre del producto correspondiente:

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

Por ejemplo, incluya solo los pedidos con productos con un valor Description.Weight de más de 1 que muestren el OrderID respectivo:

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

Como alternativa, también puede verificar si hay una declaración veraz, p. ej.

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

Además, esto se puede combinar con búsquedas con comodines si desea verificar varias claves, p. ej.

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

Otros operadores de ruta

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

^( ... ) (ordenar por)

Ordenar por OrderID descendente:

Account.Order^(>OrderID)

Ordenar del producto más barato al más caro:

Account.Order.Product^(Price)

* (comodín)

Acceda a cualquier SKU, independientemente del nombre principal directo:

Account.Order.*.SKU

Acceda a cualquier nombre de producto, independientemente de los nombres principales:

**.'Product Name'

% (principal)

Busca hacia atrás en la estructura de datos actual:

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

# (enlace de variable posicional)

Crea un índice, comenzando en 0:

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

@ (enlace de variable de contexto)

Asigna temporalmente una nueva estructura de datos, lo que permite mapeos de objetos cruzados:

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

Condicionales

 

De manera similar al operador ternario en JS, puede usar “?” para declaraciones if y “:” para declaraciones else. Los operadores booleanos and/or se pueden usar para crear condiciones en cadena.

SI LA CONDICIÓN ES CIERTA ? HAZ ESTO (DE LO CONTRARIO [ELSE], NO HAGAS NADA)

SI LA CONDICIÓN ES CIERTA ? HAZ ESTO : DE LO CONTRARIO [ELSE], HAZ ESTO

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

Manipulación de datos

Operadores admitidos

Operador Prioridad Descripción
Multiplicar (*) 5 Multiplica dos números.
Dividir (/) 5 Divide dos números.
Módulo (%) 5 Devuelve el residuo de la división de dos números.
Concatenar (&) 4 Concatena dos cadenas.
Sumar (+) 4 Suma dos números.
Restar (-) 4 Resta dos números.
Igual (=) 3 Comprueba si dos valores son iguales.
No es igual a (!=) 3 Comprueba si dos valores no son iguales.
Mayor que (>) 3 Devuelve true si el valor de la izquierda es mayor que el valor de la derecha.
Mayor o igual que (>=) 3 Devuelve true si el valor de la izquierda es mayor o igual que el valor de la derecha.
Menor que (<) 3 Devuelve true si el valor de la izquierda es menor que el valor de la derecha.
Menor o igual que (<=) 3 Devuelve true si el valor de la izquierda es menor o igual que el valor de la derecha.
Y lógico (and) 2 Devuelve true si los valores izquierdo y derecho son verdaderos.
O lógico (or) 1 Devuelve true si el valor de la izquierda es verdadero o el valor de la derecha es verdadero.

p. ej., concatenar cadenas:

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

Funciones integradas

Tenga en cuenta que se resumieron de manera importante para facilitar la lectura. La documentación completa se puede encontrar aquí: https://docs.jsonata.org/overview.html 

Nota: una expresión de varias líneas debe estar envuelta entre ().

Forzar tipo de cadena: $string(Account.Order[0].Product[0].ProductID): "858383"

Forzar tipo de número: $number(Account.Order[0].Product[0].SKU): 406654608

Cadena en mayúsculas: $uppercase(Account.Order[0].OrderID): "ORDER103"

Cadena en minúsculas: $lowercase(Account.Order[0].Product[0].Description.Colour): "purple"

Número de salida aleatorio entre 0 y 1: $random()

Contar objetos en una matriz: $count(Account.Order)

Contar objetos en una matriz que cumplen una condición: $count(Account.Order.Product[Price > 30])

Número de caracteres en una cadena: $length(Account.'Account Name')

Reemplazar/eliminar determinados caracteres de una cadena: $replace(Account.Order[0].Product[0].'Product Name', "Bowler ", ""): "Hat"

Cortar una cadena según un recuento de caracteres específico: $substring($string(Account.Order[0].Product[0].ProductID), 1, 2)

Cortar una cadena según un patrón específico: $substringAfter(Account.Order[0].OrderID, "order")

Resultado similar usando split + join:

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

También se puede escribir como una función ~>:

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

Verifique si una cadena contiene un patrón específico: el patrón puede ser una cadena exacta o una regex:

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

Fechas y horas

La mayoría de las fechas se pasarán en el estándar internacional ISO 8601 y se verán así: 2023-04-20T13:09:39+00:00 (con información de zona horaria) o 2023-04-20T13:09:39Z (con clave de milisegundos de diferencia de UTC). Estos son perfectamente legibles por humanos, pero JSONata no los puede manipular de forma nativa. 

Por lo tanto, a menudo tendrá que transformarlos en tiempo de UNIX, que es el número literal de segundos transcurridos desde las 00:00:00 UTC del 1 de enero de 1970 (época de Unix), que ya no es legible por humanos. Sin embargo, como números enteros, se pueden sumar, restar y comparar con otras fechas de UNIX. JSONata trabaja de forma nativa con millis, que son los MILISEGUNDOS desde la época de Unix (es decir, UNIX * 1000).

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

$millis(): 1681998518175

Estos millis ahora se pueden volver a transformar en el formato de fecha de su elección al definir una imagen (su patrón de destino) en una cadena: https://www.w3.org/TR/xpath-functions-31/#date-picture-string

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

Especificador Significado
Sí

Año (valor absoluto)

M Mes del año
D Día del mes
F Día de la semana
H Hora del día (24 horas)
h Hora en medio día (12 horas)
P Marcador a.m/p.m.
m Minuto de la hora
s Segundo del minuto
Z Zona horaria

Por ejemplo, $fromMillis($millis(), '[M]/[D]/[Y01]') devolverá "4/20/23". 

$fromMillis($millis(), '[D01].[M01].[Y0001] [H#1]:[m01]') devolverá "20.04.2023 13:51".

Pongamos esto en práctica: digamos que tiene dos fechas en los datos de respuesta y desea verificar cuántos días han pasado desde HOY.

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

"20.04.2023"

Transforme ambos en millis: la segunda fecha no está en el patrón estándar ISO 8601, por lo que tendrá que proporcionar la imagen para que JSONata sepa qué valor es su día, mes y año, así como cualquier información de tiempo que tenga disponible.

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

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

También tiene la hora actual en millis mediante la función estándar $millis(): 1681999968402.

Ahora puede simplemente restar una de la otra y obtener la diferencia entre las dos fechas en milisegundos: 1681999968402 - 1681948800000 = 51296367

Usando la conversión de tiempo común:

1000 milisegundos = 1 segundo

60 s = 1 minuto

60 min = 1 hora

Y redondeando el resultado hacia abajo, se obtiene un total de 14 horas que transcurrieron entre ahora y la marca de tiempo proporcionada:

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

Combinada en una sola línea, vemos una operación de:

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

Salidas especiales

Respuestas de una sola línea del ticket

Debido a que es posible que solo tenga una oportunidad para responder, le sugerimos pasar toda la información posible en un solo parámetro. JSONata maneja la agregación por usted para que pueda jugar libremente con el texto.

Supongamos que desea renderizar los SKU y los precios de todos los productos de su pedido:

Account.Order.Product

Dado que en última instancia desea tener una sola línea de texto grande con todos los productos considerados, simplemente puede crear una matriz compartida con toda la información requerida:

Account.Order.Product.(SKU & Price)

Ahora solo tiene que combinarlos en una cadena grande con un carácter de salto de línea como separador:

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

Nota: tenga en cuenta las limitaciones de su CRM: Zendesk Support ofrece algunos formatos básicos, por lo que un \n se traducirá correctamente en un salto de línea cuando se represente en un correo electrónico de respuesta, pero podría no ser el caso para todos los sistemas.

Tarjetas y carruseles

Las tarjetas y los carruseles son el verdadero punto fuerte de JSONata, ya que maneja la consulta y la agregación de datos de forma nativa, siempre que la respuesta siga el mismo esquema. Un módulo de tarjetas y carruseles (C&C) consta de una matriz de objetos en la que cada objeto representa una de las tarjetas. Un ejemplo muy sencillo de una estructura de C&C con 2 tarjetas sería similar a esto:

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

Es importante que todos los objetos de la matriz sigan la misma estructura para que se pueda acceder a ellos mediante la misma clave compartida. También tenga en cuenta las limitaciones de su CRM.

Para ver un ejemplo sencillo, construyamos nuevamente un C&C con los datos de muestra de la factura. Comencemos con una matriz desde el principio: cualquier resultado de consulta con más de un objeto de respuesta se convertirá automáticamente en una matriz, pero conviene tener esta función de seguridad en caso de que el resultado solo contenga un objeto. 

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

Estos son algunos de los campos que nos interesan. Vamos a combinarlos en un solo objeto. Asegúrese de asignar un nombre a cada clave en el objeto de destino:

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

Si necesita un valor de un nivel superior, simplemente puede comenzar la consulta en dicho nivel. Si también desea incluir [Account.Order.OrderID] en su matriz:

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

Notará que ya no hay una coincidencia 1:1 directa, ya que cada pedido puede contener varios artículos, por lo que esta respuesta crea matrices de cadenas aparentemente aleatorias. Esto se puede resolver al acceder indirectamente al objeto principal (vea el enlace principal), asignar temporalmente una estructura de objeto diferente en JSONata (vea el enlace de variable de contexto), agregar un C&C secundario que recorre los artículos en el orden elegido o transformar aún más los datos, dependiendo de su UX ideal. Este es un ejemplo transformado:

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

Si desea que la consulta sea más segura, agregue algunas pruebas de seguridad en caso de que no tenga los datos de respuesta esperados (para cubrir, por ejemplo, un 404) y un límite en caso de que la respuesta devuelva más resultados de los que su CRM puede admitir (por ejemplo, 10 para los widgets de SunCo):

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

IMPORTANTE: asegúrese de que todas las claves de C&C sigan la convención camelCase. No se admiten nombres de parámetros con guion bajo _.

Ahora todas esas claves (p. ej., orderId, name, totalPrice) estarán disponibles en el carrusel. Cambie el tipo de carrusel a dinámico en la interfaz de usuario y agregue el nombre del parámetro que aloje la consulta anterior, por ejemplo, orderList.

Ahora puede acceder a cualquier clave en los objetos de su matriz agregando un método abreviado %. Puede imprimirlos directamente en el chat en sus tarjetas:

También puede almacenarlos en la sesión al llenar la tarjeta de su elección con una acción que haga referencia a la clave del objeto elegido en el nombre de parámetro que elija, por ejemplo:

Tecnología de Zendesk