Özel tetikleyiciler
Öncesi ve sonrası değerlerini gören JavaScript koduyla, yalnızca istediğiniz koşulda çalışan özel Shopify Flow tetikleyicileri oluşturun.
Yerleşik tetikleyiciler, çoğu mağazanın önem verdiği değişiklikleri kapsar. Geri kalanları ise özel tetikleyiciler halleder: Bir Shopify olayı seçersiniz, bunun önemli olup olmadığını ve ne gönderileceğini belirlemek için birkaç satır JavaScript yazarsınız; böylece bu, Shopify Flow’da kullanabileceğiniz bir tetikleyici haline gelir.
Yerleşik bir tetikleyicinin çözemediği üç sorunu çözer:
- Sadece sizin belirlediğiniz koşulda ateşle. “Yalnızca 500 EUR’dan fazla olan siparişlere
vipetiketi verilir” ifadesi, her siparişte çalıştırılıp ardından filtreleme yapan bir iş akışı yerine tek bir kod satırıdır. - Değişim anında tetikleyin, durum anında değil. Kodunuz, değişimin öncesindeki ve sonrasındaki değeri görür; dolayısıyla “durum taslak’tan aktif’e geçti” veya “stok seviyesi 5’in altına düştü” gibi ifadeler mümkündür. Mevcut değere dayalı bir koşul ise bunu ifade edemez.
- Tam olarak istediğiniz alanları gönderin. Verileri tek tek geri okumak yerine, olayı iş akışınızın gerçekten kullandığı değerlere göre yeniden yapılandırın.
Özel bir tetikleyici, Shopify olayına bile ihtiyaç duymaz: ayrıca zamanlanmış olarak çalışabilir ve neyin değiştiğine kendisi karar verebilir.
Nasıl çalışır?
- Çalışmasını sağlayacak seçeneği belirleyin: tek bir Shopify olayı mı, yoksa bir zamanlama mı?
- Bir olay için, uygulamanın halihazırda aldığı herhangi bir Shopify olayını seçin ya da olayı seçip kodu dolduran bir şablondan başlayın.
- Gerçek bir veri yükünü yakalayın. Mağazanızda bu değişikliği yapın; uygulama, olay gövdesinin tam içeriğini yakalayacaktır.
- Bir dönüştürme işlevi yazın - tetiklemek için bir nesne döndürün, atlamak iç
nulldöndürün. - Bunu yakalanan olayla karşılaştırarak, iş akışınızın tam olarak ne alacağını görün.
- Açın.

