#はじめに
この記事では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追加でアプリが再インストールされる際に下記のような画面でスコープ許可がされることを確認してください。
webhookがストアに設定されているかを確認する場合は、
header
Content-Type: application/json
X-Shopify-Access-Token: 該当のshop.shopify_token
GET https://ストア名.myshopify.com/admin/api/2020-07/webhooks.json
で確認することもできます。