3

i'm banging my head over this for 4hours so I might need a little help.

What I wanna do is to store videos on youtube, for a video contest we are having. I really prefer a 2 legged OAuth access through Service Account (I want users even without a gmail account to be able to send us a video and I want to put these videos in private or unlisted in our youtube account).

But it seems not to work. My code right now is something like this :

function go()
{
require_once 'googleClient/Google_Client.php';
require_once 'googleClient/contrib/Google_YoutubeService.php';

define("CLIENT_ID",'xxxxxxx.apps.googleusercontent.com');
define("SERVICE_ACCOUNT_NAME",'xxxxxxx@developer.gserviceaccount.com');
define("KEY_FILE", 'googleClient/verylonghashtagprivacystuff-privatekey.p12');
define("SECRET_FILE", 'client_secrets.json');

$client = new Google_Client();
$client->setApplicationName("My Contest App");

$key = file_get_contents(KEY_FILE);
$secret = file_get_contents(SECRET_FILE);


$GAC = new Google_AssertionCredentials( SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/youtube.upload',
            'https://www.googleapis.com/auth/youtube'), 
$key ,'notasecret','http://oauth.net/grant_type/jwt/1.0/bearer');

$client->setAssertionCredentials($GAC);

$client::$auth->refreshTokenWithAssertion();
$client->setClientId(CLIENT_ID); // Did tried to put that one sooner
$client->setClientSecret($secret); // Did tried to put that one sooner
$json = $client->getAccessToken();

$accessToken = json_decode($json)->access_token;
$video = array();
$video["snippet"] = array();


$snippet = new Google_VideoSnippet();
$snippet->setTitle("Contest Video USERNAME");
$snippet->setDescription("Video for contest 2013 USERNAME.");
$snippet->setTags(array("Contest","Whatever","2013"));
$snippet->setCategoryId("22"); //Did tried "Entertainment".

$status = new Google_VideoStatus();
$status->setPrivacyStatus("unlisted");

$video = new Google_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
$client->setAccessToken($json);

$youtube = new Google_YoutubeService($client);
$url = '/projet_video.mp4';

$response = $youtube->videos->insert(
"status,snippet", 
$video, 
array(  'data' => file_get_contents($url),'mimeType' => "video/*")); 
//Did tried video/mp4


return $response ;}

And the result is :

error": {  "errors": [   {
    "domain": "youtube.header",
    "reason": "youtubeSignupRequired",
    "message": "Forbidden",
    "locationType": "header",
    "location": "Authorization"
}], "code": 403,  "message": "Forbidden" }
user2004005
  • 31
  • 1
  • 3
  • if I add "onBehalfOfContentOwner" I got a whole new error 500 with no error text (null). – user2004005 Jan 23 '13 at 15:51
  • I'm pretty sure this is the same thing that's answered at http://stackoverflow.com/questions/14453505/youtube-data-api-v3-video-upload-403-forbidden-youtubesignuprequired – Jeff Posnick Jan 24 '13 at 03:56
  • Well thanks for answering us. I thought it was better to make my own question as he gave not much of his code and we seem to use different languages. I will give a try to your answer and post feedback asap. However this is weird. The google account I used to create a client API Id, and such things (API ON etc...) is the one we use to post videos to youtube. I thought it was linked somehow. Thanks – user2004005 Jan 24 '13 at 08:53
  • "the user already has a YouTube channel". Would it help you if I give you the emails of the googledev account or the yt account ? – user2004005 Jan 24 '13 at 09:01
  • It would be great if you could pass along the login email address and/or the YouTube channel id and/or the YouTube legacy channel name—jeffy at google dot com – Jeff Posnick Jan 24 '13 at 17:50

3 Answers3

3

Service Accounts do not work with the YouTube API

Service accounts do not work for YouTube API calls because an associated YouTube channel, and you cannot associate new or existing channels with services accounts. Using a service account to make YouTube API calls will return an error with the error type set to unauthorized and the reason set to youtubeSignupRequired.

source: https://developers.google.com/youtube/v3/guides/moving_to_oauth#service_accounts

Pedro Lobito
  • 94,083
  • 31
  • 258
  • 268
1

After following up off-thread with the OP, the problem comes down to the fact that the various YouTube APIs don't have support for Service Accounts, at least not at this time. You need to go through one of the flows described in the docs (which doesn't include the Service Account flow) using the credentials of the actual Google Account that's associated with the YouTube channel you want to access.

Jeff Posnick
  • 53,580
  • 14
  • 141
  • 167
  • How'd you come to that conclusion? I ask because there is an option to enable "YouTube Data API v3" in services. – Draven Jan 26 '13 at 10:14
  • You can enable YouTube Data API v3 for any API Console project. That's orthogonal to the account you need to use when going through the OAuth 2 flow. YouTube doesn't support Service Accounts right now—that's just how things are. – Jeff Posnick Jan 26 '13 at 19:21
  • any idea when YouTube will support service accounts? we would really like to upgrade to v3 but can't because we need the service account feature. – sanjosep43 Oct 09 '13 at 17:29
  • I promise you that you don't need Service Accounts. Anything that you could theoretically do with Service Accounts you could do using OAuth 2's installed apps flow and using a Refresh Token to generate new Access Tokens without further user interaction. See https://developers.google.com/youtube/v3/guides/moving_to_oauth – Jeff Posnick Oct 15 '13 at 15:40
0

I solved it and my answer is here: How to insert video youtube api v3 through service account with ruby Enjoy!

The error you are getting is because you didn't add the person tag with the email to upload the movie to. It is all solved and working if you use the code in my answer

Community
  • 1
  • 1
dangalg
  • 6,398
  • 4
  • 27
  • 37