RailsアプリでYoutubeチャンネルの情報を取得する(Yt gemを使う）

# はじめに
Ruby on Railsでwebアプリを作成しているRails初学者です。
突然個人的な話で恐縮ですが、最近Youtuberにハマっておりまして、プログラミングの勉強以外はもっぱらYoutubeを見て過ごしています（笑）ユーチューブ楽しい・・・ユーチューバーいい・・・
そんな日常なので勉強のアウトプットとして、Youtubeの各種情報を扱うwebアプリを作りたいなぁと思い立ち、制作をはじめました。勉強＋趣味で最高！単純ですね

そのために色々調べ物をしている内に、Youtubeの情報を扱うには、**Youtube Data API**を使う必要があるとわかりました。

今回は、このYoutube APIを使ったYoutubeの情報取得について備忘録的に書いていきたいと思います。

# Youtube Data APIについて

[Youtube Data APIの概要](https://developers.google.com/youtube/v3/getting-started?hl=ja)

本APIでは様々な機能が用意されています。

・リソースの種類
![スクリーンショット 2020-10-04 14.11.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176783/b6439133-3a8f-dff1-ee27-49fac6487ff5.png)

・操作の種類
![スクリーンショット 2020-10-04 14.11.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176783/4ebf5bce-49d9-0655-f56e-da6a29be8913.png)

今回はこの中でも、Youtubeのチャンネル情報を取得するためにやったことについて書いていきたいと思います。
（上のテーブルにおける、リソース種類：channel、操作：list）

## 本記事の前提
・Google APIで各種操作を行い、Youtube Data APIへアクセスできるAPI KEYを取得していること。
API　KEY取得の手順については、以下を参照ください。

[最近のGoogle API Ruby Clientを使ってYoutubeで動画を探してファイルとしてダウンロードする](https://qiita.com/taptappun/items/a217b7017316881d6459)
[【Ruby on Rails】最もわかりやすいYouTube API 使い方](https://qiita.com/gyu_outputs/items/af4319258b3d67c57d24)

## 筆者の環境
Docker for Macでコンテナを作成し、Railsを開発しています。

```
ruby 2.4.5
Ruby on rails 5.0.7.2

#前提gem
#GOOGLE API KEYを環境変数に入れるためにdotenvを使用しています
dotenv-rails 2.7.6
```


## Gemの選定
このAPIを扱うためのgemとして有名なのは、各種Google APIをrailsで叩くために作られたgoogle公式の`google-api-ruby-client`です。

[google-api-ruby-client](https://github.com/googleapis/google-api-ruby-client)

日本語でもある程度情報があり公式のものなので、当初はこちらのgemを検討していたのですが、いかんせん今回はYoutube APIのみ使う予定で、もう少しシンプルなもので出来ないかなと考えていました。

それで見つけたのが`yt`です。

[Yt - a Ruby client for the YouTube API](https://github.com/Fullscreen/yt)

Youtube APIに特化したgemです。あまり情報なくスターも少ないので心配だったのですが、とにかくシンプルな記述で実装できるので、個人的にはアリでした！
以降は、YtでのYoutube情報取得について書いていきます。

# Ytの設定
まずはgemをダウンロードします。
ytのgithubにある通り、Gemfileに記述します。

```:Gemfile
gem 'yt', '~> 0.32.0'
```

その後bundle インストールを行います。

```:terminal
bundle install
```

※2020/10月時点、筆者の環境に入ったytのバージョンは以下の通りです。

```:gemlife.lock
yt (0.32.6)
```


ytのダウンロードが完了したら、GOOGLE API KEYをytに設定するconfigを書いてみます。
各種情報を呼び出しの際には、サーバの読み取りだけなのでこのAPI KEYのみでOKです。
※筆者は`dotenv-rails`で環境変数を管理しています。
参考）[環境変数の設定方法](https://qiita.com/yuichir43705457/items/7cfcae6546876086b849)

もしYoutubeで動画アップロードなどのウェブクライアントを操作をしたい場合は、
API KEYと別に`client_id`、`client_secret`が必要になります。
参考）[Module: Yt::Config](https://www.rubydoc.info/gems/yt/Yt/Config)

````ruby:videos_controller.rb
class VideosController < ApplicationController
 GOOGLE_API_KEY = ENV['GOOGLE_API_KEY'] #.envにAPI KEYをセット済の場合の書き方
:
 def set_yt
   Yt.configure do |config|
     config.api_key = GOOGLE_API_KEY #Configにgoogle APIをセット
   end
 end
:
end
```

これで各種操作の前に`set_yt`を事前に呼び出せば、API KEYが設定され、ytで各種操作ができるようになります。


# ytでのYoutube情報取得

以上で、事前準備は完了です。早速、色々操作をしていきましょう。

今回は、自分のwebアプリでやりたかった２つの操作について見ていきます。
**その１）指定したYoutubeのチャンネル登録者数を取得する**
**その２）指定したYoutubeのチャンネルの動画を取得し、DBに保存する**

それぞれについて見ていきましょう！


## その１）指定したYoutubeのチャンネル登録者数を取得する
まずは、YoutubeチャンネルのIDをYoutubeチャンネルのURLから持ってきます。

![スクリーンショット 2020-10-04 15.03.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176783/8be443f0-f917-8840-14e1-db7518f0b29b.png)


登録したいチャンネルのページに行き（上の画像のような画面）、URLの**channel/**以降の部分がチャンネルIDになります。この場合だと、`UCQ_MqAw18jFTlBB-f8BP7dw`の部分です。
この情報をチャンネルidとして設定していきます。

そして、そのIDを元にチャンネル情報を取得します。とてもカンタン。

```ruby:videos_controller.rb
class VideosController < ApplicationController
:

 def index #ここは適当なメソッドを
  set_yt #先ほど設定したconfigを読み込む
  channel = Yt::Channel.new id: 'UCQ_MqAw18jFTlBB-f8BP7dw' #チャンネル情報を取得
  @subscriber_count = channel.subscriber_count #登録者数を取得
 end

:
end
```

これで、`subscriber_count`を呼び出すと、登録者数を取得することができます。

```ruby:index.html.erb
:
<%= @subscriber_count %>
:
```


こんな感じ（jqueryで見せ方を加工してます。）
![スクリーンショット 2020-10-04 16.01.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176783/968d2803-9157-be99-6f39-f1815b6d53b4.png)



## その２）指定したYoutubeのチャンネルの動画を取得し、DBに保存する
チャンネルのIDの取得はその１と同様です。

その２では、
①チャンネル情報を取得
②そのチャンネルに紐づくvideoを取得
③その情報をDBに保存する
という大きく分けて３つの手順を行います。
今回使用する保存先のテーブルは、ビデオテーブルでビデオ名、URL、投稿日を保持しています。

全てのデータを一気に取得すると、Google API側の制限に引っかかる可能性があるため、一旦直近の動画30件ほどを取得するように書いてきます。
※where内の書き方については以下参照
（参考）
[Railsでyoutube APIを使ってみた](https://qiita.com/sakakinn/items/46c0d4945e4646f346f6)
[gemのytで動画の検索方法や複数情報取得がようやくわかった！！](https://yatta47.hateblo.jp/entry/2016/10/31/100755)

```ruby:videos_controller.rb
:
 #youtube動画取得を呼び出す
 def create_videodata
   create_videodata_from_youtube
   redirect_to videos_path, notice: { "動画取得が完了しました" }
 end

:
 def create_videodata_from_youtube
  set_yt
  channel = Yt::channel.new id: 'UCQ_MqAw18jFTlBB-f8BP7dw' #チャンネル情報を取得
  #直近2ヶ月間で投稿された動画を30件ほど取得する。
  channel.videos.where(publisher_afer: 2.months.ago.iso8601).first(30).each do |video|
   #保存済みのvideoデータでない場合、テーブルとして追加する
    unless Video.find_by(name: video.title)
      Video.create!(
        name: video.title,
        url: "https://www.youtube.com/watch?v=" + video.id,
        uploaded_at: video.published_at
      )
     end
   end
 end
:
```

これで、必要な場面で上記のメソッドを呼び出せば、youtubeの動画を取得することができます。
私が作成したwebアプリでは、「動画を取得」ボタンを設置し、それを押下したタイミングでcreate_videodataを呼び出し、Youtubeの情報を取得するようにしました。

これで自分が実装したかった機能は実装できました。Ytのおかげでかなりシンプルな記述に！

# トラブルシューティング（quotaExceeded）
最初、書き方はわかったのですが、なぜかうまくいかず・・・見てみると「quotaExceeded」
つまりは、使いすぎて１日ごとの割当がなくなってしまい、Google APIの制限がかかってますというエラーが出ていました。
その時点では１度も成功していなかったので、「割当がなくなるわけないんだけど・・・」と思いつつ、日を改めていたりしたのですが、

以下を参考に、自分のアカウントを変えて、作り直したらうまく行きました！
https://teratail.com/questions/270779

これは調べてもなぜかさっぱりわかりません・・・。もしも同じようにエラーが出てしまっている方がいたら、googleのアカウントを作って別アカウントでAPI KEYを再作成してみてください。


# 終わりに
Youtube APIを使って、Youtubeの情報を取得する方法を見ていきました。
Ytを使うとかなりシンプルに記述できるので、やりたいことが簡単に実装できました。
他にも持ってきたい情報は多々あるので、他の機能も調べて使っていきたいです。
最後に、参考にさせていただいた記事やブログ等の筆者のみなさん、ありがとうございました！