Leave a comment

Your email address will not be published. Required fields are marked *

62 thoughts on “Google Calendar API with PHP – Service Account

  • João Calado

    I Linda. I really need yout help. I wanted to make a small form to put a simple informacion on Google Calender. Is for a school project where I ‘ll mark meetings for teachers and the meet is automatically go to GC.

    I read some information and dont understand anything.
    Can you help me please

    PS: Sorry for my english… I portugues. Thanks for reading

    • Administrator
      Linda Lawton

      I think using a service account is a very good idea. You can have your form make changes to the calendar. But the question will be how best to show the calendars to the teachers. You will need to ensure that they either all have access to the calendar in question or make a list as part of a web page some where.

      Your English was fine 🙂

      • João Calado

        I put all code and the output is this

        Google_Service_Calendar_CalendarList Object ( [collection_key:protected] => items [internal_gapi_mappings:protected] => Array ( ) [etag] => “1418644240421000” [itemsType:protected] => Google_Service_Calendar_CalendarListEntry [itemsDataType:protected] => array [kind] => calendar#calendarList [nextPageToken] => [nextSyncToken] => 00001418644240421000 [modelData:protected] => Array ( [items] => Array ( ) ) [processed:protected] => Array ( ) )

        Something wrong? Or is ok?

  • João Calado

    My colleague allready do an email service for mark metting. But now I want use the GC service because all teachers use. So we create a “webmaster” email to do this settings thing like send an email. This email are the mail of the calendar.

    Open authentication? I do… I think =s

  • Gary Doolittle

    I have been trying to get this to work since API v2 was deprecated last month and my Zend Framework connection no longer works.
    I am not sure what I am missing.
    I have signed up for a service acct and DL the key and have it on the webserver.
    I have the calendar acct shared with the service acct email as you mentioned.
    I DL the most recent version of the php-client library at Github and have it in the appropriate file.
    I used your code with the appropriate substitutions and get this output:

    Google_Service_Calendar_CalendarList Object ( [collection_key:protected] => items [internal_gapi_mappings:protected] => Array ( ) [etag] => “1418630976822000” [itemsType:protected] => Google_Service_Calendar_CalendarListEntry [itemsDataType:protected] => array [kind] => calendar#calendarList [nextPageToken] => [nextSyncToken] => 00001418630976822000 [modelData:protected] => Array ( [items] => Array ( ) ) [processed:protected] => Array ( ) )

    Any suggestions of what I might have forgotten?
    I would be happy to buy you a month of coffee if you can figure this out

      • Gary Doolittle

        Wow you are right!!!
        I just tried adding an event and it worked. If you get a chance tell me what you think of the code. I am a total amateur – Anesthesiologist in real life.
        I dropped the ‘readaonly’ from scopes and added the add event code.

        $client_id = ‘684605746077-c3rkjhan7l06sMY_CLIENT_ID.apps.googleusercontent.com’;
        $Email_address = ‘684605746077-c3rkj_MY_SERVICE_EMAIL_q8r6@developer.gserviceaccount.com’;
        $key_file_location = ‘./Calen_MY_KEY_FILE_LOCATIONe8.p12’;
        $client = new Google_Client();
        $client->setApplicationName(“CalendarTHree”);
        $key = file_get_contents($key_file_location);
        // seproate additional scopes with a comma
        $scopes =”https://www.googleapis.com/auth/calendar”;
        $cred = new Google_Auth_AssertionCredentials(
        $Email_address,
        array($scopes),
        $key
        );
        $client->setAssertionCredentials($cred);
        if($client->getAuth()->isAccessTokenExpired()) {
        $client->getAuth()->refreshTokenWithAssertion($cred);
        }
        $service = new Google_Service_Calendar($client);

        ?>

        setSummary(‘Event 2’);
        $event->setLocation(‘Somewhere’);
        $start = new Google_Service_Calendar_EventDateTime();
        $start->setDateTime(‘2015-06-22T19:00:00.000+01:00’);
        $start->setTimeZone(‘Europe/London’);
        $event->setStart($start);
        $end = new Google_Service_Calendar_EventDateTime();
        $end->setDateTime(‘2015-06-22T19:25:00.000+01:00’);
        $end->setTimeZone(‘Europe/London’);
        $event->setEnd($end);
        //
        $calendar_id = “nmp0idjes0j03tg4uq65akhak0@group.calendar.google.com”;
        //
        $new_event = null;
        //
        try {
        $new_event = $service->events->insert($calendar_id, $event);
        //
        $new_event_id= $new_event->getId();
        } catch (Google_ServiceException $e) {
        syslog(LOG_ERR, $e->getMessage());
        }
        //
        $event = $service->events->get($calendar_id, $new_event->getId());
        //
        if ($event != null) {
        echo “Inserted:”;
        echo “EventID=”.$event->getId();
        echo “Summary=”.$event->getSummary();
        echo “Status=”.$event->getStatus();
        }

        ?>

        PS Your coffee is on the way – cheers

        • João Calado

          I try your code but give me a error about REST and RESTful

          How to fix that???

          My output by the way:

          Fatal error: Uncaught exception ‘Google_Service_Exception’ with message ‘Error calling POST https://www.googleapis.com/calendar/v3/calendars/espamol.pt_09rcn73rq50i16mege2rroj9qs%40group.calendar.google.com/events: (403) Forbidden’ in /home/luiscon1/public_html/gstor/paa/GoogleAPI/google-api-php-client/src/Google/Http/REST.php:83 Stack trace: #0 /home/luiscon1/public_html/gstor/paa/GoogleAPI/google-api-php-client/src/Google/Http/REST.php(41): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client)) #1 /home/luiscon1/public_html/gstor/paa/GoogleAPI/google-api-php-client/src/Google/Client.php(564): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request)) #2 /home/luiscon1/public_html/gstor/paa/GoogleAPI/google-api-php-client/src/Google/Service/Resource.php(227): Google_Client->execute(Object(Google_Http_Request)) #3 /home/luiscon1/public_html/gstor/paa/GoogleAPI/google-api-php-client/src/Google/Service/Calendar.php(1440): Google_Service_Resource->call(‘insert’, Array, ‘Go in /home/luiscon1/public_html/gstor/paa/GoogleAPI/google-api-php-client/src/Google/Http/REST.php on line 83.

  • Anriuz

    and when i try to implement on localhost your code example it returns:

    Fatal error: Uncaught exception ‘Google_Auth_Exception’ with message ‘Could not json decode the token’ in K:\home\localhost\www\shop\modules\gcalendarv3\api\Google\Auth\OAuth2.php:180 Stack trace: #0 K:\home\localhost\www\shop\modules\gcalendarv3\api\Google\Auth\OAuth2.php(295): Google_Auth_OAuth2->setAccessToken(‘[]’) #1 K:\home\localhost\www\shop\modules\gcalendarv3\test0.php(32): Google_Auth_OAuth2->refreshTokenWithAssertion(Object(Google_Auth_AssertionCredentials)) #2 {main} thrown in K:\home\localhost\www\shop\modules\gcalendarv3\api\Google\Auth\OAuth2.php on line 180

      • Anriuz

        Thans, for the reply.
        I regenerated the p12 fie and there were no error on authentication.
        Now there’s another problem:
        for code:
        setApplicationName(“landshaftinfo”);

        if (isset($_SESSION[‘service_token’])) {
        $client->setAccessToken($_SESSION[‘service_token’]);
        }

        $key = file_get_contents(dirname(__FILE__) . ‘/api/Google/’ .$key_file_location);

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

        $client->setAssertionCredentials($cred);

        if ($client->getAuth()->isAccessTokenExpired()) {
        try {
        $client->getAuth()->refreshTokenWithAssertion($cred);
        } catch (Exception $e) {
        var_dump($e->getMessage());
        }
        }
        $service = new Google_Service_Calendar($client);
        $_SESSION[‘service_token’] = $client->getAccessToken();
        $event = new Google_Service_Calendar_Event();
        $event->setSummary(‘Appointment’);
        $event->setLocation(‘Somewhere’);
        $event->setDescription(‘Description’);
        $start = new Google_Service_Calendar_EventDateTime();
        $start->setDateTime(‘2015-02-24T13:00:00.000+02:00’);
        $event->setStart($start);
        $end = new Google_Service_Calendar_EventDateTime();
        $end->setDateTime(‘2015-02-24T13:20:00.000+02:00’);
        $event->setEnd($end);

        $reminders = new Google_Service_Calendar_EventReminders();
        $reminders->setUseDefault(false);
        $overrides = array(“method”=> “sms”,”minutes” => “0”);
        $reminders->setOverrides(array($overrides));
        $event->setReminders($reminders);

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

        echo “Id=”.$createdEvent->getId();
        echo “Summary=”.$createdEvent->getSummary();
        echo “Status=”.$createdEvent->getStatus();
        echo “Created=”.$createdEvent->getCreated();
        $start = new Google_Service_Calendar_EventDateTime();
        $createdEvent->GetStart($start);
        echo $start->getDateTime;
        $end = new Google_Service_Calendar_EventDateTime();
        $createdEvent->GetEnd($end);
        echo $end->getDateTime;

        ?>
        i get something like:
        Id=qq5mu6efor3qhtb79192kd7s6cSummary=AppointmentStatus=confirmedCreated=2015-02-25T17:55:50.000Z
        i have event id and date of creation BUT no start date or end date, and no event is shown on calendar.

        • Anriuz

          figured out – it was the
          $createdEvent = $service->events->insert(‘pimary’, $event);
          it has to be
          $createdEvent = $service->events->insert(”, $event);
          then the event will appear in calendar.
          Now there’s only left to make it work with sms-reminder.

          • Anriuz

            Hmm, seems like service account cant override reminders.
            The way to get sms reminder how i did it:
            1)create one more calendar
            2)share it with service acccont
            3)set for this calendar sms reminding as default
            then there is no need to override it in script

    • Administrator
      Linda Lawton

      No I don’t think so. A Service account email isn’t really an email I think its more a unique identifier for the service account. Wild guess is that it has an email format so that we can add it as a user to say Google Analytics, Drive and Google calendar. These systems probably require that adding a user be email format string.

  • Michael

    Hello Linda,
    Nice tutorials!
    But I’m stuck on this one for several hours now.
    I created a service account and shared my calendar with it. The access was granted, but it returns an empty array, when I do print_r($calendarLists->getItems()).

    Meaning that I don’t receive any events from the calendar.
    Any idea what could be the cause of this?
    P.S. The calendar is public.

    • Administrator
      Linda Lawton

      I think a calendar needs to be first added to the Calendarlist for a service account. So you need to find the Calendar Id in Google Calendar web version and use that to add it to the Calendar list. I will need to test this some more.

  • Matthew

    Mrs. Linda,

    I enjoyed the tutorial and it helped me understand it easier. Everything else I had were all fragmented pieces of this.

    When I changed the creds in the code with mine, it is giving me an error code of:

    “Fatal error: Uncaught exception ‘Google_Exception’ with message ‘The Google PHP API library needs the openssl PHP extension’ in C:\wamp\www\newOLP\scripts\oAuth2\Google\Signer\P12.php on line 38”

    I am using the .p12 file. I first attempted with the JSON file and read the comments for others to see if they had the same error I have. I’m not sure what the error exactly means anymore after I thought I did what I thought it meant, but to no success I undid the changes.

    Thanks for any help,

    Matthew

    • Administrator
      Linda Lawton

      If you mean embed Google Calendar in your website probably not. You could in theory develop an application that functions similar to Google calendar and put that on your website. That would be a very big project.

  • wasim

    print_r($calendarLists->getItems()). Its coming empty why, I have created service account and shared with that email id and calendar but still that is coming empty, can yu tell me what should i need to do.

  • Paul

    Hi Linda,

    Thank you so much for this article – after 5hrs of getting nowhere – I can now access my calendar through php!

    However, I still have one problem, which I hope you can help with. The above script will not display on my website (view page source is blank) – but I can pipe it into a html file which I can then view in browser. What am I doing wrong/missing?

    Thanks for your help!

    Paul

  • MJ

    Hi, I was recently able to get the Google API to work using a service account following your Analytics tutorial (http://www.daimto.com/google_service_account_php/). My end goal is to work with the Google Calendar API, which is why i am now going through this tutorial. I’ve followed your code and am able to connect just fine. No error messages.

    My problem is that no calendars are listed. I’m not getting any output.

    In the following example, “IN WHILE TRUE” echos. But “IN FOR EACH” does not.

    I’m at a loss. any tips or points in the right direction would be very much appreciated!

    $calendarList = $service->calendarList->listCalendarList();

    while(true) {
    echo “IN WHILE TRUE”;
    foreach ($calendarList->getItems() as $calendarListEntry) {
    echo “IN FOR EACH”;

    echo $calendarListEntry->getSummary().”\n”;

    // get events
    $events = $service->events->listEvents($calendarListEntry->id);

    foreach ($events->getItems() as $event) {
    echo “—–“.$event->getSummary().””;
    }
    }
    $pageToken = $calendarList->getNextPageToken();
    if ($pageToken) {
    $optParams = array(‘pageToken’ => $pageToken);
    $calendarList = $service->calendarList->listCalendarList($optParams);
    } else {
    break;
    }
    }

  • MJ

    Also, as a note: it appears that “// separate additional scopes with a comma” produces an error. I was able to get this to work when separating additional scopes with a space. Is that right?

  • Bhavesh

    This is not work for me please help me. It shows Following Error

    Fatal error: Uncaught exception ‘Exception’ with message ‘This library must be installed via composer or by downloading the full package. See the instructions at https://github.com/google/google-api-php-client#installation.’ in /home/sadgurusoft1992/public_html/demo/cal/Google/autoload.php:14 Stack trace: #0 /home/sadgurusoft1992/public_html/demo/cal/index.php(2): require_once() #1 {main} thrown in /home/sadgurusoft1992/public_html/demo/cal/Google/autoload.php on line 14

  • Ian North

    Great tutorial and I have got the calendar API working at home but when I brought the files into work we have a Proxy server and I just get net::ERR_Connection_refused.
    What do I need to do to get through the proxy with authentication?

  • sandip

    i was add event to the google calender using google api with service account problem is when i was add event then event successfully inserted but they not showing in google calander please help me how to fix??

    • Linda Lawton
      Linda Lawton Post author

      Double check that you are adding it to the correct calendar remember a service account has its own calendar account. You need to be adding it to one of your personal calendars not the service accounts calendar.

  • Cees

    Tutorial could use a little more indepth information in the how-to section….

    I have entered the following variables:

    $client_id: I assume that this is the clientID mentioned at OAuth 2.0 client IDs in the console??? Maybe not, there is no explanation in this tutorial….
    $Email_address: I took the one that was mentioned in the downloaded JSON file, the one that ended with “gserviceaccount.com”.
    $key_file_location: the path to the downloaded JSON file? I assume so….

    And then there is the error message: Fatal error: Uncaught exception ‘Google_Auth_Exception’ with message ‘Unable to load private key’ in….

    • Linda Lawton
      Linda Lawton Post author

      I think you have miss read the tutorial. This tutorial is for service accounts not Oauth2. The file you download for service accounts is a p12 not Json. Service accounts use service account email not client id.

      To use a service account you need to create service account credentials you appear to be trying to use OAuth2 credentials.

      I have a PHP Google Calendar tutorial that uses Oauth2 here.

  • vipin shama

    I have already integrated auth2 lib for login user into my application. Can my web application access calendar data without redirect user to go on google.

    • Linda Lawton
      Linda Lawton Post author

      Yes assuming that you authenticated the user and requested access to there google calendar data then the refresh token you got from login will also work for accessing Google calendar data.

  • Jaime Ruelas

    Hi Linda,

    I followed this tutorial to create a site with the possibility of add, update events with the idea to integrate it to a joomla component.
    I am using my gmail account to access de google development api and my first intention was to use OAuth2 to allow users to add,view and update events but it would not work do to the fact that they would need a google or gmail account. I saw this other option with service account but I am stuck.

    considering the next info, could you tell me , what I am doing wrong?

    I created a new project on google developer console and I only created the “Service account keys”, only one credential.

    $client_id = ‘xxxx@appspot.gserviceaccount.com’; I am using the info from service accounts / Service Account ID
    $Email_address = ‘mymail@gmail.com’;
    $key_file_location = realpath(dirname(__FILE__) . ‘/../src/Google/xxxxxx.p12’); it create a file and I named it xxxxxx.p12 and is located in localhost/appfolder/google…/src/Google/.

    This is the error sent by safari:
    Fatal error: Uncaught exception ‘Google_Auth_Exception’ with message ‘Error refreshing the OAuth2 token, message: ‘{ “error” : “invalid_client”, “error_description” : “The OAuth client was invalid.” }” in /Library/WebServer/Documents/fullcalendar/google-api-php-client-master/src/Google/Auth/OAuth2.php:364 Stack trace: #0 /Library/WebServer/Documents/fullcalendar/google-api-php-client-master/src/Google/Auth/OAuth2.php(315): Google_Auth_OAuth2->refreshTokenRequest(Array) #1 /Library/WebServer/Documents/fullcalendar/google-api-php-client-master/examples/Service.php(42): Google_Auth_OAuth2->refreshTokenWithAssertion(Object(Google_Auth_AssertionCredentials)) #2 {main} thrown in /Library/WebServer/Documents/fullcalendar/google-api-php-client-master/src/Google/Auth/OAuth2.php on line 364

    Thanks.

    • Linda Lawton
      Linda Lawton Post author

      Invalid client means there is something wrong with the client id or how you have set it up on Google Developers console. Email address should be the service accounts email address not your gmail address.

      • Jaime Ruelas

        Thank you very much for the response, do you have an screen shoot to see from where i should get those values? or any link to a tutorial. As you say, google info is not very explicit.

        Thanks.

      • Jaime Ruelas

        I made a few changes, according to google documentation.
        Old code
        $client_id = ‘xxxx@appspot.gserviceaccount.com’; I am using the info from service accounts / Service Account ID
        $Email_address = ‘mymail@gmail.com’;
        New Code
        /*$client_id = ‘xxxx@appspot.gserviceaccount.com’;*/ I Commented the line of code
        $Email_address = ‘xxxx@appspot.gserviceaccount.com’; Changed client id to Email_Address.

        This change causes no error in authentication but the app is not getting any calendar info. In local apache web server.
        But I get the next message in online server.
        Fatal error: Class ‘Google_Config’ not found in /home/jruelas/public_html/fullcalendar/google-api-php-client-master/src/Google/Client.php on line 80

      • Jaime Ruelas

        Hi Linda.

        I final got it done. I can create,delete and update calendars. I suppose that it will be the same for events, notifications or any thing else. I have just two questions.
        1.- On your tutorials you only use 1 scope. for example.
        $scopes =”https://www.googleapis.com/auth/calendar.readonly”;
        latter in the code is array($scopes) so it would be Ok $scopes =array(“https://www.googleapis.com/auth/calendar.readonly”,”https://www.googleapis.com/auth/calendar”);
        2.- Is there a way to add those calendars to my phone? I have the email, but no password.

        I would really appreciate any response. I thank you very much for the tutorials

        • Linda Lawton
          Linda Lawton Post author

          If you have authenticated then you should have a refresh token. You could grant yourself permissions to see the calendar in question using code.

          Yes you can add more then one scope but there really isn’t a point for both readonly and calendar as calendar will give you everything anyway. Its used more for requesting access to say google drive and google calendar assuming you need access to both of those APIs.

  • ebarron38

    I am confused on how to work this .p12 file format that everyone is talking about here. When I create it, there is no email address displayed anywhere and the file that is downloaded is a certificate that does not contain an email address in it. If I use the JSON file format, I can find the email address, but apparently you don’t use the JSON file format for Server to Server according to the answers I saw here. I am totally lost on what to do next.