'Allowing Google Service Account YouTube Upload Access via API v3

I want to automatically upload videos to YouTube without user involvement so I've created a service account, jumped through the hoops, all was looking great, then the upload, chunk one, is attempted and my code bombs with this Google_Exception exception:

"Failed to start the resumable upload (HTTP 401: youtube.header, Unauthorized)"

I then dug and found on the YouTube API v3 error information:

https://developers.google.com/youtube/v3/docs/errors

"This error is commonly seen if you try to use the OAuth 2.0 Service Account flow. YouTube does not support Service Accounts, and if you attempt to authenticate using a Service Account, you will get this error."

Is this correct? I cannot use a service account to upload video to YouTube automatically?

(that was a waste of a couple of days hard work!)



Solution 1:[1]

Yes, it is correct.

The way forward is to do a manual authorisation and grab the resultant 'refresh token' and then use that for any automated uploads.

Ensure to add the refresh token to the PHP Google_Client object prior to any other action.

I am now automatically uploading to YouTube.

Solution 2:[2]

For anyone attempting to do this today, be aware that any uploads will be set as "Private (Locked)" if they are uploaded using the API unless/until the app is submitted for verification and approved.

https://github.com/porjo/youtubeuploader/issues/86

YouTube requires verification of the OAuth App/credentials used for upload, otherwise the video will be locked as Private.

It's possible to get an app approved, but if you're doing a personal project, it's less likely.

More: https://github.com/porjo/youtubeuploader/issues/86

Solution 3:[3]

Yes you can use Service Accounts for Youtube. One way is to add the service account to a CMS where the content owner is part of. When you retrieve an access_token for the Service Account, you can work with the content owners videos.

Looks like this, using Javascript:

import { google } from 'googleapis';
const youtube = google.youtube('v3');

const auth = new google.auth.GoogleAuth({
    credentials: YOUR_KEYFILE,
    scopes: ['YOUR_SCOPES'],
});

const accessToken = await auth.getAccessToken();

const { data } = await youtube.videos.list({
    part: ['snippet'],
    id: 'YOUR_VIDEO_ID',
    access_token: accessToken
});

Note that YOUR_KEYFILE is the JSON you downloaded from Gcloud when creating the service accounts keys. NOT the path pointing to the file! If you want to use path, use this instead:

const auth = new google.auth.GoogleAuth({
    keyFile: 'YOUR_PATH_TO_KEYFILE',
    scopes: ['YOUR_SCOPES'],
});

Further reading on server-server authentication using Oauth2

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Claud
Solution 2 Tronathan
Solution 3