Ruby 程式碼範例

下列程式碼範例使用 Ruby 適用的 Google API 用戶端程式庫YouTube Analytics API。您可以前往 GitHub 上的 YouTube API 程式碼範例存放區ruby 資料夾,下載這些程式碼範例。

授權要求

下列程式碼範例會檢查是否包含包含授權憑證的本機檔案,以執行 OAuth 2.0 授權。如果檔案不存在,指令碼會開啟瀏覽器並等待回應,然後將傳回的憑證儲存在本機。

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

依觀看次數顯示熱門影片前 10 名的影片

這個範例會呼叫 API 的 reports.query 方法,以擷取 YouTube 數據分析資料。根據預設,報表會擷取觀看次數的前 10 名影片,並傳回這些影片的數個指標,依觀看次數由高至低排序。設定指令列參數後,您也可以使用相同的程式碼擷取其他報表。

#!/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'

# These OAuth 2.0 access scopes allow for read-only access to the authenticated
# user's account for both YouTube Data API resources and YouTube Analytics Data.
YOUTUBE_SCOPES = ['https://www.googleapis.com/auth/youtube.readonly',
  'https://www.googleapis.com/auth/yt-analytics.readonly']
YOUTUBE_API_SERVICE_NAME = 'youtube'
YOUTUBE_API_VERSION = 'v3'
YOUTUBE_ANALYTICS_API_SERVICE_NAME = 'youtubeAnalytics'
YOUTUBE_ANALYTICS_API_VERSION = 'v1'

def get_authenticated_services
  client = Google::APIClient.new(
    :application_name => $PROGRAM_NAME,
    :application_version => '1.0.0'
  )
  youtube = client.discovered_api(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION)
  youtube_analytics = client.discovered_api(YOUTUBE_ANALYTICS_API_SERVICE_NAME, YOUTUBE_ANALYTICS_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_SCOPES
    )
    client.authorization = flow.authorize(file_storage)
  else
    client.authorization = file_storage.authorization
  end

  return client, youtube, youtube_analytics
end

def main
  now = Time.new.to_i
  seconds_in_day = 60 * 60 * 24
  seconds_in_week = seconds_in_day * 7
  one_day_ago = Time.at(now - seconds_in_day).strftime('%Y-%m-%d')
  one_week_ago = Time.at(now - seconds_in_week).strftime('%Y-%m-%d')

  opts = Trollop::options do
    opt :metrics, 'Report metrics', :type => String, :default => 'views,comments,favoritesAdded,favoritesRemoved,likes,dislikes,shares'
    opt :dimensions, 'Report dimensions', :type => String, :default => 'video'
    opt 'start-date', 'Start date, in YYYY-MM-DD format', :type => String, :default => one_week_ago
    opt 'end-date', 'Start date, in YYYY-MM-DD format', :type => String, :default => one_day_ago
    opt 'start-index', 'Start index', :type => :int, :default => 1
    opt 'max-results', 'Max results', :type => :int, :default => 10
    opt :sort, 'Sort order', :type => String, :default => '-views'
  end

  client, youtube, youtube_analytics = get_authenticated_services

  begin
    # Retrieve the channel resource for the authenticated user's channel.
    channels_response = client.execute!(
      :api_method => youtube.channels.list,
      :parameters => {
        :mine => true,
        :part => 'id'
      }
    )

    channels_response.data.items.each do |channel|
      opts[:ids] = "channel==#{channel.id}"

      # Call the Analytics API to retrieve a report. For a list of available
      # reports, see:
      # https://developers.google.com/youtube/analytics/v1/channel_reports
      analytics_response = client.execute!(
        :api_method => youtube_analytics.reports.query,
        :parameters => opts
      )

      puts "Analytics Data for Channel #{channel.id}"

      analytics_response.data.columnHeaders.each do |column_header|
        printf '%-20s', column_header.name
      end
      puts

      analytics_response.data.rows.each do |row|
        row.each do |value|
          printf '%-20s', value
        end
        puts
      end
    end
  rescue Google::APIClient::TransmissionError => e
    puts e.result.body
  end
end

main