mcpField
B
b2c-custom-objects

b2c-custom-objects

github.com/salesforcecommercecloudデータ・データベース5790 回インストール今日更新
リポジトリ

b2c-custom-objects について

Salesforce B2C Commerce の開発者向けに、標準オブジェクト以外の業務データを扱うカスタムオブジェクトの技術資料です。Script API、OCAPI、SCAPI によるスコープ、CRUD、検索、購入者の読み取り専用アクセスを説明します。

主な機能

  1. 01サイト・組織スコープ
  2. 02Script API の CRUD 操作
  3. 03OCAPI のデータ・検索エンドポイント
  4. 04SCAPI による購入者の読み取り専用アクセス
  5. 05カスタムオブジェクトの検索パターン

活用シーン

  1. 01サイト別・グローバル設定の保存
  2. 02外部連携データのキャッシュ
  3. 03ロイヤルティ階層やベンダーデータの管理
  4. 04インポートやジョブキューの一時保管

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/salesforcecommercecloud/b2c-developer-tooling --skill b2c-custom-objects

インストール後、Claude Code で/b2c-custom-objectsを入力して読み込まれたか確認します。

同梱ファイルevals/trigger-evals.jsonreferences/OCAPI-SEARCH.md

詳細

B2C カスタムオブジェクト

カスタムオブジェクトは、標準のシステムオブジェクトに適合しないビジネスデータを保存します。サイトスコープおよび組織スコープ(グローバル)のデータに対応し、Script API と OCAPI を介した完全な CRUD 操作が可能です。

カスタムオブジェクトを使用する場面

ユースケース例
ビジネス設定サイトごと、またはグローバルに設定を保存する
インテグレーションデータ外部システムの応答をキャッシュする
カスタムエンティティロイヤルティティア、カスタムプロモーション、ベンダーデータ
一時的な処理ジョブ処理キュー、インポート用ステージング

カスタムオブジェクトタイプ

カスタムオブジェクトは、Business Manager の Administration > Site Development > Custom Object Types で定義します。各タイプには次の項目があります。

  • ID:一意の識別子(例:CustomConfig)
  • キー属性:検索に使用する主キーのフィールド
  • 属性:データ保存用のカスタム属性
  • スコープ:サイトスコープまたは組織スコープ(グローバル)

Script API(CustomObjectMgr)

カスタムオブジェクトの取得
var CustomObjectMgr = require('dw/object/CustomObjectMgr');

// Get a single custom object by type and key
var config = CustomObjectMgr.getCustomObject('CustomConfig', 'myConfigKey');

if (config) {
    var value = config.custom.configValue;
}
カスタムオブジェクトの作成
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Transaction = require('dw/system/Transaction');

Transaction.wrap(function() {
    // Create new custom object (type, keyValue)
    var obj = CustomObjectMgr.createCustomObject('CustomConfig', 'newKey');
    obj.custom.configValue = 'myValue';
    obj.custom.isActive = true;
});
カスタムオブジェクトのクエリ
var CustomObjectMgr = require('dw/object/CustomObjectMgr');

// Query with attribute filter
var objects = CustomObjectMgr.queryCustomObjects(
    'CustomConfig',                    // Type
    'custom.isActive = {0}',           // Query (uses positional params)
    'creationDate desc',               // Sort order
    true                               // Parameter value for {0}
);

while (objects.hasNext()) {
    var obj = objects.next();
    // Process object
}
objects.close();
カスタムオブジェクトの削除
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Transaction = require('dw/system/Transaction');

Transaction.wrap(function() {
    var obj = CustomObjectMgr.getCustomObject('CustomConfig', 'keyToDelete');
    if (obj) {
        CustomObjectMgr.remove(obj);
    }
});
タイプの全オブジェクトの取得
var CustomObjectMgr = require('dw/object/CustomObjectMgr');

// Get all objects of a type
var allConfigs = CustomObjectMgr.getAllCustomObjects('CustomConfig');

while (allConfigs.hasNext()) {
    var config = allConfigs.next();
    // Process
}
allConfigs.close();

CustomObjectMgr API リファレンス

メソッド説明
getCustomObject(type, keyValue)タイプとキーを指定して単一のオブジェクトを取得する
createCustomObject(type, keyValue)新しいオブジェクトを作成する(トランザクション内)
remove(object)オブジェクトを削除する(トランザクション内)
queryCustomObjects(type, query, sortString, ...args)フィルターを使用してクエリする
getAllCustomObjects(type)タイプの全オブジェクトを取得する
describe(type)カスタムオブジェクトタイプのメタデータを取得する

OCAPI Data API

カスタムオブジェクトの取得
GET /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}

注: サイトスコープのオブジェクトには /s/{site_id}/dw/data/v25_6/custom_objects/... を、組織スコープ(グローバル)のオブジェクトには /s/-/dw/data/v25_6/custom_objects/... を使用してください。

カスタムオブジェクトの作成
PUT /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
Content-Type: application/json

{
    "key_property": "myKey",
    "c_configValue": "myValue",
    "c_isActive": true
}
カスタムオブジェクトの更新
PATCH /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
Content-Type: application/json

{
    "c_configValue": "updatedValue"
}
カスタムオブジェクトの削除
DELETE /s/-/dw/data/v25_6/custom_objects/{object_type}/{key}
Authorization: Bearer {token}
カスタムオブジェクトの検索
POST /s/-/dw/data/v25_6/custom_objects_search/{object_type}
Authorization: Bearer {token}
Content-Type: application/json

{
    "query": {
        "bool_query": {
            "must": [
                { "term_query": { "fields": ["c_isActive"], "operator": "is", "values": [true] } }
            ]
        }
    },
    "select": "(**)",
    "sorts": [{ "field": "creation_date", "sort_order": "desc" }],
    "start": 0,
    "count": 25
}
検索クエリのタイプ
クエリタイプ説明例
term_query完全一致/比較{"fields": ["c_status"], "operator": "is", "values": ["active"]}
text_query全文検索{"fields": ["c_name"], "search_phrase": "test"}
filtered_queryクエリとフィルターの組み合わせ。範囲検索には range_filter を使用します{"query": {"match_all_query": {}}, "filter": {"range_filter":{"field": "c_count", "from": 1, "to": 10}}}
bool_query複数のクエリを組み合わせる{"must": [...], "should": [...], "must_not": [...]}
match_all_queryすべてのレコードに一致{}

Shopper Custom Objects API(SCAPI)

ストアフロントから読み取り専用でアクセスするには、Shopper Custom Objects API を使用します。この API には特定の OAuth スコープが必要です。

カスタムオブジェクトの取得(Shopper)
GET https://{shortCode}.api.commercecloud.salesforce.com/custom-object/shopper-custom-objects/v1/organizations/{organizationId}/custom-objects/{objectType}/{key}?siteId={siteId}
Authorization: Bearer {shopper_token}
必須スコープ

Shopper Custom Objects API を使用するには、SLAS クライアントで次のスコープを設定します。

  • sfcc.shopper-custom-objects - すべてのカスタムオブジェクトタイプへのグローバルな読み取りアクセス
  • sfcc.shopper-custom-objects.{objectType} - タイプ固有の読み取りアクセス

注: SLAS クライアントに設定できるカスタムオブジェクトのスコープは最大 20 個です。

また、Business Manager でカスタムオブジェクトタイプの Shopper アクセスを有効にする必要があります。

検索可能なシステムフィールド

すべてのカスタムオブジェクトには、OCAPI 検索クエリで使用できる次のシステムフィールドがあります。

  • creation_date - オブジェクトの作成日時(Date)
  • last_modified - オブジェクトの最終更新日時(Date)
  • key_value_string - 文字列のキー値
  • key_value_integer - 整数のキー値
  • site_id - サイト識別子(サイトスコープのオブジェクト用)

ベストプラクティス

推奨事項
  • 作成/更新/削除の操作ではトランザクションを使用する
  • 使用後はクエリイテレーターを閉じる(objects.close())
  • 効率的に検索できるよう、意味のあるキー値を使用する
  • 頻繁にクエリする属性にインデックスを設定する
  • サイト固有のデータにはサイトスコープのオブジェクトを使用する
  • 共有設定には組織スコープのオブジェクトを使用する
避けること
  • 機密データを暗号化せずに保存する
  • カスタムオブジェクトの種類を過剰に作成する
  • 大量のトランザクションデータにカスタムオブジェクトを使用する
  • getCustomObject() が null を返す場合の処理を忘れる
  • クエリイテレーターを閉じずに放置する(リソースリークの原因になります)

一般的なパターン

設定ストア
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Site = require('dw/system/Site');

function getConfig(key, defaultValue) {
    var configKey = Site.current.ID + '_' + key;
    var obj = CustomObjectMgr.getCustomObject('SiteConfig', configKey);

    if (obj && obj.custom.value !== null) {
        return JSON.parse(obj.custom.value);
    }
    return defaultValue;
}

function setConfig(key, value) {
    var Transaction = require('dw/system/Transaction');
    var configKey = Site.current.ID + '_' + key;

    Transaction.wrap(function() {
        var obj = CustomObjectMgr.getCustomObject('SiteConfig', configKey);
        if (!obj) {
            obj = CustomObjectMgr.createCustomObject('SiteConfig', configKey);
        }
        obj.custom.value = JSON.stringify(value);
    });
}
処理キュー
var CustomObjectMgr = require('dw/object/CustomObjectMgr');
var Transaction = require('dw/system/Transaction');

// Add to queue
function enqueue(data) {
    var key = 'job_' + Date.now() + '_' + Math.random().toString(36).substr(2, 9);
    Transaction.wrap(function() {
        var obj = CustomObjectMgr.createCustomObject('JobQueue', key);
        obj.custom.data = JSON.stringify(data);
        obj.custom.status = 'pending';
    });
}

// Process queue
function processQueue() {
    var pending = CustomObjectMgr.queryCustomObjects(
        'JobQueue',
        'custom.status = {0}',
        'creationDate asc',
        'pending'
    );

    while (pending.hasNext()) {
        var job = pending.next();
        Transaction.wrap(function() {
            job.custom.status = 'processing';
        });

        try {
            var data = JSON.parse(job.custom.data);
            processJob(data);

            Transaction.wrap(function() {
                CustomObjectMgr.remove(job);
            });
        } catch (e) {
            Transaction.wrap(function() {
                job.custom.status = 'failed';
                job.custom.error = e.message;
            });
        }
    }
    pending.close();
}

詳細なリファレンス

コメント