92 thoughts on “Accessing Google Calendar using the php API

  1. tomek August 19, 2014 at 6:44 am Reply

    That’s great. I spend hours yesterday trying to figure out howto do this – documentation isn’t helpful.
    Thanks a lot

    • ayduns August 19, 2014 at 6:58 am Reply

      Good to know it was useful to you!

  2. Valter Luis Junior September 19, 2014 at 1:06 pm Reply

    Thank you very, very much, friend.
    The documentation on the google’s website is totally outdated and I was scratching my head out trying to figure out how to get this to work for days!

    • ayduns September 22, 2014 at 4:34 pm Reply

      You’re welcome!

  3. Mark October 17, 2014 at 2:35 pm Reply

    I copy/pasted your code and I’m getting an error that I can’t find an solution to.

    Call to a member function listEvents() on a non-object

    at

    $events = $service->events->listEvents($calName);

    Any idea how to fix?

    • ayduns November 2, 2014 at 10:03 pm Reply

      If the previous lines are working then $service should be ok, so the problem seems to be in the call to $service->events.

      Try:
      $events = $service->events;
      print_r($events);

  4. jlasiter October 29, 2014 at 9:47 pm Reply

    I’m looking for a php script that will take google calendar data api v3 JSON and reformat it into an RSS feed so I can print an event list onto a Mailchimp campaign. Will this do that? Do you take on such work for pay?

    • ayduns November 20, 2014 at 8:05 pm Reply

      If you search for “google calendar rss” you’ll find a few suggestions for how to do this without code … but if those don’t suit you, let me know!

  5. naveen November 5, 2014 at 6:37 am Reply

    how to create new calendar in google calendar

  6. Jean T November 17, 2014 at 9:33 pm Reply

    Wow, this is so wonderful! I had a bunch of php code to read some gcal feeds that has been working for years… this morning it worked, this afternoon it didn’t… After digging around, I found that the api’s I was using were ancient and deprecate, and no longer supported as today (11/17/14)… I was in a panic, my entire website depends on being able to get data from gcals. I am NOT a google api expert (or even a novice…. I just flounder around google till I find something I need). I found this, and mucked my way through, and I can now see a light at the end of the tunnel! THANK YOU, THANK YOU!

    • ayduns November 20, 2014 at 8:06 pm Reply

      Thanks – good to know it helped you!

  7. Dominique November 19, 2014 at 1:25 am Reply

    Thank you very much. This was very helpful. My question to you would be as your last line of code prints out… echo $event->getSummary(); how can you also print othe event details such as description, location, startdate and enddate?

    • ayduns November 20, 2014 at 8:37 pm Reply

      Yes, you can get all that and much more:
      $event->getDescription();
      $event->getLocation();
      $event->getStart();
      $event->getEnd();

      I haven’t found good documentation on these, but you can find the available functions: view https://github.com/google/google-api-php-client/blob/master/src/Google/Service/Calendar.php and go to the Google_Service_Calendar_Event section (line 2538) then scroll down to a group of “public function” lines.

      So eg “public function getAttendees()” is used as $event->getAttendees();

      • Dominique November 21, 2014 at 12:17 am

        Thank you for your response ayduns. I have tried adding $event->getStart(); and unfortunately, that’s where the code freezes. Any thoughts?

      • ayduns November 21, 2014 at 10:41 am

        $event->getStart() is working for me. I should have mentioned though that it returns a Google_Service_Calendar_EventDateTime object which has a getDateTime() method that returns a string… and the string is probably not the format you want, but the DateTime class can help:

        echo (new DateTime( $event->getStart()->getDateTime() ))->format( 'd/m/Y H:i' ), "\n";

        I’ve updated the original post to use this.

      • Dominique November 21, 2014 at 8:04 pm

        Thank you for your responses. Yes, you are right, your code does show dates but for some reason, I get a 50% success rate. Let me explain: on 50% of the events, it does pick up the correct date, but on the other 50%, it picks up today’s date. If you want, have a look at the resulting page: http://tvgl.barzalou.com/activites/index4.php

      • ayduns November 23, 2014 at 10:02 am

        If getDateTime() is empty, new DateTime() is called with no args and defaults to today’s date.

      • Dominique November 22, 2014 at 5:20 pm

        To be more specific, the issue, as I have found out, resides with reoccurring events. This code does not process reoccurring events correctly.

      • ayduns November 23, 2014 at 6:02 pm

        Repeating events by default are returned as one event with a recurrence rule. For creating lists of events from a calendar, the ‘singleEvents’ parameter is useful to return those recurrences as “normal” individual events. See updated code.

      • Dominique November 22, 2014 at 10:35 pm

        Hoping I don’t sound like a fool, I found more answers. It turns out the issue is not with recurring events but with events deemed as “all day events”. As such, the start datetime is not giving out a date and a time but only a date. The code – echo “Start: “, (new DateTime( $event->getStart()->getDateTime() ))->format( ‘d/m/Y H:i’), “\n”; – does not take this into account and my guess is it confuses the results and returns today’s date and the precise time the request was made. I will try different things to find the solution.

      • Dominique November 23, 2014 at 4:18 am

        Well, thanks to you and StackOverflow, I found the solution. When dealing with an all day event, the Google Calendar API uses the Date variable to store the Date. If not, if the event is at a specific, defined moment in the day, it uses DateTime. Have a look at what I have used to make this work:

        if (($event->getStart()->getDate())!= NULL) {
        $event_date = (new DateTime($event->getStart()->getDate()))->format(‘d/m/Y’);
        } else {
        $event_date = (new DateTime($event->getStart()->getDateTime()))->format(‘d/m/Y H:i’);
        }
        echo “Quand: “, $event_date, “\n”;

        Thanks again

      • ayduns November 23, 2014 at 10:05 am

        Ok, that makes sense. Thanks for sharing that here Dominique.

        Code in post updated to handle all-day events.

  8. Justin November 20, 2014 at 8:38 am Reply

    Thank you so much for this! I wasted hours chasing my tail with Google’s own docs and this worked straight away.

    You would think a company with so much resource to devote to getting this right would at least have pages that link to non depreciated repos!!

  9. Alain Y. November 20, 2014 at 3:03 pm Reply

    Thank you very very Much !!!
    I only find a simple answer on THIS page !!!

  10. Botee November 21, 2014 at 4:17 pm Reply

    The method looked promising (and I’m sure it is), however when I tried it (copy/pasted and filled with relevant credentials) got an error saying ‘Error refreshing the OAuth2 token, message: { invalid_grant….’ I googled two days chasing the solution, but can’t seem to find anything to get me closer to it. I’m not really a google api geek, so I thought I’ll ask here what can there be done to refresh the OAuth2 token? Thank you!

    • Botee November 21, 2014 at 5:06 pm Reply

      I must mention that I’ve granted the required rights for the service account to access the calendar.

    • ayduns November 23, 2014 at 10:11 am Reply

      Sorry, don’t know. Maybe someone else here has ideas.

    • ayduns November 27, 2014 at 4:19 pm Reply

      I get that error if I use the wrong service account name. Should be long-string@developer.gserviceaccount.com

    • Jan Zitniak December 18, 2014 at 10:58 am Reply

      I got same error. I agree with ayduns. The issue was in $service_account_name. Right service_account_name you get in https://console.developers.google.com after creating Service Account. It is EMAIL ADDRESS (between CLIENT ID and FINGERPRINTS)

  11. René November 21, 2014 at 4:41 pm Reply

    Hi! Don’t have a key file… how to obtain one

    • ayduns November 23, 2014 at 10:09 am Reply

      René – you get that from the Google Developer Console. See the “Create a Service Account” section above.

  12. John King November 22, 2014 at 12:22 pm Reply

    This page is saving my life after the 17th November closure of the older API.

    I need to use timeMax and timeMin, do you know how?

    • ayduns November 23, 2014 at 10:15 am Reply

      John – add a parameter array to listEvents():


      // Events for the coming week:
      $params = array(
      'timeMin' => (new DateTime())->format(DateTime::RFC3339),
      'timeMax' => (new DateTime())->add(new DateInterval('P1W'))->format(DateTime::RFC3339),
      );

      $events = $service->events->listEvents($calName, $params);

  13. Ben November 23, 2014 at 9:03 pm Reply

    Thank you much for posting this it has helped much for an un educated hack like myself to understand the changes in v3. Like most looking at this article I was taken unaware of the loss of v2 and am now scurrying to fix something I barely understood in the first place
    I’m getting an Internal Server Error with this code (update Nov 21, 2014) , a previous version was working fine, but in adding in the fmt_gdate function in it errors out. I’m still digging at the dateTime issue but when I echo $event->getstart()->getdateTime(), I see a datestamp that looks like it should be working.

    • ayduns November 24, 2014 at 10:20 am Reply

      Ben – a space crept in on the first line making it ‘ #!/usr/bin/php’ which would cause problems if your copy/paste included that space. How are you running it? e.g. in a web process, command line etc. If it’s in a web process do your server logs show any more detail?

      • Ben November 24, 2014 at 12:39 pm

        I am running this via php. I deleted the space and still get the same error. In looking at the server log I see unexpected T_OBJECT_OPERATOR, expecting ')' ...on line 38

      • Ben November 24, 2014 at 1:07 pm

        ah-ha, PHP v5.3.13, no class member access on instantiation. This was introduced in v5.4. I added an extra line to put new DateTime() into variable and it’s all happy.

  14. jlasiter November 24, 2014 at 1:59 pm Reply

    I hired a programmer and now have a working PHP script which parses Google Calendar api v3 data into a valid RSS feed. (we use it to make an event list for mailchimp campaigns) I needed this for a non-profit I volunteer for. I’m willing to share it, but would like to recoup costs. So I’m willing to offer it for $40. If there is interest I’ll set up a demo page.

  15. Jeff November 25, 2014 at 4:19 pm Reply

    I have the ‘T_OBJECT_OPERATOR, expecting ‘)’ error too.
    Php is version 5.2.8
    How should I change the code?

    I have errors in lines:

    $params = array(
    ‘singleEvents’ => TRUE,
    ‘timeMin’ => (new DateTime())->format(DateTime::RFC3339),
    ‘timeMax’ => (new DateTime())->add(new DateInterval(‘P1W’))->format(DateTime::RFC3339),
    );

    and in
    return (new DateTime($val))->format( ‘d/m/Y H:i’ );

    return (new DateTime($val))->format( ‘d/m/Y’ ) . ‘ (all day)’;

    Thanks

    • Jeff November 25, 2014 at 4:38 pm Reply

      I saw that: ‘PHP 5.3.0 or higher is required to use service accounts.’,
      so I have to upgrade php version.

      Does this requirement lowers if I set up webserver application id instead of service account?

    • ayduns November 25, 2014 at 11:14 pm Reply

      Older versions of PHP need the “new” part as a separate statement (“no class member access on instantiation” as Ben described)

      So:

      $timeMin = new DateTime();
      $params = array ('timeMin' => $timeMin->format(DateTime::RFC3339));

      etc

  16. Jeff November 26, 2014 at 9:30 am Reply

    Thanks Ayduns,
    I modified the code to work with php version 5.2.8 but I fear I will need to upgrade anyway if I want to use oAuth2.

    I’ve looked at the Google description regarding the 3 client id types, but I didn’t really understand the differences, so I’m asking you if you can give me an advice.
    This is the scenario: I need to develop a php web application installed in user’s localhost, which will permit him to insert calendar events. The application then will insert the events in his google calendar too, so when the user is outside home he can see the events in his mobile phone.
    In the previous version of this application, the user inserted his login and password for his google calendar, so that the update happened trasparently to the user, and he even didn’t notice the update into his google calendar.
    Now google has changed the rules so I need to change the mechanism accordingly.
    I know that there is a client id type where the user has to give the consent to access his calendar, but I’d like to avoid this if it’s possible. I’d like to update his calendar trasparently as it was before, or at least give the consent only once during the first installation of the application.
    What do you think would be the viable way to achieve this?

    Thanks in advance,
    Jeff

    • ayduns November 27, 2014 at 4:52 pm Reply

      Jeff, I’m no expert but let’s see if we can figure this out.
      You say: “a php web application installed in user’s localhost” – do you mean there is a web server with php running directly on the user’s device (possible, but unusual)? What platform is this?

      • Jeff November 28, 2014 at 8:02 am

        Hi,
        the platform is simply a pc. The application installs a lamp server and has pages preconfigured, something like a joomla installation or similar.
        These days I’ve tried to use both the web application as client id and the installed app.
        In both cases I’ve succeded to login via auth2 protocol, didn’t try to get the calendar events for now.
        In both cases you need to give the consent. I wanted to avoid this but it seems to me it’s not possible.
        Do you know if the consent has to given only once or every time one opens the google api connection?
        I don’t understand really what the refresh token.
        I’tell you how the work goes on.

        jeff

      • ayduns November 28, 2014 at 9:42 am

        OK, so either the web app or installed app options could work for you, though I think installed app is more appropriate. The purpose of the refresh token is to avoid the user needing to give consent repeatedly and the app needs to store it.

        From https://developers.google.com/accounts/docs/OAuth2InstalledApp :

        • Refresh token is described as: “A token that may be used to obtain a new access token, included by default for installed applications. Refresh tokens are valid until the user revokes access.”
        • “In the OAuth protocol, your app requests authorization to access resources which are identified by scopes, and assuming the user is authenticated and approves, your app receives short-lived access tokens which let it access those resources, and (optionally) refresh tokens to allow long-term access.”
        • “Note that there are limits on the number of refresh tokens that will be issued; one limit per client/user combination, and another per user across all clients. You should save refresh tokens in long-term storage and continue to use them as long as they remain valid. If your application requests too many refresh tokens, it may run into these limits, in which case older refresh tokens will stop working.”
  17. brum November 26, 2014 at 9:45 am Reply

    maybe it is the best source I found, searching the Internet. But when executing code, I get this
    Fatal error: Uncaught exception ‘Google_Service_Exception’ with message ‘Error calling GET https://www.googleapis.com/calendar/v3/calendars/XXXXXXXXXgroup.calendar.google.com/events?singleEvents=true&timeMin=2014-11-26T11%3A26%3A34%2B02%3A00&timeMax=2014-12-03T11%3A26%3A34%2B02%3A00: (404) Not Found’
    Can anyone help?

    • ayduns November 27, 2014 at 4:13 pm Reply

      Double-check the calendar name. If I deliberately add a typo to the calendar name then I get that error.

      You might want to try catching the exception to see if it provides more clues:

      try {
      // the code
      } catch (Google_Service_Exception $e) {
      print_r( $e->getErrors );
      }

  18. Vide November 28, 2014 at 4:53 pm Reply

    Thank you very much for this post! It was really really useful as a base script to interact with the new Calendar API and through all that Google Developers Console jungle. Nice done!

  19. Wayne November 30, 2014 at 3:53 am Reply

    Thanks for the lead – I’ve been pulling my hair our for a few days trying to get the new API sorted! I am getting an error, though – “Class ‘Google_Client’ not found”. Any thoughts?

  20. Ben Farmer December 5, 2014 at 12:55 am Reply

    Wayne, sounds like you might not have the API package installed or the include is not pointing to the right point.

  21. Parama D December 13, 2014 at 8:07 pm Reply

    I don’t think i missed single step here, but when i tried to run the script through the browser it keep showing “This webpage is not available”, when calling this method $cals = $service->calendarList->listCalendarList();

    • ayduns December 13, 2014 at 9:35 pm Reply

      I haven’t tried running it via a server, just from the command line. Does it work if you run it from the command line?

    • PL January 29, 2015 at 3:55 pm Reply

      I have the same problem, but I don’t understand what is the problem!

  22. Michael Stowe December 16, 2014 at 9:37 pm Reply

    Thank you for this — I’d be remiss if I didn’t point out that GetDate and GetDateTime are reversed in the fmt_gdate function.

    • ayduns January 8, 2015 at 12:48 pm Reply

      You’re right – Fixed now!

  23. Jan Zitniak December 18, 2014 at 10:59 am Reply

    Thank you for your very useful article. It works.

  24. Petey January 7, 2015 at 9:08 pm Reply

    I’m pulling my hair out trying to get this work. This is erroring out at: return $val->format( ‘l, m/d/Y’ );

    Call to a member function format() on a non-object

    Is it necessary to create $val and $gdate? Updating to 5.4 is not readily available. Any other suggestions?

    $timeMin = new DateTime();
    $timeMax = new DateTime();
    $val = new DateTime();
    $gdate = new DateTime();

    $params = array(
    ‘orderBy’ => ‘startTime’,
    ‘singleEvents’ => TRUE,
    ‘timeMin’ => $timeMin->format(DateTime::RFC3339),
    ‘timeMax’ => $timeMax-> add (new DateInterval(‘P6D’)) -> format(DateTime::RFC3339),
    );

    $events = $service->events->listEvents($calName, $params);

    print(“”);
    foreach ($events->getItems() as $event) {
    print (“” . fmt_gdate($event->getStart()) . ” – ” . $event->getSummary() . “”);
    }
    print(“”);

    function fmt_gdate ( $gdate ) {
    if ($val = $gdate->getDate()) {
    return $val->format( ‘l, m/d/Y g:iA’ );
    } else if ($val = $gdate->getDateTime()) {
    return $val->format( ‘l, m/d/Y’ ) ;
    }
    }

    • ayduns January 8, 2015 at 1:26 pm Reply

      Firstly, note that the getDate() and getDateTime() calls in fmt_gdate() are reversed as Michael pointed out – corrected now in the main post.

      You don’t need to create $val & $gdate in lines 3 and 4 – they are only used in the fmt_gdate function.

      In your version of fmt_gdate(), $val is a string and you then try to call format() on that without creating a DateTime object resulting in the error you see. If you are on an older version of php, try:

      function fmt_gdate( $gdate ) {
      if ($val = $gdate->getDateTime()) {
      $dt = new DateTime($val);
      return $dt->format(‘l, m/d/Y g:iA’ );
      } else if ($val = $gdate->getDate()) {
      $dt = new DateTime($val);
      return $dt->format( ‘l, m/d/Y’ );
      }
      }

      • Petey January 8, 2015 at 3:57 pm

        That did it! Thanks so much for your help!

  25. Naoto January 18, 2015 at 10:36 pm Reply

    Thank you very much. I have tried to find a working model for several days, and found nothing worked. And your instruction made my day!

  26. Greg January 31, 2015 at 12:48 am Reply

    Super useful, thanks!!!!!!!!!!!

  27. Gen February 5, 2015 at 12:13 am Reply

    HEY aydus. thanks for your tutorial on the google calenadr on php. I’m now trying to create an event on Google Calendar from my web page on localhost.my codes look this:

    require_once “calendar_connect.php”;

    $event = new Google_Service_Calendar_Event();
    $event->setSummary(‘New’);
    $event->setLocation(‘Singapore’);
    $start = new Google_Service_Calendar_EventDateTime();
    $start->setDateTime(‘2015-06-03T10:00:00.000-07:00’);
    $event->setStart($start);
    $end = new Google_Service_Calendar_EventDateTime();
    $end->setDateTime(‘2015-06-03T10:25:00.000-07:00’);
    $event->setEnd($end);
    $attendee1 = new Google_Service_Calendar_EventAttendee();
    $attendee1->setEmail(‘attendeeEmail’);
    // …
    $attendees = array($attendee1,
    // …
    );
    $event->attendees = $attendees;
    $createdEvent = $service->events->insert(‘primary’, $event);

    echo $createdEvent->getId();

    But i keep getting an error message after i run it which shows like this :

    ” Fatal error: Uncaught exception ‘Google_Service_Exception’ with message ‘Error calling POST https://www.googleapis.com/calendar/v3/calendars/ERP/events: (403) Insufficient Permission’ in C:\xampp\htdocs\calendar\src\Google\Http\REST.php:111 Stack trace: #0 C:\xampp\htdocs\calendar\src\Google\Http\REST.php(63): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client)) #1 [internal function]: Google_Http_REST::doExecute(Object(Google_Client), Object(Google_Http_Request)) #2 C:\xampp\htdocs\calendar\src\Google\Task\Runner.php(172): call_user_func_array(Array, Array) #3 C:\xampp\htdocs\calendar\src\Google\Http\REST.php(47): Google_Task_Runner->run() #4 C:\xampp\htdocs\calendar\src\Google\Client.php(564): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request)) #5 C:\xampp\htdocs\calendar\src\Google\Service\Resource.php(227): Google_Client->execute(Object(Google_Http_Request)) #6 C:\xampp\htdocs\calendar\src\Google\Service\Calendar.php(1440): Google_Service_Resource->call(‘in in C:\xampp\htdocs\calendar\src\Google\Http\REST.php on line 111 ”

    do you know what went wrong with the code?

    • ayduns February 10, 2015 at 2:25 pm Reply

      Gen – It’s complaining about insufficient permission so I’d start by looking at how the connection is set up. What is in calendar_connect.php?

      • Duggy February 10, 2015 at 9:31 pm

        Hi ayduns, thanks a million for this wonderful guide. Google documentations were driving me nuts until i found your blog post. Great work. 🙂

        As you mentioned, viewing all events work fine. But i need to add an event to the calendar via my PHP code. But Google throws an exception saying “(403) Insufficient Permission”. It is the same error mentioned by Gen above. My code looks very similar to his code too. What could be the issue? In my Google calendar, for permission settings I have selected “Make changes and manage sharing”

        Here is my code.

        require_once “Google/Client.php”;
        require_once “Google/Service/Calendar.php”;

        // Service Account info is set
        $client_id = ‘ADDED’;
        $service_account_name = ‘ADDED’;
        $key_file_location = ‘ADDED’;

        // Calendar id
        $calName = ‘ADDED’;

        $config = new Google_Config();
        $config->setClassConfig(‘Google_Cache_File’, array(‘directory’ => ‘../tmp/cache’));
        // Here I set a relative folder to avoid pb on permissions to a folder like /tmp that is not permitted on my mutualised host

        $client = new Google_Client($config);
        // And then, you pass the config for your GoogleClient

        //$client = new Google_Client();
        $client->setApplicationName(“Calendar test”);

        $service = new Google_Service_Calendar($client);

        $key = file_get_contents($key_file_location);
        $cred = new Google_Auth_AssertionCredentials(
        $service_account_name,
        array(‘https://www.googleapis.com/auth/calendar.readonly’),
        $key
        );

        $client->setAssertionCredentials($cred);

        //Add event

        $event = new Google_Service_Calendar_Event();
        $event->setSummary(‘Interview’);
        $event->setLocation(‘Hell’);
        $start = new Google_Service_Calendar_EventDateTime();
        $start->setDateTime(‘2015-02-12T10:00:00.000-07:00’);
        $event->setStart($start);
        $end = new Google_Service_Calendar_EventDateTime();
        $end->setDateTime(‘2015-02-12T11:00:00.000-07:00′);
        $event->setEnd($end);
        $attendee1 = new Google_Service_Calendar_EventAttendee();
        $attendee1->setEmail(’email@abc.com’);
        // …
        $attendees = array($attendee1,
        // …
        );
        $event->attendees = $attendees;
        $createdEvent = $service->events->insert(‘primary’, $event);

        echo $createdEvent->getId();

        —————————————————————————————
        Here is my error

        Fatal error: Uncaught exception ‘Google_Service_Exception’ with message ‘Error calling POST https://www.googleapis.com/calendar/v3/calendars/primary/events/quickAdd: (403) Insufficient Permission’ in /home/rent/public_html/calendar/src/Google/Http/REST.php:111 Stack trace: #0 /home/rent/public_html/calendar/src/Google/Http/REST.php(63): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client)) #1 [internal function]: Google_Http_REST::doExecute(Object(Google_Client), Object(Google_Http_Request)) #2 /home/rent/public_html/calendar/src/Google/Task/Runner.php(172): call_user_func_array(Array, Array) #3 /home/rent/public_html/calendar/src/Google/Http/REST.php(47): Google_Task_Runner->run() #4 /home/rent/public_html/calendar/src/Google/Client.php(564): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request)) #5 /home/rent/public_html/calendar/src/Google/Service/Resource.php(227): Google_Client->execute(Object(Google_Http_Request)) #6 /home/rent/public_html/calendar/src/Google in /home/rent/public_html/calendar/src/Google/Http/REST.php on line 111

      • ayduns February 10, 2015 at 11:52 pm

        Duggy – thanks for your comments!

        I haven’t tried creating events, but one thing I notice is that you’ll need to change the Google_Auth_AssertionCredentials call to use the writable scope instead of the readonly one – ie ‘https://www.googleapis.com/auth/calendar’.

        There are two constants of CALENDAR and CALENDAR_READONLY that you can use instead. See the first few lines of the Google_Service_Calendar class code at https://github.com/google/google-api-php-client/blob/master/src/Google/Service/Calendar.php

  28. Duggy February 11, 2015 at 7:44 am Reply

    @ayduns You made my day again. 🙂 That was the issue. Authentication scope should be changed to https://www.googleapis.com/auth/calendar.

    And also there is a slight modification to make.I think Google documentation is faulty on this line too as it didn’t add my events to the calendar.

    $createdEvent = $service->events->insert(‘primary’, $event);

    This line should be changed as follows. Instead of defining it as ‘primary’, directly use the calendar ID.

    $createdEvent = $service->events->insert($calName, $event);

    Hope this helps someone who wants to add events.

    Here is my working code. 🙂

    $event = new Google_Service_Calendar_Event();
    $event->setSummary(‘Interview’);
    $event->setLocation(‘Hell’);
    $start = new Google_Service_Calendar_EventDateTime();
    $start->setDateTime(‘2015-06-03T10:00:00.000-07:00’);
    $event->setStart($start);
    $end = new Google_Service_Calendar_EventDateTime();
    $end->setDateTime(‘2015-06-03T10:25:00.000-07:00′);
    $event->setEnd($end);
    $attendee1 = new Google_Service_Calendar_EventAttendee();
    $attendee1->setEmail(’email@abc.com’);
    // …
    $attendees = array($attendee1);
    $event->attendees = $attendees;

    //$createdEvent = $service->events->insert(‘primary’, $event);

    //Google code error was fixed
    $createdEvent = $service->events->insert($calName, $event);

    //echo $createdEvent->getId();

    var_dump($createdEvent);

  29. ayduns February 11, 2015 at 9:19 am Reply

    Great – thanks for sharing your code here Duggy

  30. bumbar March 11, 2015 at 2:34 pm Reply

    I use google api to access my calendar with the help of your site – REST. Everything was going perfectly until today, when a message Fatal error: Uncaught exception ‘Google_Auth_Exception’ with message ‘Error refreshing the OAuth2 token, message:’ {“error”: “invalid_grant”} ”
    Has not been changed account access. Even checked in another server script that will work with the same rights and there is no problem.
    The question is whether it is a server problem? …

  31. Callum McKay March 15, 2015 at 3:49 pm Reply

    Hello,

    I’ve tried to put together the code I’ve found here in the comments, mostly by Duggy but I’m still getting errors.

    Fatal error: Uncaught exception ‘Google_Service_Exception’ with message ‘Error calling POST https://www.googleapis.com/calendar/v3/calendars/calendar%40dsac.co.uk/events: (403) Forbidden’ in /home/d11dsac/public_html/google-api-php-client-master/src/Google/Http/REST.php:111
    Stack trace:
    #0 /home/d11dsac/public_html/google-api-php-client-master/src/Google/Http/REST.php(63): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client))

    #1 [internal function]: Google_Http_REST::doExecute(Object(Google_Client), Object(Google_Http_Request))

    #2 /home/d11dsac/public_html/google-api-php-client-master/src/Google/Task/Runner.php(172): call_user_func_array(Array, Array)

    #3 /home/d11dsac/public_html/google-api-php-client-master/src/Google/Http/REST.php(47): Google_Task_Runner->run()

    #4 /home/d11dsac/public_html/google-api-php-client-master/src/Google/Client.php(564): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request)) #5 /home/d11dsac/public_html/google-api-php-client-master/src/Go in /home/d11dsac/public_html/google-api-php-client-master/src/Google/Http/REST.php on line 111

    Here’s the code I’m using

    require_once ‘google-api-php-client-master/src/Google/Client.php’;
    require_once ‘google-api-php-client-master/src/Google/Service/Calendar.php’;

    // Service Account info is set
    $client_id = ‘jibberish.apps.googleusercontent.com’;
    $service_account_name = ‘jibberish@developer.gserviceaccount.com’;
    $key_file_location = ‘google-api-php-client-master/DSAC Calendar-jibberish.p12’;

    // Calendar id
    $calName = ‘DSAC Calendar’;

    $config = new Google_Config();
    $config->setClassConfig(‘Google_Cache_File’, array(‘directory’ => ‘../tmp/cache’));
    // Here I set a relative folder to avoid pb on permissions to a folder like /tmp that is not permitted on my mutualised host

    $client = new Google_Client($config);
    // And then, you pass the config for your GoogleClient

    //$client = new Google_Client();
    $client->setApplicationName(‘DSAC Calendar’);

    $service = new Google_Service_Calendar($client);

    $key = file_get_contents($key_file_location);
    $cred = new Google_Auth_AssertionCredentials(
    $service_account_name,
    array(‘https://www.googleapis.com/auth/calendar’),
    $key
    );

    $client->setAssertionCredentials($cred);
    $event = new Google_Service_Calendar_Event();
    $event->setSummary(‘Interview’);
    $event->setLocation(‘Hell’);
    $start = new Google_Service_Calendar_EventDateTime();
    $start->setDateTime(‘2016-06-03T10:00:00.000-07:00’);
    $event->setStart($start);
    $end = new Google_Service_Calendar_EventDateTime();
    $end->setDateTime(‘2016-06-03T10:25:00.000-07:00’);
    $event->setEnd($end);
    $attendee1 = new Google_Service_Calendar_EventAttendee();
    $attendee1->setEmail(‘test@email.com’);
    // …
    $attendees = array($attendee1);
    $event->attendees = $attendees;

    //$createdEvent = $service->events->insert(‘primary’, $event);

    //Google code error was fixed
    $createdEvent = $service->events->insert($calName, $event);

    echo $createdEvent->getId();

    var_dump($createdEvent);

  32. Ali November 18, 2015 at 11:40 am Reply

    i use this code and it helps me in case of public calendar but display some errors when calendar is not public and also shared with few email addresses. i also noticed that calendar address is still same even if i share my calendar with some other friends.

    Looking for your response.

    Thanks

    • ayduns November 18, 2015 at 1:38 pm Reply

      If the calendar is not public, you need to share it with the service account. Have you done that?

  33. Ali November 19, 2015 at 5:09 am Reply

    how can i share it with service account ?could you please help me in this regard?

    • ayduns November 19, 2015 at 9:58 am Reply

      Ali – see the “Sharing the Calendar” section above.

  34. Ali November 19, 2015 at 11:34 am Reply

    Thanks ayduns for your reply, i already follow above steps while implementing your code but still Calendar ID is same like “some@gmail.com” instead of “some@group.calendar.google.com” and also the script only capture events when calendar is made public.

  35. Ali November 19, 2015 at 12:00 pm Reply

    http://stackoverflow.com/questions/11863022/edit-google-calendar-events-from-google-service-account-403

    thanks for your time ayduns, above url resolve the issue , i was sharing calendar with other email accounts instead of service account email address which i created Google Developer Console.

    Thanks.

  36. Ali November 19, 2015 at 12:01 pm Reply

    http://stackoverflow.com/questions/11863022/edit-google-calendar-events-from-google-service-account-403

    thanks for your time ayduns, above url resolve the issue , i was sharing calendar with other email accounts instead of service account email address which i created using Google Developer Console.

    Thanks.

  37. Ali December 3, 2015 at 1:25 pm Reply

    Hi Ayduns,
    is there a way to differentiate between recurring and non-recurring events? Also how to get recurring event details?

  38. Luca (@gmusclexxx) January 29, 2016 at 4:09 pm Reply

    Hi, i have this error with this script:
    PHP Fatal error: Class ‘Google_Service’ not found in /home/shtplqjz/public_html/google-api-php-client/src/Google/Service/Calendar.php on line 32

    Is this script still working? I’m using the latest RC4 PHP APIs

  39. Cornelis Digitaal February 22, 2016 at 11:38 am Reply

    This seems to be already a bit older:

    * e-mailadresses are no longer structured like ‘groups.google.com’ as specified in the Calendar ID bit.
    * the link https://developers.google.com/api-client-library/php/guide/aaa_oauth2_service is dead
    * what is meant by “Client ID”? Is this the service accounts “Key ID” or a OAuth 2.0 client ID?

    Cheers,

    Cees

  40. Simon May 2, 2016 at 3:32 am Reply

    Hello,

    Thanks for the above example.
    I am running Debian Jessie and use the 0.6.7-2 version of google php api (from debian repository).
    I first tried to access my person calendar using normal client auth where you are directed to a google page for the user to allow permission. Like above, i want to access my calendar from a web application without the need to allow access each time.

    I have created a service account like you advise above and have managed to get a simple calendar list to work with the code above.

    I do have a question on the service account technique compared to the normal client auth approach:

    When i list calendars using “print_r($cals)” with normal client, i see all my calendars, not just the ones i have shared, and i also see what the default reminder setting is for each setting.

    However, with service account, using “print_r($cals)” only shows shared calendars (which i accept) but it doesn’t show what the default reminder settings is even though i have fully shared the calendar with the service account and have allowed full access to it.

    Is this expected behaviour for a service account? Is there anyway to fully mimic the normal client auth access with a service account (and therefore get full access programmatically to the calendar) without having to allow access from a user each time?
    Thanks,

    Simon

    • ayduns June 25, 2016 at 4:30 pm Reply

      Hi Simon,
      You may have figured this out by now! When you access the calendar with your own credentials you are accessing it as the owner (assuming it’s your calendar!). The service account is not the owner but the calendar is shared with it. So I’d expect to be able to see the same settings via service account/API as you see via GUI for a calendar that is shared with you. When you share the calendar with the service account, there are several permission options. You could try changing that to see if it gives access to the default reminder settings.

      • Simon June 26, 2016 at 11:18 am

        Hello,

        Yes, I have figured it all out, or more to the point, I’ve worked my way around it.
        I couldn’t get access to the default reminders for the calendar owner using the service account.
        So, instead, using the functions available in the library, i built up a “reminder” objects and updated my calendar with it (using the api/library update functions).
        See code below (excuse any errors, i hacked it together from some working notes from a month ago!)

        — start code

        // create service using service acct credentials (code as per examples above)
        $service = new Google_CalendarService($client);

        // fetch my calendar (replace username with your cal name)
        $mycal= $service->calendarList->get(‘username@gmail.com’);

        // create dummy calendar object
        $mycalobject = new Google_CalendarListEntry($mycal);

        // create default reminders (i wanted two)
        $myreminder1 = new google_eventreminder(array(‘method’=>’email’,’minutes’=>’1440′));
        $myreminder2 = new google_eventreminder(array(‘method’=>’popup’,’minutes’=>’10’));

        // load reminders into dummy calendar object
        $mycalobject->setDefaultReminders(array($myreminder1, $myreminder2));

        // update my real calendar with the newly populated dummy object with the reminders
        $mycalobjectnew = $service->calendarList->update(‘smkranz0506@gmail.com’, $mycalobject);

        — end code

        No matter what permissions i chose for the service account, i could not get default reminders automatically like the cal owner had, so i made my own!

        I’ve been using the calendar functions now for my personal use from PHP for about 1 month and so far so good!

        Thanks again as your article was a great start for me. Took me a few weeks of learning / practice before i could do what i wanted.

        Simon

      • ayduns June 27, 2016 at 1:17 pm

        Hi Simon – glad you’ve found a way around it. Thanks for sharing your code here.

  41. Dimple June 16, 2016 at 5:49 am Reply

    I am not getting Google/Service/Calendar.php on GitHub
    Please help me.

  42. Riya June 25, 2016 at 9:10 am Reply

    How i can use this sample code in my website? how calendar feature will work in my website?

    • ayduns June 25, 2016 at 4:07 pm Reply

      By itself, the code doesn’t do anything for your website. It gives you access to your Google Calendar from php. From there, you can do what you like with it. I used it to pull a filtered list of events to a create a “What’s on now” display.

  43. Lee Stoneman July 22, 2016 at 9:06 am Reply

    This code no longer works. Can anyone suggest a way around a PHP Fatal error: Class ‘Google_Service’ not found in /var/www/beta/src/Google/Service/Calendar.php?

    This code is the closest I’ve got to a working prototype of accessing my calendar.

    • ayduns July 22, 2016 at 4:20 pm Reply

      Hi Lee – take a look at my reply to Dimple just above

Leave a comment