Activadores personalizados

Activadores personalizados

Copiar página

Cree activadores personalizados de Shopify Flow desde cualquier evento de Shopify, con valores previos y posteriores y JavaScript para su condición exacta.

Los activadores integrados cubren los cambios que más interesan a la mayoría de las tiendas. Un activador personalizado se encarga del resto: elija un evento de Shopify, escriba unas pocas líneas de JavaScript para determinar si es relevante y qué datos debe enviar, y se convertirá en un activador que podrá utilizar en Shopify Flow.

Tres cosas que resuelve y que un activador integrado no puede:

  • Ejecute la acción únicamente según su condición. «Solo cuando un pedido superior a 500 EUR reciba la etiqueta vip» es una sola línea de código, en lugar de un flujo de trabajo que se ejecute en cada pedido y luego lo filtre.
  • Aplique la condición a una transición, no a un estado. Su código detecta el valor antes y después del cambio, por lo que es posible que «el estado haya pasado de borrador a activo» o que «las existencias hayan descendido por debajo de 5». Una condición basada en el valor actual no puede expresar eso.
  • Envíe exactamente los campos que desee. Adapte el evento a los valores que su flujo de trabajo utiliza realmente, en lugar de volver a leerlos uno por uno.

Un activador personalizado ni siquiera necesita un evento Shopify: también puede ejecutarse según una programación y determinar por sí mismo qué ha cambiado.

Cómo funciona

  1. Elija cómo se ejecutará: mediante un evento Shopify o según una programación.
  2. Para un evento, seleccione el evento al que responde - cualquier evento de Shopify que la aplicación ya reciba - o comience a partir de una plantilla, que selecciona el evento y rellena el código.
  3. Capture una carga útil real. Realice ese cambio en su tienda y la aplicación capturará el cuerpo exacto del evento.
  4. Escriba una transformación: devuelva un objeto para activarla; devuelva unnullo para omitirla.
  5. Pruébelo con el evento capturado y compruebe exactamente qué recibiría su flujo de trabajo.
  6. Enciéndalo.
El editor de activadores personalizados con nombre, identificador, la opción de elegir entre un evento Shopify y una programación, el evento y una plantilla
Un nuevo activador personalizado: elija qué lo activa, seleccione el evento y, si lo desea, comience a partir de una plantilla.

Redacción de la transformación

Su activador es un módulo de JavaScript que exporta una función denominada transform. Recibe cuatro argumentos:

  • payload - el cuerpo del evento Shopify sin procesar, tal y como se recibe.
  • topic - qué evento se ha activado; por ejemplo, PRODUCTS_UPDATE.
  • shop - su dominio de MyShopify.
  • ctx - ctx.log(...) muestra información en el panel de registro situado junto al editor, ctx.shopify(...) ejecuta una consulta GraphQL de administración y ctx.fetch(...) realiza una llamada a una URL en Internet pública.

Lo que devuelva determinará lo que suceda:

  • Devuelva un objeto y el activador se activará, transportando dicho objeto.
  • Si devuelve «null», el evento se omite. Así es como funciona el filtrado: no es necesario aprender ningún lenguaje de filtrado específico.
  • Si deja el archivo vacío, se activará con cada evento de ese tipo.
flow-triggers/high-value-vip-order.jsjavascript
/**
 * Only fire for high-value orders carrying the vip tag.
 */
export async function transform(payload, topic, shop, ctx) {
  const total = parseFloat(payload.total_price || "0");
  const tags = (payload.tags || "").split(",").map(t => t.trim());

  if (total < 500) return null;
  if (!tags.includes("vip")) return null;

  ctx.log("firing for", payload.name, total);

  return {
    orderId: payload.admin_graphql_api_id,
    orderNumber: payload.name,
    total,
    currency: payload.currency,
    customerEmail: payload.email,
  };
}

El valor antes del cambio

Shopify

