Transformatiefuncties
Met ‘Mapping’ worden waarden uit een verzoek gehaald. Een transformatiefunctie gaat nog een stap verder: het is uw eigen JavaScript-code die bij elk verzoek wordt uitgevoerd vóór Shopify Flow, zodat u de payload kunt aanpassen, iets kunt opzoeken, kunt bepalen of het verzoek het uitvoeren van een workflow überhaupt waard is, of de aanvrager zelf kunt beantwoorden.
Deze optie bevindt zich op het tabblad ‘Functie’ van een webhook. Een lege bewerkingsvlak betekent dat de functie is uitgeschakeld.
De vorm van een functie
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" }
}Wat u krijgt bij ctx
ctx.request |
method, contentType, het verzoek headers (geheime gegevens gemaskeerd) en query |
ctx.webhook |
The webhooks id en name |
ctx.shop |
Uw MyShopify-domein |
ctx.log(...) |
Schrijft een regel die u in het testpaneel en in de geschiedenis kunt lezen |
await ctx.fetch(url, init) |
Roep een openbare API aan |
await ctx.shopify(query, variables) |
Leest winkelgegevens met Admin GraphQL |
ctx.storage |
Behoudt kleine waarden tussen de uitvoeringen door (zie hieronder) |
ctx.respond(body, options) |
Neemt de telefoon onmiddellijk op |
Een payload hervormen
De meest voorkomende toepassing: de structuur van een verzender omzetten in de enkele waarden die uw workflow nodig heeft.
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,
}
}Verzoeken verwijderen die u niet nodig hebt
Er wordt null geretourneerd en het verzoek stopt daar: er wordt geen Shopify Flow uitgevoerd, er wordt geen geschiedenisvermelding aangemaakt en er wordt niets in mindering gebracht op uw abonnement. De aanroeper ontvangt 200 met { "skipped": true }, zodat er geen nieuwe poging wordt ondernomen.
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
}Zaken onthouden tussen de runs door
ctx.storage is een kleine sleutel-waarde-opslag die bij uw winkel hoort. Het is het hulpmiddel voor de vraag „heb ik dit al eens gezien?“: sla een id op wanneer er een gebeurtenis binnenkomt, en sla het volgende verzoek met hetzelfde id over, zelfs als dat pas dagen later binnenkomt.
| Bel | Is |
|---|---|
await ctx.storage.get(key) |
De opgeslagen waarde, oftewel de null |
await ctx.storage.set(key, value) |
Winkelt elke JSON-waarde, waarbij de bestaande waarde wordt overschreven |
await ctx.storage.delete(key) |
Verwijdert het; true, indien dit bestond |
await ctx.storage.list({ prefix, limit, cursor }) |
Belangrijke benamingen en afmetingen, pagina voor 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
}Aanvullen met winkelgegevens
ctx.shopify voert alleen-lezen Admin GraphQL-query’s uit voor uw winkel, zodat een workflow kan starten met gegevens waarover de afzender nooit beschikte. De functie ziet alleen wat u toestaat: verleen de benodigde scopes onder ‘Toegang tot winkelgegevens’ op het tabblad ‘Functie’. Standaard wordt er niets toegestaan en worden mutaties geweigerd.
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 }
}Zelf de telefoon opnemen
ctx.respond() stuurt onmiddellijk een antwoord terug, waardoor de webhook in feite een klein API-eindpunt wordt: iets valideren, een antwoord berekenen en reageren in één verzoek. Shopify Flow blijft gewoon werken met wat u ook terugstuurt.
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
}Testen
Het testpaneel op het tabblad ‘Functie’ voert de code in de editor uit - inclusief niet-opgeslagen wijzigingen - op basis van een voorbeeldpayload. Het toont de retourwaarde, het antwoord dat uw functie zou verzenden, de Flow-velden die het genereert, uw logregels en de duur. Er wordt geen Shopify Flow geactiveerd, er wordt niets naar de geschiedenis geschreven en er wordt niets in rekening gebracht voor uw abonnement. Opslagaanroepen zijn echter wel echt: bij een testrun wordt dezelfde opslag gelezen en geschreven als bij live verzoeken.
Wanneer een functie mislukt
Indien uw code een fout genereert, een time-out bereikt of een onbruikbaar resultaat retourneert, wordt het verzoek afgewezen met de melding 422 en wordt de fout vastgelegd in de geschiedenis, samen met de foutmelding en uw logregels, zodat u kunt zien wat er is gebeurd. Corrigeer de code en speel dat item opnieuw af: bij het opnieuw afspelen wordt de nieuwe versie uitgevoerd.
Beperkingen
- 5 seconden en 64 MB per uitvoering, en 50.000 tekens aan code.
- Geen npm-pakketten.
ctx.fetchis de enige manier, en interne of privé-adressen worden geweigerd. ctx.shopifymaakt 10 oproepen per uitvoering mogelijk, uitsluitend voor query’s, beperkt tot de scopes die u hebt toegekend.- Elke run die Shopify Flow bereikt, is een normale aanroep en telt mee voor uw abonnement. Een overgeslagen verzoek telt niet mee.

