You Tube video upload "401 Unauthorized" using youtube-data-api - java

I am trying to upload video to Youtube using the java youtube api and getting "401 Unauthorized".
I have created a service account using the developers console and using that .p12 file
Here is the code I am using.
public class YouTubeUtils {
private static YouTube youtube;
private static final String VIDEO_FORMAT = "video/*";
private static final String APPLICATION_NAME = "TestApp";
private static final String SERVICE_ACCOUNT_EMAIL = "xxxxx#developer.gserviceaccount.com";
private static HttpTransport httpTransport;
private static final JsonFactory JSON_FACTORY = new JacksonFactory();
public static void main(String[] args) {
try {
try {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
if (SERVICE_ACCOUNT_EMAIL.startsWith("Enter ")) {
System.err.println(SERVICE_ACCOUNT_EMAIL);
System.exit(1);
}
String p12Content = Files.readFirstLine(new File("C:/Workspace/TestApp.p12"),
Charset.defaultCharset());
if (p12Content.startsWith("Please")) {
System.err.println(p12Content);
System.exit(1);
}
List<String> scopes = Lists.newArrayList(YouTubeScopes.YOUTUBE_UPLOAD);
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(httpTransport)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
.setServiceAccountScopes(scopes)
.setServiceAccountPrivateKeyFromP12File(new File("C:/Workspace/TestApp.p12"))
.build();
youtube = new YouTube.Builder(httpTransport, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
Video videoObjectDefiningMetadata = new Video();
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
VideoSnippet snippet = new VideoSnippet();
Calendar cal = Calendar.getInstance();
snippet.setTitle("Test Upload via Java on " + cal.getTime());
snippet.setDescription("Video uploaded via YouTube Data API V3 using the Java library "
+ "on " + cal.getTime());
List<String> tags = new ArrayList<String>();
tags.add("test");
tags.add("video");
snippet.setTags(tags);
videoObjectDefiningMetadata.setSnippet(snippet);
FileInputStream fin = new FileInputStream(new File("C:/Workspace/small.mp4"));
InputStreamContent mediaContent = new InputStreamContent(VIDEO_FORMAT,fin);
YouTube.Videos.Insert videoInsert = youtube.videos().insert(
"snippet,statistics,status",
videoObjectDefiningMetadata, mediaContent);
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader)
throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
System.out.println("Initiation Started");
break;
case INITIATION_COMPLETE:
System.out.println("Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
System.out.println("Upload in progress");
System.out.println("Upload percentage: "
+ uploader.getProgress());
break;
case MEDIA_COMPLETE:
System.out.println("Upload Completed!");
break;
case NOT_STARTED:
System.out.println("Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
// Call the API and upload the video.
Video returnedVideo = videoInsert.execute();
// Print data about the newly inserted video from the API
// response.
System.out
.println("\n================== Returned Video ==================\n");
System.out.println(" - Id: " + returnedVideo.getId());
System.out.println(" - Title: "
+ returnedVideo.getSnippet().getTitle());
System.out.println(" - Tags: "
+ returnedVideo.getSnippet().getTags());
System.out.println(" - Privacy Status: "
+ returnedVideo.getStatus().getPrivacyStatus());
System.out.println(" - Video Count: "
+ returnedVideo.getStatistics().getViewCount());
} catch (IOException e) {
e.printStackTrace();
System.err.println(e.getMessage());
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
It prints
Initiation Started
Initiation Completed
and after that I am getting "401 Unauthorized"
Can someone help me on this.
Thanks

Please refer to this link, it says Service Accounts do not work with the YouTube API
Also, please refer to this link to know how to get authorization credentials and what type of credentials the Youtube API supports.
And here is an example of uploading a video to youtube using OAuth 2.0.

Related

how to call client_secrets.json from an external directory java?

I basically have a dynamic WEB-APP which through a servlet I am trying to retrieve a youtube video comments.
Although there is alot of article about it in the web but I don't know why none worked for me.
First Attempt:
private static int counter = 0;
private static YouTube youtube;
public static void getYoutubeOauth() throws Exception {
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = Auth.authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "KIgxmV9xXBQ";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
// Get next page of video comments threads
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
With this I am getting nullpointerexception at line: Credential credential = Auth.authorize(scopes, "commentthreads");
If you can please explain what is scope and where do you get it from.
Second Attempt I tried creating a different function for getting credentials.
Second Attempt:
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
// Load client secrets.
Reader clientSecretReader = new InputStreamReader(
Auth.class.getResourceAsStream("/home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json"));
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
// Checks that the defaults have been replaced (Default = "Enter X here").
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
return null;
}
// This creates the credentials datastore at ~/.oauth-credentials/${credentialDatastore}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
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.
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
Here also Im getting an nullpointerexception at line Reader clientSecretReader = new InputStreamReader(... although If I would try nano /home/hazrat/Documents/eclipse-jee-neon-3-linux-gtk-x86_64/eclipse/client_secrets.json in my terminal I can access the file.
Question: How to authorize my web-app and read client_secrets.json from an external directory.
Was a bit painful but made the second solution working.
So what I was doing wrong was that I was calling Auth.class.getResourceAsStream which it requires the data to be available to classLoader but to my classLoader it was not.
so what I had to do is to request my client_secrets.json from an external directory which then you have to use FileInputStream other than getResourceAsStream.
Both FileInputStream and getResourceAsStream works fine but they differ on your situation and different code.
public static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
public static final JsonFactory JSON_FACTORY = new JacksonFactory();
private static final String CREDENTIALS_DIRECTORY = ".oauth-credentials";
public static Credential authorize(List<String> scopes, String credentialDatastore) throws IOException {
Reader clientSecretReader = new InputStreamReader(
new FileInputStream("/client_secrets.json"));
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, clientSecretReader);
System.out.println(clientSecretReader.toString());
if (clientSecrets.getDetails().getClientId().startsWith("Enter")
|| clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println(
"Enter Client ID and Secret from https://console.developers.google.com/project/_/apiui/credential "
+ "into src/main/resources/client_secrets.json");
return null;
}
FileDataStoreFactory fileDataStoreFactory = new FileDataStoreFactory(new File(System.getProperty("user.home") + "/" + CREDENTIALS_DIRECTORY));
DataStore<StoredCredential> datastore = fileDataStoreFactory.getDataStore(credentialDatastore);
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, scopes).setCredentialDataStore(datastore)
.build();
LocalServerReceiver localReceiver = new LocalServerReceiver.Builder().setPort(8081).build();
return new AuthorizationCodeInstalledApp(flow, localReceiver).authorize("user");
}
private static int counter = 0;
private static YouTube youtube;
public static void getYoutubeOauth() throws Exception {
List<String> scopes = Lists.newArrayList("https://www.googleapis.com/auth/youtube.force-ssl");
Credential credential = authorize(scopes, "commentthreads");
youtube = new YouTube.Builder(Auth.HTTP_TRANSPORT, Auth.JSON_FACTORY, credential).build();
String videoId = "KIgxmV9xXBQ";
// Get video comments threads
CommentThreadListResponse commentsPage = prepareListRequest(videoId).execute();
while (true) {
handleCommentsThreads(commentsPage.getItems());
String nextPageToken = commentsPage.getNextPageToken();
if (nextPageToken == null)
break;
commentsPage = prepareListRequest(videoId).setPageToken(nextPageToken).execute();
}
System.out.println("Total: " + counter);
}
private static YouTube.CommentThreads.List prepareListRequest(String videoId) throws Exception {
return youtube.commentThreads()
.list("snippet,replies")
.setVideoId(videoId)
.setMaxResults(100L)
.setModerationStatus("published")
.setTextFormat("plainText");
}
private static void handleCommentsThreads(List<CommentThread> commentThreads) {
for (CommentThread commentThread : commentThreads) {
List<Comment> comments = Lists.newArrayList();
comments.add(commentThread.getSnippet().getTopLevelComment());
CommentThreadReplies replies = commentThread.getReplies();
if (replies != null)
comments.addAll(replies.getComments());
System.out.println("Found " + comments.size() + " comments.");
// Do your comments logic here
counter += comments.size();
}
}
Note: change FileInputStream location to your own location.
Then you can call getYoutubeOauth and hope for getting a working response :)

Not able to download google sheet from google drive using java code

Not able to download google sheet from google drive. Facing 403 Insufficient Permission issue.
Please check below code.
public class Quickstart {
/** Application name. */
private static final String APPLICATION_NAME = "Drive API Java Quickstart";
/** Directory to store user credentials for this application. */
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
".credentials/drive-java-quickstart");
/** Global instance of the {#link FileDataStoreFactory}. */
private static FileDataStoreFactory DATA_STORE_FACTORY;
/** Global instance of the JSON factory. */
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
/** Global instance of the HTTP transport. */
private static HttpTransport HTTP_TRANSPORT;
/**
* Global instance of the scopes required by this quickstart.
*
* If modifying these scopes, delete your previously saved credentials at
* ~/.credentials/drive-java-quickstart
*/
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE_METADATA_READONLY);
static {
try {
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
} catch (Throwable t) {
t.printStackTrace();
System.exit(1);
}
}
/**
* Creates an authorized Credential object.
*
* #return an authorized Credential object.
* #throws IOException
*/
public static Credential authorize() throws IOException {
// Load client secrets.
InputStream in = Quickstart.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, SCOPES).setDataStoreFactory(DATA_STORE_FACTORY).setAccessType("offline").build();
Credential credential = new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
System.out.println("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
/**
* Build and return an authorized Drive client service.
*
* #return an authorized Drive client service
* #throws IOException
*/
public static Drive getDriveService() throws IOException {
Credential credential = authorize();
return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
}
public static void main(String[] args) throws IOException {
// Build a new authorized API client service.
Drive service = getDriveService();
// Print the names and IDs for up to 10 files.
FileList result = service.files().list().setPageSize(10).setFields("nextPageToken, files(id, name)").execute();
List<File> files = result.getFiles();
if (files == null || files.size() == 0) {
System.out.println("No files found.");
} else {
System.out.println("Files:");
for (File file : files) {
System.out.printf("%s (%s)\n", file.getName(), file.getId());
}
}
downloadFile(service, "1l0dX1hOdk0xX5T2ruqnci-75sMwziwiih9BFGX6DcdA");
}
private static void downloadFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getName());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
OutputStream outputStream = new ByteArrayOutputStream();
service.files().export(fileId, "application/x-vnd.oasis.opendocument.spreadsheet")
.executeMediaAndDownloadTo(outputStream);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
}
}
}
**Output:**
403 error is displayed after executing above code. Please check below output of above code.
Credentials saved to /home/nikhil/.credentials/drive-java-quickstart
Files:
nikhil (1zNmRFWe_HABvhP_HukQIcOVdUoLllKB49RpPK3_XXn4)
Test Sheet (1l0dX1hOdk0xX5T2ruqnci-75sMwziwiih9BFGX6DcdA)
Getting started (0Bx8dATp9NaeXc3RhcnRlcl9maWxlX2Rhc2hlclYw)
Title: Test Sheet
Description: null
MIME type: application/vnd.google-apps.spreadsheet
An error occurred: com.google.api.client.http.HttpResponseException: 403
Forbidden
{
"error": {
"errors": [
{
"domain": "global",
"reason": "insufficientPermissions",
"message": "Insufficient Permission"
}
],
"code": 403,
"message": "Insufficient Permission"
}
}
Change the scope and data store directory.
private static final List<String> SCOPES = Arrays.asList(DriveScopes.DRIVE);
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"),
".credentials/drive-java-quickstart.json");
Added File path for saving the file to local machine.
public static void initialMethod() throws IOException {
// Build a new authorized API client service.
Drive service = getDriveService();
downloadFile(service, "1JYlTtznsCll16upwIIbgXjqDvjsAFO5krSiGjvciO70");
}
private static void downloadFile(Drive service, String fileId) {
try {
File file = service.files().get(fileId).execute();
System.out.println("Title: " + file.getName());
System.out.println("Description: " + file.getDescription());
System.out.println("MIME type: " + file.getMimeType());
OutputStream outputStream = new FileOutputStream(new java.io.File(Constant.DRIVE_EXCEL_PATH + "Test.xlsx"));
service.files().export(fileId, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
.executeMediaAndDownloadTo(outputStream);
System.out.println(outputStream);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
} catch (Exception e) {
System.out.println("An error occurred: " + e);
}
}
Above code helps for downloading file from google drive.

Youtube Upload API returns videoId but video is not available on youtube

In the app, there is a block of code that looks similar to official youtube sample, which uploads video file using google's lib (com.google.api). Uploading goes well and in the end of processing the id of com.google.api.services.youtube.model.Video is printed in log file. So I'm sure that uploading itself works perfectly.
Uploading small video files (less then 15mb) works. It is possible to see the resulting video on youtube, but it is not a case with a large 100+ mb video files. Large files are uploaded and I can see youtube id in log files but video is not available on youtube itself.
here's the code excerpt
private static final String VIDEO_FILE_FORMAT = "video/*";
private static YouTube youtube;
private static final List<String> SCOPES = Lists.newArrayList(
YouTubeScopes.YOUTUBE,
YouTubeScopes.YOUTUBE_UPLOAD
);
private static int uploadToYoutube(BlablaConfiguration configuration, com.blabla.youtube.model.Video videoObject, String localFilename) {
LOG.debug("UPLOAD_YOUTUBE");
try {
JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
HttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
GoogleCredential credential = new GoogleCredential.Builder()
.setTransport(HTTP_TRANSPORT)
.setJsonFactory(JSON_FACTORY)
.setServiceAccountId(configuration.getClientEmail())
.setServiceAccountPrivateKeyFromP12File(new File(configuration.getP12filename()))
.setServiceAccountScopes(SCOPES)
.setServiceAccountUser("my#account.com")
.build();
youtube = new YouTube.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(configuration.getAppName())
.build();
LOG.info("Uploading...");
Video videoObjectDefiningMetadata = new Video();
VideoStatus status = new VideoStatus();
status.setPrivacyStatus("public");
videoObjectDefiningMetadata.setStatus(status);
VideoSnippet snippet = new VideoSnippet();
StringBuffer title = new StringBuffer();
try {
String yearStr = Integer.toString(videoObject.getYear());
title.append(yearStr);
} catch (Exception e) {
//
}
String make = videoObject.getMake();
if (make != null) {
title.append(" " + make);
}
String model = videoObject.getModel();
if (model != null) {
title.append(" " + model);
}
String style = videoObject.getStyle();
if (style != null) {
title.append(" " + style);
}
snippet.setTitle(title.toString());
snippet.setDescription("Video uploaded via Blabla.com");
List<String> tags = new ArrayList<String>();
tags.add("http://www.blabla.com");
snippet.setTags(tags);
videoObjectDefiningMetadata.setSnippet(snippet);
InputStreamContent mediaContent = new InputStreamContent(VIDEO_FILE_FORMAT,
new FileInputStream(localFilename)
);
YouTube.Videos.Insert videoInsert = youtube.videos()
.insert("snippet,statistics,status", videoObjectDefiningMetadata, mediaContent);
MediaHttpUploader uploader = videoInsert.getMediaHttpUploader();
uploader.setDirectUploadEnabled(false);
MediaHttpUploaderProgressListener progressListener = new MediaHttpUploaderProgressListener() {
public void progressChanged(MediaHttpUploader uploader) throws IOException {
switch (uploader.getUploadState()) {
case INITIATION_STARTED:
LOG.debug("Initiation Started");
break;
case INITIATION_COMPLETE:
LOG.debug("Initiation Completed");
break;
case MEDIA_IN_PROGRESS:
LOG.debug("Upload in progress");
LOG.debug("Upload percentage: " + uploader.getProgress());
break;
case MEDIA_COMPLETE:
LOG.debug("Upload Completed!");
break;
case NOT_STARTED:
LOG.warn("Upload Not Started!");
break;
}
}
};
uploader.setProgressListener(progressListener);
Video returnedVideo = videoInsert.execute();
String videoID = returnedVideo.getId();
LOG.debug("\n================== Returned Video ==================\n");
LOG.debug(" - Id: " + videoID);
videoObject.setYoutubeId(videoID);
return 0;
} catch (GoogleJsonResponseException e) {
LOG.error("GoogleJSONException");
e.printStackTrace();
return 1;
} catch (IOException e) {
LOG.error("IOException: " + e.getMessage());
e.printStackTrace();
return 2;
} catch (Throwable t) {
LOG.error("Throwable: " + t.getMessage());
t.printStackTrace();
return 3;
}
}
What could be an issue here?
Any thoughts on that?
Youtube does a lot of post-processing once a video is uploaded and this time is directly proportional to the video time -- longer the video, longer the time it takes for them to process.
This may explain why while a videoId was assigned to your video, it does not show up just yet.
Give it some time and try again.
https://www.quora.com/Why-does-YouTube-take-so-long-to-process-videos-after-theyre-uploaded

Null Pointer Exception when accessing Google Analytics report data using different credentials

I am following the tutorial to get access to the GA account report data by executing a simple GA query, by using the Google Developers console.
I followed all steps mentioned in the tutorial and the code works fine.
I have included the code below.
public class GoogleAnalyticsAccess {
private static final String APPLICATION_NAME = "GAAccess/1.0";
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/analytics_sample");
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static FileDataStoreFactory dataStoreFactory;
private static HttpTransport httpTransport;
public static Credential authorizeUser() throws IOException {
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(
GoogleAnalyticsAccess.class.getResourceAsStream("/client_secrets.json")));
if (clientSecrets.getDetails().getClientId().startsWith("Enter") ||
clientSecrets.getDetails().getClientSecret().startsWith("Enter ")) {
System.out.println("Enter Client ID and Secret from https://code.google.com/apis/console/?api=analytics " +
"into Dashboard/src/main/resources/client_secrets.json");
System.exit(1);
}
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(httpTransport, JSON_FACTORY,
clientSecrets, Collections.singleton(AnalyticsScopes.ANALYTICS_READONLY))
.setDataStoreFactory(dataStoreFactory).build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static Analytics getAnalyticsServiceObject(Credential credential){
return new Analytics.Builder(httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME)
.build();
}
public static String getGAAccountId(Analytics analytics) throws IOException {
String accountId =null;
Accounts accounts = analytics.management().accounts().list().execute();
List<Account> accountsList = accounts.getItems();
if(accountsList.isEmpty()){
System.err.println("No accounts found");
}
else{
for(int i=0; i<accountsList.size();i++){
if(accountsList.get(i).getName().equals("XXXX")){
accountId = accountsList.get(i).getId();
break;
}
}
}
return accountId;
}
public static String getGAWebPropertyId(Analytics analytics,String accountId) throws IOException {
String webPropertyId = null;
Webproperties webProperties = null;
webProperties = analytics.management().webproperties().list(accountId).execute();
List<Webproperty> webPropertiesList = webProperties.getItems();
if (webPropertiesList.isEmpty()) {
System.err.println("No Web Properties found");
} else {
for (int i=0; i<webPropertiesList.size();i++){
if(webPropertiesList.get(i).getName().equals("XXXX")){
webPropertyId = webPropertiesList.get(i).getId();
}
}
}
return webPropertyId;
}
public static String getGAViewId(Analytics analytics, String accountId, String webPropertyId) throws IOException {
String viewId = null;
Profiles views = analytics.management().profiles().list(accountId, webPropertyId).execute();
List<Profile> viewsList = views.getItems();
if (viewsList.isEmpty()) {
System.err.println("No profiles found");
} else {
for(int i=0; i<viewsList.size();i++){
if(viewsList.get(i).getName().equals("XXXX")){
viewId = viewsList.get(i).getId();
}
}
}
return viewId;
}
public static List<GoogleAnalyticsData> executeGAQuery(Analytics analytics, String viewId, String dimension) throws IOException {
List<GoogleAnalyticsData> dataList = new ArrayList<GoogleAnalyticsData>();
if (viewId == null) {
System.err.println("No profiles found.");
} else {
GaData gaData = analytics.data().ga().get("ga:" + viewId, "2015-02-13", "2015-02-27", "ga:users")
.setDimensions("ga:" + dimension)
.setMaxResults(200).execute();
if (gaData.getRows() == null || gaData.getRows().isEmpty()) {
System.out.println("No results Found.");
} else {
GoogleAnalyticsData data;
for (List<String> row : gaData.getRows()) {
data = new GoogleAnalyticsData();
data.setName(row.get(0));
data.setValue(Integer.parseInt(row.get(1)));
dataList.add(data);
}
}
}
return dataList;
}
public static void main(String[] args) throws GeneralSecurityException, IOException {
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorizeUser();
Analytics analytics = getAnalyticsServiceObject(credential);
String accountId = getGAAccountId(analytics);
String webPropertyId = getGAWebPropertyId(analytics,accountId);
String viewId = getGAViewId(analytics,accountId,webPropertyId);
List<GoogleAnalyticsData> continentDataList = executeGAQuery(analytics, viewId, "continent");
List<GoogleAnalyticsData> countryDataList = executeGAQuery(analytics, viewId, "country");
for(int i =0; i <continentDataList.size();i++){
System.out.println(continentDataList.get(i).getName() + " " + continentDataList.get(i).getValue());
}
for(int i=0; i< countryDataList.size();i++){
System.out.println(countryDataList.get(i).getName() + " " + countryDataList.get(i).getValue());
}
}
}
I get an error when I access the same GA account report data by giving the credential (Client secret and Id) of another user who also has shared access to that report data.
I am successfully able to access the report data using the other users credentials If I have already run the java application using my credentials first. But If I run the app with the other users credentials first, then I get the following error.
The Stack trace is shown below.
Exception in thread "main" java.lang.NullPointerException
at com.google.api.client.repackaged.com.google.common.base.Preconditions.checkNotNull(Preconditions.java:191)
at com.google.api.client.util.Preconditions.checkNotNull(Preconditions.java:127)
at com.google.api.client.json.jackson2.JacksonFactory.createJsonParser(JacksonFactory.java:92)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:85)
at com.google.api.client.json.JsonObjectParser.parseAndClose(JsonObjectParser.java:81)
at com.google.api.client.auth.oauth2.TokenResponseException.from(TokenResponseException.java:88)
at com.google.api.client.auth.oauth2.TokenRequest.executeUnparsed(TokenRequest.java:287)
at com.google.api.client.auth.oauth2.TokenRequest.execute(TokenRequest.java:307)
at com.google.api.client.auth.oauth2.Credential.executeRefreshToken(Credential.java:570)
at com.google.api.client.auth.oauth2.Credential.refreshToken(Credential.java:489)
at com.google.api.client.auth.oauth2.Credential.intercept(Credential.java:217)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:859)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:410)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:343)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:460)
at org.dashboard.access.data.GoogleAnalyticsAccess.getGAAccountId(GoogleAnalyticsAccess.java:266)
at org.dashboard.access.data.GoogleAnalyticsAccess.main(GoogleAnalyticsAccess.java:364)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
The specific exception occurs at the following line in method getGAAccountId.
Accounts accounts = analytics.management().accounts().list().execute();
Is there any workaround for this issue?
If your client_secrets.json is well configured, you just have to delete the file .store/analytics_sample and run it again.

