Funzioni di trasformazione

La mappatura estrae i valori da una richiesta. Una funzione di trasformazione va oltre: si tratta del vostro codice JavaScript personalizzato, eseguito su ogni richiesta prima di Shopify Flow, in modo da poter rimodellare il payload, effettuare una ricerca, decidere se valga la pena avviare un workflow per quella richiesta o rispondere direttamente al richiedente.

Si trova nella scheda “Funzione” di un webhook. Se l’editor è vuoto, significa che la funzione è disattivata.

La forma di una funzione

The contractjavascript
export default async function transform(payload, ctx) {
  // payload - the parsed request body (JSON, form or XML)
  // return an object -> it becomes the payload for mapping and Flow
  // return null      -> nothing is sent to Flow, and nothing counts
  return { ...payload, source: "warehouse" }
}

Cosa vi offre ctx

ctx.request method, contentType, la richiesta headers (dati riservati oscurati) e query
ctx.webhook Gli indirizzi webhook sono id e name
ctx.shop Il Suo dominio myshopify
ctx.log(...) Scrive una riga che è possibile leggere nel pannello di prova e nella Cronologia
await ctx.fetch(url, init) Richiede un'API pubblica
await ctx.shopify(query, variables) Legge i dati dei negozi tramite Admin GraphQL
ctx.storage Conserva i valori di piccola entità tra un'esecuzione e l'altra (vedere di seguito)
ctx.respond(body, options) Risponde immediatamente a chi chiama

Riorganizzazione di un payload

L'utilizzo più comune: trasformare la struttura di un mittente nei pochi valori necessari al vostro workflow.

Flatten and normalisejavascript
export default async function transform(payload) {
  const order = payload.data.attributes
  return {
    orderNumber: String(order.number),
    email: order.customer.email.toLowerCase(),
    total: Number(order.total_cents) / 100,
  }
}

Eliminare le richieste non necessarie

Viene restituito null e la richiesta si interrompe in quel punto: non viene eseguito alcun flusso, non viene registrata alcuna voce nella cronologia e non viene addebitato alcun consumo sul Suo piano. Il chiamante riceve un 200 con { "skipped": true }, pertanto non effettua alcun nuovo tentativo.

Only paid orders above 100javascript
export default async function transform(payload, ctx) {
  if (payload.status !== "paid" || payload.total < 100) {
    ctx.log("skipping", payload.id, payload.status, payload.total)
    return null
  }
  return payload
}

Ricordare le cose tra una corsa e l’altra

ctx.storage È un piccolo sistema di archiviazione chiave-valore di proprietà del vostro negozio. È lo strumento che consente di verificare se un evento è già stato registrato: quando si verifica un evento, ne viene memorizzato l’ID; in questo modo, la richiesta successiva che riporti lo stesso ID viene ignorata, anche se perviene giorni dopo.

Chiamata È vero che
await ctx.storage.get(key) Il valore memorizzato, ovvero l’null
await ctx.storage.set(key, value) Memorizza qualsiasi valore JSON, sovrascrivendo
await ctx.storage.delete(key) Lo elimina; true qualora esistesse
await ctx.storage.list({ prefix, limit, cursor }) Nomi e dimensioni principali, pagina per pagina
Skip events you have already seenjavascript
export default async function transform(payload, ctx) {
  const key = `seen:${payload.id}`
  if (await ctx.storage.get(key)) return null
  await ctx.storage.set(key, { at: Date.now() })
  return payload
}

Arricchimento con i dati dei negozi

ctx.shopify Esegue query GraphQL di amministrazione in sola lettura per il Suo negozio, pertanto un workflow può avviarsi con dati di cui il mittente non è mai stato in possesso. Il mittente vede solo ciò che Lei gli consente: conceda gli ambiti necessari nella sezione “Accesso ai dati del negozio” nella scheda “Funzione”. Per impostazione predefinita non viene concesso nulla e le mutazioni vengono rifiutate.

Look up a variant by SKUjavascript
export default async function transform(payload, ctx) {
  const data = await ctx.shopify(
    `query($q: String!) {
      productVariants(first: 1, query: $q) { nodes { id title price } }
    }`,
    { q: `sku:${payload.sku}` },
  )
  const variant = data.productVariants.nodes[0]
  if (!variant) return null
  return { sku: payload.sku, variantId: variant.id, price: variant.price }
}

Rispondere personalmente alla chiamata

ctx.respond() invia immediatamente una risposta, trasformando così il webhook in un piccolo endpoint API: convalida un dato, calcola una risposta e risponde il tutto in un’unica richiesta. Shopify Flow continua a funzionare indipendentemente dal valore restituito.

Reply to the caller and start a workflowjavascript
export default async function transform(payload, ctx) {
  const ok = typeof payload.email === "string" && payload.email.includes("@")
  ctx.respond({ accepted: ok }, { status: ok ? 200 : 422 })
  return ok ? payload : null
}

Test

Il pannello “Test” nella scheda “Funzione” esegue il codice presente nell’editor, comprese le modifiche non salvate, utilizzando un payload di esempio. Mostra il valore di ritorno, la risposta che la Sua funzione invierebbe, i campi del Shopify Flow generati, le righe di log e la durata. Non viene attivato alcun Flow, nulla viene registrato nella Cronologia e nulla viene conteggiato ai fini del Suo piano. Le chiamate all’archivio sono tuttavia reali: un’esecuzione di test legge e scrive nello stesso archivio delle richieste in produzione.

Quando una funzione non funziona

Se il Suo codice genera un'eccezione, va in timeout o restituisce un risultato inutilizzabile, la richiesta viene respinta con il messaggio 422 e l'errore viene registrato nella Cronologia insieme al messaggio di errore e alle righe del Suo log, in modo che possa verificare cosa sia accaduto. Corregga il codice e riproduca quella voce: la riproduzione eseguirà la nuova versione.

Limiti

  • 5 secondi e 64 MB per ogni esecuzione, oltre a 50.000 caratteri di codice.
  • Nessun pacchetto npm. ctx.fetch è l'unica via d'uscita, e gli indirizzi interni o privati vengono rifiutati.
  • ctx.shopify Consente 10 chiamate per esecuzione, solo query, limitate agli ambiti da Lei concessi.
  • Ogni esecuzione che raggiunge Shopify Flow costituisce una normale invocazione e viene conteggiata ai fini del Suo piano. Una richiesta saltata, invece, non viene conteggiata.