En las actualizaciones de producto, de pedido y de cliente, payload._changes muestra todos los campos objeto de seguimiento que se han modificado en dicha actualización, junto con oldValue y newValue:

  • Productos: title, handle, description, status, vendor, productType, tags
  • Pedidos: financialStatus, fulfillmentStatus, tags, note, lineItems y customAttributes.<name>
  • Clientes: tags, note, state (ENABLED, DISABLED, INVITED, DECLINED)

Se trata de una lista vacía cuando la actualización no ha afectado a dichos campos - por ejemplo, un cambio en el inventario - o cuando la aplicación ve el registro por primera vez. El evento de ejemplo que captura en el editor muestra el campo, por lo que puede ver su estructura real antes de introducir datos en él.

flow-triggers/product-went-live.jsjavascript
/**
 * Fire only when a product BECOMES active - not on every later edit of an
 * active product, which is what a condition on the current status would do.
 */
export async function transform(payload, topic, shop, ctx) {
  const change = (payload._changes || []).find((c) => c.field === "status");
  if (!change) return null;
  if (change.oldValue !== "draft" || change.newValue !== "active") return null;

  return {
    productId: payload.admin_graphql_api_id,
    title: payload.title,
    oldStatus: change.oldValue,
    newStatus: change.newValue,
  };
}

Los eventos más específicos cuentan con sus propios valores antiguos y nuevos, por lo que no es necesario utilizar _changes en ese caso: un cambio de precio tiene oldPrice, newPrice y percentChange; un cambio de inventario tiene _oldAvailable, _newAvailable y _delta; un cambio de metacampo tiene previousValue junto a metafield.value.

Empiece con una plantilla

En la sección «Fires on» del editor, la opción «Empezar desde una plantilla» selecciona el evento e introduce código funcional. Edite las constantes de la parte superior, compruebe el funcionamiento y, a continuación, guarde los cambios. Cada plantilla lee un valor antes y después del cambio:

  • Se ha modificado un campo de un producto, un pedido o un cliente, pasando de un valor a otro: el estado ha pasado de «borrador» a «activo», un pedido ha pasado a «pagado» o una cuenta se ha activado.
  • El precio ha bajado más de un N por ciento: se trata de una auténtica rebaja, no de una simple modificación del precio.
  • Las existencias cayeron por debajo de un umbral - se activa una vez, en el momento en que las existencias cruzan la línea, no en cada venta mientras ya se encuentren en un nivel bajo - .
  • El valor de un metacampo del producto ha superado un umbral: una valoración ha descendido por debajo de 3 y un margen ha superado el 40.
  • Pedido pagado por un cliente de alto valor: lee el gasto acumulado del cliente en su tienda y se activa únicamente cuando se supera el importe que usted haya establecido.
La tarjeta «Transform» del editor con el código de una plantilla que dice «payload._changes»
Una plantilla genera código funcional. Modifique las constantes que aparecen al principio, pruébelo y, a continuación, guárdelo.

Obtención de datos adicionales con ctx.shopify

Los cuerpos de los Webhooks solo incluyen los campos que envía Shopify. Si necesita cualquier otra información - como el número de pedidos de un cliente, el inventario de una variante o un metacampo - , realice la consulta a la API de administración directamente desde su transformación:

Enrich the event before decidingjavascript
export async function transform(payload, topic, shop, ctx) {
  const data = await ctx.shopify(`
    query($id: ID!) {
      customer(id: $id) { numberOfOrders tags }
    }
  `, { id: payload.customer.admin_graphql_api_id });

  // Only fire for repeat customers
  if (data.customer.numberOfOrders < 5) return null;

  return {
    orderId: payload.admin_graphql_api_id,
    orderCount: data.customer.numberOfOrders,
  };
}

Devuelve el objeto data de la consulta y lanza una excepción si la consulta contiene errores, de modo que el error se muestre en su prueba en lugar de que la consulta no devuelva ningún resultado sin avisar.

