20
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

YouTube Data APIで登録チャンネルのリストを取得する

Posted at

はじめに

ポートフォリオにて、YouTubeで自分が登録しているチャンネル一覧を取得する機能を実装しようとした際に、参考になる記事に出会えず、なかなか苦労したので本記事を作成しました。

本記事では登録チャンネルの一覧取得のみを取り上げていますが、応用することでYouTube Data APIのリファレンスで**このパラメータは、適切に承認されたリクエストでのみ使用できます。**という記述のあるフィルタなどを利用することができるかと思います!

環境

Ruby:3.0.2
Rails:6.0.4

1.Google APIでプロジェクトを作成したりする

プロジェクトの作成

こちらからAPIのダッシュボードに移動します。
②「プロジェクトを作成」から、プロジェクトの作成します。
③「プロジェクト」に任意のプロジェクト名を入力し、「作成」。

OAuth同意画面の編集

①左側のメニューから「OAuth同意画面」を開き、「外部」を選択して「作成」。
②「① OAuth認証画面」では、必須項目にそれぞれ入力後、「保存して次へ」。
③「② スコープ」では、まず「スコープを追加または削除」から、範囲.../auth/userinfo.emailにチェックをつけて「更新」し、「保存して次へ」。
④「③ テストユーザー」では、[+ADD USERS]で自身のメールアドレスを入力して[追加]し、[保存して次へ]。
⑤「④ 概要」はこれまでの内容が表示されるだけなので、これにてOAuth同意画面の編集は完了です。

OAuthクライアントIDの作成

①画面上部の[+ 認証情報を作成]から、[OAuthクライアントID]を選択します。
②[アプリケーションの種類]でウェブアプリケーションを選択する。[名前]は任意のものでOK。
③続けて、「承認済みのリダイレクトURI」の[+ URIを追加]でhttp://localhost:3000/auth/google_oauth2/callbackと入力します。
④[作成]を押すと、クライアントIDとクライアントシークレットが表示されるので、メモ帳などにコピペしておきます。

ライブラリの有効化

左側のメニューから「ライブラリ」を開き、以下のライブラリを検索して、それぞれ有効化しておきます。

  • Google+ API
  • YouTube Data API v3

2.必要なgemをインストールする

rails newでアプリケーションを作成したら、以下のgemをGemfileに追加して、bundle installします。

Gemfile
#環境変数用
gem 'dotenv-rails'
#Googleログイン用
gem 'omniauth-google-oauth2'
gem 'omniauth-rails_csrf_protection'
#YouTubeデータ取得用
gem 'google-apis-youtube_v3'

また、bundle exec rails db:createでDBを作成しておきましょう。

3.Googleログインの実装

.envを作成し、環境変数を記述

.env
GOOGLE_CLIENT_ID='OAuthクライアントID作成時に表示されたクライアントID'
GOOGLE_CLIENT_SECRET='OAuthクライアントID作成時に表示されたクライアントシークレット'

②認証用の設定ファイルを作成
/config/initializers内に、omniauth.rbを作成し、以下のように記述します。

omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  provider :google_oauth2,
            ENV['GOOGLE_CLIENT_ID'],
            ENV['GOOGLE_CLIENT_SECRET']
end

③Userモデルを生成

$ bundle exec rails g model User name email avatar token refresh_token
$ bundle exec rails db:migrate

Userモデルの各カラムはstring型としているので、型指定を省いています。

④ログイン周りの処理を実装

bundle exec rails g controller sessions
sessions_controller.rb
class SessionsController < ApplicationController
  skip_before_action :check_logged_in, only: :create

  def create
    if user = User.find_or_create_from_auth_hash(auth_hash)
      log_in user
    end
    redirect_to root_path
  end

  def destroy
    log_out
    redirect_to root_path
  end

  private

  def auth_hash
    request.env['omniauth.auth']
  end
end

sessions_helper.rb
module SessionsHelper
  def current_user
    return unless (user_id = session[:user_id])

    @current_user ||= User.find_by(id: user_id)
  end

  def log_in(user)
    session[:user_id] = user.id
  end

  def log_out
    session.delete(:user_id)
    @current_user = nil
  end
end
application_cotroller.rb
class ApplicationController < ActionController::Base
  include SessionsHelper
  before_action :check_logged_in

  def check_logged_in
    return if current_user

    redirect_to root_path
  end
end

⑤Home画面周りの実装

bundle exec rails g controller home index
home_controller.rb
class HomeController < ApplicationController
  skip_before_action :check_logged_in, only: :index

  def index; end
end

⑥ルーティングを設定

