LoginSignup
5
2

More than 3 years have passed since last update.

Shopifyのカスタムアプリでwebhookを設定する

Last updated at Posted at 2020-09-19

はじめに

この記事ではShopifyのストア内で起こる特定のeventをrailsで作成したカスタムアプリと連動させるために使用したwebhookの設定についてお話しします。
webhookの通知を受けるためには管理画面上で設定→通知からマニュアルで設定する方法もありますが、アプリを作ったストア全ての管理画面に入れるわけではないこと、公開アプリとして運用したい人たちのために、今回は管理画面からの設定はしないこととします。

環境

Ruby 2.6.6
Rails 6.0.2

1. 必要となるアクセススコープをconfigureする

shopify_app.rb

ShopifyApp.configure do |config|
  ...
  config.scope = "read_products, read_orders" 
  ]
  ...
end

※ここで注意しなければいけないのが、この時点ですでにストアにアプリがインストールされている場合は、スコープを増やした後にアプリのアンインストール→再インストールをした方が良いという点です。

2.通知を受けたいwebhookとリクエスト先のURLを指定

gem 'shopify_app'をインストールしていることが前提でコマンドラインで下記を指定

rails g shopify_app:add_webhook -t orders/create -a https://example.com/webhooks/orders_create

この後shopify_app.rbには下記が追加される

ShopifyApp.configure do |config|
  ...
  config.webhooks = [
    {topic: 'orders/create', address: 'https://example.com/webhooks/orders_create'},
  ]
  ...
end

3.Jobの設定

それぞれのwebhookでjobを作成します
app/jobs/orders_create_job.rb

class OrdersCreateJob < ActiveJob::Base
  def perform(shop_domain:, webhook:)
    shop = Shop.find_by(shopify_domain: shop_domain)

    shop.with_shopify_session do
      # ここでimplementしたい機能を追加
    end
  end
end

sidekiq等の非同期処理を行うライブラリを使用されいる場合は、上記のjobがbackgroundで処理されます。

4.webhook用のカスタムcontrollerを作成

この部分はなくても問題ないのですが、webhookを通じてjobで行う以上の機能が必要となる場合などに必要となるので記載します。
routes.rb

...
post 'webhooks/orders_create', :to => 'custom_webhooks#orders_create'
...

app/controllers/custom_webhooks_controller.rb

class CustomWebhooksController < ApplicationController

  def orders_create
  end
  ...

  private

  def webhook_params
    params.except(:controller, :action, :type)
  end

end
  • Webhook verification 全てのwebhookはアプリがインストールされたストアからのリクエストであることを証明する必要があります。 Shopify側では、これをhttpリクエストのheaderにHMACを入れることでこれを証明するようにしています。 railsアプリの場合、幸いにも下記を入れるだけでこのHMACを識別して正しいリクエストかどうかを判断してくれます。
class CustomWebhooksController < ApplicationController
  include ShopifyApp::WebhookVerification
  ...
end
  • 必要となるmethodを作成
def orders_create
  params.permit!
  OrdersCreateJob.perform_later(shop_domain: shop_domain, webhook: webhook_params.to_h)
  head :no_content
end

webhookを通じてPOSTコールがされたあと、Shopify側に200 series statusを返す必要があります。(公式ドキュメントによると200 OK以外のレスポンスを返した場合には、48時間以内に19回のコールをしてくれるようです)
head :no_content にすることで、レスポンスは "204 no content"=どのデータもレスポンスしていない=webhookのデータは受領されたと判断されます

注意点

最初に管理画面にてwebhookの通知を設定をしている場合でも、config上で必要となるscopeのアクセスを許可されていなければhttpリクエストすらされないようでした。
ご自身のアプリがすでにストアにインストールされてしまっている場合には、このscope追加でアプリが再インストールされる際に下記のような画面でスコープ許可がされることを確認してください。
image.png

webhookがストアに設定されているかを確認する場合は、

header
Content-Type: application/json
X-Shopify-Access-Token:  該当のshop.shopify_token
GET https://ストア名.myshopify.com/admin/api/2020-07/webhooks.json

で確認することもできます。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2