Tres límites que conviene conocer:

  • Hasta 10 llamadas por ejecución. El enriquecimiento requiere unas pocas; más de eso suele suponer un bucle. Recupere lo que necesite en una sola consulta siempre que sea posible.
  • La aplicación lee, pero no escribe. Utiliza los permisos que usted le haya concedido, y la aplicación solo solicita acceso de lectura. Una consulta sobre los datos de los pedidos fallará a menos que se haya concedido el permiso «Acceso a los datos de los pedidos» en la página «Permisos». Para realizar cualquier modificación en su tienda, hágalo en las acciones de Shopify Flow que siguen al activador.
  • Las credenciales de su tienda nunca llegan a su código. La aplicación ejecuta la consulta en su nombre, por lo que no hay ningún token de acceso dentro del entorno de pruebas que pueda filtrarse.

ctx.fetch(url, options) Funciona como la función fetch del navegador para cualquier elemento de la Internet pública: el feed de existencias de un proveedor, un tipo de cambio o su propia API. Se rechazan las direcciones de redes internas y privadas. Si guarda su código de activación en GitHub, no incluya ninguna clave de API en él.

Activadores que se ejecutan según un calendario

Shopify Flow Reacciona cuando ocurre algo. No puede reaccionar cuando no ocurre nada, y no puede detectar nada fuera de su tienda. Para ello, seleccione «Según un horario» en la sección «¿Qué hace que esto se ejecute?». Este tipo de activador no se basa en ningún evento Shopify: su código se ejecuta a intervalos, desde cada 30 segundos hasta una vez al día, y decide por sí mismo qué se considera un cambio.

Se trata de la misma función transform, pero con un payload diferente y un valor de retorno distinto:

  • payload.state - el valor que su código devolvió como state en su ejecución anterior. null en la primera ejecución.
  • payload.now y payload.lastRunAt: marcas de tiempo.
  • Devuelva { state, events }»: el nuevo estado que se debe recordar (hasta 32 KB) y una lista de eventos que se deben activar (hasta 100 por ejecución). Cada evento activa «Activador personalizado» una vez; el «resourceId de un evento, si se ha establecido uno, se convierte en el ID del registro en Shopify Flow. Devuelva null cuando no haya nada que comunicar.

En la primera ejecución, recuerde: nunca active el activador. En su primera ejecución, su código no tiene nada con lo que comparar, por lo que todo le parecerá nuevo. Guarde lo que vea y no devuelva ningún evento; al activar el activador, nunca se saturarán sus flujos de trabajo. Todas las plantillas funcionan así.

El editor de activadores personalizados en el modo «Según un calendario», con el intervalo y el número de ejecuciones en 30 días
Según un calendario: elija el intervalo - el editor le indicará a cuántas ejecuciones equivale - y comience a partir de una plantilla programada.
flow-triggers/supplier-stock-changed.jsjavascript
// Fires when a value at a JSON URL changes, with the value before and after.
const URL = "https://api.example.com/stock/1042"

export async function transform(payload, topic, shop, ctx) {
  const res = await ctx.fetch(URL, { headers: { accept: "application/json" } })
  if (!res.ok) throw new Error("The URL answered with HTTP " + res.status)
  const value = String((await res.json()).stock)

  // The first run only remembers the value.
  const previous = payload.state ? payload.state.value : undefined
  if (previous === undefined || previous === value) return { state: { value } }

  return {
    state: { value },
    events: [{ oldValue: previous, newValue: value }],
  }
}

Plantillas para activadores programados, en la sección «Empezar desde una plantilla» de la ficha «Programación»:

  • Producto, pedido o cliente sin actualizar desde hace N días: revisiones de catálogo obsoletas, pedidos estancados, recuperación de clientes. Cada registro se activa una vez por cada periodo de inactividad, y los que ya estuvieran vencidos en el momento de activar la función no se activarán todos a la vez.
  • Se ha modificado un valor ajeno a Shopify: un fichero de existencias de un proveedor, un tipo de cambio o una lista de precios, con la diferencia y el porcentaje correspondientes a las cifras.
  • Nueva entrada en una fuente RSS o Atom: noticias de un proveedor, una fuente con listados, una página de estado.
  • No hay pedidos durante N horas: un indicador de actividad para su tienda. Se activa una vez cuando dejan de llegar pedidos y otra vez cuando vuelven a llegar.

