尝试使用YoutubeV3 API创建实时广播时出现“需要登录”错误

我正在尝试使用google-api-ruby-client创建新的广播

YT = Google::Apis::YoutubeV3 client = YT::YouTubeService.new client.key = 'my-api-key-here' metadata = { snippet: { title: 'test', scheduled_start_time: '2018-02-23T14:50:00.000Z' }, status: { privacy_status: 'public' } } part = 'snippet' client.insert_live_broadcast(part, metadata, {}) 

当我执行此代码时,我收到Error -#

 [5] pry(main)> CreateYoutubeBroadcast.execute Sending HTTP post https://www.googleapis.com/youtube/v3/liveBroadcasts?key=my-api-key&part=snippet 401 #<HTTP::Message:0x007f8d5356fdc8 @http_header=#<HTTP::Message::Headers:0x007f8d5356fda0 @http_version="1.1", @body_size=0, @chunked=false, @request_method="POST", @request_uri=#, @request_query=nil, @request_absolute_uri=nil, @status_code=401, @reason_phrase="Unauthorized", @body_type=nil, @body_charset=nil, @body_date=nil, @body_encoding=#, @is_request=false, @header_item=[["Vary", "Origin"], ["Vary", "X-Origin"], ["WWW-Authenticate", "Bearer realm=\"https://accounts.google.com/\""], ["Content-Type", "application/json; charset=UTF-8"], ["Content-Encoding", "gzip"], ["Date", "Thu, 15 Feb 2018 12:59:45 GMT"], ["Expires", "Thu, 15 Feb 2018 12:59:45 GMT"], ["Cache-Control", "private, max-age=0"], ["X-Content-Type-Options", "nosniff"], ["X-Frame-Options", "SAMEORIGIN"], ["X-XSS-Protection", "1; mode=block"], ["Server", "GSE"], ["Alt-Svc", "hq=\":443\"; ma=2592000; quic=51303431; quic=51303339; quic=51303338; quic=51303337; quic=51303335,quic=\":443\"; ma=2592000; v=\"41,39,38,37,35\""], ["Transfer-Encoding", "chunked"]], @dumped=false>, @peer_cert=#<OpenSSL::X509::Certificate: subject=#, issuer=#, serial=#, not_before=2018-01-30 08:56:10 UTC, not_after=2018-04-24 08:30:00 UTC>, @http_body=#, @previous=nil> Caught error Unauthorized Error - # Retrying after authentication failure Google::Apis::AuthorizationError: Unauthorized 

我已经做好了

  • 添加了Youtube API V3 https://console.developers.google.com
  • 在我的YouTube帐户上启用了直播function

知道为什么会出现这个错误吗? 谢谢

似乎无法通过API密钥创建预定的广播,我使用谷歌OAuth 2.0策略来完成这项工作。

 # lib/youtube_api/o_auth_client.rb require 'google/api_client/auth/storage' require 'google/api_client/auth/storages/file_store' require 'google/api_client/auth/installed_app' module YoutubeApi class OAuthClient YOUTUBE_SCOPE = 'https://www.googleapis.com/auth/youtube' CREDENTIALS_FILE = Rails.root.join('tmp', 'google_api_credentials.json') def initialize @credentials_storage = ::Google::APIClient::Storage.new( ::Google::APIClient::FileStore.new(CREDENTIALS_FILE) ) end def authorize @credentials_storage.authorize || begin installed_app_flow = ::Google::APIClient::InstalledAppFlow.new( client_id: Rails.application.secrets.youtube_client_id, client_secret: Rails.application.secrets.youtube_client_secret, scope: [YOUTUBE_SCOPE] ) installed_app_flow.authorize(@credentials_storage) end end end end 

和我的create_broadcast服务对象

 require 'service' require 'youtube_api' require 'google/apis/youtube_v3' class CreateBroadcast include Service YT = Google::Apis::YoutubeV3 BROADCAST_PRIVACY = 'public' def initialize(title, description, start_time) @client = YT::YouTubeService.new @client.authorization = YoutubeApi.authorize_via_google_oauth_2 @title = title @description = description @start_time = start_time end def execute @client.insert_live_broadcast(part, metadata, {}) end private def part 'id,snippet,contentDetails,status' end def metadata { snippet: { title: @title, description: @description, scheduled_start_time: @start_time, }, status: { privacy_status: BROADCAST_PRIVACY } } end end 

lib/youtube_api.rb我有

 # frozen_string_literal: true require 'youtube_api/o_auth_client' module YoutubeApi def self.authorize_via_google_oauth_2 oauth_client = OAuthClient.new oauth_client.authorize end end