前回の記事では、Google Apps Script(GAS)を使って Trading API(AddItem)での単品出品の流れを紹介しました。
(→「eBay Trading API で商品を出品する方法(スプレッドシート+GAS)」)
しかし、実際に AddItem を試すと、多くの方が次の“壁”にぶつかります。
「画像だけエラーになる」「外部URLだと読み込めない」
特に Googleドライブの共有URLや、自前サーバーの画像URLを PictureURL に指定した場合、出品時に画像取り込みエラーが多発します。本記事では、これを根本的に解決するための API「UploadSiteHostedPictures」を GAS で使う方法を詳しく解説します。
1. なぜ外部URLだと画像エラーが発生するのか?
AddItem の <PictureURL> に外部URLをそのまま指定すると、次の理由で eBay が画像を取得できない場合があります。
- GoogleドライブURLが認証・リダイレクト付きである
- 一部サーバーは画像取得時に 403 / 404 を返す
- URLに有効期限があり、出品時に切れている
- 圧縮や画像サイズが eBay の判定に合わない
結論:外部URLを直接 PictureURL に入れるのは不安定。
これを避けるには、一度 eBay Picture Service に画像をアップロードしておく必要があります。
2. UploadSiteHostedPictures とは?
UploadSiteHostedPictures は、eBayの「Picture Service」に画像をアップロードするための Trading API の1つです。アップロード成功後には、eBay ホストの公式画像URL(例:https://i.ebayimg.com/...)が返ってきます。このURLを <PictureURL> に指定することで、画像エラーが解消されます。
公式ドキュメント(UploadSiteHostedPictures): https://developer.ebay.com/devzone/xml/docs/reference/ebay/uploadsitehostedpictures.html
使用するキー
- DevID
- AppID
- CertID
- Auth’n’Auth トークン
AddItem と同じ情報を使用でき、新しいキーの取得は不要です。
3. 全体の流れ(AddItem の前処理として追加)
- 外部の画像URLを用意
- UploadSiteHostedPictures を呼び出す
- 返ってきた eBay 画像URLを取得
- AddItem の
<PictureURL>に設定して出品
この“前処理を追加するだけ”で画像エラーが大幅に減ります。
4. GASで UploadSiteHostedPictures を呼び出すコード
以下は 「test」シートのA1~A3セルに記載した画像URLをeBayの画像URLに変換しB1~B3セルに出力する例 です。
/***** eBay Trading API 設定 *****/
const EBAY_TRADING_ENDPOINT = 'https://api.ebay.com/ws/api.dll';
// サンドボックスの場合:'https://api.sandbox.ebay.com/ws/api.dll'
const EBAY_COMPAT_LEVEL = '967'; // 環境に合わせて
const EBAY_SITE_ID = '0'; // 0 = US
const setsheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("設定");
// 設定シート(APIキー類)
const ADDR_SET_APPID = 'E6'; // 設定シート内 APPID(CERT-NAME 用)
const ADDR_SET_DEVID = 'E7'; // 設定シート内 DEVID(DEV-NAME 用)
const ADDR_SET_AUTHTOKEN = 'E8'; // 設定シート内 eBayAuthToken
const ADDR_SET_CERTID = 'E9'; // 設定シート内 CERTID
// Developer アカウントから取得した値
const EBAY_DEV_ID = setsheet.getRange(ADDR_SET_DEVID).getValue();
const EBAY_APP_ID = setsheet.getRange(ADDR_SET_APPID).getValue();
const EBAY_CERT_ID = setsheet.getRange(ADDR_SET_CERTID).getValue();
// Auth'n'Auth のユーザートークン
const EBAY_AUTH_TOKEN = setsheet.getRange(ADDR_SET_AUTHTOKEN).getValue();
// Google Drive 内で画像を探すフォルダ名
const IMAGE_FOLDER_NAME = 'aaa';
// 最大何枚アップロードするか
const MAX_PICTURES = 24;
/**
* testシートの A1〜A3 に記載された画像URLを
* eBay Picture Service にアップロードし、
* 結果の FullURL を testシートの B1〜B3 に出力する。
*/
function uploadPicturesFromAaaFolder2() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('test');
if (!sheet) {
throw new Error('シート「test」が見つかりません。');
}
// A1〜A3 → 入力URL
const rangeIn = sheet.getRange('A1:A3');
const values = rangeIn.getValues(); // [[url1],[url2],[url3]]
// 空セルを除外してURL配列
const urls = values
.map(row => (row[0] || '').toString().trim())
.filter(u => u);
if (urls.length === 0) {
Logger.log('アップロード対象のURLが見つかりません。');
return [];
}
const results = [];
const count = Math.min(urls.length, MAX_PICTURES);
// 出力用配列(3行×1列)
const outValues = [[''], [''], ['']];
for (let i = 0; i < count; i++) {
const externalUrl = urls[i];
// PictureName (aaa_01, aaa_02...)
const localName = IMAGE_FOLDER_NAME + '_' + ('0' + (i + 1)).slice(-2);
// eBayへアップロード
const ebayUrl = uploadSiteHostedPicture(externalUrl, localName);
results.push({
localName: localName,
sourceUrl: externalUrl,
ebayUrl: ebayUrl
});
Logger.log(`Uploaded: ${localName} -> ${ebayUrl}`);
// B1〜B3 に書き込む値をセット
outValues[i][0] = ebayUrl;
}
// B1〜B3 へ書き込み
const rangeOut = sheet.getRange('B1:B3');
rangeOut.setValues(outValues);
return results;
}
/**
* eBay Trading API 呼び出し(共通)
* @param {string} callName - 例: 'UploadSiteHostedPictures'
* @param {string} xmlBody - ルート要素を含む XML 本文
* @returns {string} - eBay からのレスポンス XML 文字列
*/
function callEbayTrading(callName, xmlBody) {
const headers = {
'X-EBAY-API-CALL-NAME': callName,
'X-EBAY-API-COMPATIBILITY-LEVEL': EBAY_COMPAT_LEVEL,
'X-EBAY-API-SITEID': EBAY_SITE_ID,
'X-EBAY-API-DEV-NAME': EBAY_DEV_ID,
'X-EBAY-API-APP-NAME': EBAY_APP_ID,
'X-EBAY-API-CERT-NAME': EBAY_CERT_ID,
'Content-Type': 'text/xml'
};
const options = {
method: 'post',
headers: headers,
payload: xmlBody,
muteHttpExceptions: true
};
const res = UrlFetchApp.fetch(EBAY_TRADING_ENDPOINT, options);
const text = res.getContentText();
Logger.log(text);
return text;
}
/**
* 単一の画像URLを eBay Picture Service に登録する。
* - ExternalPictureURL を使うパターン
* @param {string} externalUrl - 画像の外部URL
* @param {string} pictureName - PictureName(aaa_01 など)
* @returns {string} - 登録された画像の eBay ホスト URL(FullURL)
*/
function uploadSiteHostedPicture(externalUrl, pictureName) {
const xmlBody =
'<?xml version="1.0" encoding="utf-8"?>' +
'<UploadSiteHostedPicturesRequest xmlns="urn:ebay:apis:eBLBaseComponents">' +
'<RequesterCredentials>' +
'<eBayAuthToken>' + EBAY_AUTH_TOKEN + '</eBayAuthToken>' +
'</RequesterCredentials>' +
'<WarningLevel>High</WarningLevel>' +
'<ExternalPictureURL>' + xmlEscape(externalUrl) + '</ExternalPictureURL>' +
'<PictureName>' + xmlEscape(pictureName) + '</PictureName>' +
'</UploadSiteHostedPicturesRequest>';
const resXml = callEbayTrading('UploadSiteHostedPictures', xmlBody);
const ackMatch = resXml.match(/<Ack>([^<]+)<\/Ack>/);
const ack = ackMatch ? ackMatch[1] : '';
if (ack !== 'Success' && ack !== 'Warning') {
throw new Error('UploadSiteHostedPictures エラー: ' + ack + '\n' + resXml);
}
const urlMatch = resXml.match(/<FullURL>([^<]+)<\/FullURL>/);
const fullUrl = urlMatch ? urlMatch[1] : '';
if (!fullUrl) {
throw new Error('FullURL がレスポンスから取得できませんでした。\n' + resXml);
}
return fullUrl;
}
/**
* XML 用の簡易エスケープ
*/
function xmlEscape(str) {
return String(str)
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
5. 実行結果サンプル
アップロードが成功すると、「test」シートのB1~B3セル内に次のようなURLが返ってきます。
このURLを AddItem の <PictureURL> に入れるだけで画像が表示されます。
6. ポイント
1. 返却されたURLは必ず保存すること
eBayには「アップロードした画像一覧」を取得するAPIがありません。
そのため、UploadSiteHostedPictures のレスポンスで返ってきた画像URLは、必ず自分でスプレッドシートなどに記録して管理する必要があります。
記録していなかった場合、後から同じURLを再取得することはできず、同じ画像を 再度アップロードする しか方法がありません。
2. アップロード後の画像はeBay側でリサイズされることがある
UploadSiteHostedPictures でアップロードした画像は、eBay側で自動的に圧縮・リサイズされる場合があります。
そのため、返ってきたURLを開いて画像が小さく見えても、それは仕様上の動作であり異常ではありません。
7. まとめ
外部URLをそのまま PictureURL に指定すると、認証・リダイレクト・アクセス期限 などの影響で eBay が画像を取得できず、AddItem 時に画像エラーが発生しやすくなります。
そのため、画像は UploadSiteHostedPictures を使って事前に eBay Picture Service(EPS)へアップロードしておく のが最も安定します。
アップロード後に返される eBayホスト画像URL を PictureURL に設定すれば、出品時の画像取り込みが安定し、エラーが大幅に減ります。
なお、返却される画像URLは eBay が再通知してくれるものではない ため、必ず自分のスプレッドシート等に記録して管理してください。
画像まわりの処理を安定化させることで、AddItem 出品全体の成功率も大きく向上します。

