Tilpassede utløsere

Tilpassede utløsere

Kopier side

Lag en tilpasset Shopify Flow-utløser fra enhver Shopify-hendelse eller tidsplan, med JavaScript-betingelser og verdier før og etter endringen.

De innebygde utløserne dekker endringene som de fleste butikker er opptatt av. En tilpasset utløser dekker resten: Du velger en Shopify-hendelse, skriver noen få linjer med JavaScript for å avgjøre om den er relevant og hva som skal sendes, og så blir den en utløser du kan bruke i Shopify Flow.

Tre ting den løser som en innebygd utløser ikke kan:

  • Avfyr kun på dine betingelser. «Bare når en bestilling på over 500 EUR får vip-merket» er én kodelinje, i stedet for en arbeidsflyt som kjører på hver bestilling og deretter filtrerer.
  • Bruk en overgang, ikke en tilstand. Koden din ser verdien både før og etter endringen, så uttrykk som «statusen gikk fra utkast til aktiv» eller «lagerbeholdningen falt under 5» er mulige. En betingelse basert på den nåværende verdien kan ikke uttrykke dette.
  • Send akkurat de feltene du ønsker. Tilpass hendelsen til de verdiene arbeidsflyten din faktisk bruker, i stedet for å lese dem ut én etter én.

En tilpasset utløser trenger ikke engang en Shopify-hendelse: den kan også kjøre etter en tidsplan og selv avgjøre hva som har endret seg.

Slik fungerer det

  1. Velg hva som skal utløse den: én Shopify-hendelse eller en tidsplan.
  2. For en hendelse kan du velge hvilken hendelse den skal lytte etter - en hvilken som helst Shopify-hendelse som appen allerede mottar - eller ta utgangspunkt i en mal, som velger hendelsen og fyller ut koden.
  3. Hent inn en ekte nyttelast. Gjør denne endringen i nettbutikken din, så henter appen selve hendelsesinnholdet.
  4. Skriv en transformasjon - returner et objekt for å utløse, returner null for å hoppe over.
  5. Test det mot den registrerte hendelsen, og se nøyaktig hva arbeidsflyten din ville motta.
  6. Slå den på.
Redigeringsverktøyet for egendefinerte utløsere med navn, håndtak, valg mellom én Shopify-hendelse og en tidsplan, samt hendelsen og en mal
En ny tilpasset utløser: Velg hva som skal utløse den, velg hendelsen, og bruk eventuelt en mal som utgangspunkt.

Skrive transformasjonen

Utløseren din er en JavaScript-modul som eksporterer en funksjon ved navn transform. Den tar imot fire argumenter:

  • payload - den ubehandlede Shopify-hendelsesteksten, akkurat slik den kommer inn.
  • topic - hvilken hendelse som ble utløst, for eksempel PRODUCTS_UPDATE.
  • shop - ditt myshopify-domene.
  • ctx - ctx.log(...) skriver ut til loggpanelet ved siden av redigeringsvinduet, ctx.shopify(...) kjører en Admin GraphQL-forespørsel, og ctx.fetch(...) henter data fra en URL på det offentlige internett.

Det du returnerer, avgjør hva som skjer:

  • Returner et objekt, og utløseren aktiveres med dette objektet.
  • Returner null, så hoppes hendelsen over. Slik fungerer filtrering - du trenger ikke å lære deg et eget filterspråk.
  • La feltet stå tomt, så utløses den ved hver hendelse av den typen.
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,
  };
}

Verdien før endringen

Shopify

Ved produktoppdatering, ordreoppdatering og kundeoppdatering viser payload._changes en liste over alle sporede felt som denne oppdateringen har endret, med oldValue og newValue for hvert felt:

  • Produkter: title, handle, description, status, vendor, productType, tags
  • Bestillinger: financialStatus, fulfillmentStatus, tags, note, lineItems og customAttributes.<name>
  • Kunder: tags, note, state (ENABLED, DISABLED, INVITED, DECLINED)

Listen er tom når oppdateringen ikke gjaldt disse feltene - for eksempel en endring i lagerbeholdningen - eller når appen ser posten for første gang. Eksempelhendelsen du registrerer i redigeringsverktøyet viser feltet, slik at du kan se hvordan det faktisk ser ut før du skriver inn data i det.

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