routes.rb
Rails.application.routes.draw do
  root 'home#index'

  get 'auth/:provider/callback', to: 'sessions#create'
  get 'auth/failure', to: redirect('/')
  get 'log_out', to: 'sessions#destroy', as: 'log_out'

  resources :sessions, only: %i[create destroy]
end

⑦Userモデルにメソッドを記述

user.rb
class User < ApplicationRecord
  #クラスメソッドとして定義
  class << self
    def find_or_create_from_auth_hash(auth_hash)
      user_params = user_params_from_auth_hash(auth_hash)
      #emailをキーとして検索し、重複するものがあればユーザーを作成・更新しない
      find_or_create_by(email: user_params[:email]) do |user|
        user.update(user_params)
      end
    end

    private

    #googleログイン時に渡されるauth_hashから、必要な情報を各カラムに格納
    def user_params_from_auth_hash(auth_hash)
      {
        name: auth_hash.info.name,
        email: auth_hash.info.email,
        avatar: auth_hash.info.image,
        token: auth_hash.credentials.token,
        refresh_token: auth_hash.credentials.refresh_token
      }
    end
  end

token属性には、登録チャンネルのリストを取得する際に必要なアクセストークンが格納されます。
refresh_token属性には、上記のアクセストークンを更新する際に必要なリフレッシュトークンが格納されるのですが、本記事では扱いません…
(アクセストークンの有効期限が1時間なので、時限(Rakeタスクなど?)でリフレッシュトークンを用いた更新をしてあげると良いかと思います…)

⑧ビューにログイン・ログアウト用のリンクを作成

home/index.html.erb
<% if current_user %>
  <%= image_tag current_user.avatar %>
  <%= current_user.name %>さん
  <%= link_to "ログアウト", log_out_path %>
<% else  %>
  <%= link_to "Googleでログイン", "/auth/google_oauth2", method: :post %>
<% end %>

ここまでで、Googleログインの実装は完了です。
なお、ここまでの実装については、こちらの記事を参考にさせていただきました!

4.登録チャンネルのリストを取得する

①モデルを作成する

bundle exec rails g model Subscription
subscription.rb
class Subscription < ApplicationRecord
  require 'google/apis/youtube_v3'

  def channels(user)
    service = Google::Apis::YoutubeV3::YouTubeService.new
    service.authorization =
      Signet::OAuth2::Client.new(
        access_token: user.token
      )

    service.list_subscriptions(:snippet, mine: true, max_results: 10)
  end

end

list_subscriptionsメソッドに利用できる引数はこちらで確認できます。

②コントローラーを作成する

bundle exec rails g controller subscriptions index
subscriptions_controller.rb
class SubscriptionsController < ApplicationController

  def index
    @subscription = Subscription.new
    @user = current_user
    @subscription_channels = @subscription.channels(@user)
  end

end

③ルーティングを追記する

routes.rb
resources :subscriptions, only: %i[index]

④ビューを編集する

views/subscriptions/index.html.erb
<div>
  <% if current_user %>
    <%= image_tag current_user.image %>
    <%= current_user.name %>さん
    <%= link_to "ログアウト", log_out_path %>
  <% end %>
<div>

<div>
  <% @subscription_channels.items.each do |item| %>
    <% channel_icon = item.snippet.thumbnails.medium.url %>
    <img src='<%= channel_icon %>'>
    <p><%= item.snippet.title %></p>
  <% end %>
<div>

インスタンス変数(@subscription_channels)に格納された属性から、必要なものを引っ張り出して表示しています。
なお、ここでは、以下の内容を表示させています。
・チャンネルのアイコン(item.snippet.thumbnails.medium.url)
・チャンネルのタイトル(item.snippet.title)

⑤seesionsコントローラーのcreateアクションを編集する

sessions_controller.rb
def create
  if user = User.find_or_create_from_auth_hash(auth_hash)
    user.update(token: auth_hash.credentials.token, refresh_token: auth_hash.credentials.refresh_token) # 追記
    log_in user
  end
    redirect_to subscriptions_path #リダイレクト先を変更
end

なお、localhost:3000/subscriptionsで表示される画面は以下のような感じになります。
実際には、channelsメソッド内でlist_subscriptionsに引数としてmax_results: 10を渡しているので、あと8件ほど(計10件)の登録チャンネルが表示されています。
localhost:3000/subscriptions

終わりに

最後まで目を通していただき、ありがとうございました。
ポートフォリオに組み込む前にお試しでやってみたもので、色々といけてない部分も目立つかと思いますが、参考になる部分があれば幸いです。

20
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?