Google provides a good UI for their calendars for manual use, and calendars can easily be embedded in other sites, but being able to access them programmatically adds another dimension of usefulness.
Many of Google’s services have API’s in various languages. These notes relate to using the Google Calendar API v3 with php.
Scenario
I wanted to use a php script to grab data from a Google Calendar, either to write to a file or serve up as part of a web page.
Warning
Firstly, a word of warning. I wasted some time looking at old documentation. There are multiple versions of documentation that apparently relate to the same thing but with differing information. Old documentation has not been updated or removed and there is no indication that it is old.
If you want to use the php API, DO NOT use the instructions at https://developers.google.com/google-apps/calendar/ These point to old code on http://google-api-php-client.googlecode.com/ which is deprecated.
The place to look is https://developers.google.com/api-client-library/ and the code is on github at https://github.com/google/google-api-php-client
[Looking at https://developers.google.com/api-client-library/php/guide/migration, it seems the github version is 1.0.0 of the php library for the Calendar v3 API]
Setup
Follow the instructions at https://developers.google.com/api-client-library/php/start/get_started to create a project in the Google Developer’s Console and install the client library.
Authentication and Authorization
The API key approach does not provide access to private data. In my application, I do want to access private data so we need the OAuth 2.0 approach. This is not as complicated as it sounds!
There are three different types of client id’s that can be used:
- Web application client IDs
- Installed application client IDs
- Service Account client IDs
Although the notes warn you of the importance of choosing the right type, they don’t provide guidance. See here or here (but beware of following other links from that page to old documentation)
For my purposes, I want an automated process to access some calendars, so a Service Account is most appropriate.
Create a Service Account
In Google Developer Console select your project, then ‘API’s & Auth’, then ‘Credentials’, then ‘Create New Client ID’ and choose ‘Service Account’. You will be prompted to save the private key for the id. Make sure you do save it since it can’t be downloaded later (although you can generate new keys).
You will need the ‘Client ID’ and ‘Email Address’ in the next steps.
Sharing the Calendar
The Client ID, Email Address and Private Key File will be used by the php script to authenticate to the calendar service, but it needs to be authorized to access private data. Just because we can connect to the service doesn’t mean it should give us whatever data we ask for! We need to share the calendar that we want to access with the Service Account ID we have just created.
Log in to the Calendar using the normal web GUI. Locate the calendar on the left panel under ‘My Calendars’, hover over it to reveal the dropdown arrow, then select ‘Share this Calendar’. Under the ‘Share with specific people’ section, enter the Email Address from the previous step and check it has enough access for your intended use. For me, that means ‘See all event details’. Then click ‘Add Person’, then ‘Save’.
The calendar is now shared with the service account, so our php script can access it.
Before closing the calendar, go to the ‘Calendar Details’ link, and look for the ‘Calendar Address’ section. You need to copy the Calendar ID – looks like an email address: long string of random stuff @ group.calendar.google.com
PHP script
At long last, we’re ready to start some coding.
See: https://developers.google.com/api-client-library/php/guide/aaa_oauth2_service
And the example here: https://github.com/google/google-api-php-client/blob/master/examples/service-account.php
Putting all the pieces together, we need the Client ID, Email Address, Private Key File and Calendar ID to plug into this script. Hopefully it works… Note that many errors result in a 404 status and the error message is not very useful.
I didn’t find much documentation for the PHP API, but the code is easy to read at https://github.com/google/google-api-php-client/blob/master/src/Google/Service/Calendar.php
Listing Events
To explore the API in the Developer Console, click on ‘API’s & Auth’, then ‘API’, and select the Calendar API. See the section on calendar.events.list Some useful options include:
- singleEvents – convert recurring events to single events
- timeMax, timeMin – for searching by the start time of events
- fields – to control which fields are returned
Sample Code
(Edited based on comments and questions – last update Jan 8, 2015)
#!/usr/bin/php <?php require_once "Google/Client.php"; require_once "Google/Service/Calendar.php"; // Service Account info $client_id = 'replace with Service Account Client Id'; $service_account_name = 'replace with Service Account Email Address'; $key_file_location = 'replace with Service Account Private Key filename'; // Calendar id $calName = 'replace with Calendar ID'; $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); $cals = $service->calendarList->listCalendarList(); print_r($cals); //exit; // Convert recurring events to single events // Look for events in the next week - now to now+1week $params = array( 'singleEvents' => TRUE, 'timeMin' => (new DateTime())->format(DateTime::RFC3339), 'timeMax' => (new DateTime())->add(new DateInterval('P1W'))->format(DateTime::RFC3339), ); $events = $service->events->listEvents($calName, $params); foreach ($events->getItems() as $event) { echo "Summary: ", $event->getSummary(), "\n"; echo "Location: ", $event->getLocation(), "\n"; echo "Start: ", fmt_gdate($event->getStart()), "\n"; echo "End: ", fmt_gdate($event->getEnd()), "\n"; } function fmt_gdate( $gdate ) { if ($val = $gdate->getDateTime()) { return (new DateTime($val))->format( 'd/m/Y H:i' ); } else if ($val = $gdate->getDate()) { return (new DateTime($val))->format( 'd/m/Y' ) . ' (all day)'; } }
Tagged: API, Google Calendar, OAuth2, PHP, Service Account
That’s great. I spend hours yesterday trying to figure out howto do this – documentation isn’t helpful.
Thanks a lot
Good to know it was useful to you!
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!
You’re welcome!
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?
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);
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?
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!
how to create new calendar in google calendar
Naveen – see https://developers.google.com/google-apps/calendar/v3/reference/calendars/insert
The php code sample from there is:
$calendar = new Calendar();
$calendar->setSummary('calendarSummary');
$calendar->setTimeZone('America/Los_Angeles');
$createdCalendar = $service->calendars->insert($calendar);
echo $createdCalendar->getId();
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!
Thanks – good to know it helped you!
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?
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()
;Thank you for your response ayduns. I have tried adding $event->getStart(); and unfortunately, that’s where the code freezes. Any thoughts?
$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.
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
If getDateTime() is empty, new DateTime() is called with no args and defaults to today’s date.
To be more specific, the issue, as I have found out, resides with reoccurring events. This code does not process reoccurring events correctly.
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.
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.
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
Ok, that makes sense. Thanks for sharing that here Dominique.
Code in post updated to handle all-day events.
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!!
🙂
Thank you very very Much !!!
I only find a simple answer on THIS page !!!
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!
I must mention that I’ve granted the required rights for the service account to access the calendar.
Sorry, don’t know. Maybe someone else here has ideas.
I get that error if I use the wrong service account name. Should be long-string@developer.gserviceaccount.com
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)
Hi! Don’t have a key file… how to obtain one
René – you get that from the Google Developer Console. See the “Create a Service Account” section above.
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?
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);
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.
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?
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
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.
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.
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
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?
I don’t know what PHP version is required for webserver app id’s, but the use case is rather different. Webserver id’s will require a user to log in to the calendar. See https://developers.google.com/accounts/docs/OAuth2#webserver
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
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
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?
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
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 :
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?
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 );
}
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!
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?
Wayne, sounds like you might not have the API package installed or the include is not pointing to the right point.
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();
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?
I have the same problem, but I don’t understand what is the problem!
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.
You’re right – Fixed now!
Thank you for your very useful article. It works.
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’ ) ;
}
}
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’ );
}
}
That did it! Thanks so much for your help!
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!
Super useful, thanks!!!!!!!!!!!
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?
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?
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
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
@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);
Great – thanks for sharing your code here Duggy
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? …
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);
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
If the calendar is not public, you need to share it with the service account. Have you done that?
how can i share it with service account ?could you please help me in this regard?
Ali – see the “Sharing the Calendar” section above.
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.
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.
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.
Hi Ayduns,
is there a way to differentiate between recurring and non-recurring events? Also how to get recurring event details?
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
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
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
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.
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
Hi Simon – glad you’ve found a way around it. Thanks for sharing your code here.
I am not getting Google/Service/Calendar.php on GitHub
Please help me.
Hi – looks like Google have moved things around a bit. The README.md at https://github.com/google/google-api-php-client/tree/master/src/Google/Service says “Google API Client Service classes have been moved to the google-api-php-client-services repository.” So you’ll need to get Calendar from https://github.com/google/google-api-php-client-services
How i can use this sample code in my website? how calendar feature will work in my website?
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.
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.
Hi Lee – take a look at my reply to Dimple just above