Wyzwalacze niestandardowe
Utwórz niestandardowy wyzwalacz Shopify Flow z dowolnego zdarzenia Shopify lub harmonogramu, z wartościami przed i po zmianie oraz filtrowaniem w JavaScript.
Wbudowane wyzwalacze obejmują zmiany, na których zależy większości sklepów. Wyzwalacz niestandardowy obejmuje pozostałe przypadki: wybierają Państwo zdarzenie w Shopify, piszą kilka wierszy kodu JavaScript, aby określić, czy zdarzenie to ma znaczenie i jakie dane należy przesłać, a następnie staje się ono wyzwalaczem, z którego mogą Państwo korzystać w Shopify Flow.
Trzy problemy, które rozwiązuje, a których nie jest w stanie rozwiązać wbudowany wyzwalacz:
- Proszę uruchamiać tę funkcję wyłącznie na Państwa warunkach. „Tylko wtedy, gdy zamówienie o wartości powyżej 500 EUR otrzyma oznaczenie
vip” to jedna linijka kodu, zamiast przepływu pracy, który uruchamia się przy każdym zamówieniu, a następnie je filtruje. - Należy stosować wyrażenie przejście, a nie stan. Państwa kod rozpoznaje wartość przed zmianą i po niej, więc możliwe jest stwierdzenie, że „status zmienił się z wersji roboczej na aktywną” lub „stan zapasów spadł poniżej 5”. Warunek oparty na bieżącej wartości nie pozwala tego wyrazić.
- Przesyłajcie wyłącznie te pola, które są Państwu potrzebne. Przekształcajcie zdarzenie na wartości faktycznie wykorzystywane w Państwa przepływie pracy, zamiast odczytywać je pojedynczo.
Niestandardowy wyzwalacz nie wymaga nawet zdarzenia z serwisu Shopify: może on również działać zgodnie z harmonogramem i samodzielnie rozpoznawać, co uległo zmianie.
Jak to działa
- Proszę wybrać sposób uruchamiania: jedno zdarzenie w Shopify lub harmonogram.
- W przypadku zdarzenia należy wybrać zdarzenie, na które aplikacja nasłuchuje - dowolne zdarzenie Shopify, które aplikacja już odbiera - lub skorzystać z szablonu, który wybiera zdarzenie i wypełnia kod.
- Przechwyć rzeczywistą treść żądania. Wprowadź tę zmianę w swoim sklepie, a aplikacja pobierze dokładnie tę treść zdarzenia.
- Proszę napisać transformację - w przypadku uruchomienia należy zwrócić obiekt, a w przypadku pominięcia - wartość
null. - Proszę przetestować to na podstawie zarejestrowanego zdarzenia i sprawdzić dokładnie, jakie dane otrzymałby Państwa proces.
- Proszę to włączyć.

