How to correctly obtain user's Calendar events

2020-07-11 06:11发布

问题:

I'm trying to retrive Calendar events for a user in a domain. I have service account access, but i get 404 error when I try to get specific user events. Heres connection code:

NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
    GoogleCredential credential = new GoogleCredential.Builder()
            .setTransport(httpTransport)
            .setJsonFactory(JSON_FACTORY)
            .setServiceAccountId(googleApiServiceAccountId)
            .setServiceAccountScopes(Collections.singleton(CalendarScopes.CALENDAR_READONLY))
            .setServiceAccountPrivateKey(SecurityUtils.loadPrivateKeyFromKeyStore(
                    SecurityUtils.getPkcs12KeyStore(),
                    getClass().getClassLoader().getResourceAsStream(googleApiPrivateKeyPath),
                    NOTASECRET, PRIVATEKEY, NOTASECRET))
            .build();

    calendarApi = new Calendar.Builder(httpTransport,
            JSON_FACTORY, credential).setApplicationName(getApplicactionName()).build();

Events listing method:

public List<Event> getCalendarEventsForUserAndDates(String userEmail, Long dateFrom, Long dateTo) {
    try {
        String pageToken = null;
        List<Event> allEvents = Lists.newArrayList();
        do {
            ArrayMap<String, Object> parameters = new ArrayMap<String, Object>();
            parameters.add("xoauth_requestor_id", userEmail);
            Calendar.Events.List list = calendarApiBean.getCalendarApi()
                    .events().list("primary");
            list.setTimeMax(new DateTime(dateFrom, 0))
                    .setTimeMin(new DateTime(dateTo, 0))
                    .setUnknownKeys(parameters);
            Events events = list.setPageToken(pageToken)
                    .execute();
            List<? extends Event> items = events.getItems();
            if (items != null) {
                allEvents.addAll(items);
            }
            pageToken = events.getNextPageToken();
        } while (pageToken != null);
        return allEvents;
    } catch (IOException e) {
        logger.error("error while retriving calendar events for {} and dates {} {} ", userEmail, dateFrom, dateTo);
        logger.error("exception", e);
        return Collections.emptyList();
    }

}

When i try to set xoauth_requestor_id to user's email and list 'primary', i get Calendar events for my Service Accounts. When I change events().list() parameter to user's email I get an following Error:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 404 Not Found
{
  "code" : 404,
  "errors" : [ {
    "domain" : "global",
    "message" : "Not Found",
    "reason" : "notFound"
  } ],
  "message" : "Not Found"
}

Thanks for any help.

回答1:

To solved this problem I had to add this service account to authorized API clients on Domain Administration. Client name is Service Account Client ID and scope was for Readonly Calendar



回答2:

This consists of two different parts

  1. Creating a service account
  2. Giving it permissions to access the scopes you need

Create the service account:

  1. Go to the cloud page to administer your Service Accounts: Menu on the left side -> IAM & admin -> Service accounts. Or click on this link: https://console.cloud.google.com/iam-admin/serviceaccounts
  2. Make sure you are logged in as the user you want to use, and check that the organization is correctly selected
  3. Create a new service account with Project Viewer role (you can change this later), and download the .json file with the credentials when you click to create a key.
  4. Edit the service account and enable G Suite Domain-wide Delegation
  5. Take note of the Client ID. (NOT the Key ID)

Give it permissions:

  1. Go to admin.google.com
  2. Make sure you are logged in as the user with admin rights.
  3. Then go to Security -> Settings -> Advanced settings -> Manage API client access
  4. In client name fill in the Client ID you copied above (NOT the Key id)
  5. Fill in the scopes you need and authorize the service account. ie:

    https://www.googleapis.com/auth/calendar.readonly,https://www.googleapis.com/auth/gmail.readonly
    

I tested the Python samples I link in the sources, and can confirm this works as expected.

Sources: https://developers.google.com/identity/protocols/OAuth2ServiceAccount https://support.google.com/a/answer/162106?hl=en