De mer spesifikke hendelsene har sine egne gamle og nye verdier, så du trenger ikke _changes der: en prisendring har oldPrice, newPrice og percentChange; en lagerendring har _oldAvailable, _newAvailable og _delta; en metafeltendring har previousValue ved siden av metafield.value.

Begynn med en mal

Under Fires on i redigeringsverktøyet velger Start from a template hendelsen og fyller inn fungerende kode. Rediger konstantene øverst, test, og lagre deretter. Hver mal leser inn en verdi før og etter endringen:

  • Et produkt-, ordre- eller kundefelt ble endret fra én verdi til en annen - statusen gikk fra utkast til aktiv, en ordre ble betalt, en konto ble aktivert.
  • Prisen falt med mer enn N prosent - en reell prisnedsetning, ikke bare en vanlig prisjustering.
  • Aksjekursen falt under en terskel - utløser én gang, i det øyeblikket kursen krysser linjen, ikke ved hvert salg mens den allerede er lav.
  • Et produktmetafelt har overskredet en terskel - en vurdering har falt under 3, en margin har steget over 40.
  • Bestilling betalt av en storkunde - henter kundens samlede forbruk i butikken din og utløser kun når beløpet overstiger det du har angitt.
Transform-kortet i redigeringsverktøyet med koden til en mal som heter payload._changes
En mal fyller inn fungerende kode. Rediger konstantene øverst, test den og lagre deretter.

Hente tilleggsdata med ctx.shopify

Webhook-innholdet inneholder kun feltene som Shopify sender. Når du trenger noe annet - antall bestillinger fra en kunde, lagerbeholdningen for en variant, et metafelt - kan du foreta en forespørsel til Admin API direkte fra transformasjonen din:

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

Den returnerer spørringens data og utløser et unntak hvis spørringen inneholder feil, slik at feilen blir synlig i testen din i stedet for at den uten videre ikke gir noe resultat.

Tre grenser det er verdt å kjenne til:

  • Opptil 10 oppkall per kjøring. Enrichment krever en håndfull; mer enn det er vanligvis en løkke. Hent det du trenger i én enkelt spørring der det er mulig.
  • Den leser, den skriver ikke. Den bruker de tillatelsene du har gitt, og appen ber kun om lesetilgang. En forespørsel om ordredata mislykkes med mindre «Tilgang til ordredata» er godkjent på siden «Tillatelser». Hvis du vil endre noe i butikken din, må du gjøre det i Shopify Flow-handlingene som følger etter utløseren.
  • Butikkens påloggingsopplysninger kommer aldri inn i koden din. Appen utfører forespørselen på dine vegne, så det finnes ikke noe tilgangstoken i sandkassen som kan lekke.

ctx.fetch(url, options) fungerer på samme måte som nettleserens fetch-funksjon for alt på det offentlige internett: en leverandørs lageroppdatering, en valutakurs, din egen API. Interne og private nettverksadresser avvises. Hvis utløserkoden din er lagret på GitHub, må du ikke oppgi en API-nøkkel i den.

Utløsere som kjører etter en tidsplan

Shopify Flow reagerer når noe skjer. Den kan ikke reagere når ingenting skjer, og den kan ikke se noe utenfor butikken din. For det må du velge Etter en tidsplan under Hva utløser denne prosessen. Det ligger ingen Shopify-hendelse bak en slik utløser: koden din kjører med et bestemt intervall, fra hvert 30. sekund til én gang om dagen, og avgjør selv hva som regnes som en endring.

Det er den samme transform-funksjonen, men med en annen payload og en annen returverdi:

  • payload.state - det som koden din returnerte som state ved forrige kjøring. null ved første kjøring.
  • payload.now og payload.lastRunAt - tidsstempler.
  • Returner { state, events }: den nye tilstanden som skal lagres (opptil 32 KB) og en liste over hendelser som skal utløses (opptil 100 per kjøring). Hver hendelse utløser Custom Trigger én gang; en hendelses resourceId, hvis du har angitt en, blir post-ID-en i Shopify Flow. Returner null når det ikke er noe å rapportere.

Sørg for at den første kjøringen bare registrerer, aldri utløser. Ved den første kjøringen har koden din ingenting å sammenligne med, så alt vil virke nytt. Lagre det du ser og returner ingen hendelser, og å slå på utløseren vil aldri oversvømme arbeidsflytene dine. Alle malene gjør dette.

