Reputation: 93
I am trying to upload to YouTube via the API. I am doing so with curl
and when am running following command I receive an error saying that am not unauthenticated, even though I have filled out the authentication details.
My code is:
curl -XPOST -H 'client_id: CLIENT_ID' -H 'client_secret: CLIENT_SECRET' -H 'auth_uri: https://accounts.google.com/o/oauth2/auth' -H 'token_uri: https://oauth2.googleapis.com/token' -H "Content-type: application/json" -d '{
"snippet": {
"title": "Test Title",
"description": "Test description",
"tags": ["test", "tags"],
"categoryId": 20
},
"status": {
"privacyStatus": "unlisted"
}
}' 'https://www.googleapis.com/upload/youtube/v3/videos'
Error message is 401
:
Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.
I have 100% put in the client_id
and client_secret
correctly.
Upvotes: 1
Views: 973
Reputation: 117116
If you go to the documentation for video.insert you will find an example of how the upload works in curl.
curl --request POST \
'https://youtube.googleapis.com/youtube/v3/videos?key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{}' \
--compressed
You appear to be missing a number of the headers that are required mainly that of the access token which is passed as a bearer token. What you need to understand is that the client_id
and client_secret
are used to CREATE the access token they do not by themselves grant you access to any data.
An access token needs to be created using the Oauth2 flow. I have a gist that shows how this can be done. YOu will need to use the https://www.googleapis.com/auth/youtube.upload
scope
# Client id from Google Developer console
# Client Secret from Google Developer console
# Scope this is a space seprated list of the scopes of access you are requesting.
# Authorization link. Place this in a browser and copy the code that is returned after you accept the scopes.
https://accounts.google.com/o/oauth2/auth?client_id=[Application Client Id]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=[Scopes]&response_type=code
# Exchange Authorization code for an access token and a refresh token.
curl \
--request POST \
--data "code=[Authentcation code from authorization link]&client_id=[Application Client Id]&client_secret=[Application Client Secret]&redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code" \
https://accounts.google.com/o/oauth2/token
# Exchange a refresh token for a new access token.
curl \
--request POST \
--data 'client_id=[Application Client Id]&client_secret=[Application Client Secret]&refresh_token=[Refresh token granted by second step]&grant_type=refresh_token' \
https://accounts.google.com/o/oauth2/token
Upvotes: 0
Reputation: 6975
Unfortunately, @Mac Hooper, your code suffers very badly from a whole lot of issues. Please bear with me for a while:
Videos.insert
API endpoint) has to be properly authorized:Authorization
This request requires authorization with at least one of the following scopes (read more about authentication and authorization).Scope
https://www.googleapis.com/auth/youtube.upload
https://www.googleapis.com/auth/youtube
https://www.googleapis.com/auth/youtubepartner
https://www.googleapis.com/auth/youtube.force-ssl
Uploading videos using the YouTube Data API cannot be done as simple as you're trying to do it. Although not officially documented as such, the API supports two kinds of uploading procedures:
a. Resumable uploads, and
b. One-go uploads.
The resumable uploads are achieved by means of the officially documented Resumable Uploading Protocol.
The resumable uploading protocol is quite tricky to correctly be implemented regardless of the implementation language/environment. Google provides open-source code that implements the protocol for a plethora of languages/environments. Although it is achievable, I'd recommend against implementing this protocol in shell scripts using curl
.
On the other hand, uploading videos in one go is what you'll have to do if expecting to issue only one curl
call per video upload (excluding the calls implied by the procedure of obtaining an access token). But that curl
call requires certain things to be prepared beforehand.
There's this answer of mine that indicated the path to be taken when employing curl
in one-go uploads.
Basically, your curl
call would look like the one below:
$ curl \
--data-binary "@$MULTIPART_RELATED" \
--header "Content-Type: $CONTENT_TYPE" \
--header "Authorization: Bearer $ACCESS_TOKEN" \
'https://www.googleapis.com/upload/youtube/v3/videos?uploadType=multipart&part=snippet,status'
(Do note that above I presume issuing curl
at a bash
command line prompt. When being at a Windows command line prompt things work similarly, but the above curl
command should properly be adapted.)
The curl
command above has three parameters: $MULTIPART_RELATED
, $CONTENT_TYPE
and $ACCESS_TOKEN
. The latter is your credentials data that gets passed on to YouTube's server such that your API call be authorized.
Do read the section Obtaining OAuth 2.0 access tokens of the official document OAuth 2.0 for Mobile & Desktop Apps for to see how to obtain a valid (non-expired) access token upon completing successfully an OAuth 2 authentication/authorization flow.
The parameter $MULTIPART_RELATED
is the name of the file you should have composed (programmatically) before issuing the actual curl
call. The format of this file is not documented officially as such, but is derived upon inspecting Google's own open-source code.
The parameter $CONTENT_TYPE
is a string that specifies the Content-Type
header needed by the HTTP POST
method to be issued via curl
.
Again, my answer to the SO question How to upload video to youtube using google api. Without libraries provides all the details for one to be able to generate properly the file $MULTIPART_RELATED
and the string $CONTENT_TYPE
.
Upvotes: 1