javayoutubeyoutube-apiyoutube-data-apigoogle-data-api

Create YouTube Event using java without prompting login from browser


I am trying to create Event using Java Program on youtube. I am able to do this but it opens a browser where ask me to enter user login info and then validate and create .oauth-credentials/createbroadcast file. I need a solution where my java code itself validate user using some API key/secret key etc, wihtout user intervention.

Providing code snippet for more understanding.

 // Authorize the request.
        Credential credential = Auth.authorize(scopes, "createbroadcast");

        // This object is used to make YouTube Data API requests.
        youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential)
                .setApplicationName("youtube-cmdline-createbroadcast-sample").build();

Above code has Auth.authorize method. which is given below.

public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {

    // Load client secrets.
    Reader clientSecretReader = new InputStreamReader(Auth.class.getResourceAsStream("./client_secrets.json"));
    GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);

    // This creates the credentials datastore at
    // ~/.oauth-credentials/${credentialDatastore}
    FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(
            new File(System.getProperty("user.home") + "/.oauth-credentials"));
    DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
            clientSecrets, scopes).setCredentialDataStore(datastore).build();

    // Build the local server and bind it to port 8080
    LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8080).build();

    **// Authorize.
    // ------------------------Problem is here-------------------------------------
    // This method calls authorize which check if the file under "/.oauth-credentials" folder is less then 60 sec.**
    // If its not it get expires and opens a browser where i requred to login.
    return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}

return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user"); I dont want user intervention and my program should handle this so that on some even i can excute it and get it authorized without user asking for userid and passwrod. (Motive is 0 intervention of user) In the above code last line validate user and opens browser where ask me to login. how can we handle this part from code as i want this code to be deployed on server and on action of user on my webpage i want to create this event in my account. Kinldy help.

My Finding till now is.. com.google.api.client.auth.oauth2.Credential has open to either check for refreshtoken or expire time. how can we set token and what to set in token to avoid refresh token. A Method from the class which athorize it.

public Credential authorize(String userId) throws IOException {
try {
  Credential credential = flow.loadCredential(userId);
  if (credential != null
      && (credential.getRefreshToken() != null || credential.getExpiresInSeconds() > 60)) {
    return credential;
  }
  // open in browser
  String redirectUri = receiver.getRedirectUri();
  AuthorizationCodeRequestUrl authorizationUrl =
      flow.newAuthorizationUrl().setRedirectUri(redirectUri);
  onAuthorization(authorizationUrl);
  // receive authorization code and exchange it for an access token
  String code = receiver.waitForCode();
  TokenResponse response = flow.newTokenRequest(code).setRedirectUri(redirectUri).execute();
  // store credential and return it
  return flow.createAndStoreCredential(response, userId);
} finally {
  receiver.stop();
}

}

As of now it gives me null for get refresh token how can i set so that i get token insted of validating for ExpireTimeinSec.


Solution

  • Below solution is working fine and i have tested it for almost 10 days now. You just need below code change and genrate the file. use it anywhere.

    new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
            clientSecrets, scopes).setAccessType("offline").setCredentialDataStore(datastore).build();
    

    .setAccessType("offline") Till now its working after 1 hour also. will be validating it for few day.

    [Update]

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
                        clientSecrets, scopes).setAccessType("offline").setCredentialDataStore(datastore).build();
    

    .setAccessType("offline") This line in the above code works fine and it will just refresh the auth token. User never requires to update auth file genratated by above code. you can create this file from local and put it at secure location of your project and keep using it.