Offline Access to google calendar using java
Asked Answered
K

1

2

We have code to sync our application calendar with google calendar of logged in user. The code is using AuthSub and CalendarService class but it does not provide offline access to google calendar using access token and refresh token for that i want to use OAuth v3 using calendar class. I am facing problem to merge my old code to new v3 Calendar class which is not having getFeed() function. Here is some code from my application

if(StringUtil.isValid(request.getQueryString())) {
                onetimeUseToken = AuthSubUtil.getTokenFromReply(request.getQueryString());
            }       

            if(StringUtil.isValid(onetimeUseToken)) {           

                    String sessionToken = AuthSubUtil.exchangeForSessionToken(onetimeUseToken,null);
                    CalendarService calendarService = new CalendarService("myapp");
                    calendarService.setAuthSubToken(sessionToken, null);    
                    session.setAttribute("calendarServicesession",calendarService);
                    userIDforCalendar = (String) session.getAttribute("calendar_user_no");
                        }

                       CalendarFeed myResultsFeed1 =service.getFeed(new URL("https://www.google.com/calendar/feeds/default/allcalendars/full"),CalendarFeed.class);

            for (int i = 0; i < myResultsFeed1.getEntries().size(); i++) {
                CalendarEntry entry = myResultsFeed1.getEntries().get(i);
                           .....

}

Please provide me some way to give offline access using CalendarService so that I don't have to change my code much. Hoping for a quick reply.

Thanks- Dravit Gupta

Koffman answered 18/1, 2013 at 6:27 Comment(0)
B
4

Google deprecated AuthSub from 20 April 2012. So it is time you migrated to OAuth 2.0 and Google Calendar API v3. First download the jar files from these following links:

https://google-api-client-libraries.appspot.com/download/library/calendar/v3/java

http://google-oauth-java-client.googlecode.com/files/google-oauth-java-client-1.13.1-beta.zip

Remove the old calendar and Authsub jar files from your project and add the jar files from this link.

Then go to google api console to get your client id, client secret and create a redirect uri. And from the same api console enable google calendar api.

I am giving you a sample code that authenticates the user and shows the calendars that he has you have to store the refresh token that you get in the output and store it so that you can access the calendar offline.

This following function is for OAuth authorization.

 public void authenticate(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    String client_id                = "xxxx";
    String redirect_uri             = "xxxxxx";
    String scope                    = "https://www.googleapis.com/auth/calendar";
    String client_secret            = "xxxxxx";
    List <String> scopes;
    HttpTransport transport         = new NetHttpTransport();
    JsonFactory jsonFactory         = new JacksonFactory();

    scopes = new LinkedList<String>();
    scopes.add(scope);
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(transport, jsonFactory, client_id, client_secret, scopes).build();
    GoogleAuthorizationCodeRequestUrl url = flow.newAuthorizationUrl();
    url.setRedirectUri(redirect_uri);
    url.setApprovalPrompt("force");
    url.setAccessType("offline");
    String authorize_url = url.build();
    response.sendRedirect(authorize_url);
}

You have to add values to the variables client_id, client_secret and redirect_uri. All these values are in your google api console.

The authorization function forwards me to the authorize url which gives me an access token and a refresh token. However, access token expires after a time interval. So if you want the access token you need to store the refresh token and using that generate it whenever you access the calendar api.

This following function generates access token and refresh token and prints the list of calendars in the users google calendar.

public void importCalendarList(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    HttpSession session = request.getSession();
    String staffKey = (String) session.getAttribute("staffKey");
    ContactJdo staffDetails = staff.getStaffDetail(staffKey);
    String code = request.getParameter("code");
    String calendarId="";

    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(transport, jsonFactory, client_id, client_secret, scopes).build();
    GoogleTokenResponse res = flow.newTokenRequest(code).setRedirectUri(redirect_uri).execute();
    String refreshToken = res.getRefreshToken();
    String accessToken = res.getAccessToken();

    List <CalendarListEntry>list1= getCalendars(accessToken);

    for(CalendarListEntry temp:list1) {
        System.out.println(temp.getId());
    }}

If you look at the above function, it generates both access and refresh tokens. If you want to generate access token again use this function:

public static String getAccessToken(String refreshToken, String client_id, String client_secret) throws IOException {
    HttpTransport transport         = new NetHttpTransport();
    JsonFactory jsonFactory         = new JacksonFactory();

    GoogleRefreshTokenRequest req = new GoogleRefreshTokenRequest(transport, jsonFactory, refreshToken, client_id, client_secret);
    GoogleTokenResponse res = req.execute();
    String accessToken = res.getAccessToken();
    return accessToken;
}

Store the refresh token somewhere and you can do all the operations that are mentioned in the calendar documentation. Find it here

https://google-api-client-libraries.appspot.com/documentation/calendar/v3/java/latest/index.html

Bently answered 24/1, 2013 at 10:43 Comment(4)
But what if the user already has made such an authorization? What if I have only the accessToken (+ appToken + appSecret)? Is it possible with the v3? How is your getCalendars method implemented?Ard
ah, it looks like this should work: GoogleCredential credential = new GoogleCredential().setAccessToken("atoken"); client = new Calendar.Builder(new NetHttpTransport(), new JacksonFactory(), credential) .setApplicationName(APPLICATION_NAME) .build(); -> groups.google.com/forum/#!topic/google-api-java-client/…Ard
Yeah, this worked + I had to enable the calendar API in google console + the following maven deps: <dependency> <groupId>com.google.apis</groupId> <artifactId>google-api-services-calendar</artifactId> <version>v3-rev47-1.15.0-rc</version> </dependency> <dependency> <groupId>com.google.api-client</groupId> <artifactId>google-api-client</artifactId> <version>1.15.0-rc</version> <groupId>com.google.http-client</groupId> <artifactId>google-http-client-jackson2</artifactId>Ard
getCalendars method private List<CalendarListEntry> getCalendars(String accessToken) throws IOException{ Calendar calendarService = AppointmentUtilities.getCalendar(accessToken); Calendar.CalendarList.List list = calendarService.calendarList().list(); list.setOauthToken(accessToken); return list.execute().getItems(); } And for your first question REfresh tokens come in handy when we use offline mode because the access token expires. If you want access again you need to generate access token using the refresh tokenBently

© 2022 - 2024 — McMap. All rights reserved.