
Stripe: 商品を検索 (Stripe: Search Products)
この工程は、検索クエリに合致する Stripe 上の商品オブジェクトを検索します。
Configs:共通設定
- 工程名
- メモ
Configs
- C1: API シークレットキーを設定した認証設定 *
- C2: 検索クエリ#{EL}
- C3: 商品 ID の一覧を保存するデータ項目
- C4: 商品詳細ページの URL の一覧を保存するデータ項目
- C5: 商品名の一覧を保存するデータ項目
- C6: デフォルトの商品価格 ID の一覧を保存するデータ項目
Notes
- Stripe の API シークレットキーを取得するには https://dashboard.stripe.com/apikeys を参照してください(要 Stripe ログイン)
- 検索クエリで使用可能なフィールドと演算子については、Stripe のドキュメントを参照してください
- 商品を追加後、検索結果に反映されるまでには少し時間がかかることがあります
Capture

See also
Script (click to open)
- 下記のスクリプトを記述した XML ファイルをダウンロードできます
- stripe-product-search.xml (C) Questetra, Inc. (MIT License)
- Professional をご利用であればファイルの内容を改変することでオリジナルのアドオンとして活用できます
const STRIPE_API_VERSION = '2022-08-01';
main();
function main(){
//// == Config Retrieving / 工程コンフィグの参照 ==
const auth = configs.get('conf_Auth');
let query = configs.get('conf_Query');
if (query === '') { // 検索クエリが空の場合、全件取得する
query = 'active:"true" OR active:"false"'; // 商品オブジェクトは created フィールドで検索不可
}
const productIdsDef = configs.getObject('conf_ProductIds');
const productUrlsDef = configs.getObject('conf_ProductUrls');
const productNamesDef = configs.getObject('conf_ProductNames');
const defaultPriceIdsDef = configs.getObject('conf_DefaultPriceIds');
//// == Calculating / 演算 ==
const singleLineFlag = checkDataDefs(productIdsDef, productUrlsDef, productNamesDef, defaultPriceIdsDef);
const {productIds, productNames, defaultPriceIds} = searchProducts(auth, query, singleLineFlag);
//// == Data Updating / ワークフローデータへの代入 ==
saveData(productIdsDef, productIds);
saveData(productUrlsDef, productIds.map(id => `https://dashboard.stripe.com/products/${id}`));
saveData(productNamesDef, productNames);
saveData(defaultPriceIdsDef, defaultPriceIds);
}
/**
* 保存先データ項目をチェックし、以下の場合にエラー
* - 保存先データ項目が一つも設定されていない
* - 保存先データ項目が重複
* @param {List<ProcessDataDefinitionView>} dataDefs 保存先データ項目
* @return {boolean} singleLineFlag 保存先データ項目のいずれかが単一行であれば true
*/
function checkDataDefs(...dataDefs) {
const dataDefList = dataDefs.filter(dataDef => dataDef !== null);
if (dataDefList.length === 0) { // 保存先データ項目が一つも設定されていない
throw 'No data item to save the search result is set.';
}
const dataNumSet = new Set(dataDefList.map(dataDef => dataDef.getNumber())); // 重複確認用
if (dataNumSet.size < dataDefList.length) { // 保存先データ項目が重複
throw 'Same data item is set multiple times.';
}
return dataDefList.some(dataDef => dataDef.matchDataType("STRING_TEXTFIELD"));
}
/**
* 商品を検索する
* @param {String} oauth 認証設定
* @param {String} query 検索クエリ
* @param {boolean} singleLineFlag 保存先データ項目のいずれかが単一行であれば true
* @return {Object} returnObj
* @return {List<String>} returnObj.productIds 商品 ID の一覧
* @return {List<String>} returnObj.productNames 商品名の一覧
* @return {List<String>} returnObj.defaultPriceIds デフォルトの商品価格 ID の一覧
*/
function searchProducts(auth, query, singleLineFlag) {
const productIds = [];
const productNames = [];
const defaultPriceIds = [];
let nextPage = search(auth, query, null, productIds, productNames, defaultPriceIds);
if (singleLineFlag && productIds.length > 1) { // 保存先データ項目が単一行なのに複数件あればエラー
throw 'More than one products were found while the data item to save the result is Single-Line.';
}
while (nextPage !== null) {
engine.log(`Current search result: ${productIds.length} products found. Fetching next page...`);
nextPage = search(auth, query, nextPage, productIds, productNames, defaultPriceIds);
}
engine.log(`Search result: ${productIds.length} products found.`);
return {productIds, productNames, defaultPriceIds};
}
/**
* 商品を検索する API リクエストを送信する
* @param {String} oauth 認証設定
* @param {String} query 検索クエリ
* @param {String} page 取得するページ。最初のリクエストの場合は null
* @param {List<String>} productIds 検索結果の商品 ID を格納する配列
* @param {List<String>} productNames 検索結果の商品名を格納する配列
* @param {List<String>} defaultPriceIds 検索結果のデフォルトの商品価格 ID を格納する配列
* @return {String} nextPage 次のページ
*/
function search(auth, query, page, productIds, productNames, defaultPriceIds) {
const apiUri = 'https://api.stripe.com/v1/products/search';
let request = httpClient.begin()
.authSetting(auth) // with "Authorization: Bearer XX"
.header('Stripe-Version', STRIPE_API_VERSION)
.queryParam('query', query) // required
.queryParam('limit', '100'); // maximum limit
if (page !== null) {
request = request.queryParam('page', page);
}
const response = request.get(apiUri);
const status = response.getStatusCode();
const responseStr = response.getResponseAsString();
if (status !== 200) {
engine.log(responseStr);
throw `Failed to search products. status: ${status}`;
}
const responseObj = JSON.parse(responseStr);
const products = responseObj.data;
if (page === null && products.length === 0) { // 1 回目の検索で、結果の件数が 0
throw 'No products found.';
}
// 結果を配列に追加
products.forEach(product => {
productIds.push(product.id);
productNames.push(product.name);
defaultPriceIds.push(product.default_price);
});
if (responseObj.has_more) { // 次のページがある場合
return responseObj.next_page;
}
// 次のページがない場合
return null;
}
/**
* データ項目に出力する
* @param {ProcessDataDefinitionView} dataDef 保存先データ項目
* @param {List<String>} dataList 保存するデータの配列
*/
function saveData(dataDef, dataList) {
if ( dataDef === null ) {
return;
}
engine.setData(dataDef, dataList.join("\n"));
}