Transformationsfunktioner

Transformationsfunktioner

Kopiera sidan

Kör egen JavaScript-kod på varje webhook-förfrågan innan Shopify Flow: omforma datapaketet, hämta butiksdata, filtrera bort förfrågningar eller svara direkt.

Mappning hämtar värden ur en förfrågan. En transformeringsfunktion går ett steg längre: det är din egen JavaScript-kod som körs på varje förfrågan innan den når Shopify Flow, så att du kan omforma datapaketet, söka efter information, avgöra om förfrågan överhuvudtaget är värd att köra ett arbetsflöde för, eller själv svara den som skickat förfrågan.

Den finns på fliken ”Funktion” i en webhook. Om redigeringsfältet är tomt är funktionen avstängd.

En funktions form

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" }
}

Vad ctx ger dig

ctx.request method, contentType, begäranens headers (hemliga uppgifter dolda) och query
ctx.webhook Webhookens id och name
ctx.shop Din myshopify-domän
ctx.log(...) Skriver ut en rad som du kan läsa i testpanelen och i historiken
await ctx.fetch(url, init) Anropar ett offentligt API
await ctx.shopify(query, variables) Läser butiksdata med Admin GraphQL
ctx.storage Bevarar små värden mellan körningarna (se nedan)
ctx.respond(body, options) Svarar omedelbart på samtalet

Omformning av en nyttolast

Den vanligaste användningen: omvandla avsändarens struktur till de få värden som ditt arbetsflöde behöver.

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,
  }
}

Ta bort förfrågningar som du inte behöver

Returnera null, så avbryts begäran där: ingen Shopify Flow-körning, ingen historikpost och inget räknas mot ditt abonnemang. Den som skickar begäran får svaret 200 med { "skipped": true }, så den gör inget nytt försök.

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
}

Att komma ihåg saker mellan löprundorna

ctx.storage är ett litet nyckel-värde-lager som tillhör din butik. Det är verktyget för att avgöra ”har jag sett det här förut?”: spara ett ID när en händelse inträffar och hoppa över nästa förfrågan med samma ID, även om den kommer flera dagar senare.

Ring Gör
await ctx.storage.get(key) Det lagrade värdet, eller null
await ctx.storage.set(key, value) Lagrar valfritt JSON-värde och skriver över
await ctx.storage.delete(key) Tar bort den; true om den fanns
await ctx.storage.list({ prefix, limit, cursor }) Viktiga namn och storlekar, sida för sida
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
}

Berika med butiksdata

ctx.shopify kör skrivskyddade Admin GraphQL-frågor för din butik, vilket innebär att ett arbetsflöde kan starta med data som avsändaren aldrig har haft tillgång till. Det ser endast det du tillåter: bevilja de behörighetsområden du behöver under ”Butiksdatatillgång” på fliken ”Funktion”. Inget är beviljat som standard, och mutationer avvisas.

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 }
}

Att själv svara på samtalet

ctx.respond() skickar tillbaka ett svar direkt, vilket förvandlar webhooken till en liten API-ändpunkt: verifiera något, beräkna ett svar och svara i en enda förfrågan. Shopify Flow fortsätter att köras oavsett vad du returnerar.

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
}

Testning

Testpanelen på fliken Funktion kör koden i redigeraren, inklusive osparade ändringar, mot en exempelpayload. Den visar returvärdet, det svar som din funktion skulle skicka, de Shopify Flow-fält som den genererar, dina loggrader och hur lång tid det tar. Inget utlöser Shopify Flow, inget skrivs till historiken och inget räknas in i ditt abonnemang. Lagringsanropen är dock verkliga: en testkörning läser och skriver till samma butik som liveförfrågningar.

När en funktion misslyckas

Om din kod genererar ett undantag, överskrider tidsgränsen eller returnerar något oanvändbart, avvisas begäran med koden 422 och felet registreras i historiken tillsammans med felmeddelandet och dina loggrader, så att du kan se vad som hände. Korrigera koden och kör om den posten: vid omkörningen körs den nya versionen.

Gränser

  • 5 sekunder och 64 MB per körning, samt 50 000 tecken kod.
  • Inga npm-paket. ctx.fetch är den enda lösningen, och interna eller privata adresser tillåts inte.
  • ctx.shopify tillåter 10 anrop per körning, endast sökningar, begränsat till de behörighetsområden du har beviljat.
  • Varje körning som når Shopify Flow räknas som en vanlig anropning och ingår i ditt abonnemang. En förbipasserad begäran räknas inte.