Dönüşümün yazılması
Tetikleyiciniz, transform adlı bir işlevi dışa aktaran bir JavaScript modülüdür. Bu işlev dört argüman alır:
payload- Shopify olay gövdesinin işlenmemiş hali, tam olarak geldiği şekliyle.topic- hangi olayın tetiklendiği; örneğinPRODUCTS_UPDATE.shop- myshopify alan adınız.ctx-ctx.log(...), düzenleyicinin yanındaki günlük paneline çıktı verir;ctx.shopify(...), bir Admin GraphQL sorgusu çalıştırır;ctx.fetch(...)ise genel internetteki bir URL’yi çağırır.
Ne geri döndürdüğünüz, ne olacağını belirler:
- Bir nesne döndürüldüğünde tetikleyici devreye girer ve bu nesneyi taşır.
nulldeğerini döndürürseniz olay atlanır. Filtreleme işte bu şekilde çalışır - öğrenilmesi gereken ayrı bir filtre dili yoktur.- Dosyayı boş bırakırsanız, o türdeki her olayda tetiklenir.
/**
* 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,
};
}Değişiklikten önceki değer
Shopify
Ürün Güncellemesi, Sipariş Güncellemesi ve Müşteri Güncellemesi işlemlerinde, payload._changes bu güncellemeyle değiştirilen tüm izlenen alanları listeler; her birinin yanında oldValue ve newValue değerleri bulunur:
- Ürünler:
title,handle,description,status,vendor,productType,tags - Siparişler:
financialStatus,fulfillmentStatus,tags,note,lineItemsvecustomAttributes.<name> - Müşteriler:
tags,note,state(ENABLED,DISABLED,INVITED,DECLINED)
Güncelleme bu alanların dışında yapıldığında - örneğin, bir envanter değişikliği - ya da uygulama kaydı ilk kez gördüğünde liste boştur. Düzenleyicide yakaladığınız örnek olay, ilgili alanı gösterir; böylece bu alana veri yazmadan önce gerçek yapısını görebilirsiniz.
/**
* 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,
};
}Daha spesifik olaylar kendi eski ve yeni değerlerini barındırır; bu nedenle orada _changes’e ihtiyacınız yoktur: bir fiyat değişikliğinde oldPrice, newPrice ve percentChange değerleri bulunur; bir stok değişikliğinde _oldAvailable, _newAvailable ve _delta değerleri bulunur; bir meta alan değişikliğinde ise metafield.value değerinin yanında previousValue değeri bulunur.
Bir şablondan başlayın
Düzenleyicide Fires on seçeneği altında, Şablondan başla seçeneği olayı seçer ve çalışan kodu doldurur. En üstteki sabitleri düzenleyin, test edin, ardından kaydedin. Her şablon, değişiklikten önce ve sonra bir değer okur:
- Bir ürün, sipariş veya müşteri alanı bir değerden başka bir değere değişti - durum “taslak”tan “aktif”e geçti, bir sipariş “ödenmiş” hale geldi, bir hesap “etkin” hale geldi.
- Fiyat N yüzde'den fazla düştü - bu gerçek bir indirimdir, her fiyat değişikliği değildir.
- Hisse senedi belirli bir eşiğin altına düştü - bu durum, hisse senedinin çizgiyi aştığı anda bir kez tetiklenir; hisse senedi zaten düşük seviyedeyken her satışta tetiklenmez.
- Ürün meta alanı değeri bir eşiği aştı - bir puan 3'ün altına düştü, bir marj ise 40'ın üzerine çıktı.
- Yüksek değerli bir müşteri tarafından ödenen sipariş - müşterinin mağazanızdaki toplam harcama tutarını okur ve yalnızca belirlediğiniz tutarın üzerinde siparişler için tetiklenir.

ctx.shopify ile ek verilerin alınması
Webhook gövdeleri yalnızca Shopify’ın gönderdiği alanları içerir. Başka bir şeye ihtiyacınız olduğunda - bir müşterinin sipariş sayısı, bir varyantın stok durumu, bir meta alan gibi - dönüştürme işleminizden doğrudan Admin API’sine sorgu gönderin:
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,
};
}Sorgunun data değerini döndürür; sorguda hata varsa bir istisna oluşturur, böylece testinizde hiçbir çıktı üretilmeden sessizce sonlanmak yerine hata görünür.
Bilmeniz gereken üç sınır:
- Her çalıştırmada en fazla 10 çağrı. Veri zenginleştirme için bir avuç kadar yeter; bundan fazlası genellikle bir döngü anlamına gelir. Mümkün olduğunda ihtiyacınız olanı tek bir sorguyla alın.
- Uygulama okur, yazmaz. Verdiğiniz izinleri kullanır ve uygulama yalnızca okuma erişimi ister. “İzinler” sayfasında “Sipariş Verilerine Erişim” izni verilmedikçe, sipariş verilerine yönelik sorgu başarısız olur. Mağazanızda bir değişiklik yapmak istiyorsanız, bunu tetikleyicinin ardından gelen Shopify Flow eylemlerinde gerçekleştirin.
- Mağazanızın kimlik bilgileri hiçbir zaman kodunuza ulaşmaz. Sorgu, uygulama tarafından sizin adınıza yürütülür; dolayısıyla sanal ortamda sızabilecek bir erişim jetonu bulunmaz.
ctx.fetch(url, options), genel internetteki her şey için (bir tedarikçinin stok verileri, döviz kuru, kendi API’niz gibi) tarayıcının fetch işlevi gibi çalışır. Dahili ve özel ağ adresleri kabul edilmez. Tetikleyici kodunuz GitHub’a kaydedilmişse, içine API anahtarı eklemeyin.
Zamanlanmış olarak çalışan tetikleyiciler
Shopify Flow, bir olay gerçekleştiğinde tepki verir. Bir olay gerçekleşmediğinde tepki veremez ve mağazanızın dışındaki hiçbir şeyi algılayamaz. Bunun için, Bu işlemin ne zaman çalıştırılacağı bölümünden **Zamanlamaya göre **seçeneğini seçin. Böyle bir tetikleyicinin arkasında herhangi bir Shopify olayı yoktur: kodunuz, her 30 saniyeden günde bir kez olmak üzere belirli aralıklarla çalışır ve neyin bir değişiklik olarak kabul edileceğine kendisi karar verir.
Bu, farklı bir transform ve farklı bir payload ile aynı transform işlevidir:
payload.state- kodunuzun bir önceki çalıştırılmasındastateolarak döndürdüğü değer. İlk çalıştırmadanull.payload.nowvepayload.lastRunAt- zaman damgaları.{ state, events }değerini döndür: hatırlanacak yeni durum (en fazla 32 KB) ve tetiklenecek olayların listesi (her çalıştırmada en fazla 100 adet). Her olay, Özel Tetikleyiciyi bir kez tetikler; bir olayınresourceIddeğeri (eğer ayarlanmışsa), Shopify Flow’da kayıt kimliği olur. Raporlanacak bir şey olmadığındanulldeğerini döndür.
İlk çalıştırmada sadece hatırla, asla tetikleme. İlk çalıştırmada kodunuzun karşılaştıracak bir şeyi yoktur, bu yüzden her şey yeni görünecektir. Gördüklerinizi kaydedin ve hiçbir olay döndürmeyin; tetikleyiciyi açık konuma getirmeniz iş akışlarınızı asla aşırı yüklemez. Tüm şablonlar bu şekilde çalışır.

// 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 }],
}
}Zamanlanmış tetikleyiciler için şablonlar, Zamanlama kartındaki Şablondan başla seçeneği altında:
- N gündür güncellenmemiş ürün, sipariş veya müşteri - güncelliğini yitirmiş katalog incelemeleri, takılmış siparişler, müşteri geri kazanımı. Her kayıt, hareketsiz kalınan her dönem için bir kez tetiklenir; özelliği etkinleştirdiğinizde zaten vadesi geçmiş olan kayıtlar ise tek seferde tetiklenmez.
- Shopify dışındaki bir değerde değişiklik oldu - bir tedarikçi stok verisi, bir döviz kuru, bir fiyat listesi; sayılarla ilgili fark ve yüzde değerleri.
- RSS veya Atom beslemesindeki yeni öğe - tedarikçi haberleri, ürün listesi beslemesi, durum sayfası.
- N saat boyunca sipariş gelmediğinde - mağazanızın nabzı. Siparişler durduğunda bir kez, yeniden başladığında bir kez tetiklenir.
Test, kodunuzu hiçbir işlemi tetiklemeden ve durumu kaydetmeden tek seferlik çalıştırır; böylece istediğiniz sıklıkta çalıştırabilirsiniz.
Shopify Flow'da kullanma
Her özel tetikleyici, Shopify Flow’da aynı tetikleyici olarak görünür: Özel Tetikleyici. Bunu bir iş akışına ekleyin, ardından “Tetikleyici tanıtıcısı, tetikleyicinizin tanıtıcısına eşittir” koşulunu ekleyin.
Bu ad, tetikleyicinin sayfasında gösterilir ve tetikleyicinin adını değiştirseniz bile asla değişmez; böylece iş akışınız kesintisiz bir şekilde devam eder.
Dönüşümünüzün döndürdüğü her anahtar, tetikleyicide bir alan haline gelir; ayrıca, nesneyi kendiniz ayrıştırmak isterseniz, nesnenin tamamı JSON biçiminde de kullanılabilir.
Kodu GitHub’da saklayın
Bir GitHub deposu bağlayarak tetikleyici kodunuzun sürüm kontrolü altında kalmasını sağlayabilirsiniz. Değişiklikler bir çekme isteğinde incelenebilir hale gelir; kimin neyi değiştirdiğini görebilir ve artık çalışmayan bir dönüştürmeyi geri alabilirsiniz.
Bunu, Geliştirici sayfasındaki Bağlantılar bölümünden bağlayın. Uygulamanın hangi depolara erişebileceğini siz seçersiniz ve bu erişimi GitHub’dan istediğiniz zaman iptal edebilirsiniz.
Bir depo seçildiğinde, mevcut tüm tetikleyiciler derhal bu depoya kaydedilir ve her iki yönde de senkronizasyon korunur:
| Ne yapıyorsunuz? | Ne olur? |
|---|---|
| Uygulamada bir tetikleyici oluşturun, düzenleyin veya kopyalayın | Dosya, deponuza kaydedildi |
| Uygulamada bir tetikleyiciyi silme | Dosya, deponuzdan kaldırıldı |
| Bağlı dalda bir değişikliği kaydet | Uygulamada tetikleyicinin kodu güncellendi |
Her tetikleyici, kendi tanıtıcısının adını taşıyan tek bir dosyadır ve bu dosya, düzenleyicide gördüğünüz modülü tam olarak içerir; etrafında hiçbir ek unsur bulunmaz. Bu sayede, dosyayı kendi düzenleyicinizde açabilir, çalıştırabilir ve diğer JavaScript dosyaları gibi hatalarını kontrol edebilirsiniz.
Daha önceki bir sürüme dönmek
Bir değişikliği geri almak için Git'i bilmenize gerek yoktur. Bir depo bağlandığında, düzenleyicide o dosyanın tarihi ve yazarıyla birlikte önceki tüm sürümlerini listeleyen bir Sürüm açılır menüsü görünür. Bunlardan birini seçtiğinizde, dosya düzenleniciye kaydedilmemiş bir değişiklik olarak yüklenir; böylece önce içeriğini okuyabilirsiniz - kaydetme işlemi, dosyayı eski haline getirir.
Yerel olarak düzenlerken test edin
Dosyayı kendi düzenleyicinizde düzenliyorsanız, dosyayı önce uygulamaya kaydetmeden yakalanan örnek olay üzerinde çalıştırabilirsiniz. Geliştirici sayfasından execute düzeyine sahip bir API anahtarı kullanın:
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}')"Uygulamanın “Test” düğmesinde gösterilenle aynı sonucu alırsınız: komutun çalışıp çalışmayacağı, çıktı nesnesi, ctx.log satırlarınız ve çalışma süresi.
Bu uç nokta hiçbir işlemi tetiklemez ve hiçbir şeyi kaydetmez; ayrıca herhangi bir plan kotası kullanmaz - bu nedenle, bir dosya izleyicisi tarafından yapılan her kaydetme işleminde güvenle çalıştırılabilir. (Uygulama içindeki Testi Çalıştır düğmesi, Shopify Flow iş akışınızı tetikler; böylece iş akışının baştan sona çalışmasını izleyebilirsiniz; bu da ücretsizdir.)
Ayrıca, bir okuma anahtarı kullanarak örnek yükü tek başına alabilir, yerel olarak kaydedebilir ve dosyayı tamamen çevrimdışı olarak çalıştırabilirsiniz:
curl https://shopify.workflow-trigger-extensions.app/api/v1/triggers/custom/high-value-vip-order/test \
-H "Authorization: Bearer ftk_your_key_here"Özel bir tetikleyici, planımdaki kotamı tüketir mi?
Evet, ve tetikleyici, yalnızca üzerinde tetiklenen olayları değil, incelediği her olayı sayar. Tetikleyiciniz “Ürün Güncellemesi” olayını dinliyorsa ve mağazanızda ayda 60.000 ürün güncellemesi gerçekleşiyorsa, kodunuz bunlardan sadece 100’ünde tetiklense bile bu sayı 60.000 olay anlamına gelir.
Bu olayların her birini alıyoruz, tekilleştiriyoruz ve sıraya koyuyoruz; ardından kodunuzun tetiklenip tetiklenmeyeceğine karar vermeden önce, kodunuzu izole edilmiş bir sanal ortamda çalıştırıyoruz. Bu sayı, söz konusu işleme ilişkin verileri yansıtmaktadır.
Başka bir deyişle: Aynı olay için yerleşik tetikleyicinin maliyeti ne olsaydı, bu da o kadar tutar. Filtreleme için ek ücret alınmaz ve testler her zaman ücretsizdir. Zamanlanmış bir tetikleyici, her çalıştırmada bir kez sayılır.
Test ücretsiz mi?
Evet. Uygulamadaki Testi Çalıştır düğmesi ve /test API uç noktası, her ikisi de kotanızdan düşmez; oysa “Testi Çalıştır” seçeneği, Shopify Flow iş akışınızı gerçekten tetikleyerek çalışmasını izlemenizi sağlar. Yalnızca canlı yürütmeler kotanızdan düşer; bu sayede bir dönüştürme işlemini istediğiniz kadar tekrarlayabilirsiniz.
payload._changes neden boş?
Ya güncelleme izlenen alanların dışında kalmıştır - örneğin, bir üründe envanter veya varyant değişikliği - ya da uygulamanın o kayıt için henüz bir referans değeri yoktur. Referans değeri, uygulama bir kaydı ilk kez gördüğünde kaydedilir; bu nedenle, daha önce hiç görmediği bir kaydın ilk güncellemesinde eski değer bulunmaz. Bundan sonraki her güncellemede ise eski değer bulunur.
Kodum, mağazamdaki verileri değiştirebilir mi?
Hayır. ctx.shopify, sizin verdiğiniz okuma izinleriyle çalışır ve uygulama hiçbir zaman yazma erişimi talep etmez. Bu kasıtlı bir durumdur: Dinlediği kaydı düzenleyen bir tetikleyici, kendisini yeniden başlatır; bu da Shopify’un iş akışlarını devre dışı bırakmasına neden olan döngüdür. Verileri, tetikleyicinin ardından gelen Shopify Flow eylemlerinde değiştirin.
Kolu daha sonra değiştirebilir miyim?
Hayır, ve bu kasıtlı olarak yapılmıştır. Shopify Flow’daki iş akışınız, “handle” değerine göre filtreleme yapar; dolayısıyla bu değeri değiştirirseniz, iş akışının çalışması fark edilmeden durdurulur. Tetikleyicinin adını istediğiniz gibi değiştirebilirsiniz; ancak “handle” değeri değişmez.
Bu kullanıcı adı aynı zamanda GitHub deponuzdaki dosya adıdır; dolayısıyla o da asla değişmez.
Kodumda bir hata olursa ne olur?
Olay atlanır ve hata tetikleyicide kaydedilir; böylece neyin ters gittiğini görebilirsiniz. Başarısız olan bir dönüştürme işlemi hiçbir zaman başka bir şeyi engellemez - diğer tetikleyicileriniz, ister özel ister yerleşik olsun, bundan etkilenmeden çalışmaya devam eder.
Kodum nerede çalışıyor?
Uygulamanın geri kalanından ayrı, izole bir sanal ortamda; kısa bir zaman sınırı dahilinde ve mağazanızın kimlik bilgilerine erişim olmaksızın çalışır. Yalnızca yakaladığınız olay yükünü ve ctx.shopify veya ctx.fetch ile aldığınız verileri görür.
Ya dosyayı hem GitHub’da hem de uygulamada aynı anda düzenlersem ne olur?
En son kaydettiğiniz versiyon geçerli olur. Uygulamada kaydetme işlemi dosyaya kaydedilir ve bağlı dala gönderme işlemi, uygulamada bulunan kodun üzerine yazar. Çoğunlukla deponuzda çalışıyorsanız, beklenmedik durumlarla karşılaşmamak için uygulamanın düzenleyicisini salt okunur olarak değerlendirin.
Depomdaki bir dosya yeni bir tetikleyici oluşturabilir mi?
Hayır. Bir tetikleyicinin hangi Shopify olayını dinlediğini de bilmesi gerekir ve dosya yalnızca kod içerir; olayı tahmin etmek, tetikleyicinin yanlış bir şeye bağlanmasına neden olur. Önce uygulamada tetikleyiciyi oluşturun, ardından dosyasını istediğiniz gibi düzenleyin.
Uygulamanın henüz almadığı olaylara karşı tetiklenebilir mi?
Hayır. Özel bir tetikleyici, uygulamanın mağazanız için halihazırda abone olduğu olayları izler; bu durum, verdiğiniz izinlere bağlıdır. Bir kaynağa izin verdiğinizde, o kaynağın olayları özel tetikleyiciler tarafından da kullanılabilir hale gelir. Diğer her şey için ise zamanlanmış bir işlem olarak çalıştırın.
Sonraki adımlar
- Geliştirici API'si, MCP, GitHub ve tetikleyici simülasyonu - Kendi kodunuzdan veya bir yapay zeka asistanından tetikleyicileri yönetin ve test edin.
- AI ile tetikleyici kodu oluştur - Tetikleyiciyi sade bir dille açıklayın ve kodun yazılmasını yapay zekaya bırakın.
- Planlar ve kullanım - Neyin bir olay olarak kabul edildiği ve kotanın nasıl işlediği.
- Tetikleyiciler nasıl çalışır? - yerleşik tetikleyiciler ve nasıl tetiklendikleri.