«Test» ejecuta su código una vez sin activar nada y sin guardar el estado, por lo que puede ejecutarlo tantas veces como desee.

Cómo utilizarlo en Shopify Flow

Todos los activadores personalizados se importan a Shopify Flow con el mismo nombre: «Activador personalizado». Añádalo a un flujo de trabajo y, a continuación, añada una condición que establezca que «El identificador del activador es igual al identificador de su activador».

Ese identificador aparece en la página del activador y nunca cambia, incluso si le cambia el nombre al activador, por lo que su flujo de trabajo seguirá funcionando.

Cada clave que devuelve su transformación se convierte en un campo del activador, y el objeto completo también está disponible en formato JSON si prefiere analizarlo usted mismo.

Guarde el código en GitHub

Puede conectar un repositorio de GitHub para que su código de activador quede bajo control de versiones. Los cambios se pueden revisar en una solicitud de incorporación de cambios, podrá ver quién ha modificado qué y podrá revertir una transformación que haya dejado de funcionar.

Conéctelo en la página «Desarrollador», en la sección «Conexiones». Usted elige a qué repositorios puede acceder la aplicación y puede revocar dicho acceso desde GitHub en cualquier momento.

Una vez seleccionado un repositorio, todos los activadores existentes se registran en él de inmediato, y se mantiene la sincronización en ambas direcciones:

A qué se dedica ¿Qué ocurre?
Crear, editar o duplicar un activador en la aplicación El archivo se ha incorporado a su repositorio
Eliminar un activador en la aplicación El archivo se ha eliminado de su repositorio
Envíe una modificación a la rama conectada El código del activador se actualiza en la aplicación

Cada activador es un archivo cuyo nombre coincide con su identificador, y que contiene exactamente el módulo que ve en el editor, sin ningún código adicional a su alrededor. Esto significa que puede abrirlo en su propio editor, ejecutarlo y comprobar su sintaxis como cualquier otro archivo JavaScript.

Volver a una versión anterior

No es necesario conocer Git para deshacer un cambio. Una vez conectado el repositorio, el editor muestra un menú desplegable «Versión» en el que aparecen todas las versiones anteriores de ese archivo, junto con su fecha y autor. Si selecciona una de ellas, se cargará en el editor como un cambio sin guardar, de modo que pueda leerla primero; al guardarla, se restablecerá la versión anterior.

Realice pruebas mientras edita de forma local

Si está editando el archivo en su propio editor, puede ejecutarlo con el evento de muestra capturado sin necesidad de guardarlo primero en la aplicación. Utilice una clave de API con nivel de ejecución de la página de desarrolladores:

Test the file you are editingbash
curl -X POST https://shopify.workflow-trigger-extensions.app/api/v1/triggers/custom/high-value-vip-order/test \
  -H "Authorization: Bearer ftk_your_key_here" \
  -H "Content-Type: application/json" \
  -d "$(jq -Rn --rawfile c flow-triggers/high-value-vip-order.js '{code:$c}')"

Obtendrá el mismo resultado que muestra el botón «Probar» de la aplicación: si se ejecutaría, el objeto de salida, sus líneas de ctx.log y el tiempo de ejecución.

Este punto final no** activa ninguna acción ni realiza ningún guardado**, y no consume ninguna cuota del plan; por lo tanto, se puede ejecutar con total seguridad cada vez que se guarde desde un observador de archivos. (El botón «Ejecutar prueba» de la aplicación sí que activa su flujo de trabajo de Shopify Flow, por lo que podrá ver cómo se ejecuta de principio a fin; esto también es gratuito).

También puede descargar el payload de ejemplo por separado con una clave de lectura, guardarlo localmente y ejecutar el archivo sin conexión alguna:

Get the captured sample payloadbash
curl https://shopify.workflow-trigger-extensions.app/api/v1/triggers/custom/high-value-vip-order/test \
  -H "Authorization: Bearer ftk_your_key_here"
¿Un activador personalizado consume la asignación de mi plan?

