Rails MWS 見積もり手数料の取得 GetMyFeesEstimate

# はじめに
MWSで見積もり手数料を取得できるオペレーションと言えばGetMyFeesEstimateですね？

- [GetMyFeesEstimate](http://docs.developer.amazonservices.com/ja_JP/products/Products_GetMyFeesEstimate.html)

リクエストクォーターは以下の通りです。

|最大リクエストクォータ|回復レート|時間あたりのリクエストクォータ|
|:--|:--|:--|:--|:--|
|20リクエスト|1秒あたり10商品|1時間あたり36000リクエスト|

思ってたより緩いですね。

# 実装

## 事前準備
[Rails MWS APIを利用するまでの事前準備](https://qiita.com/ayies128/items/7ce8530574122dfec507)
こちらよりpeddlerのclientインスタンスを作成できる状態にしておいてください:point_up:

## リクエストの送信
[リファレンス](https://www.rubydoc.info/gems/peddler/MWS/Products/Client#get_my_fees_estimate-instance_method)ではこう書いてあります。
``get_matching_product_for_id(*fees_estimate_requests)``
> Parameters:
fees_estimate_requests (Array\<Struct, Hash>)

うわぁ...それ以上でも以下でもねえ...
fees_estimate_requestsを作るのがキモになりますね。
（全然難しくないけどね）

```ruby
client = MWS.products( 
  # 省略
)

# 取得したい商品のID（タイプは指定できる）と価格のリスト
id_prices = [
  {id: AAA, price: 100 },
  {id: BBB, price: 200 },
  {id: CCC, price: 300 },
  {id: DDD, price: 400 },
  {id: EEE, price: 500 },
  {id: FFF, price: 600 },
  {id: GGG, price: 700 },
  {id: HHH, price: 800 },
  {id: III, price: 900 },
  {id: JJJ, price: 1000 },
]

# 1リクエストごとにリクエストのハッシュを作成してそれを配列に
fees_estimate_requests = []
id_prices.each do |id_price|
  fees_estimate_requests << {
    marketplace_id: client.marketplace_id,
    id_type: id_type,
    id_value: id_price[:id],
    identifier: id_price[:id],
    is_amazon_fulfilled: true,
    price_to_estimate_fees: {
      listing_price: {
        currency_code: 'USD',
        amount: id_price[:price]
      },
      shippment: {...}, # 必要なら
      points: {...} # 必要なら
    }
  }
end

client.get_my_fees_estimate(fees_estimate_requests).xml
```
identifierはMWSのリファレンスには一意の値と記述されていますが、全部同じでも一応エラーが出ずに取得できました。

レスポンス例は以下の通りです。

```xml
<?xml version="1.0"?>
<GetMyFeesEstimateResponse
  xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01">
  <GetMyFeesEstimateResult>
    <FeesEstimateResultList>
      <FeesEstimateResult>
        <Status>Success</Status>
        <FeesEstimateIdentifier>
          <MarketplaceId>XXXXXXXXXX</MarketplaceId>
          <IdValue>XXXXXXXXXX</IdValue>
          <IdType>ASIN</IdType>
          <IsAmazonFulfilled>True</IsAmazonFulfilled>
          <PriceToEstimateFees>
            <ListingPrice>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>58.00</Amount>
            </ListingPrice>
            <Shipping>
              <CurrencyCode>USD</CurrencyCode>
              <Amount>0.00</Amount>
            </Shipping>
            <Points>
              <PointsNumber>0</PointsNumber>
            </Points>
          </PriceToEstimateFees>
          <SellerInputIdentifier>IDDDDDDDD</SellerInputIdentifier>
        </FeesEstimateIdentifier>
        <FeesEstimate>
          <TimeOfFeesEstimation>2015-07-19T23:15:11.859Z</TimeOfFeesEstimation>
          <TotalFeesEstimate>
            <CurrencyCode>USD</CurrencyCode>
            <Amount>10.00</Amount>
          </TotalFeesEstimate>
          <FeeDetailList>
            <FeeDetail>
              <FeeType>AmazonReferralFee</FeeType>
              <FeeAmount>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>8.70</Amount>
              </FeeAmount>
              <FeePromotion>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>1.00</Amount>
              </FeePromotion>
              <FinalFee>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>7.70</Amount>
              </FinalFee>
            </FeeDetail>
            <FeeDetail>
              <FeeType>VariableClosingFee</FeeType>
              <FeeAmount>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>0.00</Amount>
              </FeeAmount>
              <FinalFee>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>0.0</Amount>
              </FinalFee>
            </FeeDetail>
            <FeeDetail>
              <FeeType>FulfillmentFees</FeeType>
              <FeeAmount>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>2.30</Amount>
              </FeeAmount>
              <FinalFee>
                <CurrencyCode>USD</CurrencyCode>
                <Amount>2.30</Amount>
              </FinalFee>
              <IncludedFeeList>
                <FeeDetail>
                  <FeeType>OrderHandlingFee</FeeType>
                  <FeeAmount>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FeeAmount>
                  <FinalFee>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FinalFee>
                </FeeDetail>
                <FeeDetail>
                  <FeeType>PickAndPackFee</FeeType>
                  <FeeAmount>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>0.30</Amount>
                  </FeeAmount>
                  <FinalFee>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>0.30</Amount>
                  </FinalFee>
                </FeeDetail>
                <FeeDetail>
                  <FeeType>WeightHandlingFee</FeeType>
                  <FeeAmount>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FeeAmount>
                  <FinalFee>
                    <CurrencyCode>USD</CurrencyCode>
                    <Amount>1.00</Amount>
                  </FinalFee>
                </FeeDetail>
              </IncludedFeeList>
            </FeeDetail>
          </FeeDetailList>
        </FeesEstimate>
      </FeesEstimateResult>
    </FeesEstimateResultList>
  </GetMyFeesEstimateResult>
  <ResponseMetadata>
    <RequestId>21534f03-e7e3-4d9a-9bea-0e15add3326d</RequestId>
  </ResponseMetadata>
</GetMyFeesEstimateResponse>
```

## レスポンスの解析
レスポンスを掘って掘って解析していきます。
今回の例は単純にReferralFeeを配列に格納するだけのロジックです。

```ruby

# 先ほどの続き
responce = client.get_my_fees_estimate(fees_estimate_requests).xml
referral_fees = []
results = response.dig('GetMyFeesEstimateResponse', 'GetMyFeesEstimateResult', 'FeesEstimateResultList', 'FeesEstimateResult', 'FeesEstimate', 'FeeDetailList', 'FeeDetail')
# [注意] 1商品だけ取得した場合eachで回す必要はないです。
results.each do |result|
  result.each do |fees|
    referral_fees << fees.dig('FinalFee', 'Amount').to_f if fees.dig('FeeType') == 'ReferralFee'
  end
end
```

最終的に欲しいデータは結構深いのでデバッグしながら試した方が確実です。

# 思ったこと
なんでこんなにレスポンスがごちゃごちゃしてるのかというと、FeesEstimateIdentifierがあるからだと思います。
FeesEstimateIdentifierは実際どんなリクエスト出した内容がそのまま返ってくるんですけど、
これ必要なんでしょうか？
同一商品で違う価格を設定してリクエストすることもあると思うので、
リクエストを一意に絞るための情報は必要なのは分かるのですが、
そのためにリクエストパラメータにidentifierがあるんじゃないんです？
まあなんでもいいんですけどね！

ブログで見たい方はこちら
[Rails MWS 見積もり手数料の取得 GetMyFeesEstimate](http://nabesys.com/article/2018/11/14629/)