APIを利用してeBayに動画をアップロードしてみる

## ドキュメント
使用するAPIは「MediaAPI」
ドキュメントの内容をざっくり要約すると以下の通り
eBayドキュメントリンク:
https://developer.ebay.com/api-docs/commerce/media/resources/methods

・createVideo,getVideo,uploadVideoの3つのメソッドが用意されている
・createVideoでメタデータを作成するとレスポンスとしてvideo_idが返される
・このvideo_idを指定してuploadVideoで動画ファイルをアップロードする
・getVideoはvideo_idを指定してその動画ファイルの情報を取得できる(今回は使用しない)

ビデオの要件は以下の通り(ドキュメントより抜粋)
・サポートされる最大ビデオ サイズは 150 MB です
・最大アップロード解像度は1080pです
・サポートされている出力解像度は 240p、360p、480p、720p です。
・MP4 ファイル タイプ - MPEG-4 Part 10 または Advanced Videocoding (MPEG-4 AVC)
・YouTube やその他のビデオ プラットフォームへのリンクの提供はサポートされていません
・バリエーションのある商品は動画をサポートしていません

## createVideo(メタデータの作成)
リクエスト内容は以下の通り
![スクリーンショット 2023-11-12 22.51.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083940/686a5250-0b76-23da-58f2-ccff3b410d72.png)
![スクリーンショット 2023-11-12 22.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083940/a3e88c14-e954-bb33-f6ee-122385313f0c.png)
Content-Type:：application/json
classification：ビデオの利用目的らしいが、'ITEM'と入力すればOKのよう
description：ビデオの説明
size：アップロードするビデオのbyteサイズ
title：ビデオのタイトル

これらを踏まえて以下のようにリクエスト内容を作成してリクエストを実行
```ruby
        def client_opts
          {
            size:  File.size(video_file),
            title: "Product introduction video",
            description: "Show off product details",
            classification: [
                "ITEM"
            ]
          }
        end

```


ドキュメントによると![スクリーンショット 2023-11-12 22.45.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083940/4c6ad18e-6d59-118c-0c87-460146ff5af0.png)
ヘッダーにURLを返し、その中にvideo_idが含まれているようなので、
binding.pryで内容を確認し以下のようにvideo_idを取得
```
[4] pry(#<Ebay::Media::CreateVideo::Client>)> res
=> #<Net::HTTPCreated 201 Created readbody=true>
[5] pry(#<Ebay::Media::CreateVideo::Client>)> res[:Location]
=> "https://apim.ebay.com/commerce/media/v1_beta/video/c3bf3c3818b0ab8e87e3c0xxxxxxxxxx"
[6] pry(#<Ebay::Media::CreateVideo::Client>)> res[:Location].split('/').last
=> "c3bf3c3818b0ab8e87e3c0xxxxxxxxxx"
```

## uploadVideo(動画ファイルのアップロード)

リクエスト内容は先ほど取得したvideo_idのみ

![スクリーンショット 2023-11-12 22.49.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083940/d57c2438-22ec-18f3-4a0d-2f041e7ffaa0.png)

headerはapplication/octet-stream
初めてみるタイプだったので調べたところ「ファイルの種類が分からないとき」
「個別のMIMEタイプが用意されていないとき」「ファイルの種類を通知したくないとき」
に使用されるMIMEタイプとのこと。

![スクリーンショット 2023-11-12 22.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083940/d75e646c-7926-564d-828c-221c4696fc66.png)

rubyでの動画ファイルアップロードについては[こちら](https://qiita.com/asukamirai/items/c950c65c6473ca8ca96c#nethttp-%E3%81%AE%E5%A0%B4%E5%90%88)の記事を参考にさせていただき、
以下のように実装。
```ruby
        def call(video_id, video_file)
          @video_id = video_id
          @request_uri = URI.parse(uri)
          http.start do |http|
            req = Net::HTTP::Post.new(request_uri, headers)
            Rails.logger.info video_file if video_file.present?
            File.open(video_file, 'rb') do |f|
              req.body_stream = f
              req["Content-Length"] = f.size
              res = http.request(req)
            end
          end
        end

        private

        def http
          httq = Net::HTTP.new(request_uri.host, request_uri.port)
          if request_uri.port == 443
            httq.use_ssl = true
            httq.verify_mode = OpenSSL::SSL::VERIFY_NONE
          end
          httq
        end

        def headers
          {
            'Authorization' => "Bearer #{auth_token}",
            'Content-Type' => 'application/octet-stream'
          }
        end

        def uri
          "https://apim.ebay.com/commerce/media/v1_beta/video/#{video_id}/upload"
        end

        def method
          :post
        end
```

レスポンスは何も返さないので200を確認できればOK
```
pry(#<ListingsController>)> res
=> #<Net::HTTPOK 200 OK readbody=true>
```

### 商品への反映
MediaAPIではあくまで動画ファイルをアップロードするまでしかできないので、
アップロードした動画を商品に紐づけるには出品時(Additemなど)にvideo_idをリクエストすればOK
```ruby
      VideoDetails: {
        VideoID: video_id
      }
```

createVideo→uploadVideo→出品まで一連の流れで行うと、
動画がebayにアップロードされるまで時間がかかるため、
出品後しばらくして動画がアップロードされることもあるため注意。