Use-Cases of this Tutorial
- Learn how to create a Google Calendar event using APIs in PHP
- Handle the timezone of the created event in correct way
This article was updated on June 26th 2019 and is edited as per the new Google API requirements. Using Calendar API now requires verification by Google to make the application public to all. Also HTTPS is now mandatory.
Creating an event using Google Calendar API consists of 5 steps:
- Register a Google Application and enable Calendar API.
- In your web application, request user for authorization of the Google Application.
- Get the user's timezone.
- Use the primary calendar of the user. Or else get the list of his calendars and let the user choose.
- Create an event on this calendar.
This tutorial covers version 3 of Calendar API. Google also provides a PHP Client Library through which you can make Calendar API calls, but is is 6 MB in size. It is better to write custom code, about 100 lines, for small API requirements.
Is Verification Required ?
Google is now requiring application verification to use Calendar API. You will need to submit your application for verification if you are looking to make it public (although it will work normally for the members of the Google API project).
Is HTTPS Required ?
Yes, Calendar API authentication needs HTTPS. HTTP will not work.
Step 1) Register a Google Application and enable Calendar API
You need a Google Application so that you can get API keys through which you can make API calls. If you have an existing Google Application you can use that, just make sure that you enable Calendar API. If you don't have an existing Google Application follow the below steps to get one :
- Go to Google API Console
- Create a project by clicking "Select a project" (at the top), and then clicking on the "+" button in the dialogbox. In the next screen enter your project name, and agree with the Terms and Conditions.
- After the project is created, select the created project from the top dropdown.
- Click the Library tab on the left. Search for "Calendar API" and enable it.
By enabling "Calendar API", your Google application can get access to the user's Calendar. - Now click on Credentials tab on the left. In the next screen click on "OAuth consent screen". Fill out the mandatory fields. Save it.
- Now click on the "Credentials" tab (just beside "OAuth consent screen"). In the screen, click on "Create credentials". Choose "OAuth Client ID" as the type.
- In the next screen fill out the name. The Application type should be "Web application"
- Add a redirect url in the section Authorised redirect URIs. This url should point to your redirect url script. A redirect url is the url where Google redirects the user after he authorizes your Google Application.
You can even add a localhost url if you want.
If you are using the attached codes in this tutorial, the redirect url should point to google-login.php (give the full url) - You can leave out Authorised JavaScript origins as blank. Click on the Create button.
- On success you will get the App Client ID and App Secret. Save those as they will be required later.
Step 2) Redirect Users to Google OAuth Login and Get an Access Token
Google uses OAuth2 for authorization. You need to redirect users to Google Oauth Login url where they can authorize your application to manage their Calendar. You need to pass the scope parameter as https://www.googleapis.com/auth/calendar
$login_url = 'https://accounts.google.com/o/oauth2/auth?scope=' . urlencode('https://www.googleapis.com/auth/calendar') . '&redirect_uri=' . APPLICATION_REDIRECT_URL . '&response_type=code&client_id=' . APPLICATION_ID . '&access_type=online';
After the user authorizes your Google Application, he will be redirected to your given redirect url. Google passes an authorization code as a GET parameter named code. You must use this code and make an API call to get an access token.
Check out Google Login API with PHP Curl for a detailed tutorial about Login with Google. Remember, the login process is common for all Google REST APIs. All you need to do is to pass a different scope (depends on which API you are using). It also covers how to get a refresh token, through which events can be created even if the user is offline.
<?php
session_start();
// Holds the Google application Client Id, Client Secret and Redirect Url
require_once('settings.php');
// Holds the various APIs involved as a PHP class. Download this class at the end of the tutorial
require_once('google-login-api.php');
// Google passes a parameter 'code' in the Redirect Url
if(isset($_GET['code'])) {
try {
$capi = new GoogleCalendarApi();
// Get the access token
$data = $capi->GetAccessToken(APPLICATION_ID, APPLICATION_REDIRECT_URL, APPLICATION_SECRET, $_GET['code']);
// Access Token
$access_token = $data['access_token'];
// The rest of the code to add event to Calendar will come here
}
catch(Exception $e) {
echo $e->getMessage();
exit();
}
}
?>
The API call to get an access token using the authorization code :
class GoogleCalendarApi
{
......
public function GetAccessToken($client_id, $redirect_uri, $client_secret, $code) {
$url = 'https://www.googleapis.com/oauth2/v4/token';
$curlPost = 'client_id=' . $client_id . '&redirect_uri=' . $redirect_uri . '&client_secret=' . $client_secret . '&code='. $code . '&grant_type=authorization_code';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if($http_code != 200)
throw new Exception('Error : Failed to receieve access token');
return $data;
}
......
}
So, at the end of this step you have got the access token. You can use this access token to make API calls to get user calendars, create events etc.
Step 3) Getting the User's Timezone from Calendar Settings
Timezones play a very important role in Calendar API. Time of events in Google Calendar API are of the forms :
// Combined date-time & timezone
{
"dateTime": "2016-12-31T15:59:60-08:00"
}
// Separate date-time & timezone
{
"dateTime": "2016-12-31T15:59:60",
"timeZone": "America/New_York"
}
// Separate date & timezone
{
"date": "2016-12-31",
"timeZone": "America/New_York"
}
In most of the cases, your application's timezone will be different from the user's Google Calendar timezone. You can set a default timezone through PHP code, or you can figure out the user browser's timezone through Javascript code. But they have their own issues — the user's Calendar timezone might be different from one that you are setting with PHP, and with Javascript it would take some effort (playing with Date objects in Javascript is not very direct).
The wisest soluion would be to get the default timezone of the user's Google Calendar. You can rest assure that user would have a habit of creating events in this timezone.
The API call to get the user's Calendar timezone :
class GoogleCalendarApi
{
......
public function GetUserCalendarTimezone($access_token) {
$url_settings = 'https://www.googleapis.com/calendar/v3/users/me/settings/timezone';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_settings);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if($http_code != 200)
throw new Exception('Error : Failed to get timezone');
return $data['value'];
}
......
}
// Get user calendar timezone
$capi = new GoogleCalendarApi();
$user_timezone = $capi->GetUserCalendarTimezone($access_token);
Step 4) Getting a Calendar to Create Event
You can only create an event on a user calendar. That is why you need a specific calendar ID.
Each user has a default calendar. In addition to that, user may also have created extra calendars.
If your application wants to create an event on the user's default calendar, Calendar API provides a special keyword for it - primary
Otherwise you can get the list of the user's calendars of which he is an owner. (Google Calendar provides some calendars like Holidays of which the user is not the owner). You can also get the timezone of each calendar. Your application can ask the user to choose a specific calendar, through which you can get its ID.
The API call to get the user's list of calendars :
class GoogleCalendarApi
{
......
public function GetCalendarsList($access_token) {
$url_parameters = array();
$url_parameters['fields'] = 'items(id,summary,timeZone)';
$url_parameters['minAccessRole'] = 'owner';
$url_calendars = 'https://www.googleapis.com/calendar/v3/users/me/calendarList?'. http_build_query($url_parameters);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_calendars);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token));
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if($http_code != 200)
throw new Exception('Error : Failed to get calendars list');
return $data['items'];
}
......
}
Remember, primary is the ID of the user's default calendar. Your application need not get the list of user's calendars if it wants to create an event on the default calendar.
Step 5) Creating an Event on a Specific Calendar
Now that you have got the calendar ID, you can create an event.
The full code will be something like :
$capi = new GoogleCalendarApi();
// Get the access token
$data = $capi->GetAccessToken(APPLICATION_ID, APPLICATION_REDIRECT_URL, APPLICATION_SECRET, $_GET['code']);
$access_token = $data['access_token'];
// Get user calendar timezone
$user_timezone = $capi->GetUserCalendarTimezone($access_token);
$calendar_id = 'primary';
$event_title = 'Event Title';
// Event starting & finishing at a specific time
$full_day_event = 0;
$event_time = [ 'start_time' => '2016-12-31T15:00:00', 'end_time' => '2016-12-31T16:00:00' ];
// Full day event
$full_day_event = 1;
$event_time = [ 'event_date' => '2016-12-31' ];
// Create event on primary calendar
$event_id = $capi->CreateCalendarEvent($calendar_id, $event_title, $full_day_event, $event_time, $user_timezone, $access_token);
The API call to create an event :
class GoogleCalendarApi
{
......
public function CreateCalendarEvent($calendar_id, $summary, $all_day, $event_time, $event_timezone, $access_token) {
$url_events = 'https://www.googleapis.com/calendar/v3/calendars/' . $calendar_id . '/events';
$curlPost = array('summary' => $summary);
if($all_day == 1) {
$curlPost['start'] = array('date' => $event_time['event_date']);
$curlPost['end'] = array('date' => $event_time['event_date']);
}
else {
$curlPost['start'] = array('dateTime' => $event_time['start_time'], 'timeZone' => $event_timezone);
$curlPost['end'] = array('dateTime' => $event_time['end_time'], 'timeZone' => $event_timezone);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_events);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Bearer '. $access_token, 'Content-Type: application/json'));
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($curlPost));
$data = json_decode(curl_exec($ch), true);
$http_code = curl_getinfo($ch,CURLINFO_HTTP_CODE);
if($http_code != 200)
throw new Exception('Error : Failed to create event');
return $data['id'];
}
......
}
The above code handles only events running for a specific time / full day. There are also many other options that you can set through API like recurring events, attendees etc. See the full event options here.
Updating & Deleting Events
This is discussed in part 2 of this tutorial How to Update and Delete an Event with Google Calendar API using PHP