0
votes

I am trying to create Google calendar events using Google Api OAuth service Account from PHP GAE.

I need the correct Session ID or the user EMail ID in the Calendar events field ‘created by’. This is possible well in Google Apps Script(GAS), it creates the events with the correct session ID.

But, I want the same to be done in PHP GAE(Google App Engine). So, I tried to impersonate the user ID as follows:Perform Google Apps Domain-Wide Delegation of Authority

My aim is to insert the correct user ID of any end user automatically as like in GAS(Google Apps Script). I don't want any default credentials to be set in the field ‘created by’..

Using the PHP client library i tried to impersonate a user in Calendar API.I didn't get any complete sample for Calendar API.So, I tried the Drive API documentation sample, this sample seems to be working fine, Using other domain user also

Using Calendar API I wrote the below example.

 <?php
    require_once realpath(dirname(__FILE__).'/google-api-php-client-master/src/Google/autoload.php');
    require_once realpath(dirname(__FILE__).'/google-api-php-client-master/src/Google/Service/Calendar.php');
    require_once realpath(dirname(__FILE__).'/google-api-php-client-master/src/Google/Service/Oauth2.php');

    use google\appengine\api\users\User;
    use google\appengine\api\users\UserService;

    $user = UserService::getCurrentUser();
    $userEmail=$user->getEmail();

    $client_email = '34234242424-qssjf8kg1kk42dnjdvd2ndrk7rou44@developer.gserviceaccount.com';
    $private_key = file_get_contents('key.p12');
    $scopes = array('https://www.googleapis.com/auth/calendar');

    $credentials = new Google_Auth_AssertionCredentials(
    $client_email,
        $scopes,
        $private_key
    );
    $credentials->sub = $userEmail;
    $client = new Google_Client();
    $client->setAssertionCredentials($credentials);
    if ($client->getAuth()->isAccessTokenExpired()) {
        $client->getAuth()->refreshTokenWithAssertion();
    }
    $service =new Google_Service_Calendar($client);
    $event = new Google_Service_Calendar_Event();
    $start = new Google_Service_Calendar_EventDateTime();
    $start->setDateTime('2015-09-26T10:00:00.000-07:00');
    $event->setStart($start);
    $end = new Google_Service_Calendar_EventDateTime();
    $end->setDateTime('2015-09-26T10:00:00.000-07:00');
    $event->setEnd($end);
    $createdEvent = $service->events->insert('[email protected]', $event);

It’s working well when i check this email, i got the correct service account credentials. But when i used different email ID, i got this below error

PHP Fatal error: Uncaught exception 'Google_Auth_Exception' with message 'Error refreshing the OAuth2 token, message: '{ "error" : "unauthorized_client", "error_description" : "Unauthorized client or scope in request." }'' in /base/data/home/apps/s~production/1.3874/google-api-php-client-master/src/Google/Auth/OAuth2.php:363 Stack trace: #0 /base/data/home/apps/s~production/1.387/google-api-php-client-master/src/Google/Auth/OAuth2.php(314): Google_Auth_OAuth2->refreshTokenRequest(Array) #1 /base/data/home/apps/s~ei-html-production/1.3874/final.php(34): Google_Auth_OAuth2->refreshTokenWithAssertion() #2 {main} thrown in /base/data/home/apps/s~production/1.38742/google-api-php-client-master/src/Google/Auth/OAuth2.php on line 363

Plz help me what i did wrong.Why the issue happens, when I used diff email ID, my end user who'll create cal events, could be any GMAIL or Google based domain ID.

So, plz help with at least a sample part...

Reference links:

How do I Insert Google Calendar Event using Google Api 3 for any user in the domain?

How to create a Google Calendar event without a reminder / How to get Service Accounts to impersonate users

1

1 Answers

1
votes

You can only impersonate users on a google apps domain where you have the necessary permission for (search for 'domain wide delegation'). You've got that covered.

Once you're authorized for impersonation you have to recreate a fresh Google Client for each user you impersonate. You'll only receive an access_token you can use for this very user. If you just change the email address once you're authorized it will not work.