9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Shopify開発を盛り上げる(Liquid, React, Node.js, Graph QL)Advent Calendar 2020

Day 14

shopifyで在庫が切れそうな商品を通知するbotの作成

Last updated at Posted at 2020-12-14

はじめに

この記事はShopify開発を盛り上げる Advent Calendar 2020 14日目の記事です。
shopifyはデフォルトで商品が売れていき、在庫が切れると自動的に売り切れの表記になるのはありがたいのですが、
そもそも在庫が切れそうになったら教えて欲しいです。
しかしデフォルトでそういう機能が見つからなかったのでサクッと商品が売れて在庫が切れそうになったらslackに通知してくれるbotを作成しました。

やること

  1. slackのWebhookを受けるボットを用意する
  2. ShopifyのWebhookを受けるサーバーを用意する
  3. Webhookを受けたあとの処理の実装をする
  4. Shopifyの管理画面から「商品更新」のWebhookを設定する
  5. 実際に更新通知を受けてslackに通知するか確認する

やることとしてはこの程度です。とても簡単です。

1. 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を設定します。
スクリーンショット 2020-12-10 16.56.16.png
スクリーンショット 2020-12-10 16.58.01.png

先程index.jsに記述のあった


const shopifySecret = "各自置き換えてください"

この部分はWebhookのページにsecretの情報があるのでそれに各自置き換えてください
スクリーンショット 2020-12-13 1.18.08.png

5. 実際に更新通知を受けてslackに通知するか確認する

ここまでくれば準備完了です。あとは試しにショップで商品を購入してみましょう
在庫が1以下になったときにアラートが来るように設定しているので、商品の在庫数を2個にして購入してください。
購入後slackのWebhookに通知がくれば完成です。

スクリーンショット 2020-12-13 1.11.37.png

さいごに

shopifyのWebhookはかなり充実しています。だいたいのアクションに対してWebhookを設定できるのでまだまだ便利な使い方ができそうです。
ちなみに今回のbotは「商品更新」に設定しており、商品の注文が入ったときだけでなく管理画面から商品を更新したときもWebhookが飛んできます。なのでもともと在庫が少ないような商品は管理画面で更新しても来てしまうのでそのあたりは注文作成のWebhookなどと組み合わせていい感じに実装する必要が出てきそうです。

9
5
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
9
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?