背景
Google Apps ScriptからeBayのAPIを叩こうとしたら、その手前の準備段階でつまずいたので、回避方法をここに記す。
つまずいた時期
2021年10月
何が問題だったのか
eBay developers program の日本語版に記載されている情報がobsoletteだった。
- アカウント登録
- Sandboxユーザ登録
- アプリケーションキーの取得
- ユーザトークン取得
ここまでは、上記のガイドを参考にして済ませておく。
アプリケーションキーの取得
ユーザトークン取得
APIテストツールをセットアップ
この次に、公式ドキュメントでは SoapUIを使ったテスト方法について記載されているが、APIリクエストのテンプレートが古いのか、SoapUIの仕様が変わったのかわ分からないが、手順通りにやると400 Bad Request エラーになる。
(執筆時のSoapUIのバージョンは5.6.0)
解決方法
eBay deveropers program サイト内にあるAPI Explorerを使って、POSTするヘッダとボディのXMLをテストしましょう。
(HTTP HeadersとRequest Bodyは編集できます)
投げつけるヘッダとXMLが出来上がってしまえば、あとはいつも通りに、UrlFetchApp.fetchで投げつければOK。
レスポンスでXMLが返ってくるので、xml2json.gsを使ってJSONに変換すると後が楽です。
const EBAY_API_ENDPOINT = 'https://api.sandbox.ebay.com/ws/api.dll';
const EBAY_USER_TOKEN = 'AgAA(中略)1d6u';
function geteBayOfficialTime() {
let url = EBAY_API_ENDPOINT;
let content = '<?xml version="1.0" encoding="utf-8"?><GeteBayOfficialTimeRequest xmlns="urn:ebay:apis:eBLBaseComponents"><RequesterCredentials><eBayAuthToken>'
+ EBAY_USER_TOKEN
+ '</eBayAuthToken></RequesterCredentials><ErrorLanguage>en_US</ErrorLanguage><WarningLevel>High</WarningLevel></GeteBayOfficialTimeRequest>';
const postheader = {
'X-EBAY-API-SITEID':'0',
'X-EBAY-API-COMPATIBILITY-LEVEL':'967',
'X-EBAY-API-CALL-NAME':'GeteBayOfficialTime',
'X-EBAY-API-DETAIL-LEVEL':'0'
}
const parameters = {
"method": "post",
"muteHttpExceptions": true,
"headers": postheader,
'payload': content
}
Utilities.sleep(500);
try {
var response = UrlFetchApp.fetch(url, parameters);
}
catch (e) {
Logger.log(e.toString());
return 'eBay:Exception';
}
let response_code = response.getResponseCode().toString();
Logger.log(response_code + ':' + url);
if (response_code != 200) return 'eBay:HTTP Error(' + response_code + ')';
let xml = response.getContentText('UTF-8');
let json = XML_to_JSON(xml);
return json;
}
/* Source: https://gist.github.com/erickoledadevrel/6b1e9e2796e3c21f669f */
/**
* Converts an XML string to a JSON object, using logic similar to the
* sunset method Xml.parse().
* @param {string} xml The XML to parse.
* @returns {Object} The parsed XML.
*/
function XML_to_JSON(xml) {
var doc = XmlService.parse(xml);
var result = {};
var root = doc.getRootElement();
result[root.getName()] = elementToJSON(root);
return result;
}
/**
* Converts an XmlService element to a JSON object, using logic similar to
* the sunset method Xml.parse().
* @param {XmlService.Element} element The element to parse.
* @returns {Object} The parsed element.
*/
function elementToJSON(element) {
var result = {};
// Attributes.
element.getAttributes().forEach(function(attribute) {
result[attribute.getName()] = attribute.getValue();
});
// Child elements.
element.getChildren().forEach(function(child) {
var key = child.getName();
var value = elementToJSON(child);
if (result[key]) {
if (!(result[key] instanceof Array)) {
result[key] = [result[key]];
}
result[key].push(value);
} else {
result[key] = value;
}
});
// Text content.
if (element.getText()) {
result['Text'] = element.getText();
}
return result;
}
愚痴
こんなので潰れた半日を返してほしい……orz