Stripeの商品データをAlgoliaにインデックスする方法

Algolia Advent Calendar 2021 19日目の記事です。 Stripeには、ベータ版ですが「Search API」があります。これを使うことで、商品データの検索などを行うことができます。 ですが、複 […]

広告ここから
広告ここまで

目次

    Algolia Advent Calendar 2021 19日目の記事です。

    Stripeには、ベータ版ですが「Search API」があります。これを使うことで、商品データの検索などを行うことができます。

    ですが、複数のデータを使った検索やレコメンデーションなどを求め始めると、Algoliaを使った方が効率的なケースが多いでしょう。

    ということで、今回は簡単にですが、Stripeに登録または更新した商品データをAlgoliaにインデックスする方法を紹介します。

    データの流れ

    商品更新からインデックスまでは、以下のようなフローで行います。

    • Stripeで商品データを更新する
    • Stripe WebhookがAPIを呼び出す
    • Expressで実装したAPIが、Algoliaにインデックスする

    Stripe Webhook用 APIを用意する

    まずはStripeのWebhookイベントを受け付けるAPIを用意します。

    いろいろ方法はありますが、今回は手軽にStripe CLIを利用します。

    サンプルアプリをセットアップ

    Stripe CLIでサンプルアプリをローカルにDLします。accept-a-paymentなど、Webhookの実装があるものを選ぶようにしましょう。

    % stripe samples create accept-a-payment
     ⣾ Downloading accept-a-payment ✔ Finished downloading
     ✔ Selected integration: prebuilt-checkout-page 
     ✔ Selected client: react-cra 
     ✔ Selected server: node 
     ⣾ Copying files over… accept-a-payment ✔ Files copied
     ⣷ Configuring your code… accept-a-payment ✔ Project configured

    サーバー側のプロジェクトをセットアップ、起動させましょう。

    % cd accept-a-payment/server
    % npm install
    % npm start
    $ node server.js
     body-parser deprecated undefined extended: provide extended option server.js:20:17
     Node server listening on port 4242!

    Stripe CLIで、ローカルのAPIにWebhookイベントをforwardする

    Stripe CLIのlistenコマンドで、Stripe WebhookのイベントをローカルAPIで受けれるようにしましょう。

    % stripe  listen --forward-to localhost:4242/webhook
     ⡿ Getting ready… > Ready! You are using Stripe API Version [2020-08-27]. Your webhook signing secret is whsec_xxxx

    Webhookの実装を変更する

    最後に商品データの作成と更新を受け付けるように、Webhookの実装を変更します。

    
    app.post('/webhook', async (req, res) => {
      let event;
    
      // Check if webhook signing is configured.
      if (process.env.STRIPE_WEBHOOK_SECRET) {
        // Retrieve the event by verifying the signature using the raw body and secret.
        let signature = req.headers['stripe-signature'];
    
        try {
          event = stripe.webhooks.constructEvent(
            req.rawBody,
            signature,
            process.env.STRIPE_WEBHOOK_SECRET
          );
        } catch (err) {
          console.log(`⚠️  Webhook signature verification failed.`);
          return res.sendStatus(400);
        }
      } else {
        // Webhook signing is recommended, but if the secret is not configured in `.env`,
        // retrieve the event data directly from the request body.
        event = req.body;
      }
    
      if (!/product/.test(event.type)) {
        res.sendStatus(200);
        return
      }
      if (['product.updated','product.created'].includes(event.type)) {
        const product = event.data.object
        const param = {
          objectID: product.id,
          description: product.description,
          name: product.name,
        }
        if (product.metadata) {
          Object.entries(product.metadata).forEach(([key, value]) => {
            param[key] = value
          })
        }
        // Algolia Index処理
      }
      res.sendStatus(200);
    });

    APIにAlgoliaのクライアントライブラリを追加

    Algoliaへのインデックス処理を実行するライブラリを追加します。

    % npm i -S algoliasearch

    Algoliaに商品データをインデックスする

    先ほど変更したコードをさらに編集します。// Algolia Index処理部分を以下のように変更しましょう。

      const algoliaApplicationId = 'XXXX'
      const algoliaAdminApiKey = 'XXXX'
      const client = algoliasearch(algoliaApplicationId, algoliaAdminApiKey);
      const index = client.initIndex("IndexName");
      await index.saveObject(param)

    この状態で、npm startを再実行し、サーバーを再起動させましょう。

    Stripeの商品を追加または更新する

    あとはStripe DashboardまたはCLI、APIでデータを更新して実際に動かしてみましょう。Stripe CLIの場合は、以下のような形になります。

    % stripe products create --name test --description "example product from cli" 
     {
       "id": "prod_Knw0BhTC5MOcdI",
       "object": "product",
       "active": true,
       "attributes": [
     ],
       "created": 1639900154,
       "description": "example product from cli",
       "images": [
     ],
       "livemode": false,
       "metadata": {
       },
       "name": "test",
       "package_dimensions": null,
       "shippable": null,
       "statement_descriptor": null,
       "tax_code": null,
       "type": "service",
       "unit_label": null,
       "updated": 1639900154,
       "url": null
     }

    AlogliaのIndexを確認する

    Algolia側のDashboardで、データの追加や更新が確認できていればOKです。

    Tips1: データ更新時のキーについて

    algoliasearchライブラリのsaveObjectでは、objectIDが更新時のキーになります。

    自動生成させてもよいのですが、Stripeの商品IDがユニークなので、そのままobjectIDに指定して作成も更新も同じ処理でできるようにしています。

    Tips2: 価格について

    Stripeは、商品データに価格情報を持ちません。商品のIDを利用して、stripe.prices.listを実行し、価格データを取得する必要があります。

    AlgoliaにIndexする場合、ケースによってはprice側でIndexをそれぞれ作成し、productが持つデータをそこにマージする形が良いケースもあるかもしれません。

    この辺りは、もう少しまとめたものを来年にでも公開できればと思います。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark