要点
- フィードのアップロードステップは下記
- createFeedDocument でフィードドキュメントを作成(S3の署名付きURLが発行される)
- S3にフィードの内容をJSONでアップロード
- createFeed でフィードを生成
- 2025年3月以降、 JSON_LISTINGS_FEED のフィードタイプでアップロードする必要がある(本記事で対応)
- XMLのアップロードは非推奨
- フィードのアップロードステータスはセラーセントラル上で確認できる
- 在庫と価格は同時に変更可能
- 最大1万件まで同時に更新可能
- 処理はかなり高速(3000件でも5分以内)
事前準備
セラーセントラルでアプリの作成
Amazonの新しいAPI、SP-APIをとにかく動かしてみる
を参考に、次の3つの情報を用意し環境変数に設定
- リフレッシュトークン (YOUR_REFRESH_TOKEN)
- クライアントID (SELLING_PARTNER_APP_CLIENT_ID)
- クライアント機密情報 (SELLING_PARTNER_APP_CLIENT_SECRET)
なお、2024年9月現在はIAMユーザーは不要
セラーIDの確認
AmazonセラーIDを取得し、環境変数に設定(AMAZON_SELLER_ID)
セラーセントラルのユーザー作成
開発時にセラーセントラルの中を確認できると便利なので、作成しておく
下記の権限をつけておく
- 在庫の管理/商品の追加
- トランザクション (表示と編集)
コード
下記の createFeed() を使用
createFeed.ts
import axios from 'axios';
import { config } from 'dotenv';
import { SellingPartner } from 'amazon-sp-api';
const JP_MARKET_PLACE_ID = "A1VC38T7YXB528"; //日本のマーケットプレイスID(固定値)
/**
* 型定義 ============================================
*/
// 商品情報
type Item = {
readonly sku: string;
readonly quantity: number;
readonly leadTime: number;
};
// createFeedDocumentのレスポンス
type ICreateFeedDocumentResBody = {
readonly feedDocumentId: string;
readonly url: string;
};
// 以下、Feeds JSONのフォーマット
type IFeedJsonMessageFulfillmentPatchValue = {
readonly fulfillment_channel_code: "DEFAULT";
readonly quantity: number;
readonly lead_time_to_ship_max_days: number;
};
type IFeedJsonMessageFulfillmentPatch = {
readonly op: "replace";
readonly path: "/attributes/fulfillment_availability";
readonly value: IFeedJsonMessageFulfillmentPatchValue[];
};
type IFeedJsonMessage = {
readonly messageId: number;
readonly sku: string;
readonly operationType: "PATCH";
readonly productType: "PRODUCT";
readonly patches: IFeedJsonMessageFulfillmentPatch[];
};
type IFeedJson = {
readonly header: {
readonly sellerId: string;
readonly version: "2.0";
readonly issueLocale: "en_US";
};
readonly messages: IFeedJsonMessage[];
};
/**
* ==================================================================
*/
config(); // 環境変数を読み込む
// Selling Partner APIクライアントの初期化
const spApi = new SellingPartner({
region: 'fe', // 日本ならfe
refresh_token: process.env.YOUR_REFRESH_TOKEN,
credentials: {
SELLING_PARTNER_APP_CLIENT_ID: process.env.SELLING_PARTNER_APP_CLIENT_ID,
SELLING_PARTNER_APP_CLIENT_SECRET: process.env.SELLING_PARTNER_APP_CLIENT_SECRET,
},
options: {
auto_request_tokens: true,
}
});
/**
* フィードJSONを生成する
*/
const generateFeedJson = async (items: Item[]): Promise<IFeedJson> => {
const feedJson: IFeedJson = {
"header": {
"sellerId": process.env.AMAZON_SELLER_ID,
"version": "2.0",
"issueLocale": "en_US"
},
"messages": []
};
let index = 1;
for (let item of items) {
const message = {
messageId: index,
sku: item.sku,
operationType: "PATCH",
productType: "PRODUCT",
patches: [{
"op": "replace",
"path": "/attributes/fulfillment_availability",
"value": [
{
"fulfillment_channel_code": "DEFAULT",
"quantity": item.quantity, // 在庫数
"lead_time_to_ship_max_days": item.leadTime // 在庫を更新する時はリードタイムも同時に更新する必要がある
}
]
}],
};
feedJson.messages.push(message);
index++;
}
return feedJson;
};
/**
* S3に フィードをアップロードする
*/
const uploadToS3 = async (url: string, feedJson: IFeedJson): Promise<void> => {
const response = await axios.put(url, feedJson, {
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
});
if (response.status !== 200) {
throw new Error(`フィードアップロードに失敗 code: ${response.status} message: ${response.statusText}`)
}
}
/**
* SP-APIのCreateFeedを呼び出す
* @param feedDocumentId
*/
const callCreateFeed = async (feedDocumentId: string) => {
return spApi.callAPI({
operation: 'createFeed',
endpoint: 'feeds',
body: {
feedType: 'JSON_LISTINGS_FEED',
marketplaceIds: [JP_MARKET_PLACE_ID],
inputFeedDocumentId: feedDocumentId
}
});
}
/**
* 商品情報を元にフィードを作成し、Amazonにアップロードする
*/
export const createFeed = async (items: Item[]): Promise<IFeedJson | null> => {
// フィードの中身を生成
const feedJson = await generateFeedJson(items);
if (feedJson.messages.length === 0) {
return null
}
// フィードドキュメントの作成
//@ts-ignore
const feedDocument: ICreateFeedDocumentResBody = await spApi.callAPI({
operation: 'createFeedDocument',
endpoint: 'feeds',
body: {
contentType: 'application/json; charset=utf-8'
}
});
// フィードデータを S3にアップロード
await uploadToS3(feedDocument.url, feedJson);
// フィードドキュメントを元に、フィードの作成
const feed = await callCreateFeed(feedDocument.feedDocumentId);
console.log('Feed created:', feed); // Feed created: { feedId: '618797019996' }
return feed.feedId;
}
参考ドキュメント
SP-APIを利用するうえで非常に参考になる記事
Amazon公式のFeeds API ユースケースガイド
(非推奨となったXMLフィードのアップについて触れていたりと、情報が古いところも多い)