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