Tworzenie transformacji
Pański wyzwalacz to moduł JavaScript, który eksportuje funkcję o nazwie transform. Funkcja ta przyjmuje cztery argumenty:
payload- nieprzetworzona treść zdarzenia Shopify, dokładnie w takiej postaci, w jakiej została przesłana.topic- jakie zdarzenie zostało wywołane, na przykładPRODUCTS_UPDATE.shop- Państwa domena w serwisie myshopify.ctx-ctx.log(...)wyświetla dane w panelu dziennika obok edytora,ctx.shopify(...)uruchamia zapytanie GraphQL w panelu administracyjnym, actx.fetch(...)wywołuje adres URL w publicznej sieci internetowej.
To, co zwrócą Państwo, decyduje o dalszym przebiegu wydarzeń:
- Zwróć obiekt, a wyzwalacz zostanie uruchomiony, przenosząc ten obiekt.
- W przypadku zwrócenia wartości
nullzdarzenie zostanie pominięte. Tak właśnie działa filtrowanie - nie ma potrzeby nauki żadnego odrębnego języka filtrowania. - Jeśli** plik pozostanie pusty**, funkcja zostanie wywołana przy każdym zdarzeniu tego typu.
/**
* 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,
};
}Wartość przed zmianą
Shopify
W przypadku aktualizacji produktu, zamówienia i **danych klienta **w polu payload._changes wymienione są wszystkie śledzone pola, których wartości uległy zmianie w wyniku tej aktualizacji, a każde z nich zawiera wartości oldValue oraz newValue:
- Produkty:
title,handle,description,status,vendor,productType,tags - Zamówienia:
financialStatus,fulfillmentStatus,tags,note,lineItemsorazcustomAttributes.<name> - Klienci:
tags,note,state(ENABLED,DISABLED,INVITED,DECLINED)
Lista jest pusta, gdy aktualizacja nie dotyczyła tych pól - na przykład w przypadku zmiany stanu magazynowego - lub gdy aplikacja wyświetla ten rekord po raz pierwszy. Przykładowe zdarzenie, które rejestrują Państwo w edytorze, pokazuje to pole, dzięki czemu mogą Państwo zapoznać się z jego rzeczywistym kształtem przed wprowadzeniem do niego danych.
/**
* 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,
};
}Poszczególne zdarzenia zawierają własne wartości stare i nowe, więc nie ma tam potrzeby stosowania _changes: zmiana ceny posiada oldPrice, newPrice oraz percentChange; zmiana stanu magazynowego posiada _oldAvailable, _newAvailable oraz _delta; zmiana metapola posiada previousValue obok metafield.value.
Zacznij od szablonu
W edytorze, w sekcji Fires on, opcja Start from a template wybiera zdarzenie i wypełnia kod roboczy. Proszę edytować stałe u góry, przetestować, a następnie zapisać. Każdy szablon odczytuje wartość przed i po zmianie:
- Pole dotyczące produktu, zamówienia lub klienta uległo zmianie z jednej wartości na inną - status zmienił się z „wersja robocza” na „aktywny”, zamówienie zostało opłacone, konto zostało aktywowane.
- Cena spadła o ponad N procent - to prawdziwa obniżka, a nie zwykła zmiana ceny.
- Stan zapasów spadł poniżej progu - sygnał wyzwalany jest jednorazowo, w momencie przekroczenia tej granicy przez stan zapasów, a nie przy każdej sprzedaży, gdy poziom ten jest już niski.
- Wartość pola meta produktu przekroczyła próg - ocena spadła poniżej 3, a marża wzrosła powyżej 40.
- Zamówienie opłacone przez klienta o wysokiej wartości - system odczytuje łączną kwotę wydatków klienta w Państwa sklepie i uruchamia działanie funkcji wyłącznie w przypadku, gdy kwota ta przekracza ustaloną przez Państwa wartość.

Pobieranie dodatkowych danych za pomocą ctx.shopify
Treści webhooków zawierają wyłącznie pola przesyłane przez Shopify. Jeśli potrzebują Państwo innych danych - np. liczby zamówień klienta, stanu magazynowego wariantu lub metapola - proszę wykonać zapytanie do interfejsu API administracyjnego bezpośrednio z poziomu funkcji transformacji:
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,
};
}Zwraca dane zapytania (data), a w przypadku wystąpienia błędów w zapytaniu generuje wyjątek, dzięki czemu błąd zostanie wykryty w Państwa teście, a nie zostanie pominięty bez żadnej informacji zwrotnej.
Trzy ograniczenia, o których warto wiedzieć:
- Maksymalnie 10 wywołań na jedno wykonanie. Wzbogacanie danych wymaga kilku wywołań; większa liczba oznacza zazwyczaj pętlę. Jeśli to możliwe, proszę pobrać potrzebne dane w ramach jednego zapytania.
- Aplikacja odczytuje dane, ale ich nie zapisuje. Korzysta z przyznanych przez Państwa uprawnień, a aplikacja prosi wyłącznie o dostęp do odczytu. Zapytanie o dane dotyczące zamówień zakończy się niepowodzeniem, o ile na stronie „Uprawnienia” nie przyznano uprawnienia „Dostęp do danych dotyczących zamówień”. Aby wprowadzić zmiany w Państwa sklepie, należy to zrobić w ramach działań Shopify Flow, które następują po wyzwalaczu.
- Dane uwierzytelniające Państwa sklepu nigdy nie trafiają do Państwa kodu. Zapytanie jest wykonywane przez aplikację w Państwa imieniu, więc w środowisku testowym nie ma żadnego tokenu dostępu, który mógłby zostać ujawniony.
Funkcja ctx.fetch(url, options) działa podobnie jak funkcja fetch w przeglądarce w odniesieniu do wszelkich zasobów dostępnych w publicznej sieci internetowej: danych o stanach magazynowych dostawcy, kursów walutowych czy Państwa własnego interfejsu API. Adresy w sieciach wewnętrznych i prywatnych są odrzucane. Jeśli Państwa kod wyzwalacza jest zapisany na GitHubie, proszę nie umieszczać w nim klucza API.
Wyzwalacze uruchamiane zgodnie z harmonogramem
Shopify Flow reaguje, gdy coś się dzieje. Nie może reagować, gdy nic się nie dzieje, i nie ma wglądu w sytuację poza Państwa sklepem. W tym celu proszę wybrać opcję Zgodnie z harmonogramem w sekcji Co powoduje uruchomienie tej akcji. Za takim wyzwalaczem nie stoi żadne zdarzenie Shopify: Państwa kod uruchamia się w określonych odstępach czasu, od co 30 sekund do raz dziennie, i samodzielnie decyduje, co uznaje za zmianę.
Jest to ta sama funkcja transform, z innym parametrem payload i inną wartością zwracaną:
payload.state- wartość zwrócona przez Państwa kod jakostatepodczas poprzedniego uruchomienia.nullpodczas pierwszego uruchomienia.payload.noworazpayload.lastRunAt- znaczniki czasu.- Zwróć
{ state, events }: nowy stan do zapamiętania (maksymalnie 32 KB) oraz listę zdarzeń do wywołania (maksymalnie 100 na jedno uruchomienie). Każde zdarzenie wywołuje Custom Trigger jednokrotnie; identyfikatorresourceIdzdarzenia, o ile został ustawiony, staje się identyfikatorem rekordu w Shopify Flow. Proszę zwrócićnull, jeśli nie ma żadnych danych do zgłoszenia.
Podczas pierwszego uruchomienia pamiętaj tylko o jednym: nigdy nie uruchamiaj akcji. Podczas pierwszego uruchomienia kod nie ma z czym porównać, więc wszystko będzie wyglądało jak nowe. Zapisz to, co widzisz, i nie zwracaj żadnych zdarzeń, a włączenie wyzwalacza nigdy nie spowoduje zalania Państwa przepływów pracy. Wszystkie szablony działają w ten sposób.

// 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 }],
}
}Szablony dla wyzwalaczy zaplanowanych, dostępne w sekcji Rozpocznij od szablonu na karcie „Harmonogram”:
- Produkt, zamówienie lub klient nieaktualizowane od N dni - przestarzałe recenzje w katalogu, zablokowane zamówienia, działania mające na celu odzyskanie klientów. Każdy rekord uruchamia się raz na okres braku aktywności, a rekordy, które były już przeterminowane w momencie włączenia tej funkcji, nie są uruchamiane wszystkie naraz.
- Zmieniono wartość spoza platformy Shopify - dane dotyczące stanów magazynowych dostawcy, kurs walutowy, cennik - wraz z różnicą i wartością procentową w odniesieniu do liczb.
- Nowy wpis w kanale RSS lub Atom - aktualności od dostawcy, kanał z listą produktów, strona informacyjna.
- Brak zamówień przez N godzin - sygnał kontrolny dla Państwa sklepu. Uruchamia się raz, gdy zamówienia ustaną, i raz, gdy ponownie się pojawią.
Funkcja Test uruchamia Państwa kod jednokrotnie, nie wywołując żadnych akcji i nie zapisując stanu, dzięki czemu mogą Państwo uruchamiać go tyle razy, ile tylko Państwo chcą.
Korzystanie z tej funkcji w Shopify Flow
Każdy niestandardowy wyzwalacz pojawia się w Shopify Flow jako ten sam wyzwalacz: Wyzwalacz niestandardowy. Proszę dodać go do przepływu pracy, a następnie dodać warunek: „Identyfikator wyzwalacza jest równy identyfikatorowi Państwa wyzwalacza”.
Ten identyfikator jest wyświetlany na stronie wyzwalacza i nigdy się nie zmienia, nawet jeśli zmieni Pan/Pani nazwę wyzwalacza - dzięki czemu Państwa proces pracy działa bez zakłóceń.
Każdy klucz zwrócony przez Państwa transformację staje się polem w wyzwalaczu, a cały obiekt jest również dostępny w formacie JSON, jeśli wolą Państwo samodzielnie go przetworzyć.
Proszę przechowywać kod na GitHubie
Można podłączyć repozytorium GitHub, dzięki czemu kod wyzwalacza będzie objęty kontrolą wersji. Zmiany będą dostępne do przeglądu w ramach pull requestu, będzie można sprawdzić, kto wprowadził jakie zmiany, a także cofnąć transformację, która przestała działać.
Proszę podłączyć je na stronie Developer w sekcji Connections. Można wybrać, do których repozytoriów aplikacja ma dostęp, a dostęp ten można w dowolnym momencie cofnąć w serwisie GitHub.
Po wybraniu repozytorium wszystkie istniejące wyzwalacze są natychmiast do niego zapisywane, a synchronizacja odbywa się w obu kierunkach:
| Czym się Państwo zajmują | Co się dzieje |
|---|---|
| Proszę utworzyć, edytować lub skopiować wyzwalacz w aplikacji | Plik został zapisany w Państwa repozytorium |
| Usunięcie wyzwalacza w aplikacji | Plik został usunięty z Państwa repozytorium |
| Proszę zatwierdzić zmianę w podłączonej gałęzi | Kod wyzwalacza został zaktualizowany w aplikacji |
Każdy wyzwalacz to pojedynczy plik o nazwie odpowiadającej jego identyfikatorowi, zawierający dokładnie ten sam moduł, który widzą Państwo w edytorze - bez żadnych dodatkowych elementów. Oznacza to, że mogą Państwo otworzyć go we własnym edytorze, uruchomić i sprawdzić pod kątem poprawności tak jak każdy inny plik JavaScript.
Powrót do wcześniejszej wersji
Nie muszą Państwo znać systemu Git, aby cofnąć zmianę. Po nawiązaniu połączenia z repozytorium w edytorze pojawia się lista rozwijana Wersja, zawierająca wszystkie poprzednie wersje danego pliku wraz z datą i nazwiskiem autora. Wystarczy wybrać jedną z nich, a zostanie ona załadowana do edytora jako niezapisana zmiana, dzięki czemu mogą Państwo najpierw ją przejrzeć - dopiero zapisanie spowoduje przywrócenie tej wersji.
Proszę przeprowadzać testy podczas edycji w trybie lokalnym
Jeśli edytują Państwo plik we własnym edytorze, mogą Państwo uruchomić go w odniesieniu do przechwyconego przykładowego zdarzenia bez konieczności uprzedniego zapisywania go w aplikacji. Proszę użyć klucza API z uprawnieniem execute dostępnego na stronie dla programistów:
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}')"Otrzymują Państwo ten sam wynik, jaki wyświetla przycisk „Test” w aplikacji: informację, czy akcja zostałaby uruchomiona, obiekt wyjściowy, wiersze z pliku ctx.log oraz czas wykonania.
Ten punkt końcowy nie wyzwala żadnych akcji ani nie zapisuje żadnych danych, a ponadto nie wykorzystuje limitu przyznanego w ramach planu - dzięki temu można go bezpiecznie uruchamiać przy każdym zapisaniu danych przez moduł monitorujący pliki. (Przycisk Uruchom test w aplikacji wyzwala jednak Państwa przepływ pracy w Shopify Flow, dzięki czemu mogą Państwo obserwować jego przebieg od początku do końca; ta funkcja jest również bezpłatna.)
Można również pobrać sam przykładowy ładunek przy użyciu klucza odczytu, zapisać go lokalnie i uruchomić plik całkowicie w trybie offline:
curl https://shopify.workflow-trigger-extensions.app/api/v1/triggers/custom/high-value-vip-order/test \
-H "Authorization: Bearer ftk_your_key_here"Czy spust niestandardowy wykorzystuje limit przewidziany w moim planie?
Tak, i zlicza on każde zdarzenie, które analizuje - nie tylko te, w związku z którymi uruchamia się kod. Jeśli Państwa wyzwalacz nasłuchuje zdarzenia „Aktualizacja produktu”, a w Państwa sklepie występuje 60 000 aktualizacji produktów miesięcznie, oznacza to 60 000 zdarzeń, nawet jeśli Państwa kod uruchamia się tylko w przypadku 100 z nich.
Otrzymujemy każde z tych zdarzeń, usuwamy duplikaty i umieszczamy je w kolejce, a następnie uruchamiamy Państwa kod w izolowanym środowisku testowym - wszystko to jeszcze zanim Państwa kod podejmie decyzję o jego uruchomieniu. Liczba ta odzwierciedla ten nakład pracy.
Innymi słowy: kosztuje to tyle samo, ile kosztowałby wbudowany wyzwalacz dla tego samego zdarzenia. Nie ponoszą Państwo dodatkowych opłat za filtrowanie, a testowanie jest zawsze bezpłatne. Zaplanowany wyzwalacz jest liczony raz na cykl działania.
Czy badanie jest bezpłatne?
Tak. Zarówno przycisk Uruchom test w aplikacji, jak i punkt końcowy API /test stanowią wyjątek, mimo że opcja „Uruchom test” faktycznie uruchamia Państwa przepływ pracy w Shopify Flow, dzięki czemu mogą Państwo obserwować jego przebieg. Państwa limit jest wykorzystywany wyłącznie podczas rzeczywistych uruchomień, więc mogą Państwo dowolnie powtarzać przetwarzanie danych.
Dlaczego pole `payload._changes` jest puste?
Albo aktualizacja dotyczyła pól nieobjętych monitorowaniem - na przykład zmiany stanu magazynowego lub wariantu produktu - albo aplikacja nie posiada jeszcze wartości bazowej dla tego rekordu. Wartość bazowa jest zapisywana przy pierwszym wykryciu rekordu przez aplikację, więc pierwsza aktualizacja rekordu, którego aplikacja nigdy wcześniej nie widziała, nie zawiera żadnej poprzedniej wartości. Każda kolejna aktualizacja już ją zawiera.
Czy mój kod może zmieniać dane w moim sklepie?
Nie. ctx.shopify działa w oparciu o przyznane przez Państwa uprawnienia do odczytu, a aplikacja nigdy nie prosi o uprawnienia do zapisu. Jest to zamierzone działanie: wyzwalacz, który edytuje rekord, którego nasłuchuje, uruchamia się ponownie, co stanowi pętlę, z powodu której Shopify wyłącza przepływy pracy. Proszę wprowadzać zmiany w danych w działaniach Shopify Flow, które następują po wyzwalaczu.
Czy mogę później wymienić klamkę?
Nie, i jest to zamierzone. Pański przepływ pracy w Shopify Flow stosuje filtrowanie na podstawie identyfikatora, więc jego zmiana spowodowałaby ciche wstrzymanie działania tego przepływu. Mogą Państwo dowolnie zmieniać nazwę wyzwalacza - identyfikator pozostaje niezmieniony.
Nazwa użytkownika stanowi również nazwę pliku w Państwa repozytorium na GitHubie, więc ona również nigdy się nie zmienia.
Co się stanie, jeśli mój kod zawiera błąd?
Zdarzenie zostaje pominięte, a błąd jest rejestrowany w wyzwalaczu, dzięki czemu można sprawdzić, co poszło nie tak. Nieudana transformacja nigdy nie blokuje żadnych innych operacji - pozostałe wyzwalacze, zarówno niestandardowe, jak i wbudowane, działają dalej bez zakłóceń.
Gdzie wykonywany jest mój kod?
W izolowanym środowisku testowym, oddzielonym od reszty aplikacji, z krótkim limitem czasowym i bez dostępu do danych uwierzytelniających Państwa sklepu. Dostępne są wyłącznie dane zdarzenia, które Państwo przechwycili, oraz informacje pobrane za pomocą ctx.shopify lub ctx.fetch.
Co się stanie, jeśli będę edytować plik jednocześnie w serwisie GitHub i w aplikacji?
Wygrywa ta operacja, którą zapiszą Państwo jako ostatnią. Zapisanie w aplikacji powoduje zatwierdzenie zmian w pliku, a przesłanie zmian do podłączonej gałęzi nadpisuje kod przechowywany w aplikacji. Jeśli pracują Państwo głównie w swoim repozytorium, proszę traktować edytor w aplikacji jako dostępny wyłącznie do odczytu, aby uniknąć nieoczekiwanych sytuacji.
Czy plik znajdujący się w moim repozytorium może utworzyć nowy wyzwalacz?
Nie. Wyzwalacz musi również wiedzieć, na które zdarzenie w Shopify ma nasłuchiwać, a plik zawiera wyłącznie kod - zgadywanie, jakie to zdarzenie, spowodowałoby powiązanie go z niewłaściwym elementem. Proszę najpierw utworzyć wyzwalacz w aplikacji, a następnie swobodnie edytować jego plik.
Czy może on wyzwalać się w przypadku zdarzeń, których aplikacja jeszcze nie otrzymuje?
Nie. Wyzwalacz niestandardowy monitoruje zdarzenia, na które aplikacja jest już subskrybowana w Państwa sklepie, co zależy od przyznanych przez Państwa uprawnień. Po przyznaniu uprawnienia do danego zasobu jego zdarzenia stają się dostępne również dla wyzwalaczy niestandardowych. W pozostałych przypadkach należy uruchamiać je zgodnie z harmonogramem.
Kolejne kroki
- Interfejs API dla programistów, MCP, GitHub oraz symulacja wyzwalaczy - zarządzanie i testowanie wyzwalaczy z poziomu własnego kodu lub asystenta AI.
- Wygeneruj kod wyzwalacza za pomocą sztucznej inteligencji - opisz wyzwalacz prostym językiem, a sztuczna inteligencja napisze kod.
- Plany i sposób użytkowania - co uznaje się za zdarzenie i na jakich zasadach działa limit.
- Jak działają wyzwalacze - wbudowane wyzwalacze i sposób ich uruchamiania.
