engeeaitch
engeeaitch

Reputation: 101

Authentication with Google Calendar API using Server Account and PHP

I'm struggling with this one: I am trying to create an event in a Google Calendar from a PHP script, using a Service Account.

Here’s what I’ve done:

And here is my code:

<?php

require_once 'google_api_src/Google_Client.php';
require_once 'google_api_src/contrib/Google_CalendarService.php';

const CLIENT_ID = 'xxxxxxxxxxxxx.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = '[email protected]';

// Make sure you keep your key.p12 file in a secure location, and isn't
// readable by others.
const KEY_FILE = 'google_api_src/xxxxxxxxx-privatekey.p12';

$client = new Google_Client();
$client->setApplicationName("Hall Booking");

session_start();
if (isset($_SESSION['token']))
{
    $client->setAccessToken($_SESSION['token']);
}

// Load the key in PKCS 12 format
$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);

$client->setAssertionCredentials(new Google_AssertionCredentials(
    SERVICE_ACCOUNT_NAME,
    array('https://www.googleapis.com/auth/calendar', "https://www.googleapis.com/auth/calendar.readonly"),
    $key));

$service = new Google_CalendarService($client);

//Save token in session
if ($client->getAccessToken())
{
    $_SESSION['token'] = $client->getAccessToken();
}  

?>

I have debugged the code as far as I can, but the token is always set to null after the call to SetAssertionCredentials. There are no PHP errors.

Any idea what is wrong, or how to debug further please? Do I have to make any changes to config.php in the api src folder (I haven’t so far)? Is the Application Name important? What’s it used for?

Upvotes: 0

Views: 3566

Answers (2)

josh.thomson
josh.thomson

Reputation: 905

Checkout the demo: http://amazewebs.com/demo

Or get 1-to-1 help on this: http://amazewebs.com/go-premium

I have gotten this working with a service account, you are using the wrong URL in your code, or at least I have it working with no problems with my method...

See my code here: http://amazewebs.com

Or here:

<!-- language: php -->

<?php
ini_set('display_errors', 1);
require_once '../google-api/Google_Client.php';
require_once '../google-api/contrib/Google_CalendarService.php';

session_start();

const CLIENT_ID = '<YOUR-CLIENT-ID-HERE>.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = '<YOUR-SERVICE-EMAIL-HERE>@developer.gserviceaccount.com';
const KEY_FILE = '<YOUR-FINGERPRINT-HERE>-privatekey.p12';

$client = new Google_Client();
$client->setApplicationName("<PUT-YOUR-PROJECT-NAME-HERE");
$client->setUseObjects(true); //IF USING SERVICE ACCOUNT (YES)


if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}

/* This next snippet of code is commonly written wrong, be sure to use the correct URL specified as below: */

$key = file_get_contents(KEY_FILE);
$client->setClientId(CLIENT_ID);
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME, 'https://www.google.com/calendar/feeds/<YOUR-CALENDAR-ID-HERE-WITHOUT-THE-TRAILING"@group.calendar.google.com">/private/full/',
$key)
);

$client->setClientId(CLIENT_ID);
$cal = new Google_CalendarService($client);
$event = new Google_Event();
$event->setSummary('<PUT-AN-EVENT-TITLE-HERE-OR-PASSED-VARIABLE>');
$event->setLocation('<PUT-A-LOCATION-HERE-OR-PASSED-VARIABLE>');

...The Full script can be found @ AmazeWebs.com

& Also I recommend downloading the older google api library as it doesn't seem to work with their latest 0.6.7!

...I have downloaded and packaged all the files in the correct path structure for you: http://amazewebs.com/downloads/google-api.zip

Alternatively, you can download every individual file and package it yourself if you want to download it from google directly: http://google-api-php-client.googlecode.com/svn/trunk/src/

Good luck :)

Upvotes: 1

engeeaitch
engeeaitch

Reputation: 101

OK - so it turns out that the above code is working fine. My misunderstanding was in thinking that the Google_CalendarService performed the authentication. In fact, the authentication is only performed when an actual call to the calendar is made (such as insert Event).

However, I think that saving the token in the session is in the wrong place - it should be after an action has been performed.

To answer my other questions: No, you don't have to make any changes to config.php. The Application Name can be set to anything (but I don't know what it's used for).

One other problem I came across: I was creating an event using a calendar ID of 'primary'. This sent back a success message, but I could not see the event in the calendar (I only have one calendar for that account). It was only when I changed 'primary' to '[email protected]' that it started working. Sounds like a bug in the API to me?

Upvotes: 1

Related Questions