How to get the auth token for dropbox directly into java program so that user don't need to copy paste it

I am developing an application where I have to upload file and download file from dropbox account, application is a java desktop application. I have used the sample code and was able to run it without any glitch. But I want to bypass that user needs to copy the auth code form browser to the application, how can be that done. I want my application to get the auth token directly into the application, because this is causing overhead on user.
All the experts please help me.
Here's the code I have Implemented.
import com.dropbox.core.*;
import java.awt.Desktop;
import java.io.*;
import java.util.Locale;
public class Main {
public static void main(String[] args) throws IOException, DbxException {
// Get your app key and secret from the Dropbox developers website.
final String APP_KEY = "xxxxxxxxxxxxxxxx";
final String APP_SECRET = "xxxxxxxxxxxxxxxx";
DbxAppInfo appInfo = new DbxAppInfo(APP_KEY, APP_SECRET);
DbxRequestConfig config = new DbxRequestConfig("JavaTutorial/1.0",
Locale.getDefault().toString());
DbxWebAuthNoRedirect webAuth = new DbxWebAuthNoRedirect(config, appInfo);
// Have the user sign in and authorize your app.
String authorizeUrl = webAuth.start();
System.out.println("1. Go to: " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first)");
System.out.println("3. Copy the authorization code.");
Desktop.getDesktop().browse(java.net.URI.create(authorizeUrl));
String code = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();
// This will fail if the user enters an invalid authorization code.
DbxAuthFinish authFinish = webAuth.finish(code);
DbxClient client = new DbxClient(config, authFinish.accessToken);
System.out.println("Linked account: " + client.getAccountInfo().displayName);
File inputFile = new File("OpenCv_Video_display_link.txt");
FileInputStream inputStream = new FileInputStream(inputFile);
try {
DbxEntry.File uploadedFile = client.uploadFile("/OpenCv_Video_display_link.txt",
DbxWriteMode.add(), inputFile.length(), inputStream);
System.out.println("Uploaded: " + uploadedFile.toString());
} finally {
inputStream.close();
}
DbxEntry.WithChildren listing = client.getMetadataWithChildren("/");
System.out.println("Files in the root path:");
for (DbxEntry child : listing.children) {
System.out.println(" " + child.name + ": " + child.toString());
}
FileOutputStream outputStream = new FileOutputStream("121verbs.pdf");
try {
DbxEntry.File downloadedFile = client.getFile("/121verbs.pdf", null,
outputStream);
System.out.println("Metadata: " + downloadedFile.toString());
} finally {
outputStream.close();
}
}
}
Go to https://www.dropbox.com/developers/apps
Click on the app. On this page under Outh 2, look for Generated access token.
Click on Generate.
This is your access token. This authenticates that the user is you and you don't have to go through the standard authorization flow everytime.
I have commented the unnecessary code, you will only need the last line.
/* // Have the user sign in and authorize your app.
String authorizeUrl = webAuth.start();
System.out.println("1. Go to: " + authorizeUrl);
System.out.println("2. Click \"Allow\" (you might have to log in first)");
System.out.println("3. Copy the authorization code.");
String code = new BufferedReader(new InputStreamReader(System.in)).readLine().trim();
// This will fail if the user enters an invalid authorization code.
DbxAuthFinish authFinish = webAuth.finish(code); */
String accessToken = "Your access token goes here";
Based in this example from dropbox blog i made this example in java it will open a Webview where you can introduce your dropbox credentials after that dropbox will redirect you and the redirection url will have the token then we get the token from the URl and print to the console.
public class AnotherClass extends Application {
public static void main(String[] args) {
java.net.CookieHandler.setDefault(new com.sun.webkit.network.CookieManager());
launch(args);
}
//This can be any URL. But you have to register in your dropbox app
final String redirectUri = "https://www.dropbox.com/1/oauth2/redirect_receiver";
final String AppKey = "YOUR APP KEY ";
final String url = "https://www.dropbox.com/1/oauth2/authorize?client_id=" + AppKey + "&response_type=token&redirect_uri=" + redirectUri;
#Override
public void start(Stage pStage) throws Exception {
Stage primaryStage = pStage;
primaryStage.setTitle("Dropbox Sign In");
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.load(url);
webEngine.locationProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(ObservableValue<? extends String> arg0, String oldLocation, String newLocation) {
try {
if (newLocation.startsWith(redirectUri)) {
ArrayMap<String, String> map = parseQuery(newLocation.split("#")[1]);
if (map.containsKey("access_token")) {
System.out.print("Token: " + map.get("access_token"));
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
});
StackPane stackPane = new StackPane();
stackPane.getChildren().add(webView);
Scene rootScene = new Scene(stackPane);
primaryStage.setScene(rootScene);
primaryStage.show();
}
ArrayMap<String, String> parseQuery(String query) throws UnsupportedEncodingException {
ArrayMap<String, String> params = new ArrayMap<String, String>();
for (String param : query.split("&")) {
String[] pair = param.split("=");
String key = URLDecoder.decode(pair[0], "UTF-8");
String value = URLDecoder.decode(pair[1], "UTF-8");
params.put(key, value);
}
return params;
}
}
Based on my development experience on Android platform, you may insert JavaScript code to scan the web page and extract the auth code, like below :
#Override
public void onPageFinished(final WebView webView, final String url) {
if (AUTHORIZE_SUBMIT_URL.equalsIgnoreCase(url)
&& AUTHORIZE_SUBMIT_TITLE.equalsIgnoreCase(webView.getTitle())) {
webView.loadUrl("javascript:HtmlViewer.showHTML"
+ "('<html>'+document.getElementById('auth-code').innerHTML+'</html>');");
}
}

Categories