【Ruby on Rails】最もわかりやすいYouTube API 使い方 

#導入
下記の記事で、APIキーの取得など解説されているので、まずはそちらを参考にしてみてください
[最近のGoogle API Ruby Clientを使ってYoutubeで動画を探してファイルとしてダウンロードする](https://qiita.com/taptappun/items/a217b7017316881d6459)

## Google APIをを触るための準備
### API Keyの取得

 * [Google API Console](https://console.developers.google.com/?hl=ja)に行く
 * プロジェクトを作成する
![GenerateProgect1.png](https://qiita-image-store.s3.amazonaws.com/0/72596/997dd6e1-eb67-891c-f6aa-c54f5262866b.png)
![GenerateProject2.png](https://qiita-image-store.s3.amazonaws.com/0/72596/153633e7-dc8d-184a-23d6-c7884971e6cb.png)

 * APIキーを取得する(プロジェクトを作成できればできています)
![GetNewAPIKey.png](https://qiita-image-store.s3.amazonaws.com/0/72596/af9dcd96-ac83-56d2-dedb-a3b9446af69e.png)

 * Youtube Data APIを有効にする
![EnableYoutubeDataAPI.png](https://qiita-image-store.s3.amazonaws.com/0/72596/b3823a98-7754-933a-c7ec-dd9d4dbd04e0.png)


### Google API Ruby Clientを使うための準備
[google-api-ruby-client](https://github.com/google/google-api-ruby-client)はGoogleのAPIを触るための、Google謹製のRubyライブラリです。
<font color="#FF0000">0.8.x以降にて大幅な変更があり、ライブラリの使い方が大きく変更しています</font>
Gemfileに記述する場合は

```ruby:Gemfile
gem 'google-api-client', '~> 0.11'
```

Ruby on Railsで導入する場合は、下記の記事を参考にしてみてください
[Railsでyoutube APIを使ってみた](https://qiita.com/sakakinn/items/46c0d4945e4646f346f6)

[gemについてのGithubはこちら](https://github.com/googleapis/google-api-ruby-client)


```:コマンド
$ bundle install
```
### APIkeyをcredentials.ymlにセットする
以前に記事を作成しているので、こちらを参考にして、環境変数を定義しましょう
[たった30分でわかるcredentials.yml.enc[rails5.2] - 環境変数を定義する使い方 ](https://qiita.com/mylevel/items/92c4a2a2f96edb10e298)



# クラスGoogle::Apis::YoutubeV3::YouTubeService
gem 'google-api-client'をインストールすることで利用できるようになったクラス。

[参考リンク](https://www.rubydoc.info/github/google/google-api-ruby-client/Google/Apis/YoutubeV3/YouTubeService)を翻訳しながら理解していきます。

GoogleのAPIを利用するには下記のように記述して、サービス名を指定します。

```ruby
Google::Apis::~サービス名
```
サービスはたくさんあるので、詳しくみたい方は次のリンクを開いてください。
[参考リンク](https://www.rubydoc.info/github/google/google-api-ruby-client/Google)

今回は``YoutubV3``を指定しています

```ruby
require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

Google::Apis::YoutubeV3
```
このYoutubeV3にもたくさんのサービスがあり、今回はYouTubeServiceを利用します。

```ruby
require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

Google::Apis::YoutubeV3::YouTubeService
```

このYouTubeServiceは、
動画のアップロード、プレイリストの作成と管理、コンテンツの検索など、YouTubeのコア機能をサポートします。

YouTubeServiceのクラスを利用するには、下記のように記述します

```ruby:例
require 'google/apis/youtube_v3'

Youtube = Google::Apis::YoutubeV3::YouTubeService.new
```
これでクラスを作成し、インスタンスメソッドが継承される

[Google::Apis::YoutubeV3::YouTubeServiceのGithubはこちら](https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google/apis/youtube_v3/service.rb#L39)

## インスタンス属性の概要
### key ⇒ String
APIの秘密鍵を入れる

```ruby:keyにAPIキーを定義
require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = "API KEY"
```
```ruby:でkeyにAPIキーを環境変数で定義
require 'google/apis/youtube_v3' #YoutubeV3を使用するために、呼び出す

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]
```

### quota_user ⇒ String
サーバーサイドアプリケーションのクォータ目的で利用可能です. ユーザーに割り当てられた任意の文字列を指定することができますが、40文字を超えてはいけません。
（どうもあまり使っている例はないので、さほど重要ではなさそうです）

### user_ip ⇒ String
非推奨です。代わりに quotaUser を使用してください。



## 補足でより理解する


```ruby:
class YouTubeService < Google::Apis::Core::BaseService

```
この``Google::Apis::YoutubeV3::YouTubeService``は``Google::Apis::Core::BaseService``を継承している

なので、``Google::Apis::Core::BaseService``のメソッドやインスタンス属性も利用可能

[Google::Apis::Core::BaseServiceのGithub](https://github.com/googleapis/google-api-ruby-client/blob/32749a8657477b82aaf8f8d6d2fcc157e7b45bd9/lib/google/apis/core/base_service.rb#L92)




##インスタンスメソッド　list_〇〇〇
クラスGoogle::Apis::YoutubeV3::YouTubeServiceには、list_〇〇〇メソッドが用意されている。


```:基本の型
list_〇〇〇(part名, デフォルトのnilから変更したいオプションキー)
```
基本的にマニュアルページでlistがあるものは利用できます。
[Channels:listの場合](https://developers.google.com/youtube/v3/docs/channels/list?hl=ja&apix=true#try-it)は、``list_channels``
[searchs:listの場合](https://developers.google.com/youtube/v3/docs/search/list?hl=ja#ruby)は、``list_searches``
[videos: listの場合](https://developers.google.com/youtube/v3/docs/videos/list?hl=ja)は、``list_videos``

他にもあるので、一度Githubを確認しておきましょう！
[githubはこちら](https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google/apis/youtube_v3/service.rb#L39)

### channels
[Channels:listの場合](https://developers.google.com/youtube/v3/docs/channels/list?hl=ja&apix=true#try-it)のページには、チャンネル情報を取得できる。
これをRailsで取得するには、メソッドで``list_channels``利用する

```ruby:元のインスタンスメソッド
      def list_channels(part, category_id: nil, for_username: nil, hl: nil, id: nil, managed_by_me: nil, max_results: nil, mine: nil, my_subscribers: nil, on_behalf_of_content_owner: nil, page_token: nil, fields: nil, quota_user: nil, options: nil, &block)
          command = make_simple_command(:get, 'youtube/v3/channels', options)
          command.response_representation = Google::Apis::YoutubeV3::ListChannelsResponse::Representation
          command.response_class = Google::Apis::YoutubeV3::ListChannelsResponse
          command.query['categoryId'] = category_id unless category_id.nil?
          command.query['forUsername'] = for_username unless for_username.nil?
          command.query['hl'] = hl unless hl.nil?
          command.query['id'] = id unless id.nil?
          command.query['managedByMe'] = managed_by_me unless managed_by_me.nil?
          command.query['maxResults'] = max_results unless max_results.nil?
          command.query['mine'] = mine unless mine.nil?
          command.query['mySubscribers'] = my_subscribers unless my_subscribers.nil?
          command.query['onBehalfOfContentOwner'] = on_behalf_of_content_owner unless on_behalf_of_content_owner.nil?
          command.query['pageToken'] = page_token unless page_token.nil?
          command.query['part'] = part unless part.nil?
          command.query['fields'] = fields unless fields.nil?
          command.query['quotaUser'] = quota_user unless quota_user.nil?
          execute_or_queue_command(command, &block)
        end
```

デフォルトがnilになっているので、

``list_channels(part名必須, nilから変更したいオプション）``と利用すれば良いでしょう。

#### 使用できるpart

|part名  | 情報 |
|:--|:--|
|id|--|
|snippet|--|
|brandingSettings|--|
|contentDetails|--|
|invideoPromotion|--|
|statistics|--|
|topicDetails|--|
part パラメータには、API レスポンスに含める 1 つまたは複数の channel リソース プロパティをカンマ区切りリストの形式で指定します。このパラメータに指定できる part 名は id、snippet、 brandingSettings、 contentDetails、 invideoPromotion、 statistics、 topicDetails です。このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、channel リソースで、contentDetails プロパティに uploads プロパティなど、他のプロパティが含まれているとします。この場合、part=contentDetails と設定すると、API レスポンスには、これらのネストされたプロパティもすべて含まれることになります。 


```ruby:part例
youtube.list_channels("id", オプションキー)
youtube.list_channels("snippet", オプションキー)
youtube.list_channels("brandingSettings", オプションキー)
youtube.list_channels("contentDetails", オプションキー)
youtube.list_channels("invideoPromotion", オプションキー)
youtube.list_channels("statistics", オプションキー)
youtube.list_channels("topicDetails", オプションキー)
```

#### オプション

[オプションは公式ガイドで解説](https://developers.google.com/youtube/v3/docs/channels/list?hl=ja&apix=true#try-it)

オプションに``適切に承認されたリクエストでのみ使用できます``と記述されている場合
> そのアカウントでログイン認証が成功した場合のみ、確認が可能
> つまり、他人のアカウント情報を確認できない。

##### フィルタ



#### レスポンス

```
{
  "kind": "youtube#channelListResponse", #list_channelsを利用していることがわかる
  "etag": etag,
  "nextPageToken": string,
  "prevPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    チャンネル リソース #ここに取得したい情報一覧が表示
  ]
}
```

```:実例
{
  "kind": "youtube#channelListResponse",
  "etag": "kEY0ccyV8cSoyol7-OVNH4UXvKw",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#channel",
      "etag": "WdLWGmqdwWdL0EWpqGLJ_eTOzjA",

      #portのidから得られる情報
      "id": "UCPyNsNSTUtywkekbDdCA_8Q", #portのidから得られる情報。この例では"youtubeチャンネルのid"を指定しているので、指定したチャンネルidが表示されている

      #portのsnippetから得られる情報
      "snippet": { #portのsnippetから得られる情報
        "title": "はなおでんがん",
        "description": "どうもおはえりすめんてん、はなおです。おはえりすめんてんは\nおはよう+ミカエリスメンテンの造語です。\nuuumっぽく無いですが、uuumです。uuumの闇担当です笑\n文系でも楽しめる理系動画をメインに\nいろいろやってます。編集には定評があります。チャンネル登録よろしくお願いしますψ(｀∇´)ψ\n2017年6月1日急上昇1位、登録者増加数日本1位に輝きました！\n\n☆twitterフォローお願いします(^^)→https://twitter.com/hanao87_0",
        "customUrl": "はなおchannnel",
        "publishedAt": "2014-11-27T13:34:05Z",
        "thumbnails": {
          "default": {
            "url": "https://yt3.ggpht.com/a/AATXAJyJBq8uwiGgJMOUoj9iEsOZgzrZszNMwMPRi8C8HxU=s88-c-k-c0xffffffff-no-rj-mo",
            "width": 88,
            "height": 88
          },
          "medium": {
            "url": "https://yt3.ggpht.com/a/AATXAJyJBq8uwiGgJMOUoj9iEsOZgzrZszNMwMPRi8C8HxU=s240-c-k-c0xffffffff-no-rj-mo",
            "width": 240,
            "height": 240
          },
          "high": {
            "url": "https://yt3.ggpht.com/a/AATXAJyJBq8uwiGgJMOUoj9iEsOZgzrZszNMwMPRi8C8HxU=s800-c-k-c0xffffffff-no-rj-mo",
            "width": 800,
            "height": 800
          }
        },
        "localized": {
          "title": "はなおでんがん",
          "description": "どうもおはえりすめんてん、はなおです。おはえりすめんてんは\nおはよう+ミカエリスメンテンの造語です。\nuuumっぽく無いですが、uuumです。uuumの闇担当です笑\n文系でも楽しめる理系動画をメインに\nいろいろやってます。編集には定評があります。チャンネル登録よろしくお願いしますψ(｀∇´)ψ\n2017年6月1日急上昇1位、登録者増加数日本1位に輝きました！\n\n☆twitterフォローお願いします(^^)→https://twitter.com/hanao87_0"
        }
      },

      #portのcontentDetailsから得られる情報
      "contentDetails": {
        "relatedPlaylists": {
          "likes": "",
          "favorites": "",
          "uploads": "UUPyNsNSTUtywkekbDdCA_8Q",
          "watchHistory": "HL",
          "watchLater": "WL"
        }
      },

      #portのstatisticsから得られる情報
      "statistics": {
        "viewCount": "757628049",
        "commentCount": "0",
        "subscriberCount": "1650000",
        "hiddenSubscriberCount": false,
        "videoCount": "628"
      },

      #portのtopicDetailsから得られる情報
      "topicDetails": {
        "topicIds": [
          "/m/02jjt",
          "/m/02jjt"
        ],

      #portのtopicCategoriesから得られる情報
        "topicCategories": [
          "https://en.wikipedia.org/wiki/Entertainment"
        ]
      },

      #portのbrandingSettingsから得られる情報
      "brandingSettings": {
        "channel": {
          "title": "はなおでんがん",
          "description": "どうもおはえりすめんてん、はなおです。おはえりすめんてんは\nおはよう+ミカエリスメンテンの造語です。\nuuumっぽく無いですが、uuumです。uuumの闇担当です笑\n文系でも楽しめる理系動画をメインに\nいろいろやってます。編集には定評があります。チャンネル登録よろしくお願いしますψ(｀∇´)ψ\n2017年6月1日急上昇1位、登録者増加数日本1位に輝きました！\n\n☆twitterフォローお願いします(^^)→https://twitter.com/hanao87_0",
          "keywords": "はなおチャンネル はなおでんがんチャンネル はなおでんがん",
          "defaultTab": "Featured",
          "moderateComments": true,
          "showRelatedChannels": true,
          "showBrowseView": true,
          "featuredChannelsTitle": "サブちゃんっ！",
          "featuredChannelsUrls": [
            "UCYeEDmOpvEtnKM6KSSqC4UA"
          ],
          "unsubscribedTrailer": "7YfzRxQWuAQ",
          "profileColor": "#000000"
        },
        "image": {
          "bannerImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletLowImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerTabletExtraHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileLowImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileMediumHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerMobileExtraHdImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj",
          "bannerTvImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
          "bannerTvLowImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
          "bannerTvMediumImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj",
          "bannerTvHighImageUrl": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj"
        },
        "hints": [
          {
            "property": "channel.featured_tab.template.string",
            "value": "Everything"
          },
          {
            "property": "channel.modules.show_comments.bool",
            "value": "True"
          },
          {
            "property": "channel.banner.mobile.medium.image.url",
            "value": "https://yt3.ggpht.com/Pp6VqShVmX38AglMkQpx5n-xGMyDoUKieYZWxGZY5H9waV157hONO_K0VqohkqxoF4-SAG-SjC4=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj"
          }
        ]
      }
    }
  ]
}
```

#### 実例
##### チャンネル名を取得(title)

```ruby:チャンネル登録者数を取得(subscriberCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("snippet", options)

@channel_title = response[:items][0][:snippet][:title]

```

##### チャンネルアイコンを取得(icon)

```ruby:チャンネル登録者数を取得(subscriberCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("snippet", options)

@channnel_icon = response[:items][0][:snippet][:thumbnails][:high]

```

##### チャンネル登録者数を取得

```ruby:チャンネル登録者数を取得(subscriberCount)
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("statistics", options)

@subscriberCount = response[:items][0][:statistics][:subscriberCount]

```

##### 総閲覧数を取得（viewCount）
```ruby:総閲覧数を取得（viewCount）
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :id => 'UCPyNsNSTUtywkekbDdCA_8Q' #YouTubeチャンネルのIDを指定
}

response = youtube.list_channels("statistics", options)

@viewCount = response[:items][0][:statistics][:viewCount]

```

### searchs
[searchs:listの場合](https://developers.google.com/youtube/v3/docs/search/list?hl=ja#ruby)
これをRailsで取得するには、メソッド``list_searchs``利用する

```ruby:元のインスタンスメソッド
def list_searches(part, channel_id: nil, channel_type: nil, event_type: nil, for_content_owner: nil, for_developer: nil, for_mine: nil, location: nil, location_radius: nil, max_results: nil, on_behalf_of_content_owner: nil, order: nil, page_token: nil, published_after: nil, published_before: nil, q: nil, region_code: nil, related_to_video_id: nil, relevance_language: nil, safe_search: nil, topic_id: nil, type: nil, video_caption: nil, video_category_id: nil, video_definition: nil, video_dimension: nil, video_duration: nil, video_embeddable: nil, video_license: nil, video_syndicated: nil, video_type: nil, fields: nil, quota_user: nil, options: nil, &block) 
           command = make_simple_command(:get, 'youtube/v3/search', options) 
           command.response_representation = Google::Apis::YoutubeV3::SearchListsResponse::Representation 
           command.response_class = Google::Apis::YoutubeV3::SearchListsResponse 
           command.query['channelId'] = channel_id unless channel_id.nil? 
           command.query['channelType'] = channel_type unless channel_type.nil? 
           command.query['eventType'] = event_type unless event_type.nil? 
           command.query['forContentOwner'] = for_content_owner unless for_content_owner.nil? 
           command.query['forDeveloper'] = for_developer unless for_developer.nil? 
           command.query['forMine'] = for_mine unless for_mine.nil? 
           command.query['location'] = location unless location.nil? 
           command.query['locationRadius'] = location_radius unless location_radius.nil? 
           command.query['maxResults'] = max_results unless max_results.nil? 
           command.query['onBehalfOfContentOwner'] = on_behalf_of_content_owner unless on_behalf_of_content_owner.nil? 
           command.query['order'] = order unless order.nil? 
           command.query['pageToken'] = page_token unless page_token.nil? 
           command.query['part'] = part unless part.nil? 
           command.query['publishedAfter'] = published_after unless published_after.nil? 
           command.query['publishedBefore'] = published_before unless published_before.nil? 
           command.query['q'] = q unless q.nil? 
           command.query['regionCode'] = region_code unless region_code.nil? 
           command.query['relatedToVideoId'] = related_to_video_id unless related_to_video_id.nil? 
           command.query['relevanceLanguage'] = relevance_language unless relevance_language.nil? 
           command.query['safeSearch'] = safe_search unless safe_search.nil? 
           command.query['topicId'] = topic_id unless topic_id.nil? 
           command.query['type'] = type unless type.nil? 
           command.query['videoCaption'] = video_caption unless video_caption.nil? 
           command.query['videoCategoryId'] = video_category_id unless video_category_id.nil? 
           command.query['videoDefinition'] = video_definition unless video_definition.nil? 
           command.query['videoDimension'] = video_dimension unless video_dimension.nil? 
           command.query['videoDuration'] = video_duration unless video_duration.nil? 
           command.query['videoEmbeddable'] = video_embeddable unless video_embeddable.nil? 
           command.query['videoLicense'] = video_license unless video_license.nil? 
           command.query['videoSyndicated'] = video_syndicated unless video_syndicated.nil? 
           command.query['videoType'] = video_type unless video_type.nil? 
           command.query['fields'] = fields unless fields.nil? 
           command.query['quotaUser'] = quota_user unless quota_user.nil? 
           execute_or_queue_command(command, &block) 
         end 
```
デフォルトがnilになっているので、

``list_searches(part, nilから変更したいオプション）``と利用すれば良いでしょう。

#### 使用できるpart


|part名  | 情報 |
|:--|:--|
|id|--|
|snippet|--|

part パラメータには、API レスポンスに含める 1 つまたは複数の search リソースのプロパティをカンマ区切りリストの形式で指定します。このパラメータに指定できる part 名は id と snippet です。

このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、search の結果では、snippet プロパティには、結果のタイトルや説明などを識別する別のプロパティが含まれます。この場合、part=snippet と設定すると、API レスポンスには、ネストされているプロパティもすべて含まれることになります。

```ruby:part例
youtube.list_searches("id", オプションキー)
youtube.list_searches("snippet", オプションキー)
```
##### レスポンス

```
{
  "kind": "youtube#searchListResponse", #ここでlist_searchesを利用していることがわかる
  "etag": etag,
  "nextPageToken": string,
  "prevPageToken": string,
  "pageInfo": {
    "totalResults": integer,
    "resultsPerPage": integer
  },
  "items": [
    検索リソース
  ]
}
```

```:portsがidの場合
{
  "kind": "youtube#searchListResponse",
  "etag": "LvvBU1w1wIcopnyguJvHCsjcfiU",
  "nextPageToken": "CAEQAA",
  "regionCode": "JP",
  "pageInfo": {
    "totalResults": 656,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "qxByuq8_-FH49yZF8MSHKK-b5lA",
      #idしか得られていない
      "id": {
        "kind": "youtube#video",
        "videoId": "E69J8_CyuWo"
      }
    }
  ]
}
```

```:portsがsnippetの場合
{
  "kind": "youtube#searchListResponse",
  "etag": "vF-cucsIawV9-XYHVe_HDOX5X64",
  "nextPageToken": "CAEQAA",
  "regionCode": "JP",
  "pageInfo": {
    "totalResults": 656,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "JIYYfrcpdz_hJ5uGqaeeqal5n3s",
      "id": {
        "kind": "youtube#video",
        "videoId": "E69J8_CyuWo"
      },
      #snippetの項目があり、動画のタイトルなどの情報がある
      "snippet": {
        "publishedAt": "2020-07-23T11:02:06Z",
        "channelId": "UCPyNsNSTUtywkekbDdCA_8Q",
        "title": "「車で東京行こ？」ペーパードライバーの後輩がアルファードで拉致して東京まで運転するドッキリで車内ガチギレ大発狂ｗｗｗｗｗｗｗｗ",
        "description": "練習中、2回くらい死にかけました ((( ))) 編集：マコ チャンネル登録お願いします！ ○はなおのtwitter→ https://twitter.com/hanao87_0 ○でんがんのtwitter→ ...",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/E69J8_CyuWo/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/E69J8_CyuWo/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/E69J8_CyuWo/hqdefault.jpg",
            "width": 480,
            "height": 360
          }
        },
        "channelTitle": "はなおでんがん",
        "liveBroadcastContent": "none",
        "publishTime": "2020-07-23T11:02:06Z"
      }
    }
  ]
}
```

#### オプション




```ruby:list_searchesのオプジョン
list_searches(part, channel_id: nil, channel_type: nil, event_type: nil, for_content_owner: nil, for_developer: nil, for_mine: nil, location: nil, location_radius: nil, max_results: nil, on_behalf_of_content_owner: nil, order: nil, page_token: nil, published_after: nil, published_before: nil, q: nil, region_code: nil, related_to_video_id: nil, relevance_language: nil, safe_search: nil, topic_id: nil, type: nil, video_caption: nil, video_category_id: nil, video_definition: nil, video_dimension: nil, video_duration: nil, video_embeddable: nil, video_license: nil, video_syndicated: nil, video_type: nil, fields: nil, quota_user: nil, user_ip: nil, options: nil)
```
このオプションは大量にあるので、必要な分optionに定義して、省略する

```ruby:通常
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = "API KEY"
youtube_search_list = youtube.list_searches("id,snippet", type: "video", q: "キーワード", max_results: 50)
```

```ruby:list_searchesのオプションを定義して省略
require 'google/apis/youtube_v3'
option = {
    q: keyword,
    type: 'video',
    max_results: 2,
    order: :date,
    page_token: next_page_token,
    published_after: after.iso8601,
    published_before: before.iso8601
  }
response = youtube.list_searches(:snippet, option)


youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = "API KEY"
youtube_search_list = youtube.list_searches(:snippet, option)

```

[それぞれのオプションの解説はこちら](https://developers.google.com/youtube/v3/docs/search/list?hl=ja#ruby)

オプションに``適切に承認されたリクエストでのみ使用できます``と記述されている場合
> そのアカウントでログイン認証が成功した場合のみ、確認が可能
> つまり、他人のアカウント情報を確認できない。




#### 実例
##### 動画のURLを取得する

```ruby:動画のURLを作成する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :channelId => 'UCPyNsNSTUtywkekbDdCA_8Q', #YouTubeチャンネルのIDを指定
  :order => "date"
}

response = youtube.list_searches(:id, options)

video_id = response[:items][0][:id][:videoId]
@video_url = "https://www.youtube.com/watch?v=#{video_id}"

```

##### 動画タイトルを取得する

```ruby:動画タイトルを取得する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :channelId => 'UCPyNsNSTUtywkekbDdCA_8Q', #YouTubeチャンネルのIDを指定
  :order => "date"                          #日付順で動画を取得
}

response = youtube.list_searches(:snippet, options)

@video_title = response[:items][0][:snippet][:title]

```

##### 動画サムネイル画像を取得する

```ruby:動画タイトルを取得する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

options = {
  :channelId => 'UCPyNsNSTUtywkekbDdCA_8Q', #YouTubeチャンネルのIDを指定
  :order => "date"                          #日付順で動画を取得
}

response = youtube.list_searches(:snippet, options)

@video_image = response[:items][0][:snippet][:thumbnails][:high]

```

##### YouTubeチャンネルのURLを取得する

```ruby:YouTubeチャンネルURLを取得する
require 'google/apis/youtube_v3'

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = Rails.application.credentials.google[:api_key]

keyword = "はなおでんがん" #実際には検索フォームで取得するが、今回は例として”はなおでんがん”をセット
options = {
  :q => keyword,   #キーワード検索している想定
  :order => "date" #日付順で動画を取得
}

response = youtube.list_searches("id, snippet", options)

channel_id = response[:items][0][:snippet][:channelId]
@channel_url = "https://www.youtube.com/channel/#{channel_id}" #aタグに挿入するURL
@channel_title = response[:items][0][:channelTitle]            #aタグのテキスト用
```
##### その他

```ruby:実例
require 'google/apis/youtube_v3'
require 'active_support/all'

GOOGLE_API_KEY="<API_KEY>" #上記で作成したキー

def find_videos(keyword, after: 1.months.ago, before: Time.now) #検索キーワードと検索範囲を変えれるように引数に値を取っています
  service = Google::Apis::YoutubeV3::YouTubeService.new
  service.key = GOOGLE_API_KEY
  next_page_token = nil
  opt = {
    q: keyword,
    type: 'video',
    max_results: 2,
    order: :date,
    page_token: next_page_token,
    published_after: after.iso8601,
    published_before: before.iso8601
  }
  results = service.list_searches(:snippet, opt)
  results.items.each do |item|
    id = item.id
    snippet = item.snippet
    puts "\"#{snippet.title}\" by #{snippet.channel_title} (id: #{id.video_id}) (#{snippet.published_at})"
  end
end

find_videos('明日香ちゃんねる')
```

### subscriptions
[Subscriptions: listの場合](https://developers.google.com/youtube/v3/docs/subscriptions/list?hl=ja)
これをRailsで取得するには、メソッド``list_subscriptions``利用する

#### 使用できるpart

|part名  | 情報 |
|:--|:--|
|id|--|
|snippet|part=snippet と設定すると、API レスポンスには、ネストされているプロパティもすべて含まれることになります。|
|contentDetails|--|

```ruby:partの例
youtube.list_videos("id", オプションキー)
youtube.list_videos("snippet", オプションキー)
youtube.list_videos("contentDetail", オプションキー)
```

このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、subscription リソースの snippet プロパティに、登録チャンネルの表示タイトルなど、他のプロパティが含まれているとします。この場合、part=snippet と設定すると、API レスポンスには、ネストされているプロパティもすべて含まれることになります。

####オプション

オプションに``適切に承認されたリクエストでのみ使用できます``と記述されている場合
> そのアカウントでログイン認証が成功した場合のみ、確認が可能
> つまり、他人のアカウント情報を確認できない。


### videos
[videos: listの場合](https://developers.google.com/youtube/v3/docs/videos/list?hl=ja)
これをRailsで取得するには、メソッド``list_videos``利用する

#### 使用できるpart

|part名  | 情報 |
|:--|:--|
|id|--|
|snippet|part=snippet と設定すると、API レスポンスにはこれらのプロパティすべてが含まれることになります。

|
|contentDetails|--|
|fileDetailsn|--|
|liveStreamingDetails|--|
|player|--|
|processingDetails|--|
|recordingDetails|--|
|statistics|--|
|status|--|
|suggestions|--|

このパラメータに子プロパティを持つプロパティが指定されている場合、その子プロパティもレスポンスに含まれます。たとえば、video リソースで、snippet プロパティに channelId、title、description、tags、categoryId などのプロパティが含まれているとします。この場合、part=snippet と設定すると、API レスポンスにはこれらのプロパティすべてが含まれることになります。

```ruby:partの例
youtube.list_videos("id", オプションキー)
youtube.list_videos("snippet", オプションキー)
youtube.list_videos("contentDetail", オプションキー)
youtube.list_videos("fileDetailsn", オプションキー)
youtube.list_videos("liveStreamingDetails", オプションキー)
youtube.list_videos("player", オプションキー)
youtube.list_videos("processingDetails", オプションキー)
youtube.list_videos("recordingDetails", オプションキー)
youtube.list_videos("statistics", オプションキー)
youtube.list_videos("status", オプションキー)
youtube.list_videos("recordingDetails", オプションキー)
youtube.list_videos("suggestions", オプションキー)
```




#### オプション

```ruby:list_videosのオプジョン
list_videos(part, chart: nil, hl: nil, id: nil, locale: nil, max_height: nil, max_results: nil, max_width: nil, my_rating: nil, on_behalf_of_content_owner: nil, page_token: nil, region_code: nil, video_category_id: nil, fields: nil, quota_user: nil, user_ip: nil, options: nil) 
```



このオプジョンが長いのでoptionを定義して、省略している例

```ruby:optionを定義して省略
options = {
  :id => 'xftKTwxb5oE'
}

response = youtube.list_videos("statistics", options)
```

オプションに``適切に承認されたリクエストでのみ使用できます``と記述されている場合
> そのアカウントでログイン認証が成功した場合のみ、確認が可能
> つまり、他人のアカウント情報を確認できない。


#### 実例

[参考資料:Google:Auth](https://www.rubydoc.info/gems/googleauth/0.5.0/Google/Auth/UserAuthorizer)

```ruby:例
require 'googleauth'
require 'googleauth/stores/file_token_store'
require 'google/apis/youtube_v3'

OOB_URI = 'urn:ietf:wg:oauth:2.0:oob'
APPLICATION_NAME = 'idolsongplaylist'
CLIENT_SECRETS_PATH = 'client_secret.json'
CREDENTIALS_PATH = File.join(Dir.home, '.credentials', "tokens.yaml")
SCOPE = [ "https://www.googleapis.com/auth/youtube" ]

# 認証メソッド
def authorize
  FileUtils.mkdir_p(File.dirname(CREDENTIALS_PATH))

  client_id = Google::Auth::ClientId.from_file(CLIENT_SECRETS_PATH)
  token_store = Google::Auth::Stores::FileTokenStore.new(file: CREDENTIALS_PATH)
  authorizer = Google::Auth::UserAuthorizer.new(client_id, SCOPE, token_store)
  user_id = 'default'
  credentials = authorizer.get_credentials(user_id)
  if credentials.nil?
    url = authorizer.get_authorization_url(base_url: OOB_URI)
    puts 'Open the following URL in the browser and enter the ' +
         'resulting code after authorization'
    puts url
    code = gets
    credentials = authorizer.get_and_store_credentials_from_code(
      user_id: user_id, code: code, base_url: OOB_URI)
  end
  credentials
end

youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.client_options.application_name = APPLICATION_NAME #Google::Apis::Core::BaseServiceから継承したメソッド
youtube.authorization = authorize #作成したauthorizeメソッドを実施

options = {
  :id => 'xftKTwxb5oE'
}

response = youtube.list_videos("statistics", options)
pp response
```
[参考：Ruby で YouTube Data API (v3) を使う](https://qiita.com/eggman/items/b254612d36eba4370a17)


[これらのメソッドまとめページはこちら](https://www.rubydoc.info/github/google/google-api-ruby-client/Google/Apis/YoutubeV3/YouTubeService)



## 参考リンク
[最近のGoogle API Ruby Clientを使ってYoutubeで動画を探してファイルとしてダウンロードする](https://qiita.com/taptappun/items/a217b7017316881d6459)
[Railsでyoutube APIを使ってみた](https://qiita.com/sakakinn/items/46c0d4945e4646f346f6)
[Ruby で YouTube Data API (v3) を使う](https://qiita.com/eggman/items/b254612d36eba4370a17)
[Youtubeのチャンネル登録者数を取得する](https://qiita.com/k8uwall/items/b3a2c09d15f827fe888e)
[メソッド一覧](https://www.rubydoc.info/github/google/google-api-ruby-client/Google/Apis/YoutubeV3/YouTubeService)
[RubyとPythonでGoogle APIを叩いてみた − データベースをSpreadsheetにしてGoogle Driveで管理する](https://qiita.com/Yama-to/items/74273213d5d89db7eb37)