eBay APIを叩いてみようとしたら初手からつまずいた件

# 背景
Google Apps ScriptからeBayのAPIを叩こうとしたら、その手前の準備段階でつまずいたので、回避方法をここに記す。

#### つまずいた時期
2021年10月

# 何が問題だったのか
eBay developers program の日本語版に記載されている情報がobsoletteだった。

https://www.ebay.co.jp/developer/guide

1. アカウント登録
1. Sandboxユーザ登録
1. アプリケーションキーの取得
1. ユーザトークン取得

ここまでは、上記のガイドを参考にして済ませておく。

---
##### アプリケーションキーの取得
![スクリーンショット 2021-10-26 163748.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/e3f1d4e6-496f-45aa-1ab7-336223fc7e96.png)

---
##### ユーザトークン取得
![スクリーンショット 2021-10-26 164202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/0773893b-4be1-4c6d-72dd-5c611d4c7481.png)

---
##### APIテストツールをセットアップ
この次に、公式ドキュメントでは SoapUIを使ったテスト方法について記載されているが、APIリクエストのテンプレートが古いのか、SoapUIの仕様が変わったのかわ分からないが、手順通りにやると**400 Bad Request エラー**になる。
(執筆時のSoapUIのバージョンは*5.6.0*)

![スクリーンショット 2021-10-26 165837.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/9ad63d76-67b2-c36a-7112-b9a1d7d818b4.png)

# 解決方法

eBay deveropers program サイト内にある**API Explorer**を使って、POSTするヘッダとボディのXMLをテストしましょう。
(HTTP HeadersとRequest Bodyは編集できます)

![スクリーンショット 2021-10-26 170106.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/13741f53-3b82-2b45-dcd7-1bdb84c383de.png)

![スクリーンショット 2021-10-26 171055.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/bd489fd6-9106-4071-8efe-f3431ca1f636.png)

![スクリーンショット 2021-10-26 171028.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/dd5a228f-d233-e959-751d-fc90e4c91cec.png)

![スクリーンショット 2021-10-26 172229.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13281/0ea013e0-d6fd-a8bb-b067-f2d2cc5cbec5.png)

---

投げつけるヘッダとXMLが出来上がってしまえば、あとはいつも通りに、UrlFetchApp.fetchで投げつければOK。
レスポンスでXMLが返ってくるので、xml2json.gsを使ってJSONに変換すると後が楽です。

https://www.labnol.org/code/19952-convert-xml-to-json

```ebay_test.gs
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;

}

```

```xml2json.gs
/* 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