0

With the Youtube API v3 is it possible to upload a video from browser with an access_code that was generated in the server.

The web server running on RoR has a client certificate which is authenticated using

Google::APIClient::JWTAsserter

I'm able to get the access_code which is valid for one hour.

I also have a developer key for the application to use with browser based uploading.

I want to share the access_code with the browser so that the user does not have to login with his/her google account.

To simulate this in one single script I used RestClient in ruby.

Here's a sample I tried based on the docs.

require 'google/api_client'
require 'nokogiri'
require 'rest_client'

client = Google::APIClient.new
youtube_service = client.discovered_api('youtube', 'v3')

key = Google::APIClient::PKCS12.load_key('keyfile.p12', 'password')
service_account = Google::APIClient::JWTAsserter.new(
        'certificate_email',
        'https://www.googleapis.com/auth/youtube.upload',
        key)
client.authorization = service_account.authorize

access_token = client.authorization.access_token

dev_key = "developer_key"

upload_metadata_xml = <<-EOF
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
  xmlns:media="http://search.yahoo.com/mrss/"
  xmlns:yt="http://gdata.youtube.com/schemas/2007">
  <media:group>
    <media:title type="plain">Test upload one</media:title>
    <media:description type="plain">
      I gave a bad toast at my friend's wedding.
    </media:description>
    <media:category
      scheme="http://gdata.youtube.com/schemas/2007/categories.cat">People
    </media:category>
    <media:keywords>upload, test, one</media:keywords>
  </media:group>
</entry>
EOF

headers = {
    "Authorization" => "Bearer #{access_token}",
    "GData-Version" => "2",
    "X-GData-Key" => "key=#{dev_key}",
    "Content-Type" => "application/atom+xml; charset=UTF-8"
}

upload_response = RestClient.post("https://gdata.youtube.com/action/GetUploadToken", upload_metadata_xml, headers)
xml_response = Nokogiri::XML.parse(upload_response)
upload_url = xml_response.xpath("//url").first.children.inner_text()
upload_token = xml_response.xpath("//token").first.children.inner_text()

I keep getting an error at the line where I'm posting the data.

upload_response = RestClient.post("https://gdata.youtube.com/action/GetUploadToken", upload_metadata_xml, headers)

The error says 401 Unauthorized!

I tried the same with Postman extension in Google Chrome. Throws the same error.

I'm sure that the access credentials are correct. I've checked that multiple times.

Has someone implemented this before? Or is there any alternate way for achieving this without the user having to login to google.

EDIT 1

Based on this question on SF: Google Calendar API v3 hardcoded credentials

I tried the same script by changing the authorization alone to use Google::APIClient::InstalledAppFlow and it still throws the same 401 Unauthorized!.

Community
  • 1
  • 1
Praveenram Balachandar
  • 1,587
  • 1
  • 13
  • 16

1 Answers1

0

It will be an installed application unless you will run it in a web server. Otherwise you'll select web application with correctly identifying the redirect address.

You can do so by getting a refresh token from OAuth2 Playground and setting it in your youtube object.

Here it explains a little more.

And a step by step video.

Ibrahim Ulukaya
  • 12,767
  • 1
  • 33
  • 36
  • I want to run the authorization part on a webserver and upload from the browser using browser based upload. based on the oauth2 link seems like cannot prevent Google from launching a dialog for user to login. I don't want to fall back to the deprecated login methods. is there a way in which I can achieve this setup? auth at server, token being shared to browser and browser uploads directly to YouTube.? – Praveenram Balachandar Nov 26 '13 at 03:40
  • If you read the doc, and watch video before commenting, you will see, there is. – Ibrahim Ulukaya Nov 26 '13 at 16:58
  • I did read and watch video just fyi. But there were issues with authentication still. Ended up using this example which works like magic: [https://github.com/chebyte/youtube_it_rails_app_example](https://github.com/chebyte/youtube_it_rails_app_example) – Praveenram Balachandar Nov 27 '13 at 07:25