はじめに
GreenSnapの開発者ブログを始めることになりました。エンジニアの高畑です。 初回ということで何を書こうかと思いましたが最近の取り組みとしてshopifyの在庫切れ通知を生産者と繋げた事例を紹介します。
GreenSnapではshopifyを利用して植物に関するECをGreenSnapStoreとして展開しています。 greensnap.co.jp 商品は全国の提携している生産者や市場から直接卸しており、商品が売り切れると補充しないといけないのですが都度在庫を問い合わせるのは時間がかかるのが問題でした。 もともと運用上、各市場や生産者の方は弊社のSlackチャンネルに招待していたのでそれを利用し商品が売り切れるとリアルタイムで何の商品が売り切れたのかを通知する仕組みを作りました。現在はある市場の方に協力をいただいて試運用しておりそれがうまくまわってきたので実際にどのようにshopifyで在庫切れ通知を実装したかを紹介します。
在庫切れアラートの実装
実装のステップとしては以下のとおりです。
- slackのWebhookを受けるボットを用意する
- ShopifyのWebhookを受けるサーバーを用意する
- Webhookを受けたあとの処理の実装をする
- Shopifyの管理画面から「商品更新」のWebhookを設定する
- 実際に更新通知を受けてslackに通知するか確認する
「3. Webhookを受けたあとの処理の実装をする」の実装に関しては本記事では実際に運用しているものよりは簡略化したものを紹介します。
slackのWebhookを受けるボットを用意する
slackのIncoming WebhookのチュートリアルどおりにIncoming WebhookのURLを取得してください。
2. ShopifyのWebhookを受けるサーバーを用意する
サーバーは正直なんでも良いです。本記事ではfirebaseのcloud functionsで実装します。 AWSのAPIGatewayでも自前のサーバーにWebhookを受ける口を用意しても良いと思います。
cloud functionsの導入方法は割愛します。公式のチュートリアルにしたがって導入してください https://firebase.google.com/docs/functions/get-started?hl=ja
3. Webhookを受けたあとの処理の実装をする
ここからが本題です。 Webhookの実装にあたって2つnpmでモジュールを追加しました
npm install shopify-hmac-validation npm install request
shopify-hmac-validationを導入していますがこれはPOSTされたデータがshopifyからのものかを検証するロジックを簡略化するためにいれました。 公式にruby,php,pythonのサンプルソースコードはあるのでそちらの言語を使っている場合は参考にしてください。 https://shopify.dev/tutorials/manage-webhooks
index.jsを以下のように実装します。
const functions = require('firebase-functions'); const http = require('request'); const checkHmacValidity = require('shopify-hmac-validation').checkWebhookHmacValidity const slackWebhookUrl = "各自置き換えてください"//SlackのIncoming WebhookのURLに置き換えてください const shopifySecret = "各自置き換えてください" //後述します exports.webhookProduct = functions.https.onRequest((request, response) => { //POST出ない場合は何もしない if (request.method !== 'POST') { response.status(405).send('Method Not Allowed'); return; } const checkHmac = checkHmacValidity(shopifySecret, request.rawBody.toString(), request.header("x-shopify-hmac-sha256")); //shopifyからのリクエスト出ない場合はなにもせずにreturn if (!checkHmac) { functions.logger.info("Hmac does not match", request.rawBody.toString()); response.send("Hmac does not match"); return; } //公開済み商品でない場合は何もしない if(request.body.published_at === null) { response.send("OK"); return; } request.body.variants.forEach(variant => { //商品の在庫が1以下の場合はslackにメッセージPOSTのデータ if (variant.inventory_quantity <= 1) { http.post({ uri: slackWebhookUrl, headers: { "Content-type": "application/json", }, json: { "text": "「" + request.body.title + "」の在庫が切れそうです" } }, (error, response, body) => { }); } }) response.send("OK"); });
firebaseにデプロイします。
firebase deploy --only functions
以上でfirebase側の実装は終了です。
4. Shopifyの管理画面から「商品更新」のWebhookを設定する
「商品更新」のshopifyのショップ管理画面から「設定」→「通知」→「Webhookを作成」と遷移し 「商品更新」のWebhookを作成し、Webhookを受けるURLに先程deployしたfirebaseのcloud functionのURLを設定します。
先程index.jsに記述のあった
const shopifySecret = "各自置き換えてください"
この部分はWebhookのページにsecretの情報があるのでそれに各自置き換えてください
5. 実際に更新通知を受けてslackに通知するか確認する
ここまでくれば準備完了です。あとは試しにショップで商品を購入してみましょう 在庫が1以下になったときにアラートが来るように設定しているので、商品の在庫数を2個にして購入してください。 購入後slackのWebhookに通知がくれば完成です。
弊社の実際の通知例
弊社の実際の通知例を紹介しますと
在庫が0になったタイミングで通知をしており、商品のバリエーションの情報も追加で載せています。 これを見て市場の方がいくつ追加可能かレスをくださっています。 これにより在庫追加がスムーズになりました。 余談ですが、この仕組がうまくまわってきたので在庫を追加するのもSlackからできるように改善中です。
さいごに
GreenSnapでは「次代のみどりのインフラをつくる。」をミッションに絶賛メンバーを募集中です。 興味がある方は気軽に話だけでも聞きにきてもらえるとうれしいです。 www.wantedly.com