Den tilpassede utløserredigereren i «Etter tidsplan»-modus, med intervall og antall kjøringer i løpet av 30 dager
Etter en tidsplan: Velg intervall - redigeringsverktøyet viser hvor mange gjennomkjøringer det blir totalt - og start med en forhåndsdefinert mal.
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 }],
  }
}

Maler for planlagte utløsere, under Start fra en mal i «Planlegg»-kortet:

  • Produkt, ordre eller kunde som ikke har blitt oppdatert på N dager - utdaterte katalogvurderinger, fastlåste ordrer, gjenvinning av kunder. Hver post utløser en handling én gang per inaktiv periode, og oppgaver som allerede var forfalt da du aktiverte funksjonen, utløses ikke alle på en gang.
  • En verdi utenfor Shopify har endret seg - en lageroppdatering fra en leverandør, en valutakurs, en prisliste, med differansen og prosentandelen for tallene.
  • Nytt innlegg i en RSS- eller Atom-feed - nyheter fra leverandøren, en produktliste-feed, en statusside.
  • Ingen bestillinger i N timer - en «hjerteslag»-funksjon for butikken din. Utløses én gang når bestillingene opphører, og én gang når de kommer tilbake.

Test kjører koden din én gang uten å utløse noe og uten å lagre tilstanden, slik at du kan kjøre den så ofte du vil.

Bruk av det i Shopify Flow

Hver tilpasset utløser vises i Shopify Flow som den samme utløseren: Tilpasset utløser. Legg den til i en arbeidsflyt, og legg deretter til et vilkår som sier at «Utløserhåndtaket er likt utløserens håndtak».

Dette navnet vises på utløserens side og endres aldri, selv om du gir utløseren et nytt navn - slik at arbeidsflyten din fortsetter å fungere.

Hver nøkkel som transformasjonen din returnerer, blir et felt i utløseren, og hele objektet er også tilgjengelig som JSON hvis du heller vil analysere det selv.

Legg koden på GitHub

Du kan koble til et GitHub-repositorium, slik at utløserkoden din blir underlagt versjonskontroll. Endringer blir tilgjengelige for gjennomgang i en pull-forespørsel, du kan se hvem som har endret hva, og du kan tilbakestille en transformasjon som har sluttet å fungere.

Koble den til på utviklersiden, under Tilkoblinger. Du velger selv hvilke repositorier appen skal ha tilgang til, og du kan når som helst trekke tilbake denne tilgangen fra GitHub.

Når et arkiv er valgt, blir alle eksisterende utløsere umiddelbart lagret der, og synkroniseringen skjer i begge retninger:

Hva du gjør Hva skjer?
Opprett, rediger eller dupliser en utløser i appen Filen er lagt inn i depotet ditt
Slette en utløser i appen Filen blir fjernet fra arkivet ditt
Send inn en endring til den tilkoblede grenen Koden for utløseren oppdateres i appen

Hver utløser er én fil som er oppkalt etter håndtaket sitt, og som inneholder nøyaktig den modulen du ser i redigeringsprogrammet - uten noe ekstra rundt den. Det betyr at du kan åpne den i ditt eget redigeringsprogram, kjøre den og sjekke den for feil på samme måte som enhver annen JavaScript-fil.

Gå tilbake til en tidligere versjon

Du trenger ikke å kunne bruke Git for å angre en endring. Når et arkiv er koblet til, viser redigeringsprogrammet en rullegardinmeny under Versjon som inneholder alle tidligere versjoner av den aktuelle filen, med dato og forfatter. Velg en av dem, så lastes den inn i redigeringsprogrammet som en ulagret endring, slik at du kan lese den først - det er først når du lagrer at den blir gjenopprettet.

Test mens du redigerer lokalt

Hvis du redigerer filen i din egen editor, kan du kjøre den mot den innspilte eksempelhendelsen uten å lagre den i appen først. Bruk en API-nøkkel med «execute»-nivå fra utviklersiden:

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

Du får tilbake det samme resultatet som vises når du trykker på «Test»-knappen i appen: om den ville utløses, utdataobjektet, linjene i ctx.log og kjøretiden.

Dette endepunktet utløser ingenting og lagrer ingenting, og det bruker ikke noe av kvoten din - så det er trygt å kjøre det hver gang en filovervåker lagrer. (Knappen Kjør test i appen utløser imidlertid Shopify Flow-arbeidsflyten din, slik at du kan se den kjøre fra start til slutt; det er også gratis.)

