バリエーションの価格変更時に、バンドルの価格を自動同期する
コンポーネントのバリエーション価格が変更された際に、Shopify Flow を使用して、Shopifyのバンドルバリエーション価格を自動更新します。
(Shopify)の**「Bundles」**アプリ()を使用して商品バンドルを作成する場合、構成商品の商品バリエーション価格を変更しても、バンドル商品の商品バリエーション価格は自動的に更新されません。(Workflow Trigger Extensions)の「Product Variant Price Changed」トリガーは、価格の変更を検知し、バンドルの商品バリエーション価格を自動的に再計算・更新することで、この問題を解決します。
**「商品バリエーションの価格変更」**トリガーを使用して、バンドル価格を同期させる方法を理解するために、以下のシナリオを想定します。
シナリオ:コンポーネントのバリエーション価格が変更された際に、バンドル価格を自動更新する
Shopifyの「Bundles」アプリを使用して作成されたバンドル商品(例:Tシャツのバンドル)があると想像してください。このバンドルには、「黒のTシャツ」、「灰色のTシャツ」、「白のTシャツ」という3つの構成商品が含まれており、各バリエーションの価格は10.00ユーロです。 バンドルのバリエーション価格は30.00ユーロ(構成商品の価格の合計)です。構成商品のバリエーション価格を変更すると、このShopify Flowによって対応するバンドルのバリエーション価格が自動的に更新されます。
アプリの設定 → 「商品バリエーション」 → 「バリエーション価格の変更」から、このトリガーを有効にしてください。
商品バリエーションの価格が変更されました
親バンドル商品を取得し、更新後のバリエーション価格を算出し、Admin API を通じてバンドルのバリエーション価格を一括更新します
動画ガイド
この動画でも、手順を視覚的に確認することができます(動画には音声がありません。必要に応じて再生速度を調整できます)。
このShopify Flowをどのように進めていくか
設定について
- 当社には、S、M、L、XL、2XLのバリエーションがあり、それぞれ10.00ユーロで販売されている商品(例:グレーのTシャツ)があります。
- 弊社では、「Shopify Bundles」アプリを使用して作成したバンドル商品があります。このバンドル商品には、3つの商品(黒のTシャツ、灰色のTシャツ、白のTシャツ)が含まれており、それぞれに5つのバリエーションがあります。バンドルのバリエーション価格は30.00ユーロです(構成商品の価格の合計:3 × 10.00ユーロ)。
ここをクリックすると、手順を視覚的に確認できます:
- Workflow Trigger Extensions で、「トリガー」を開き、「価格」を検索して、「商品バリエーションの価格変更」を有効にしてください。これには「商品」、「バリエーション」、「コレクション」のデータアクセス権が必要です。権限が不足している場合は、アプリから権限の付与を求められます。
- 「Shopify Flow」アプリから新しい空白のワークフローを作成し、「Workflow Trigger Extensions」アプリから「**商品バリエーション価格変更」**トリガーを選択してください
- 「商品データを取得」アクションを追加し、高度なクエリを使用して、「作成日時」を昇順で並べ替えた変更後の商品を取得します。このステップでは、
productParentsフィールドを介して、商品の親バンドル情報を取得します。クエリは次のようになります:id:{{productVariant.product.id | split: "gid://shopify/Product/" | last}} - 「**コードを実行」**ステップを追加し、「
getProductData」の結果から親バンドルの商品IDを抽出します。このコードは、productParentsから親商品のIDを抽出し、クエリ用にidsConditionという文字列を生成します。
「コードの実行」ステップでは、親製品のIDを取得するために、以下のGraphQL入力、JavaScriptコード、および出力を使用します:
GraphQLの入力、JavaScriptコード、およびプレビュー出力が表示される「コードの実行」ステップを実行します


{
getProductData {
productParents {
id
}
}
}export default function main(input) {
const productIds = input.getProductData[0]?.productParents?.map(p => p.id) ?? [];
const productId = productIds[0] ?? null;
const idsCondition = productIds
.map(gid => "id:" + gid.split("gid://shopify/Product/").pop())
.join(" OR ");
return {
productId: productId,
productIds: productIds,
idsCondition: idsCondition,
};
}type Output {
productId: String
productIds: [String!]!
idsCondition: String!
}- 「Run」コードの出力「
productId」が空ではなく、かつ存在するかを確認する「条件」ステップを追加します。これにより、変更された製品が実際にバンドルの一部である場合にのみ、処理が継続されるようになります。 - True → バンドル価格の更新を継続します
- False → 停止(その製品はバンドルの構成要素ではありません)
- 条件が「True」の場合、「**商品データの取得 (1)」**アクションをもう1つ追加し、「コードの実行」ステップの「
idsCondition」を使用して、親バンドル商品のバリエーションおよび価格データを取得します。 - 更新されたコンポーネント価格に基づいて、新しいバンドルバリエーションの価格を計算するために、2つ目の「**コードを実行 (1)」**ステップを追加してください。このステップでは、各バンドルバリエーションの新しい価格を含む
variantPrices配列が出力されます。
この「**コードを実行(1)」**ステップでは、更新されたコンポーネント価格に基づいて、バンドルバリエーションの価格を再計算します。その処理内容は以下の通りです。まず、トリガーから2つの重要な情報を取得します:
changedVariantId先ほど変更されたバリエーション(...158920)newPriceそのバリエーションの新しい価格(11.00)を算出します**。その後、すべてのバンドルバリエーションを順に処理し、その合計価格を再計算します。各バンドルバリエーションには、3つの構成バリエーション(黒のTシャツ、灰色のTシャツ、白のTシャツ)があります。 各構成アイテムについて、次のチェックを行います。「これは先ほど変更されたバリエーションですか?」もし「はい」であれば、Shopify(10.00)にまだ保存されている古い価格の代わりに、newPrice(11.00)を使用します。もし「いいえ」であれば、既存のcomponent.productVariant.price.Itを使用します。構成アイテムの価格を合計して、新しいバンドルバリエーションの価格を算出します。この処理が機能している様子は、出力データでご確認いただけます。 バリエーション...088840をご覧ください。その構成要素には、...158920(変更されたバリエーション)が含まれています。したがって、その価格は 11 + 10 + 10 = 31 となりますが、他のすべてのバンドルバリエーションは、構成要素に変更がないため、合計は依然として 30 のままです。これがこのステップの重要なポイントです。「Shopify」はまだバンドルデータ内の構成要素の価格を更新していないため、コードは既存の価格を単純に合計するだけでは不十分で、変更されたバリエーションの価格をその場で新しい価格に置き換える必要があります。 これを行わないと、すべてのバリエーションが依然として 30 と表示されてしまいます。出力されたvariantPrices配列は、**For eachループに渡され、そこでproductVariantsBulkUpdateが呼び出されて、再計算された価格がバンドル商品に実際に書き戻されます。
{
productVariant {
id
}
priceChange {
oldPrice { amount }
newPrice { amount }
}
getProductData1 {
id
variants {
id
productVariantComponents {
productVariant {
id
price
}
}
}
}
}export default function main(input) {
const changedVariantId = input.productVariant.id;
const newPrice = parseFloat(input.priceChange.newPrice.amount);
const variantPrices = input.getProductData1.flatMap(product =>
product.variants.map(variant => ({
productId: product.id,
id: variant.id,
price: variant.productVariantComponents.reduce((sum, component) => {
const p = component.productVariant.id === changedVariantId
? newPrice
: parseFloat(component.productVariant.price);
return sum + p;
}, 0)
}))
);
return { variantPrices };
}type VariantPrice {
productId: String!
id: String!
price: Float!
}
type Output {
variantPrices: [VariantPrice!]!
}runCode1.variantPrices内の各項目を順に処理する「For each」**ループ(反復処理)**を追加します。各バリエーションの価格について、productVariantsBulkUpdateミューテーションを使用した「Send Admin APIリクエスト」アクションを実行し、バンドルのバリエーション価格を更新します。 この入力は、ミューテーションに使用できます:
{
"variants": [
{
"id": "{{variantPricesForeachitem.id}}",
"price": "{{variantPricesForeachitem.price}}"
}
],
"productId": "{{variantPricesForeachitem.productId}}",
"allowPartialUpdates": true
}全体としてどのように機能するのか
構成商品のバリエーション価格が変更された場合(例:グレーのTシャツ「S」サイズのバリエーション価格を10.00ユーロから15.00ユーロに更新した場合):
- 「**商品バリエーションの価格が変更された」**というトリガーが作動します
- このShopify Flowでは、
productParentsを使用して、製品の親バンドルを取得します。 - 「コードを実行」ステップでは、バンドル製品のIDが抽出されます
- この条件は、この商品がバンドルに含まれているかどうかを確認するものです
- 「はい」の場合、バンドル商品のデータを取得します
- 2回目の「コードを実行」ステップでは、バンドルバリエーションの価格が再計算されます
- このループは各バリエーションを順に処理し、productVariantsBulkUpdate 管理 API ミューテーションを通じてバンドル価格を更新します
バンドルSのバリエーション価格は、30.00ユーロから35.00ユーロ(15.00ユーロ+10.00ユーロ+10.00ユーロ)に更新されます。
