Shopify アプリを開発していると、Webhook は避けて通れない仕組みである。商品が更新された、注文が作成された、顧客情報が変更された、など、 Shopify 側の変化を外部アプリへ伝えるために、多くの連携処理が Webhook を起点に作られている。
一方で、従来の Webhook には扱いづらさもあった。たとえば Webhook の商品の更新イベント(products/update)を受信すると、商品のタイトルが変わっても、説明文が変わっても、価格が変わっても同じように通知が届く。外部アプリ側では毎回ペイロードを受け取り、「今回の変更は本当に処理対象なのか」を判定しなければならない。
Shopify が Developer Preview として公開し、6月18日の Shopify Editions でも発表された Next Generation Events は、この課題に対する新しいイベント受信の仕組みである。Webhook が単に Events という名前に変わったわけではない。Shopify 上で発生する出来事を、より細かい条件で受信し、必要な情報だけを受け取れるようにする仕組みと考えると分かりやすい。
参照: Shopify Developer Changelog / 公式ドキュメント
本記事は基本的にはShopifyでアプリを開発しているエンジニアまたはその関係者向けだが、弊社内のビジネス職及びPMスタッフへの共有を兼ねさせていただいているので、少しカジュアルな部分があることはいつも通りのご愛嬌と受け取っていただければ幸い。
Webhook と Events の関係
Shopify の連携開発では、これまで商品更新や注文作成などの変更を外部アプリへ通知する仕組みとして Webhook が使われてきた。アプリは、商品の更新(products/update)や顧客の作成(customers/create)のようなイベントを受信し、Shopify 側で該当する変更が発生すると、指定したエンドポイントへ HTTP リクエストとして通知を受け取る。
今回の Next Generation Events は、この Webhook という通知方式が単に「Events」という名前に変わったものではない。技術的には、Shopify 内で発生する出来事をより細かく受信し、必要な条件を満たしたものだけを、必要なデータ構造で受け取るための新しいイベント受信モデルと捉えるのが自然である。
つまり、Event は Shopify 上で発生した「出来事」そのもの、Webhook はその出来事をアプリへ届けるための「配送手段」である。Next Generation Events では、従来のように固定された Webhook トピックと固定ペイロードを受け取るだけでなく、topic、actions、triggers、query、query_filter を組み合わせて、どの変更を受け取り、どのデータをペイロードに含めるかをアプリ側で定義できる。
前章でも触れたが、従来の Webhook では、商品が更新されるたびに Webhook を受け取り、アプリ側で「価格が変わったのか」「タイトルが変わっただけなのか」等を判定する必要があった。Next Generation Events では、価格フィールドが変わった場合だけ発火するように指定したり、受け取るペイロードを GraphQL クエリで必要最小限に絞ったりできる。
現時点では Developer Preview の機能であり、まだ本番環境での利用を想定したものではない。また、既存 Webhook をすぐに置き換えるものというより、従来 Webhook の制約を解消する新しい受信方式として、用途に応じて共存・移行を検討する段階である。既存 Webhook と Events を同時に設定した場合、同じ変更が両方に届く可能性があるため、導入時には受信経路や重複処理の設計が必要である。
Events でできるようになったこと
細かい話に入る前に、まずできるようになったことを簡単に整理する。
- バーコードや価格など、特定の値が変更された時だけ通知を受け取れる
- 商品ステータスや価格などの条件に基づいて、必要な情報だけを受け取れる
- 通知を受け取った時点で、どこが変わったのかが分かる
- 受け取るペイロードを必要最小限に絞れる
これだけでも、Webhook 連携の設計はかなり変わる。従来は「通知を受け取ってからアプリ側で捨てる」設計になりがちだったが、Next Generation Events では「そもそも不要な通知を受け取らない」設計に近づけることができる。
従来 Webhook の課題
たとえば外部 POS や在庫管理システムと Shopify の商品情報を同期しているケースを考える。連携に必要なのは商品バリエーションのバーコードだけだとする。
従来の Webhook では、商品更新を検知するために商品の更新(products/update)のようなイベントを受信することになる。しかし、この通知はバーコード変更だけでなく、商品名、説明文、タグ、画像、公開ステータスなど、商品に関するさまざまな変更で発火する。
結果として、アプリ側では次のような処理が必要になる。
- Webhook を受信する
- 対象商品やバリエーションの現在値を確認する
- 前回値と比較して、バーコードが変わったかを判定する
- 変更がなければ処理をスキップする
- 必要な場合だけ外部システムへ同期する
この流れは珍しいものではないが、地味に保守コストがかかる。通知数が増えればログも増える。処理対象外のイベントでもエンドポイントは呼ばれる。エラーが起きた時には、本当に重要な失敗なのか、無視してよい通知だったのかを切り分ける必要がある。
こうした「本質的ではない処理」が積み重なると、アプリ実装コードの複雑性は増し、連携システムの見通しは悪くなる。
最小限の設定イメージ
たとえば、商品バリエーションのバーコードが変更された時だけ受け取りたい場合は、次のような Events 通知設定になる。
[[events.subscription]]
handle = "product-barcode-changed"
topic = "Product"
actions = ["update"]
triggers = ["product.variants.barcode"]
uri = "/shopify/events/product-barcode-changed"
query = """
query barcodeChanged($productId: ID!, $variantsId: ID!) {
product(id: $productId) {
id
title
status
}
productVariant(id: $variantsId) {
id
barcode
sku
price
}
}
"""
query_filter = "product.status:'ACTIVE'"
この例では、Product トピックの update アクションのうち、product.variants.barcode が変わった時だけ通知を受け取る。さらに query_filter によって、公開中の商品だけを処理対象にしている。
なお、handle には固有識別のために任意の文字列を入れる。また、topic には対象を、actions にはどのようになった時にチェックするかを設定する。
価格変更を監視したい場合は、triggers に価格系のフィールドを指定する。
[[events.subscription]]
handle = "product-price-changed"
topic = "Product"
actions = ["update"]
triggers = ["product.variants.price",
"product.variants.compareAtPrice"]
uri = "/shopify/events/product-price-changed"
query = """..."""
query_filter = "product.status:'ACTIVE' AND
productVariant.price:>0"
この Events の設定は、2026年6月現在のプレビューでは、Shopify アプリの設定ファイルである shopify.app.toml に記述する。ローカルで設定を書くだけでは Shopify 側には反映されないため、アプリ設定として shopify コマンドを用いて Shopify にデプロイする必要がある。
shopify コマンドは、Shopify が提供しているコマンドラインツール Shopify CLI のことである。Shopify アプリの作成、開発サーバーの起動、設定ファイルの検証、デプロイなどをターミナルから行うためのツールである。
Shopify CLI を使うには、事前に Node.js と Shopify CLI が必要になる。未インストールの場合は、次のようにインストールできる。
npm install -g @shopify/cli@latest
Events の設定を Shopify に反映する最小限の流れは次のようになる。
-
shopify.app.tomlに[[events.subscription]]設定を必要な数だけ追加する -
read_productsやread_customersなど、受信対象に必要なスコープをshopify.app.tomlの[access_scopes]に設定する -
uriに指定した受信エンドポイントをアプリ側に実装する -
shopify app config validate --jsonでアプリ設定に問題がないか確認する - 開発中は
shopify app devで動作確認する - Shopify 側へ反映する場合は
shopify app deployを実行する
スコープについては shopify.app.toml の [access_scopes] にまとめて設定する。たとえば Product トピックを受信する場合は read_products、Customer トピックを受信する場合は read_customers が必要になる。
[access_scopes]
scopes = "read_products,read_customers"
このスコープ設定は、アプリがストア上のどのデータへアクセスできるかを決めるものである。Events の受信設定で Product や Customer を指定していても、対応するスコープが不足していると必要なデータを受け取れない可能性がある。
設定ファイルの検証だけを先に行いたい場合は、次のコマンドを使う。
shopify app config validate --json
Shopify 側へ反映する場合は、次のコマンドを実行する。
shopify app deploy
スコープを追加・変更した場合は、対象ストアでアプリの再承認が必要になることがある。また、Events は Developer Preview の機能であるため、実際のコマンドやサポート状況は公式ドキュメントと Shopify CLI の出力を確認しながら進める必要がある。
Next Generation Events の主なポイント
triggers — 変更フィールドで絞る
update アクションに対して、どのフィールドが変わったときに発火するかを指定できる。複数指定は OR 条件(どれか1つが変われば発火)である。フィルタリングは Shopify サーバー側で行われるため、アプリへの不要なリクエストがゼロになる。
triggers = ["product.variants.price"]
# price だけを指定すれば、タイトル変更・タグ変更では一切発火しない
triggers で指定したフィールドは query に含めることで query_filter の条件としても使用できるが、記法の違いに注意が必要である。triggers は product.variants.price のような topic path 形式、query_filter は query のルートフィールドから始まるパス(productVariant.price 等)を使う。
Product フィールドの一例(read_products スコープが必要)
| フィールドパス | 発火タイミング |
|---|---|
| product.status | 公開ステータス変更(ACTIVE/DRAFT/ARCHIVED) |
| product.tags | タグ変更 |
| product.options | オプション(サイズ・カラー等)変更 |
| product.media | 画像・メディア変更 |
| product.variants | バリアント追加・削除 |
| product.variants.price | バリアント販売価格変更 |
Customer フィールドの一例(read_customers スコープが必要)
| フィールドパス | 発火タイミング |
|---|---|
| customer.defaultEmailAddress | メールアドレス変更 |
| customer.defaultEmailAddress.marketingState | メールマーケティング同意状態変更 |
| customer.defaultEmailAddress.marketingOptInLevel | メールマーケティング同意レベル変更 |
| customer.defaultPhoneNumber.marketingState | SMS マーケティング同意状態変更 |
| customer.defaultPhoneNumber.marketingOptInLevel | SMS マーケティング同意レベル変更 |
| customer.tags | タグ変更 |
| customer.note | メモ変更 |
| customer.amountSpent | 累計購入金額変更 |
| customer.numberOfOrders | 注文件数変更 |
| customer.lastOrder | 最終注文変更 |
| customer.productSubscriberStatus | 商品サブスクリプション状態変更 |
指定できるフィールドの詳細については、公式ドキュメントを確認してみてほしい。
- https://shopify.dev/docs/api/events/latest/product
- https://shopify.dev/docs/api/events/latest/customer
query — ペイロードを定義する
受け取るペイロードを GraphQL クエリで自由に定義できる。固定スキーマに縛られず、必要なフィールドだけ受け取れる。そのため、これまでのような Webhook 受信後の追加 API 呼び出しが不要になる。
query = """
query barcodeChanged($productId: ID!, $variantsId: ID!) {
product(id: $productId) {
id
title
status
}
productVariant(id: $variantsId) {
id
barcode
sku
price
}
}
"""
注意: query の複雑度には上限がある(現在 250 ポイント)。ポイントはフィールド数・取得件数・ネストの深さによって増加する。Admin API の上限(1,000 ポイント)と比べると 1/4 のため、variants(first: 100) のような大量リスト取得は上限を超えやすい。取得フィールドや件数は必要最小限に絞る必要がある。
query_filter — 現在値で破棄する
query 実行後の現在値に基づいてデリバリーを破棄できる。AND / OR 演算子で複合条件も記述可能である。そのため、DRAFT 商品への誤同期リスクをインフラ層で排除できる。
query_filter = "product.status:'ACTIVE' AND
productVariant.price:>0"
# ACTIVE かつ価格が 0 より大きい商品の変更のみ受け取る
新しいペイロード構造(fields_changed)
従来 Webhook は「何が変わったか」がペイロードに含まれず、前回値との差分比較が必要だった。Events では fields_changed に変更されたフィールドパスが明示される。
{
"topic": "Product",
"action": "update",
"handle": "product-barcode-changed",
"fields_changed": [
"product[id: 'gid://shopify/Product/8407379181638'].variants[id: 'gid://shopify/ProductVariant/45083652096070'].barcode"
],
"data": {
"product": {
"id": "gid://shopify/Product/8407379181638",
"title": "Sample T-Shirt",
"status": "ACTIVE"
},
"productVariant": {
"id": "gid://shopify/ProductVariant/45083652096070",
"barcode": "12345678901111",
"sku": "TSHIRT-BLACK-M",
"price": "3980"
}
}
}
Events の活用イメージ
triggers と query_filter を組み合わせることで、目的に特化した受信パターンを複数同時に設定できる。ここでは一例を紹介しよう。
商品の価格変更を検知して顧客に伝える
顧客が気になっている商品の価格が変わった時に、メール、LINE、アプリ通知などで知らせる使い方である。
従来は商品更新の Webhook を広く受け取り、アプリ側で価格が変わったかどうかを判定する必要があった。Next Generation Events であれば、価格系フィールドの変更だけを受信できるため、価格通知に関係のない商品名や画像の変更を処理対象から外しやすい。
[[events.subscription]]
handle = "product-price-changed-for-customer"
topic = "Product"
actions = ["update"]
triggers = ["product.variants.price","product.variants.compareAtPrice"]
uri = "/shopify/events/product-price-changed-for-customer"
query = """..."""
query_filter = "product.status:'ACTIVE' AND productVariant.price:>0"
このイベントを受け取ったアプリ側で、該当商品をお気に入り登録している顧客や、再入荷・値下げ通知を希望している顧客を検索し、通知を送る流れが考えられる。
新規商品を検知して顧客に伝える
新しい商品が作成された時に、特定カテゴリに興味がある顧客へ案内する使い方である。
新規商品は create アクションで検知できる。公開前の商品まで通知してしまわないよう、公開ステータスや必要な商品情報を確認してから顧客へ案内する設計にしておくとよい。
[[events.subscription]]
handle = "product-created-for-customer"
topic = "Product"
actions = ["create"]
uri = "/shopify/events/product-created-for-customer"
query = """..."""
query_filter = "product.status:'ACTIVE'"
このイベントを起点に、商品のタグ、商品タイプ、ベンダーなどを見て、通知対象の顧客セグメントを決めることができる。
顧客の購買金額が一定を超えたら自動処理する
顧客の累計購入金額が一定額を超えた時に、VIP タグを付与したり、特典案内を送ったりする使い方である。
顧客の購買金額に関する変更だけを受信すれば、住所変更やメモ変更のような関係のない顧客更新イベントを処理せずに済む。しきい値の判定は、query_filter で表現できる範囲で絞り込み、最終的な判定やタグ付与はアプリ側で行う設計が現実的である。
[[events.subscription]]
handle = "customer-amount-spent-changed"
topic = "Customer"
actions = ["update"]
triggers = ["customer.amountSpent"]
uri = "/shopify/events/customer-amount-spent-changed"
query = """..."""
このイベントを受け取った後、Admin API で顧客タグを付与する、CRM 側のランクを更新する、特典メールを送るといった処理につなげられる。
顧客のメールアドレスが変更されたら自動処理する
顧客のメールアドレスが変更された時に、外部 CRM、メール配信基盤、会員管理システムへ同期する使い方である。
顧客情報の更新は頻繁に発生するが、メールアドレス変更だけを処理したいケースは多い。customer.defaultEmailAddress に絞ることで、住所、タグ、メモなどの変更をメール同期処理に流さずに済む。
[[events.subscription]]
handle = "customer-email-changed"
topic = "Customer"
actions = ["update"]
triggers = ["customer.defaultEmailAddress"]
uri = "/shopify/events/customer-email-changed"
query = """..."""
このイベントを起点に、外部システムのメールアドレス更新、メール認証状態の確認、重複アカウントの検知などを行える。
顧客のタグが変更されたら自動処理する
顧客タグを業務フローの状態管理に使っている場合、タグ変更は重要なイベントになる。
たとえば vip タグが付いたら専用 CRM セグメントに追加する、wholesale タグが付いたら B2B 向けの案内を送る、review-requested タグが付いたらレビュー依頼のワークフローを開始する、といった処理が考えられる。
[[events.subscription]]
handle = "customer-tags-changed"
topic = "Customer"
actions = ["update"]
triggers = ["customer.tags"]
uri = "/shopify/events/customer-tags-changed"
query = """..."""
タグは自由度が高い一方で、運用ルールが曖昧だと自動処理が複雑になりやすい。Events を使う場合でも、どのタグを業務イベントとして扱うのかを先に決めておく必要がある。
重要なのは、これらを「全部 Shopify 側で自動化できる」と捉えないことである。Events はあくまで起点である。通知を受け取った後に何をするかは、引き続きアプリや外部システム側の設計に委ねられる。
とはいえ、PMやビジネスサイドにおいても、コードを書けなくても設計という意味ではある程度直感的にワークフローを構築出来るため、クライアントワークにおいても提案の幅が広がるのではないかと思われる。
Events を用いるとどのようなメリット・デメリットがあるか
実際に導入を検討する場合は、管理者・開発者目線(技術面)と営業サイド目線(ビジネス面)の両方でメリット・注意点を見ておくとよい。
管理者・開発者目線
メリット
- ノイズ削減: 指定フィールド変更時のみ受信できるため、不要な同期処理が走りにくい
- fields_changed で何が変わったか即判断できるため、差分チェックのロジックを減らせる
- カスタム query でペイロードを最適化できるため、受信後の追加 API 呼び出しを減らせる
- query_filter で ACTIVE 商品のみなどに絞れるため、DRAFT 商品の誤同期リスクを下げられる
- 複数パターンを shopify.app.toml に並べるだけで、目的別の受信設定を管理できる
デメリット・注意点
- query には複雑度上限があるため、取得フィールドや件数を絞る必要がある
- 既存 Webhook と共存させる場合、同一変更が両方に届く可能性があるため二重処理への対策が必要である
営業サイド目線
メリット
- 「バーコード変更時だけ同期」「価格変更時だけ通知」など、細かい要件への対応がしやすくなる
- 無駄な同期を減らすことで、処理遅延リスク、エラーリスク、サーバーコストの削減につながる可能性がある
- 受け取るデータを最適化できるため、追加 API 呼び出しコストを削減できる可能性がある
- 「どのフィールドが変わったか」を証跡として残しやすくなり、ログの解析コスト低減が期待できるとともに、顧客への状況説明がしやすくなる
デメリット・注意点
- 対応には開発工数が必要である
- API 仕様変更リスクがあるため、追加サポートコストが発生する可能性がある
- Webhook の同期数をもとに課金等を行っている場合、同期数が削減されることで課金額も減ってしまう可能性がある
既存 Webhook をすぐ置き換えるべきか
2026年6月時点では、Next Generation Events は Developer Preview である。まだ安定版としては使えない。
Next Generation Events は、既存の Webhook をすぐに全面移行するというより、ノイズが多い連携や、変更判定のコードが複雑になっている箇所から試すのが現実的である。
また、既存 Webhook と Events を共存させる場合、同じ変更が両方に届く可能性がある。移行時には二重処理を避けるための設計が必要になる。
その意味では、最初に見るべきなのは新機能の設定方法ではなく、自社の連携処理の中で「受け取っているが、ほとんど捨てている通知」がどこにあるかである。
まとめ
Next Generation Events は、Webhook 連携をより細かく、より無駄なく扱うための新しいイベント受信モデルである。
特定フィールドの変更だけを受け取れる。条件に合うものだけを届けられる。受け取るデータを絞れる。どこが変わったのかも分かる。これらは派手な機能ではないが、運用中の連携システムではかなり効く。
EC 店舗の機能を拡張するのに、連携アプリとの Webhook 連携は必要不可欠だが、アプリ実装コードが複雑となったり、通知のノイズが多いために、不具合が発生したり、顧客の要件への対応が困難であったり、イベント受信の動作ログの解析工数がかかってしまったりといった課題に直面することがある。こうしたケースが思い当たる場合は、Next Generation Events の利用を検討する価値がある。
