How to Get List of YouTube Channel Videos using YouTube API
I’ve got 150+ videos on @SupeRails Youtube channel, and now I want to list them on my own superails.com website.
I could copypaste the information manually, but that would take ages.
I could use web scraping, but what’s the point, if there is an easy to use Youtube API?
Youtube API is accessible in Ruby via the gem ‘google-api-client’
1. Generate a Youtube API key
First, access Google Cloud Console. Search for YouTube Data API v3:
Click to enable the API:
Create an API key:
View Youtube API docs
2. Find a youtube channel ID
To make the API call to list videos, you need to provide a channel ID. Here’s how you can access any channel ID:
3. API call to list all videos on a channel
Install the gem:
# Gemfile
# gem 'google-api-client' # https://github.com/googleapis/google-api-ruby-client
gem 'google-apis-youtube_v3'
Make a list_searches
API call to get up to 50 videos per page form the selected channel.
# rails c
require 'google/apis/youtube_v3'
CHANNEL_ID = 'UCyr6ZTmztFW3FB4qG_97FoA'
YOUTUBE_KEY = 'MySecretKey'
youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = YOUTUBE_KEY
# list videos and playlists
response = youtube.list_searches('snippet', channel_id: CHANNEL_ID, max_results: 50)
# list only videos
response = youtube.list_searches('snippet', channel_id: CHANNEL_ID, max_results: 5, type: 'video')
This will provide you basic information about up to 50 videos per page.
4. API call to show details of one video
If you want to have more detailed info about a specific video, you should make a list_videos
API call while passing the video_id
.
# rails c
require 'google/apis/youtube_v3'
CHANNEL_ID = 'UCyr6ZTmztFW3FB4qG_97FoA'
YOUTUBE_KEY = 'MySecretKey'
youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = YOUTUBE_KEY
video_id = "07XQY8nRvd0"
video_response = youtube.list_videos('snippet', id: video_id)
5. Import Youtube videos into a Rails app
Genarate a Post
model, and jobs to make async API calls:
rails g model Post video_id title description:text tags:text published_at:datetime cover_image_url
rails g job Youtube::ListVideosJob
rails g job Youtube::CreateVideoJob
The API call will give us tags as an array, so let’s store them as such:
# app/models/post.rb
serialize :tags, Array
Job to LIST and Paginate all the videos on a Youtube channel:
# app/jobs/youtube/list_videos_job.rb
require 'google/apis/youtube_v3'
# Youtube::ListVideosJob.perform_later
class Youtube::ListVideosJob < ApplicationJob
queue_as :default
CHANNEL_ID = Rails.application.credentials.dig(:youtube, :channel_id)
YOUTUBE_KEY = Rails.application.credentials.dig(:youtube, :youtube_key)
def perform
youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = YOUTUBE_KEY
video_ids = fetch_all_videos(youtube)
process_videos(video_ids)
end
private
def fetch_all_videos(youtube)
video_ids = []
next_page_token = nil
loop do
response = youtube.list_searches('snippet', channel_id: CHANNEL_ID, max_results: 50, page_token: next_page_token)
response_ids = response.items.map { |item| item.id.video_id }.compact
video_ids += response_ids
next_page_token = response.next_page_token
break if next_page_token.nil?
end
video_ids
end
def process_videos(video_ids)
video_ids.each do |video_id|
Youtube::CreateVideoJob.perform_later(video_id)
end
end
end
Job to get detailed info for a specific youtube video and create a local record:
# app/jobs/youtube/create_video_job.rb
require 'google/apis/youtube_v3'
# Youtube::CreateVideoJob.perform_later
class Youtube::CreateVideoJob < ApplicationJob
queue_as :default
CHANNEL_ID = Rails.application.credentials.dig(:youtube, :channel_id)
YOUTUBE_KEY = Rails.application.credentials.dig(:youtube, :youtube_key)
def perform(video_id)
youtube = Google::Apis::YoutubeV3::YouTubeService.new
youtube.key = YOUTUBE_KEY
video_response = youtube.list_videos('snippet', id: video_id)
video = video_response.items.first.snippet
video_hash = {
video_id: video_id,
title: video.title,
description: video.description,
tags: video.tags,
published_at: video.published_at,
cover_image_url: video.thumbnails.maxres.url
}
Post.find_or_create_by(video_id: video_hash[:video_id]).update(video_hash)
end
end
6. Display videos in a view:
<% @posts.each do |post| %>
<h3><%= post.title %></h3>
<p><%= post.description %></p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/<%= post.video_id %>" frameborder="0" allowfullscreen></iframe>
<hr>
<% end %>
Example fixture of a stored video:
one:
youtube_video_id: "Ubrr9mqE94o"
title: "Ruby on Rails #27 Gem Letter Opener - best way to preview emails in development"
description: "gem letter_opener:\nhttps://github.com/ryanb/letter_opener\nSource Code for the Post:\nhttps://github.com/corsego/26-action-mailer/commit/24fb10065fb5c4502b15ea75d651aec8e61413e0\n\nTo fix Launchy error - run these commands in console:\nexport BROWSER=/dev/null\nexport LAUNCHY_DRY_RUN=true"
tags: ["ruby", "rails", "ruby on rails", "tutorial", "programming"]
published_at: "2021-05-19T13:00:15Z"
cover_image_url: "https://i.ytimg.com/vi/Ubrr9mqE94o/maxresdefault.jpg"