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が持つデータをそこにマージする形が良いケースもあるかもしれません。
この辺りは、もう少しまとめたものを来年にでも公開できればと思います。