I want to list all events all events from Google calendar using this code:
public class GoogleCalendarImpl
{
private static final String APPLICATION_NAME = "";
private static final java.io.File DATA_STORE_DIR = new java.io.File(System.getProperty("user.home"), ".store/calendar_sample");
private static FileDataStoreFactory dataStoreFactory;
private static HttpTransport httpTransport;
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static com.google.api.services.calendar.Calendar client;
static final java.util.List<Calendar> addedCalendarsUsingBatch = Lists.newArrayList();
private static final String calId = "edrhrtherherh#development-1384.iam.gserviceaccount.com";
private static Credential authorize() throws Exception
{
// load client secrets
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY,
new InputStreamReader(GoogleCalendarImpl.class.getResourceAsStream("/development-241a19899242.json")));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
httpTransport, JSON_FACTORY, clientSecrets,
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(dataStoreFactory).build();
return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
}
public static void main(String[] args)
{
try
{
httpTransport = GoogleNetHttpTransport.newTrustedTransport();
dataStoreFactory = new FileDataStoreFactory(DATA_STORE_DIR);
Credential credential = authorize();
client = new com.google.api.services.calendar.Calendar.Builder(
httpTransport, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();
getAllEvents();
}
catch (IOException e)
{
System.err.println(e.getMessage());
}
catch (Throwable t)
{
t.printStackTrace();
}
System.exit(1);
}
private static List<Event> getAllEvents() throws IOException
{
List<Event> events = new ArrayList<>();
String nextPageToken = null;
do
{
System.out.println("Loading page " + nextPageToken);
Events feed = client.events().list(calId).setPageToken(nextPageToken).execute();
events.addAll(feed.getItems());
nextPageToken = feed.getNextPageToken();
}
while (nextPageToken != null);
return events;
}
}
But when I run the code Firefox(default web browser) is started and I'm redirected to page:
Error: redirect_uri_mismatch
The redirect URI in the request, http://localhost:56345/Callback, does not match the ones authorized for the OAuth client. Visit https://console.developers.google.com/apis/credentials/oauthclient/1024206104045435454813?project=762076316631 to update the authorized redirect URIs.
I would like to get all entried from Google calendar configured into my account.
How I can fix this issue?
How to fix Error: redirect_uri_mismatch
Go to your GDC and check what you specified as URI redirect. It should be
http://localhost:portnumber/oauth2callback.
Don't forget the 'oauth2' part.
Related
I'm trying to connect to the Google Calendar API. I am have followed the step in Google calendar quick start for Java
{ "error" : "invalid_grant", "error_description" : "Bad Request" }
Can you please advise on how to debug this? The error message is unfortunately not helpful and I already tried everything I could find about this particular error on Stack overflow or elsewhere
Every time I got the same access token for different credentials:
Access token: {user=Class{accessToken=null, refreshToken="" expirationTimeMilliseconds=null}}
code:
public class CalendarServiceImpl implements CalendarService {
public static final String APPLICATION_NAME = "GoogleCalenderApi";
public static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
public static final String TOKENS_DIRECTORY_PATH = "/data.json";
public static final List<String> SCOPES = Collections.singletonList(CalendarScopes.CALENDAR);
public static final String CREDENTIALS_FILE_PATH = "/data.json";
public Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT, HttpServletRequest request)
throws IOException {
InputStream in = CalendarServiceImpl.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
if (in == null) {
log.info("Resource not found: " + CREDENTIALS_FILE_PATH);
throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
}
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY,
clientSecrets, SCOPES)
.setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
.setAccessType("offline")
.build();
System.out.println("Access token: " + flow.getCredentialDataStore());
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(80)
.build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
}
public void createCalendarEvent(String candidateMailId, String companyEmailId, DateTime fromTime, DateTime toTime,
String summary, String description, HttpServletRequest request)
throws GeneralSecurityException, IOException {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Event event = new Event().setSummary(summary).setLocation("Test").setDescription(description);
EventDateTime start = new EventDateTime().setDateTime(fromTime).setTimeZone("Asia/Kolkata");
event.setStart(start);
EventDateTime end = new EventDateTime().setDateTime(toTime).setTimeZone("Asia/Kolkata");
event.setEnd(end);
String[] recurrence = new String[] { "RRULE:FREQ=DAILY" };
event.setRecurrence(Arrays.asList(recurrence));
EventAttendee[] attendees = new EventAttendee[] { new EventAttendee().setEmail(candidateMailId),
new EventAttendee().setEmail(companyEmailId) };
event.setAttendees(Arrays.asList(attendees));
EventReminder[] reminderOverrides = new EventReminder[] { new EventReminder().setMethod("email").setMinutes(10),
new EventReminder().setMethod("popup").setMinutes(10), };
Event.Reminders reminders = new Event.Reminders().setUseDefault(false)
.setOverrides(Arrays.asList(reminderOverrides));
event.setReminders(reminders);
// Build service account credential.
Credential credential = getCredentials(HTTP_TRANSPORT, request);
log.info("got credential:" + event);
Calendar service = new Calendar.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
.setApplicationName(APPLICATION_NAME).build();
String calendarId = "primary";
try {
System.out.printf("Event started" + event);
event = service.events().insert(calendarId, event).setSendUpdates("all").execute();
} catch (IOException e) {
log.info("event IOException:" + e);
e.getMessage();
}
log.info("Event created:" + event.getHtmlLink());
}
}
You appear to be using AuthorizationCodeInstalledApp which as it stats is for installed applications. for web applications you need to use AuthorizationCodeFlow.
The official example can be found here
Web server application
public class CalendarServletSample extends AbstractAuthorizationCodeServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// do stuff
}
#Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
#Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new GoogleAuthorizationCodeFlow.Builder(
new NetHttpTransport(), JacksonFactory.getDefaultInstance(),
"[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
DATA_STORE_FACTORY).setAccessType("offline").build();
}
#Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
// return user ID
}
}
public class CalendarServletCallbackSample extends AbstractAuthorizationCodeCallbackServlet {
#Override
protected void onSuccess(HttpServletRequest req, HttpServletResponse resp, Credential credential)
throws ServletException, IOException {
resp.sendRedirect("/");
}
#Override
protected void onError(
HttpServletRequest req, HttpServletResponse resp, AuthorizationCodeResponseUrl errorResponse)
throws ServletException, IOException {
// handle error
}
#Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
#Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new GoogleAuthorizationCodeFlow.Builder(
new NetHttpTransport(), JacksonFactory.getDefaultInstance()
"[[ENTER YOUR CLIENT ID]]", "[[ENTER YOUR CLIENT SECRET]]",
Collections.singleton(CalendarScopes.CALENDAR)).setDataStoreFactory(
DATA_STORE_FACTORY).setAccessType("offline").build();
}
#Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
// return user ID
}
}
AuthorizationCodeFlow opens the consent browser window in the machine that the code is running on. When you are running something as a website it needs to open on the client machine so that the user can see it.
I am trying to access Google Docs API V1 document in Java Servlet using AbstractAuthorizationCodeServlet provide by google api client library but code give error it can't build object of Doc Builder. I have auth 2 creatential and Google doc api is enable from google developer console. below is my code.
#WebServlet("/GetGoogleDoc")
public class GetGoogleDoc extends AbstractAuthorizationCodeServlet {
private static final long serialVersionUID = 1L;
private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private static final List<String> SCOPES = Collections.singletonList(DocsScopes.DOCUMENTS_READONLY);
private static final String DOCUMENT_ID = "";
private static final String CLIENT_ID="";
private static final String CLIENT_SECRET="";
public GetGoogleDoc() {
super();
// TODO Auto-generated constructor stub
}
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
Docs service = new Docs.Builder(HTTP_TRANSPORT, JSON_FACTORY, initializeFlow())
.build();
}
#Override
protected String getRedirectUri(HttpServletRequest req) throws ServletException, IOException {
GenericUrl url = new GenericUrl(req.getRequestURL().toString());
url.setRawPath("/oauth2callback");
return url.build();
}
#Override
protected AuthorizationCodeFlow initializeFlow() throws IOException {
return new GoogleAuthorizationCodeFlow.Builder(
new NetHttpTransport(), JSON_FACTORY, CLIENT_ID,CLIENT_SECRET,SCOPES).build();
}
#Override
protected String getUserId(HttpServletRequest req) throws ServletException, IOException {
return null;
// return user ID
}
static void replaceNamedRange(Docs service, String documentId, String rangeName, String newText)
throws IOException {
Document document = service.documents().get(documentId).execute();
NamedRanges namedRangeList = document.getNamedRanges().get(rangeName);
if (namedRangeList == null) {
throw new IllegalArgumentException("The named range is no longer present in the document.");
}
List<Range> allRanges = new ArrayList<>();
Set<Integer> insertIndexes = new HashSet<>();
for (NamedRange namedRange : namedRangeList.getNamedRanges()) {
allRanges.addAll(namedRange.getRanges());
insertIndexes.add(namedRange.getRanges().get(0).getStartIndex());
}
// Sort the list of ranges by startIndex, in descending order.
allRanges.sort(Comparator.comparing(Range::getStartIndex).reversed());
// Create a sequence of requests for each range.
List<Request> requests = new ArrayList<>();
for (Range range : allRanges) {
// Delete all the content in the existing range.
requests.add(
new Request().setDeleteContentRange(new DeleteContentRangeRequest().setRange(range)));
if (insertIndexes.contains(range.getStartIndex())) {
// Insert the replacement text.
requests.add(
new Request()
.setInsertText(
new InsertTextRequest()
.setLocation(
new Location()
.setSegmentId(range.getSegmentId())
.setIndex(range.getStartIndex()))
.setText(newText)));
// Re-create the named range on the new text.
requests.add(
new Request()
.setCreateNamedRange(
new CreateNamedRangeRequest()
.setName(rangeName)
.setRange(
new Range()
.setSegmentId(range.getSegmentId())
.setStartIndex(range.getStartIndex())
.setEndIndex(range.getStartIndex() + newText.length()))));
}
}
BatchUpdateDocumentRequest batchUpdateRequest =
new BatchUpdateDocumentRequest()
.setRequests(requests)
.setWriteControl(new WriteControl().setRequiredRevisionId(document.getRevisionId()));
service.documents().batchUpdate(documentId, batchUpdateRequest).execute();
}
}
The application freezes while Google Calendar API authentication is in progress.
Below is my source code.
private final String APPLICATION_NAME = "Google Calendar API Java Quickstart";
private java.io.File DATA_STORE_DIR;
private FileDataStoreFactory DATA_STORE_FACTORY;
private final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
private HttpTransport HTTP_TRANSPORT;
private final List<String> SCOPES = Arrays.asList(CalendarScopes.CALENDAR);
#Value("#{config['path.googleAuth']}")
private String googleAuthPath;
public void setGoogleData(String member_id_num) throws Exception{
String userHome = "";
if(System.getProperty("os.name").toLowerCase().indexOf("win") >= 0) {
userHome = System.getProperty("user.home");
}else if(System.getProperty("os.name").toLowerCase().indexOf("linux") >= 0) {
userHome = googleAuthPath;
}else {
userHome = System.getProperty("user.home");
}
HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
DATA_STORE_DIR = new java.io.File(userHome,".credentials_sellers/calendar-java-quickstart_sellers"+File.separator+member_id_num);
DATA_STORE_FACTORY = new FileDataStoreFactory(DATA_STORE_DIR);
log.info("DATA_STORE_DIR=" + DATA_STORE_DIR);
}
public Credential authorize(String member_id_num) throws Exception {
setGoogleData(member_id_num);
InputStream in = GoogleCalendarService.class.getResourceAsStream("/client_secret.json");
GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));
log.info("clientSecrets = " + clientSecrets);
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");
log.info("Credentials saved to " + DATA_STORE_DIR.getAbsolutePath());
return credential;
}
my client_secret.json
{
"installed": {
"client_id": "459740830795-lm5pnqsule6jg4ufu3uvnufgr7tdajn6.apps.googleusercontent.com",
"project_id": "the-sellers-255504",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "L3kDYxfDoSDUG5wM3XEMDi9H",
"redirect_uris": ["urn:ietf:wg:oauth:2.0:oob", "http://localhost", "http://xxx.xxx.x.xxx", "http://xxx.xxx.x.xxx:8090", "http://xxx.xxx.x.xxx", "http://xxx.xxx.x.xxx:8090"]
}
}
In my local environment, the test was successful.
However, the website hangs because I try to link it to a Linux server.
help me please ....
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 :)
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.