Google Calendar API Does Not Return Newly Created Events

794 Views Asked by At

I am working on a script to pull an event from Google Calendar and put it on a website. The purpose is to be able to put the operating hours for my employer (a university library) on our website. Basically we create events in Google Calendar with the operating hours in the summary. My aim is to pull the relevant information from the Calendar programmatically and put it into a div tag on our home page.

It was not difficult to modify the basic PHP example from Google to retrieve the requisite information. Unfortunately the controller code stopped retrieving newly created events. It is not a permissions issue since I am the owner of the calendar. And up until yesterday afternoon I was able create new events and have the script print them to my browser. Here is my code:

<?php
require __DIR__ . '/vendor/autoload.php';

define('APPLICATION_NAME', 'Library Hours Script');
define('CREDENTIALS_PATH', '~/path-to-credentials');
define('CLIENT_SECRET_PATH', __DIR__ . '/private key file');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-php-quickstart.json
define('SCOPES', implode(' ', array(
  Google_Service_Calendar::CALENDAR_READONLY)
));

/**
 * Returns an authorized API client.
 * @return Google_Client the authorized client object
 */
$client_email = '[email protected]';
$private_key = file_get_contents('/path-to-private-key');
$credentials = new Google_Auth_AssertionCredentials(
  $client_email,
  SCOPES,
  $private_key
);

// Get the API client and construct the service object.
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
    $client->getAuth()->refreshTokenWithAssertion();
}
$service = new Google_Service_Calendar($client);

// Get the calendar ID.  The script currently uses the "Regular Hours" calendar.
$calendarId = '[email protected]';
$optParams = array(
  'maxResults' => 1,
  'singleEvents' => TRUE,
  'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);

if (count($results->getItems()) == 0) {
  print "<a href='http://www.deltastate.edu/academics/libraries/libraries-hours-of-operation/' target='_blank'>Click here for Library hours</a>.\n";
} else {
    foreach ($results->getItems() as $event) {
      $opHours = $event->getSummary();
      $start = $event->start->dateTime;

      if (empty($start)) {
        $start = $event->start->date;
      }

    print($opHours . " " . $start . " " . date('c'));
  }
}

Essentially the code above makes a request to the Calendar API for a list of events with the maximum number of results being 1, filtered by the current date. Then it prints the start date and summary to the screen.

The API explorer returns the same results as when I run the script on a web server. It only shows events in the future created some time ago. The events I created yesterday and today for later this week are not returned. The problem does not seem to be very common, but no one who has reported it has found a solution. Any help would be greatly appreciated.

2

There are 2 best solutions below

0
KENdi On

I think it is related in pagination issue when setting the maxResult parameter.

According to the document. You can control the maximum number of resources the server returns in the response to a list request by setting the maxResults field. Furthermore, for some collections (such as Events) there is a hard limit on the number of retrieved entries that the server will never exceed. If the total number of events exceeds this maximum, the server returns one page of results.

Incomplete results can be detected by a non-empty nextPageToken field in the result. In order to retrieve the next page, perform the exact same request as previously and append a pageToken field with the value of nextPageToken from the previous page. A new nextPageToken is provided on the following pages until all the results are retrieved.

Check this SO question in how to use the pageToken.

1
Mike P On

Figured it out! The issue was related to pagination, but not in the way expected. One of the changes I made to Google's sample script was to remove 'orderBy' from the optParams array thinking only one single event would be returned. Indeed the script did so. However the page of results was still given in a particular order, probably date created, with the top result being printed. So events recently added to the calendar were buried at the bottom of the events list and not printed to the screen. I added the key back in so the array looks as follows:

 $optParams = array(
  'maxResults' => 5,
  'orderBy' => 'startTime',
  'singleEvents' => TRUE,
  'timeMin' => date('c'),
);

Now the script returns the date I want it to. When returning multiple results they are now ordered by start date. Thank you for pointing me in the right direction.