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
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.
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.
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 |
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.
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.
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.shopifyConsente 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.

