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.
- Authorize a request
- Post a channel bulletin (
activities.insert) - Retrieve my uploads (
playlistItems.list) - Search by keyword (
search.list) - Add a channel subscription (
subscriptions.insert) - Upload a video (
videos.insert)
Authorize a request
The code sample below 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
Post a channel bulletin
The code sample below calls the API's activities.insert method to post a bulletin to the channel associated with the request.
#!/usr/bin/ruby
require 'rubygems'
require 'google/api_client'
# The oauth/oauth_util code is not part of the official Ruby client library.
# Download it from:
# http://samples.google-api-ruby-client.googlecode.com/git/oauth/oauth_util.rb
require 'oauth/oauth_util'
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'
client = Google::APIClient.new
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
auth_util = CommandLineOAuthHelper.new(YOUTUBE_SCOPE)
client.authorization = auth_util.authorize()
opts = Trollop::options do
opt :message, 'Required text of message to post.', :type => String
opt :videoid, 'Optional ID of video to post.', :type => String
opt :playlistid, 'Optional ID of playlist to post.', :type => String
end
# You can post a message with or without an accompanying video or playlist.
# However, you can't post a video and a playlist at the same time.
if opts[:videoid] and opts[:playlistid]
Trollop::die 'You cannot post a video and a playlist at the same time'
end
Trollop::die :message, 'is required' unless opts[:message]
body = {
:snippet => {
:description => opts[:message]
}
}
if opts[:videoid]
body[:contentDetails] = {
:bulletin => {
:resourceId => {
:kind => 'youtube#video',
:videoId => opts[:videoid]
}
}
}
end
if opts[:playlistid]
body[:contentDetails] = {
:bulletin => {
:resourceId => {
:kind => 'youtube#playlist',
:playlistId => opts[:playlistid]
}
}
}
end
# Call the API's youtube.activities.insert method to post the channel bulletin.
client.execute!(
:api_method => youtube.activities.insert,
:parameters => {
:part => body.keys.join(',')
},
:body_object => body
)
puts 'The bulletin was posted to your channel.'
Retrieve my uploads
The code sample below 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'
require 'google/api_client'
# The oauth/oauth_util code is not part of the official Ruby client library.
# Download it from:
# http://samples.google-api-ruby-client.googlecode.com/git/oauth/oauth_util.rb
require 'oauth/oauth_util'
# 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'
client = Google::APIClient.new
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
auth_util = CommandLineOAuthHelper.new(YOUTUBE_READONLY_SCOPE)
client.authorization = auth_util.authorize()
# 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.
playlistitems_response = client.execute!(
:api_method => youtube.playlist_items.list,
:parameters => {
:playlistId => uploads_list_id,
:part => 'snippet',
:maxResults => 50
}
)
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
puts
end
Search by keyword
The code sample below calls the API's search.list method to retrieve search results associated with a particular keyword.
#!/usr/bin/ruby
require 'rubygems'
require 'google/api_client'
require 'trollop'
# Set DEVELOPER_KEY to the "API key" value from the "Access" tab of the
# Google Developers 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"
opts = Trollop::options do
opt :q, 'Search term', :type => String, :default => 'Google'
opt :maxResults, 'Max results', :type => :int, :default => 25
end
client = Google::APIClient.new(:key => DEVELOPER_KEY,
:authorization => nil)
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
# Call the search.list method to retrieve results matching the specified
# query term.
opts[:part] = 'id,snippet'
search_response = client.execute!(
:api_method => youtube.search.list,
:parameters => opts
)
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.push("#{search_result.snippet.title} (#{search_result.id.videoId})")
when 'youtube#channel'
channels.push("#{search_result.snippet.title} (#{search_result.id.channelId})")
when 'youtube#playlist'
playlists.push("#{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"
Add a channel subscription
The code sample below calls the API's subscriptions.insert method to add a subscription to a specified channel.
#!/usr/bin/ruby
require 'rubygems'
require 'google/api_client'
# The oauth/oauth_util code is not part of the official Ruby client library.
# Download it from:
# http://samples.google-api-ruby-client.googlecode.com/git/oauth/oauth_util.rb
require 'oauth/oauth_util'
# 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'
client = Google::APIClient.new
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
auth_util = CommandLineOAuthHelper.new(YOUTUBE_SCOPE)
client.authorization = auth_util.authorize()
body = {
:snippet => {
:resourceId => {
:kind => 'youtube#channel',
# Replace the value below with the ID of the channel being subscribed to.
:channelId => 'UCtVd0c0tGXuTSbU5d8cSBUg'
}
}
}
# Call the API's youtube.subscriptions.insert method to add the subscription
# to the specified channel.
begin
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::ClientError => e
puts "#{e}: Unable to add subscription. Are you already subscribed?"
end
Upload a video
The code sample below calls the API's videos.insert method to upload a video to the channel associated with the request.
#!/usr/bin/ruby
require 'rubygems'
require 'google/api_client'
# The oauth/oauth_util code is not part of the official Ruby client library.
# Download it from:
# http://samples.google-api-ruby-client.googlecode.com/git/oauth/oauth_util.rb
require 'oauth/oauth_util'
require 'trollop'
# This OAuth 2.0 access scope allows an application to upload files to the
# authenticated user's YouTube channel, but doesn't allow other types of access.
YOUTUBE_READ_WRITE_SCOPE = 'https://www.googleapis.com/auth/youtube.upload'
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
client = Google::APIClient.new(:application_name => $0, :application_version => '1.0')
youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
auth_util = CommandLineOAuthHelper.new(YOUTUBE_READ_WRITE_SCOPE)
client.authorization = auth_util.authorize()
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 :categoryId, '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 :privacyStatus, '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
body = {
:snippet => {
:title => opts[:title],
:description => opts[:description],
:tags => opts[:keywords].split(','),
:categoryId => opts[:categoryId],
},
:status => {
:privacyStatus => opts[:privacyStatus]
}
}
# Call the API's videos.insert method to create and upload the video.
videos_insert_response = client.execute!(
:api_method => youtube.videos.insert,
:body_object => body,
:media => Google::APIClient::UploadIO.new(opts[:file], 'video/*'),
:parameters => {
'uploadType' => 'multipart',
:part => body.keys.join(',')
}
)
puts "'#{videos_insert_response.data.snippet.title}' (video id: #{videos_insert_response.data.id}) was successfully uploaded."