The following code samples, which use the
Google APIs Client Library for
Ruby
, are available for the
YouTube Data API
. You can download these code samples from the
ruby
folder of the
YouTube APIs code sample repository on GitHub
.
Add a channel subscription
This sample calls the API's
subscriptions.insert
method to add a subscription
to a specified channel.
#!/usr/bin/ruby
require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
require 'trollop'
# This OAuth 2.0 access scope allows for full read/write access to the
# authenticated user's account.
YOUTUBE_SCOPE = 'https://www.googleapis.com/auth/youtube'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
def get_authenticated_service
client = Google::APIClient.new(
:application_name => $PROGRAM_NAME,
:application_version => '1.0.0'
)
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
if file_storage.authorization.nil?
client_secrets = Google::APIClient::ClientSecrets.load
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => client_secrets.client_id,
:client_secret => client_secrets.client_secret,
:scope => [YOUTUBE_SCOPE]
)
client.authorization = flow.authorize(file_storage)
else
client.authorization = file_storage.authorization
end
return client, youtube
end
def main
opts = Trollop::options do
opt :channel_id, 'ID of the channel to subscribe to.', :type => String,
:default => 'UCtVd0c0tGXuTSbU5d8cSBUg'
end
client, youtube = get_authenticated_service
begin
body = {
:snippet => {
:resourceId => {
:channelId => opts[:channel_id]
}
}
}
# Call the API's youtube.subscriptions.insert method to add the subscription
# to the specified channel.
subscriptions_response = client.execute!(
:api_method => youtube.subscriptions.insert,
:parameters => {
:part => body.keys.join(',')
},
:body_object => body
)
puts "A subscription to '#{subscriptions_response.data.snippet.title}' was added."
rescue Google::APIClient::TransmissionError => e
puts e.result.body
end
end
main
Authorize a request
The following code sample performs OAuth 2.0 authorization by checking for the presence of a local
file that contains authorization credentials. If the file is not present, the script opens a browser and waits
for a response, then saves the returned credentials locally.
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'json'
require 'launchy'
require 'thin'
RESPONSE_HTML = <<stop
<html>
<head>
<title>OAuth 2 Flow Complete</title>
</head>
<body>
You have successfully completed the OAuth 2 flow. Please close this browser window and return to your program.
</body>
</html>
stop
FILE_POSTFIX = '-oauth2.json'
# Small helper for the sample apps for performing OAuth 2.0 flows from the command
# line. Starts an embedded server to handle redirects.
class CommandLineOAuthHelper
def initialize(scope)
credentials = Google::APIClient::ClientSecrets.load
@authorization = Signet::OAuth2::Client.new(
:authorization_uri => credentials.authorization_uri,
:token_credential_uri => credentials.token_credential_uri,
:client_id => credentials.client_id,
:client_secret => credentials.client_secret,
:redirect_uri => credentials.redirect_uris.first,
:scope => scope
)
end
# Request authorization. Checks to see if a local file with credentials is present, and uses that.
# Otherwise, opens a browser and waits for response, then saves the credentials locally.
def authorize
credentialsFile = $0 + FILE_POSTFIX
if File.exist? credentialsFile
File.open(credentialsFile, 'r') do |file|
credentials = JSON.load(file)
@authorization.access_token = credentials['access_token']
@authorization.client_id = credentials['client_id']
@authorization.client_secret = credentials['client_secret']
@authorization.refresh_token = credentials['refresh_token']
@authorization.expires_in = (Time.parse(credentials['token_expiry']) - Time.now).ceil
if @authorization.expired?
@authorization.fetch_access_token!
save(credentialsFile)
end
end
else
auth = @authorization
url = @authorization.authorization_uri().to_s
server = Thin::Server.new('0.0.0.0', 8080) do
run lambda { |env|
# Exchange the auth code & quit
req = Rack::Request.new(env)
auth.code = req['code']
auth.fetch_access_token!
server.stop()
[200, {'Content-Type' => 'text/html'}, RESPONSE_HTML]
}
end
Launchy.open(url)
server.start()
save(credentialsFile)
end
return @authorization
end
def save(credentialsFile)
File.open(credentialsFile, 'w', 0600) do |file|
json = JSON.dump({
:access_token => @authorization.access_token,
:client_id => @authorization.client_id,
:client_secret => @authorization.client_secret,
:refresh_token => @authorization.refresh_token,
:token_expiry => @authorization.expires_at
})
file.write(json)
end
end
end
Retrieve my uploads
This sample calls the API's
playlistItems.list
method to retrieve a list of videos uploaded
to the channel associated with the request. The code also calls the
channels.list
method with the
mine
parameter set to
true
to retrieve the playlist ID that identifies the channel's
uploaded videos.
#!/usr/bin/ruby
require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
# This OAuth 2.0 access scope allows for read-only access to the authenticated
# user's account, but not other types of account access.
YOUTUBE_READONLY_SCOPE = 'https://www.googleapis.com/auth/youtube.readonly'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
def get_authenticated_service
client = Google::APIClient.new(
:application_name => $PROGRAM_NAME,
:application_version => '1.0.0'
)
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
if file_storage.authorization.nil?
client_secrets = Google::APIClient::ClientSecrets.load
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => client_secrets.client_id,
:client_secret => client_secrets.client_secret,
:scope => [YOUTUBE_READONLY_SCOPE]
)
client.authorization = flow.authorize(file_storage)
else
client.authorization = file_storage.authorization
end
return client, youtube
end
def main
client, youtube = get_authenticated_service
begin
# Retrieve the "contentDetails" part of the channel resource for the
# authenticated user's channel.
channels_response = client.execute!(
:api_method => youtube.channels.list,
:parameters => {
:mine => true,
:part => 'contentDetails'
}
)
channels_response.data.items.each do |channel|
# From the API response, extract the playlist ID that identifies the list
# of videos uploaded to the authenticated user's channel.
uploads_list_id = channel['contentDetails']['relatedPlaylists']['uploads']
# Retrieve the list of videos uploaded to the authenticated user's channel.
next_page_token = ''
until next_page_token.nil?
playlistitems_response = client.execute!(
:api_method => youtube.playlist_items.list,
:parameters => {
:playlistId => uploads_list_id,
:part => 'snippet',
:maxResults => 50,
:pageToken => next_page_token
}
)
puts "Videos in list #{uploads_list_id}"
# Print information about each video.
playlistitems_response.data.items.each do |playlist_item|
title = playlist_item['snippet']['title']
video_id = playlist_item['snippet']['resourceId']['videoId']
puts "#{title} (#{video_id})"
end
next_page_token = playlistitems_response.next_page_token
end
puts
end
rescue Google::APIClient::TransmissionError => e
puts e.result.body
end
end
main
Search by keyword
This sample calls the API's
search.list
method to retrieve search results
associated with a particular keyword.
#!/usr/bin/ruby
require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'trollop'
# Set DEVELOPER_KEY to the API key value from the APIs & auth > Credentials
# tab of
# {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
# Please ensure that you have enabled the YouTube Data API for your project.
DEVELOPER_KEY = 'REPLACE_ME'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
def get_service
client = Google::APIClient.new(
:key => DEVELOPER_KEY,
:authorization => nil,
:application_name => $PROGRAM_NAME,
:application_version => '1.0.0'
)
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
return client, youtube
end
def main
opts = Trollop::options do
opt :q, 'Search term', :type => String, :default => 'Google'
opt :max_results, 'Max results', :type => :int, :default => 25
end
client, youtube = get_service
begin
# Call the search.list method to retrieve results matching the specified
# query term.
search_response = client.execute!(
:api_method => youtube.search.list,
:parameters => {
:part => 'snippet',
:q => opts[:q],
:maxResults => opts[:max_results]
}
)
videos = []
channels = []
playlists = []
# Add each result to the appropriate list, and then display the lists of
# matching videos, channels, and playlists.
search_response.data.items.each do |search_result|
case search_result.id.kind
when 'youtube#video'
videos << "#{search_result.snippet.title} (#{search_result.id.videoId})"
when 'youtube#channel'
channels << "#{search_result.snippet.title} (#{search_result.id.channelId})"
when 'youtube#playlist'
playlists << "#{search_result.snippet.title} (#{search_result.id.playlistId})"
end
end
puts "Videos:\n", videos, "\n"
puts "Channels:\n", channels, "\n"
puts "Playlists:\n", playlists, "\n"
rescue Google::APIClient::TransmissionError => e
puts e.result.body
end
end
main
Upload a video
This sample calls the API's
videos.insert
method to upload a video to the channel
associated with the request.
#!/usr/bin/ruby
require 'rubygems'
gem 'google-api-client', '>0.7'
require 'google/api_client'
require 'google/api_client/client_secrets'
require 'google/api_client/auth/file_storage'
require 'google/api_client/auth/installed_app'
require 'trollop'
# A limited OAuth 2 access scope that allows for uploading files, but not other
# types of account access.
YOUTUBE_UPLOAD_SCOPE = 'https://www.googleapis.com/auth/youtube.upload'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
def get_authenticated_service
client = Google::APIClient.new(
:application_name => $PROGRAM_NAME,
:application_version => '1.0.0'
)
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
file_storage = Google::APIClient::FileStorage.new("#{$PROGRAM_NAME}-oauth2.json")
if file_storage.authorization.nil?
client_secrets = Google::APIClient::ClientSecrets.load
flow = Google::APIClient::InstalledAppFlow.new(
:client_id => client_secrets.client_id,
:client_secret => client_secrets.client_secret,
:scope => [YOUTUBE_UPLOAD_SCOPE]
)
client.authorization = flow.authorize(file_storage)
else
client.authorization = file_storage.authorization
end
return client, youtube
end
def main
opts = Trollop::options do
opt :file, 'Video file to upload', :type => String
opt :title, 'Video title', :default => 'Test Title', :type => String
opt :description, 'Video description',
:default => 'Test Description', :type => String
opt :category_id, 'Numeric video category. See https://developers.google.com/youtube/v3/docs/videoCategories/list',
:default => 22, :type => :int
opt :keywords, 'Video keywords, comma-separated',
:default => '', :type => String
opt :privacy_status, 'Video privacy status: public, private, or unlisted',
:default => 'public', :type => String
end
if opts[:file].nil? or not File.file?(opts[:file])
Trollop::die :file, 'does not exist'
end
client, youtube = get_authenticated_service
begin
body = {
:snippet => {
:title => opts[:title],
:description => opts[:description],
:tags => opts[:keywords].split(','),
:categoryId => opts[:category_id],
},
:status => {
:privacyStatus => opts[:privacy_status]
}
}
videos_insert_response = client.execute!(
:api_method => youtube.videos.insert,
:body_object => body,
:media => Google::APIClient::UploadIO.new(opts[:file], 'video/*'),
:parameters => {
:uploadType => 'resumable',
:part => body.keys.join(',')
}
)
videos_insert_response.resumable_upload.send_all(client)
puts "Video id '#{videos_insert_response.data.id}' was successfully uploaded."
rescue Google::APIClient::TransmissionError => e
puts e.result.body
end
end
main