Du kan også hente selve eksempelpayloaden med en lesenøkkel, lagre den lokalt og kjøre filen helt uten nettilgang:

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"
Bruker en tilpasset utløser kvoten i abonnementet mitt?

Ja, og den teller alle hendelser den overvåker - ikke bare de den utløser. Hvis utløseren din overvåker «Produktoppdatering» og nettbutikken din har 60 000 produktoppdateringer i måneden, blir det 60 000 hendelser, selv om koden din bare utløses på 100 av dem.

Vi mottar, fjerner duplikater og setter hver av disse hendelsene i kø, før vi kjører koden din i en isolert sandkasse - alt dette skjer før koden din avgjør om den skal utløses. Antallet gjenspeiler dette arbeidet.

For å si det på en annen måte: Det koster det samme som den innebygde utløseren ville ha kostet for den samme hendelsen. Du blir ikke belastet ekstra for filtrering, og testing er alltid gratis. En planlagt utløser teller én gang per kjøring.

Er testingen gratis?

Ja. Både **«Kjør **test»-knappen i appen og API-endepunktet /test er unntatt, selv om «Kjør test» faktisk setter i gang Shopify Flow-arbeidsflyten din, slik at du kan se den i gang. Det er kun live-kjøringer som bruker kvoten din, så du kan prøve deg frem med en transformasjon så mye du vil.

Hvorfor er payload._changes tomt?

Enten lå oppdateringen utenfor de feltene som spores - for eksempel en endring i lagerbeholdningen eller en variantendring på et produkt - eller så har appen ennå ikke noen referanseverdi for den aktuelle posten. Referanseverdien lagres første gang appen registrerer en post, så den aller første oppdateringen av en post den aldri har sett før, har ingen tidligere verdi. Alle oppdateringer etter det har det.

Kan koden min endre dataene i butikken min?

Nei. ctx.shopify kjører med de lesetillatelsene du har gitt, og appen ber aldri om skrivetilgang. Dette er gjort med vilje: en utløser som redigerer posten den overvåker, starter seg selv på nytt, og det er nettopp denne sløyfen Shopify-slår av arbeidsflyter på grunn av. Endre dataene i Shopify Flow-handlingene som følger etter utløseren.

Kan jeg bytte ut håndtaket senere?

Nei, og det er med vilje. Arbeidsflyten din i Shopify Flow filtrerer etter håndtaket, så hvis du endrer det, vil arbeidsflyten automatisk slutte å kjøre. Du kan gi utløseren et nytt navn uten problemer - håndtaket forblir det samme.

Håndtaket er også filnavnet i GitHub-depotet ditt, så det flyttes heller aldri.

Hva skjer hvis koden min inneholder en feil?

Hendelsen hoppes over, og feilen loggføres i utløseren, slik at du kan se hva som gikk galt. En mislykket transformasjon blokkerer aldri noe annet - de andre utløserne dine, enten de er tilpassede eller innebygde, fortsetter som vanlig.

Hvor kjører koden min?

I en isolert sandkasse, adskilt fra resten av appen, med en kort tidsbegrensning og uten tilgang til butikkens påloggingsopplysninger. Den får kun tilgang til hendelsesdataene du har hentet inn, samt det du henter inn med ctx.shopify eller ctx.fetch.

Hva skjer hvis jeg redigerer filen både i GitHub og i appen samtidig?

Den du lagrer sist, vinner. Når du lagrer i appen, blir endringene lagt inn i filen, og når du sender endringene til den tilknyttede grenen, overskrives koden som ligger i appen. Hvis du hovedsakelig jobber i repositoriet ditt, bør du behandle appens redigeringsverktøy som skrivebeskyttet for å unngå uventede overraskelser.

Kan en fil i mitt arkiv utløse en ny trigger?

Nei. En utløser må også vite hvilken Shopify-hendelse den skal lytte etter, og filen inneholder kun kode - hvis man prøver å gjette seg frem til hendelsen, vil utløseren kobles til feil ting. Opprett først utløseren i appen, og rediger deretter filen fritt.

Kan den utløses av hendelser som appen ikke allerede mottar?

Nei. En tilpasset utløser overvåker hendelsene som appen allerede abonnerer på for butikken din, avhengig av hvilke tillatelser du har gitt. Når du gir tillatelse til en ressurs, blir hendelsene knyttet til den også tilgjengelige for tilpassede utløsere. For alt annet må du kjøre det etter en tidsplan.

Neste trinn