Sí, y cuenta todos los eventos que supervisa, no solo aquellos que activan su ejecución. Si su activador está configurado para detectar «Actualización de producto» y su tienda registra 60 000 actualizaciones de producto al mes, eso supone 60 000 eventos, aunque su código solo se active en 100 de ellos.

Recibimos, eliminamos los duplicados y ponemos en cola cada uno de esos eventos; a continuación, ejecutamos su código en un entorno aislado - todo ello antes de que su código decida si se activa o no - . El recuento refleja ese trabajo.

Dicho de otro modo: tiene el mismo coste que tendría el activador integrado para el mismo evento. No se le cobra ningún suplemento por el filtrado, y las pruebas son siempre gratuitas. Un activador programado cuenta una vez por ejecución.

¿La prueba es gratuita?

Sí. Tanto el botón «Ejecutar prueba» de la aplicación como el punto final de la API /test están exentos, aunque la opción «Ejecutar prueba» active realmente su flujo de trabajo de Shopify Flow para que pueda ver cómo se ejecuta. Solo las ejecuciones en tiempo real consumen su cuota, por lo que puede realizar tantas iteraciones de una transformación como desee.

¿Por qué está vacío el campo «payload._changes»?

O bien la actualización se ha producido fuera de los campos objeto de seguimiento - por ejemplo, un cambio en el inventario o en una variante de producto - o bien la aplicación aún no dispone de una línea de base para ese registro. La línea de base se almacena la primera vez que la aplicación detecta un registro, por lo que la primera actualización de un registro que nunca ha visto antes no incluye ningún valor anterior. Todas las actualizaciones posteriores sí lo incluyen.

¿Puede mi código modificar los datos de mi tienda?

N.º ctx.shopify se ejecuta con los permisos de lectura que ha concedido, y la aplicación nunca solicita acceso de escritura. Esto es intencionado: un activador que modifica el registro que supervisa se vuelve a activar, lo que provoca el bucle por el que Shopify desactiva los flujos de trabajo. Modifique los datos en las acciones del flujo que siguen al activador.

¿Puedo cambiar el tirador más adelante?

No, y eso es intencionado. Su flujo de trabajo de Shopify Flow aplica un filtro en función del identificador, por lo que cambiarlo detendría de forma silenciosa la ejecución de dicho flujo de trabajo. Puede cambiar el nombre del activador libremente; el identificador permanece inalterado.

El nombre de usuario es también el nombre del archivo en su repositorio de GitHub, por lo que tampoco cambia nunca.

¿Qué ocurre si mi código tiene un error?

El evento se omite y el error queda registrado en el activador, por lo que podrá ver qué ha fallado. Una transformación fallida nunca bloquea nada más: el resto de sus activadores, ya sean personalizados o integrados, continúan funcionando sin verse afectados.

¿Dónde se ejecuta mi código?

En un entorno aislado, separado del resto de la aplicación, con un límite de tiempo reducido y sin acceso a las credenciales de su tienda. Solo tiene acceso a la carga útil del evento que haya capturado, además de cualquier dato que obtenga mediante ctx.shopify o ctx.fetch.

¿Qué ocurre si edito el archivo en GitHub y en la aplicación al mismo tiempo?

Gana la última acción que haya guardado. Al guardar en la aplicación, se confirma el cambio en el archivo, y al enviarlo a la rama conectada se sobrescribe el código que figura en la aplicación. Si trabaja principalmente en su repositorio, considere el editor de la aplicación como de solo lectura para evitar sorpresas.

¿Puede un archivo de mi repositorio crear un nuevo activador?

No. Un activador también debe saber a qué evento de Shopify está atento, y el archivo solo contiene código; si se intentara adivinar el evento, se vincularía a algo incorrecto. Cree primero el activador en la aplicación y, a continuación, edite su archivo como desee.

¿Puede activarse ante eventos que la aplicación aún no haya recibido?

No. Un activador personalizado detecta los eventos a los que la aplicación ya está suscrita para su tienda, lo cual depende de los permisos que haya concedido. Si concede el permiso para un recurso, sus eventos también estarán disponibles para los activadores personalizados. Para cualquier otra cosa, ejecútelo según una programación.

Próximos pasos