I'm trying to add events and reminders programmatically on my Google Calendar. I am using a Service Account .
I can successfully add events to my Google Calendar but not the reminders. This is because the events are added by the Service Account Email (something like xyz@developer.gserviceaccount.com), and I should add reminders using my Gmail account, not the Service Account).
Fortunately, it is possible to act on behalf of my Gmail Account. See bottom of this page: https://developers.google.com/api-client-library/php/guide/aaa_oauth2_service#using
It suggests to add $cred->sub = "emailaddress@yourdomain.com";
But I get the following error when adding this code:
Google_Auth_Exception: Error refreshing the OAuth2 token, message: '{ "error" : "internal_failure" }'
I'm doing something wrong but I don't know what, here is my code below:
$applicationName = 'applicationName';
$serviceAccountEmail = 'xyzg@developer.gserviceaccount.com';
$serviceAccountKeyPath = __DIR__ . '/xyz-privatekey.p12';
$serviceAccountClientId = 'xyz.apps.googleusercontent.com';
$client = new \Google_Client();
$client->setApplicationName($applicationName);
$service = new \Google_Service_Calendar($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($serviceAccountKeyPath);
$cred = new \Google_Auth_AssertionCredentials(
// $serviceAccountName
$serviceAccountEmail,
// $scopes array List of scopes
array('https://www.googleapis.com/auth/calendar'),
// $privateKey
$key
);
$client->setClientId($serviceAccountClientId);
$cred->sub = 'myEmail@gmail.com';
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion(); // fails on this line
}
$_SESSION['service_token'] = $client->getAccessToken();
PS: If I uncomment $cred->sub = 'myEmail@gmail.com';
the code doesn't throw an exception
Service account impersonating the user only applies to Google Apps, see https://code.google.com/p/google-apps-manager/wiki/GAM3OAuthServiceAccountSetup
If you want your app to access any user's Calendar, you should use the standard OAuth2 flow to get the consent of the user and store the refresh token for future use (since you're trying to use service account I assume this is a server side app). If the only user is yourself and you don't plan to distribute you app to anyone else, you could hardcode the refresh token in your server. Here is the documentation for Google OAuth2 web server flow: https://developers.google.com/accounts/docs/OAuth2WebServer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.