Order / Collection / InventoryItem / InventoryShipment / Location が購読可能に。さらに Product・Order・Customer・Collection・Location の メタフィールド変更そのもの を namespace と key 単位で購読できるようになった。「全更新を受けて自前で差分を取る」handler が要らなくなる。
「この 1 つのメタフィールドが変わったときだけ動きたい」場合でも、リソースの update をまるごと購読し、handler 側でペイロードを差分比較する必要があった。
triggers に対象のメタフィールドを書けば、その値が変わったときだけイベントが飛ぶ。変わったリソースを自分で query して、必要なデータだけ受け取れる。
| リソース | メタフィールド購読 | 備考 |
|---|---|---|
| Product | 対応 | ProductVariant のメタフィールドも Product トピック経由でサポート |
| Order | 対応 | — |
| Customer | 対応 | — |
| Collection | 対応 | — |
| Location | 対応 | — |
| 上記以外 | 未対応 | 未対応トピックは引き続き webhooks を併用する(同じ shopify.app.toml 内で共存可) |
$app メタフィールドも通常のメタフィールドも、どちらもサポート対象。アプリ予約の namespace と、マーチャントが定義した custom 等の namespace を同じ subscription で並べて指定できる。query_variables。「どのメタフィールドが変わったか」が変数としてクエリに渡るので、1 つのクエリ定義で複数のメタフィールドを使い回せる。トリガーごとにクエリを書き分ける必要がない。公式が示している「Product の 2 つのメタフィールドを狙い撃ちし、実際に変わった方を query_variables で取得する」例。
[events] api_version = "unstable" [[events.subscription]] handle = "product_material_sync" topic = "Product" actions = ["update"] triggers = [ "product.metafield(namespace: 'custom', key: 'material').value", "product.metafield(namespace: '$app', key: 'sourcing_status').value" ] uri = "/events/product" query = """ query ProductMetafieldSync( $productId: ID! $metafieldNamespace: String! $metafieldKey: String! ) { product(id: $productId) { id title metafield(namespace: $metafieldNamespace, key: $metafieldKey) { namespace key value type } } } """
product.metafield(namespace: …, key: …).value という形。custom のような通常の namespace と $app を同じ配列に並べられる。
GraphQL クエリを toml 内に書いて、ペイロードの形をアプリ側で決める。namespace / key を変数化しておけば複数トリガーで共用できる。
この例では actions = ["update"]。handle はペイロードにもそのまま入るので、ルーティングの識別子として使える。
上記の設定で custom.material が変わったときに届くペイロード。
{
"topic": "Product",
"action": "update",
"handle": "product_material_sync",
"data": {
"product": {
"id": "gid://shopify/Product/1234567890",
"title": "Canvas Tote",
"metafield": {
"namespace": "custom",
"key": "material",
"value": "Cotton",
"type": "single_line_text_field"
}
}
},
"fields_changed": [
"product.metafield(namespace: 'custom', key: 'material').value"
],
"query_variables": {
"productId": "gid://shopify/Product/1234567890",
"metafieldNamespace": "custom",
"metafieldKey": "material"
}
}
| キー | 中身 | handler での使いどころ |
|---|---|---|
topic / action | Product / update | 大枠の振り分け |
handle | subscription の handle | どの購読設定由来かの識別 |
data | toml に書いた query の結果 | そのまま業務処理に投入できる |
fields_changed | 実際に変わったフィールドパスの配列 | 複数トリガーを 1 subscription に束ねたときの分岐 |
query_variables | クエリに渡された変数の実値 | ログ・冪等キー・再取得時の入力として再利用 |
対応リソースのメタフィールド変更イベントも 受け取るようになる。取りこぼしは無いが通知量は最大。
親を指定した場合も、同様にメタフィールド変更イベントが届く。既存の購読設定のまま範囲が広がる形。
namespace と key を明示した metafield トリガーを追加すると、その変更だけを受け取る。通知量は最小。
アプリがそのメタフィールドへのアクセス権を持っていることが、購読とデータ受信の条件。権限が無ければ購読もクエリ結果の受け取りもできない。
Events は開発者プレビュー中で、unstable API バージョンでのみ利用可能。安定版での提供時期は記載なし。
まだ Events が対応していないトピックは、これまで通り webhooks を使う。同じ shopify.app.toml の中で Events と webhooks を並記するのが公式の案内。
バリアントのメタフィールドに独立したトピックがあるわけではなく、Product トピックを通じてサポートされる。購読設定は Product 側に書く。
これまで handler 内にあった「前回値をどこかに保持して比較する」ロジックが不要になる。状態を持つ受信側から、状態を持たない受信側へ。KVS への前回値キャッシュを撤去できる余地がある。
query_variables でクエリを共通化できるnamespace / key を変数として受け取れるので、複数のメタフィールドトリガーを 1 つのクエリ定義でさばける。トリガーが増えても toml が線形に膨らまない。
$app と通常 namespace を混在できるアプリ専用の $app メタフィールドと、マーチャント側の custom を同じ triggers 配列に書ける。「アプリの内部状態」と「マーチャントの入力」を同じ経路で拾える。
アクセス権が無いメタフィールドは購読もデータ取得もできない。スコープ/メタフィールドアクセスの申請漏れが「イベントが飛んでこない」という形で表面化するので、切り分け時はまず権限を疑う。
triggers 無し、あるいは product のような親トリガーで購読しているアプリは、今回の変更でメタフィールド変更でも呼ばれるようになる。エンドポイントの呼び出し回数・課金・ジョブキューの流入量が想定より増える可能性があるため、リリース後は受信量をモニタし、必要ならターゲット指定に絞り込む。
triggers にターゲット指定し、query で変更されたメタフィールドの値と型だけを取得。fields_changed で連携先のどのカラムを更新するか分岐する。$app メタフィールドを使えばアプリ自身が書いたステータス遷移も同じ仕組みで拾える。query で必要な項目を最初から取得する形に置き換える。未対応トピックは webhooks を同じ shopify.app.toml に残して併用する。shopify.dev/docs/api/events/latest/intentory-item
※ 原文記載のままの URL(原文に intentory-item という表記あり)