Search code examples
phpapigoogle-calendar-apishared

Google Calendar Service Account with PHP API oauth2.0 - How to access calendars that are not shared


I'm having trouble reading calendar events with the PHP libraries provided by Google. The calendars that I want to read are NOT publicly shared, but I want to read them on my server application.

The account that holds the calendars is separate from mine (I'll refer to it as the API account), though the calendars are shared with me.

According to the not publicly shared Calendar Details on Google:

Anyone can: See nothing

You can: See only free/busy (hide details).

Both the API account and my account have an OAuth2.0 Service Accounts with a P12 key.

I've followed a guide at: http://www.daimto.com/google_service_account_php/ which has helped me figure out the authentication process. I've managed to read calendars that are shared publicly without any problems on either account. Here's my code:

// Start the Google client
$client = new Google_Client();
$client->setClientId({{client_id from google}});
$client->setApplicationName("Project Name");
$client->setClientSecret({{client_secret from google}});
$key = file_get_contents({{key_file_location on my server}});
$cred = new Google_Auth_AssertionCredentials(
        $Email_address,
        // Scopes that we will be using
        array(
           "https://www.googleapis.com/auth/calendar"
        ),
        $key
);

$client->setAssertionCredentials($cred);

if($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion($cred);
}

// Use Google Calendar API plugin
$service = new Google_Service_Calendar($client);

$optParams = array(
    'singleEvents'=> true,
    'timeMin'=>date(DateTime::ATOM),
    'timeMax' => date(DateTime::ATOM, time()+(3 * 24 * 60 * 60))
);

$results = $service->events->listEvents(
    '{{Calendar ID from Google Calendar Settings}}',
    $optParams
);

However, when attempting to use the code for calendars that are not shared publicly I get the following error on either account:

Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/calendar/v3/calendars{{CalendarID}}:(404) Not Found...

When I try var_dump($client->getAuth()), I noticed that there is a value that might suggests that the authentication didn't work:["authenticated":"Google_Client":private]=> bool(false). This happens on both accounts and both publicly shared and publicly not shared calendars.

I'm able to use the Google API Explorer with my account to show the JSON data on calendars that aren't shared publicly. Is there something missing with the Google PHP API or Google Account Settings that will allow me to do what I want?

Thank you for your time.


Solution

  • If you want to access private calendars with a service account, you will need to either perform an authority delegation if you own the domain containing those calendars (https://developers.google.com/drive/web/delegation describes it for drive but it works for calendar) or you will need to share the private calendar with the email address of the service account.