I'm fairly sure all 11 views of this question (as of this writing) are me, but I'm going to post an answer just in case it helps someone in the future:
There was no problem with my code itself. The problem was when I initially created my refresh_token
for this account.
For the uninitiated, the YouTube Data API (v3) does not support "service accounts," which, elsewhere in the Google API ecosystem, are the way you would normally accomplish setting up an OAuth2 auth'd client when the only client is yourself. The workaround is something you have to do by hand. Take the steps below:
First, go to the Google "API Console." There, under "API Access," you need to "Create a client ID" for an "installed application." This will give you a Client ID
, a Client secret
and a Redirect URI
(you'll want the non-localhost
one). Write these down.
Next, you need to manually obtain an authorization code by visiting a URL like the following in your favorite web browser, while logged in to the same account you just created the client ID for:
https://accounts.google.com/o/oauth2/auth
?client_id={client_id}
&redirect_uri={redirect_uri}
&scope={space separated scopes}
&response_type=code
&access_type=offline
Of course, you need to enter the client_id
, redirect_uri
and scope
query parameters. In my case, this is where I went wrong. When I did this manual step, I should have put the scope
param as:
https://www.googleapis.com/auth/youtube https://www.googleapis.com/auth/youtube.upload
But instead I just did https://www.googleapis.com/auth/youtube.upload
, which is insufficient to update/delete videos!
Last, you need to obtain a refresh_token
, by taking a URL like this:
https://accounts.google.com/o/oauth2/token
?code={authorization_code}
&client_id={client_id}
&client_secret={client_secret}
&redirect_uri={redirect_uri}
&grant_type=authorization_code
And curl'ing it with a command like:
$ curl https://accounts.google.com/o/oauth2/token -d "code=..."
This will return a JSON response that contains your refresh_token
, which you then use when authorizing your request programmatically through the Google API.