Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

YouTube API without user OAuth process

I am trying to fetch captions from YouTube video using YouTube Data API (v3) https://developers.google.com/youtube/v3/guides/implementation/captions

So, first I tried to retrieve a captions list using this url: https://www.googleapis.com/youtube/v3/captions?part=snippet&videoId=KK9bwTlAvgo&key={My API KEY}

I could retrieve the caption id that I'd like to download (jEDP-pmNCIqoB8QGlXWQf4Rh3faalD_l) from the above link.

Then, I followed this instruction to download the caption: https://developers.google.com/youtube/v3/docs/captions/download

However, even though I input the caption id and my api key correctly, it shows "Login Required" error.

I suppose I need OAuth authentication, but what I am trying to do is not related to my users's account, but simply downloading public caption data automatically.

My question is: Is there any way to process OAuth authentication just once to get an access token of my own YouTube account and then reuse it whenever I need it in my application?

like image 950
MaxHeap Avatar asked May 17 '16 14:05

MaxHeap


1 Answers

I can't speak to the permissions needed for the captions API in particular, but in general, yes, you can OAuth to your app once using your own account and use the access and refresh tokens to make subsequent OAuth'd requests to the API. You can find the details of generating tokens here:

https://developers.google.com/youtube/v3/guides/auth/server-side-web-apps#Obtaining_Access_Tokens

To perform the steps manually (fortunately, you only need to do this once):

  1. If access has already been granted for an app, it needs to be removed so that new auth credentials can be established. Go to https://security.google.com/settings/security/permissions (while logged into your account) and remove access to the app. If the client ID or secret change (or you need to create one), find them at https://console.developers.google.com under API Manager.
  2. To grant access and receive a temporary code, enter this URL in a browser:

    https://accounts.google.com/o/oauth2/auth?
    client_id=<client_id>&
    redirect_uri=http://www.google.com&
    scope=https://www.googleapis.com/auth/youtube.force-ssl&
    response_type=code&
    access_type=offline&
    approval_prompt=force
    

    Follow the prompt to grant access to the app.

  3. This will redirect to google.com with a code parameter (e.g., https://www.google.com/?code=4/ux5gNj-_mIu4DOD_gNZdjX9EtOFf&gws_rd=ssl#). Save the code.
  4. Send a POST request (e.g., via Postman Chrome plugin) to https://accounts.google.com/o/oauth2/token with the following in the request body:

    code=<code>&
    client_id=<client_id>&
    client_secret=<client_secret>&
    redirect_uri=http://www.google.com&
    grant_type=authorization_code
    
  5. The response will contain both an access token and refresh token. Save both, but particularly the refresh token (because the access token will expire in 1 hour).

You can then use the access token to send an OAuth'd request manually, following one of the options here, essentially:

curl -H "Authorization: Bearer ACCESS_TOKEN" https://www.googleapis.com/youtube/v3/captions/<id>

or

curl https://www.googleapis.com/youtube/v3/captions/<id>?access_token=ACCESS_TOKEN

(When I tried the second option for captions, however, I got the message: "The OAuth token was received in the query string, which this API forbids for response formats other than JSON or XML. If possible, try sending the OAuth token in the Authorization header instead.")

You can also use the refresh token in your code to create the credential needed when building your YouTube object. In Java, this looks like the following:

String clientId = <your client ID>
String clientSecret = <your client secret>
String refreshToken = <refresh token>

HttpTransport transport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();

GoogleCredential credential = new GoogleCredential.Builder()
    .setTransport(transport)
    .setJsonFactory(jsonFactory)
    .setClientSecrets(clientId, clientSecret)
    .build()
    .setRefreshToken(refreshToken);

try {
    credential.refreshToken();
} catch (IOException e) {
    e.printStackTrace();
}

youtube = new YouTube.Builder(transport, jsonFactory, credential).build();

I imagine you can do something similar in Python with the API Client Libraries, although I haven't tried Python.

like image 131
Tyler C. Avatar answered Nov 15 '22 20:11

Tyler C.