I have problem with creating folder on my google drive by using Google Drive API.
The script successfully display me all files i have on my google drive from this part of code.
// Print the names and IDs for up to 10 files.
$optParams = array(
'pageSize' => 10,
'fields' => 'nextPageToken, files(id, name)'
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0) {
print "No files found.<br>";
} else {
print "Files:<br>";
foreach ($results->getFiles() as $file) {
printf("%s (%s)<br>", $file->getName(), $file->getId());
}
}
but doesn't create folder from this part of code
// Create Test folder
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'Test',
'mimeType' => 'application/vnd.google-apps.folder'));
$file = $service->files->create($fileMetadata, array(
'fields' => 'id'));
printf("<br>Folder ID: %s<br>", $file->id);
There is full code of my php script.
<?php
require __DIR__ . '/google-api-php-client/vendor/autoload.php';
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Test Google Drive API');
$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setAuthConfig('client_secret.json');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Drive($client);
// Print the names and IDs for up to 10 files.
$optParams = array(
'pageSize' => 10,
'fields' => 'nextPageToken, files(id, name)'
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0) {
print "No files found.<br>";
} else {
print "Files:<br>";
foreach ($results->getFiles() as $file) {
printf("%s (%s)<br>", $file->getName(), $file->getId());
}
}
// Create Test folder
$fileMetadata = new Google_Service_Drive_DriveFile(array(
'name' => 'Test',
'mimeType' => 'application/vnd.google-apps.folder'));
$file = $service->files->create($fileMetadata, array(
'fields' => 'id'));
printf("<br>Folder ID: %s<br>", $file->id);
error: Fatal error: Uncaught exception 'Google_Service_Exception' with message '{ "error": { "errors": [ { "domain": "global", "reason": "insufficientPermissions", "message": "Insufficient Permission: Request had insufficient authentication scopes." } ], "code": 403, "message": "Insufficient Permission: Request had insufficient authentication scopes." } }
Hope on your help. Thanks.
Related
I'm trying to get the calendar, but it's returning an error
Uncaught Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "notFound", "message": "Not Found" } ], "code": 404, "message": "Not Found" } } in
Below is my code, where I already have the auth2 access token
require "../_lib/libraries/grp/googleCalendar/vendor/autoload.php";
$client = new Google_Client();
$client->setApplicationName('Google Calendar API PHP Quickstart');
$client->setScopes(Google_Service_Calendar::CALENDAR_READONLY);
$client->setAuthConfig('../_lib/libraries/grp/googleCalendar/credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
//$_SESSION['access_token'] = '';
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
print_r($_SESSION['access_token']);
// Exchange authorization code for an access token.
//$accessToken = $client->fetchAccessTokenWithAuthCode($_SESSION['access_token']);
$client->setAccessToken($_SESSION['access_token']);
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Exchange authorization code for an access token.
$accessToken = $_SESSION['access_token'];
$client->setAccessToken($accessToken);
}
}
$service = new Google_Service_Calendar($client);
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => true,
'timeMin' => date('c'),
);
//here the error occurs
$calendar = $service->calendars->get('calendarid');
echo $calendar->getSummary();
$results = $service->events->listEvents($calendarId, $optParams);
$events = $results->getItems();
if (empty($events)) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($events as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'].'/scriptcase9/app/project_gestao/oauth2callback/index.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
it is part of obtaining the access token auth02 is working, but now I need the calendarid and the error returns as I explained above.
as said the access token is already working and is showing events correctly, but I need the calendarid.
Your code contains the line
$calendar = $service->calendars->get('calendarid');
Hereby 'calendarid' should either be replaced by a real id (of a calendar to which you have access!) or through a variable.
Given that before you already defined $calendarId = 'primary'; it makes sense to modify your code to
$calendar = $service->calendars->get($calendarId);
I am trying to upload file in google drive using google drive api in php.
I am getting Files name and Id from google drive correctly.But It could not uploding files to google drive and show some error. I could not identify if some client library package is missing or something else happens in it
Fatal error: Uncaught Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "insufficientPermissions", "message": "Insufficient Permission: Request had insufficient authentication scopes." } ], "code": 403, "message": "Insufficient Permission: Request had insufficient authentication scopes." } } in C:\xampp\htdocs\googledrive\vendor\google\apiclient\src\Google\Http\REST.php:118 Stack trace: #0 C:\xampp\htdocs\googledrive\vendor\google\apiclient\src\Google\Http\REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #1 C:\xampp\htdocs\googledrive\vendor\google\apiclient\src\Google\Task\Runner.php(181): Google_Http_REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #2 C:\xampp\htdocs\googledrive\vendor\google\apiclient\src\Google\Http\REST.php(58): Google_Task_Runner->run() #3 C:\xampp\htdocs\googledrive\vendor\google\apiclient\src\Google in C:\xampp\htdocs\googledrive\vendor\google\apiclient\src\Google\Http\REST.php on line 118
My Source Code is
<?php
require __DIR__ . '/vendor/autoload.php';
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Drive($client);
// Print the names and IDs for up to 10 files.
$optParams = array(
'pageSize' => 10,
'fields' => 'nextPageToken, files(id, name)'
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($results->getFiles() as $file) {
printf("%s (%s)\n</br>", $file->getName(), $file->getId());
}
}
$pasta = 'img';
$arquivo = 'photo.jpg'; // file.mp4
printf("Folder: %s || File: %s\n", $pasta, $arquivo);
$parentId = 'replace with Folder ID';
if ( !empty($arquivo) ) {
//Define localização da pasta e arquivo
$file_path = $pasta.'/'.$arquivo;
//Conecta no Drive da sua conta
$file = new Google_Service_Drive_DriveFile();
//Define nome do arquivo
$file->setName($arquivo);
//Define Diretório Destino lá no Google Drive
$file->setParents(array($parentId));
//Cria o arquivo no GDrive
$service->files->create(
$file,
array(
'data' => file_get_contents($file_path),
'mimeType' => 'application/octet-stream',
'uploadType' => 'resumable'
)
);
// Grava Log do que foi feito UTC -3 horas;
$DateTime = new DateTime();
$DateTime->modify('-3 hours');
$now = $DateTime->format("Y-m-d H:i:s");
$logfile = $now.' Upload OK :: '.$arquivo.PHP_EOL;
$myfile = file_put_contents('logs.txt', $logfile, FILE_APPEND | LOCK_EX);
} else {
//Grava Log
$now = date("Y-m-d H:i:s");
$logfile .=$now.' =====WITHOUT FILES========'.PHP_EOL;
$myfile = file_put_contents('logs.txt', $logfile, FILE_APPEND | LOCK_EX);
}
Please help me, What is the problem behind it.
The scope of DRIVE_METADATA_READONLY is https://www.googleapis.com/auth/drive.metadata.readonly. In this case, the method of Files: create cannot be used. I think that the reason of your error message is this. So in this case, how about modifying as follows?
I think that other parts of your script works.
From:
$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
To:
$client->setScopes(Google_Service_Drive::DRIVE);
The scope of DRIVE is https://www.googleapis.com/auth/drive.
Note:
When you modified the scope, please delete the file of token.json of $tokenPath = 'token.json'; and authorize the scopes again. By this, new scopes are reflected to the access token and refresh token. Please be careful this.
References:
Authorizing requests with OAuth 2.0
If I misunderstood your question and this was not the direction you want, I apologize.
drive. google .com
press "new"
copy and paste your source code and save
Am trying to upload a files to my google drive account with php and curl. I do not want all these long authentication flow of a thing. To this effect,I implemented the code below
$secret ="xxxxxx";
$clientid ="xxxxxxx";
$ch = curl_init ();
curl_setopt_array ( $ch, array (
CURLOPT_URL => "https://www.googleapis.com/upload/drive/v3/files?uploadType=media&clientID=xxxxxxx&secret=xxxxxxx",
CURLOPT_HTTPHEADER => array (
'Content-Type: image/png'),
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => file_get_contents ('iconc.png' ),
CURLOPT_RETURNTRANSFER => 1
) );
$res = curl_exec($ch);
$err = curl_error($ch);
echo $res;
var_dump($res);
echo "<br>";
echo "<br>";
echo $err ;
I have enabled my google Drive Api and I have been assigned client id and secret but when I run the code its saying invalid credentials as per below
{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } } string(238) "{ "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } } "
Please where do I pass the client id and secret in the code above or do i need something like access token. if yes where do I get the google drive API access token. any solution is welcome. Thanks
You have two options the first is to add the access token to the request
https://www.googleapis.com/upload/drive/v3/files?access_token={YourToken}
The second is to add it as a header in the request
curl -H 'Accept: application/json' -H "Authorization: Bearer ${TOKEN}"
https://www.googleapis.com/upload/drive/v3/files
Using the client id as you have done here clientID=xxxxxxx&secret=xxxxxxx is basic authorization not Oauth2 you are missing the authorization step.
You should consider following the php quickstart here
<?php
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Drive API PHP Quickstart');
$client->setScopes(Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Drive($client);
// Print the names and IDs for up to 10 files.
$optParams = array(
'pageSize' => 10,
'fields' => 'nextPageToken, files(id, name)'
);
$results = $service->files->listFiles($optParams);
if (count($results->getFiles()) == 0) {
print "No files found.\n";
} else {
print "Files:\n";
foreach ($results->getFiles() as $file) {
printf("%s (%s)\n", $file->getName(), $file->getId());
}
}
I can read my Google Sheet Doc use this tutorial: https://developers.google.com/sheets/api/quickstart/php
quickstart.php:
<?php
require_once __DIR__ . '/vendor/autoload.php';
define('APPLICATION_NAME', 'Google Sheets API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/sheets.googleapis.com-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/sheets.googleapis.com-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Sheets::SPREADSHEETS_READONLY)
));
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* #param string $path the path to expand.
* #return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Sheets($client);
// Prints the names and majors of students in a sample spreadsheet:
$spreadsheetId = 'myfileid';
$range = 'Class Data!A2';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (count($values) == 0) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s\n", $row[0], $row[4]);
}
}
All is Ok. I can read my Google Sheet Doc. But I need have only one additional possibility: writing to a single range. I added to end of quickstart.php this code:
$values = array(
array(
5
),
// Additional rows ...
);
$body = new Google_Service_Sheets_ValueRange(array(
'values' => $values
));
$params = array(
'valueInputOption' => $valueInputOption
);
$result = $service->spreadsheets_values->update($spreadsheetId, $range,
$body, $params);
frome here: https://developers.google.com/sheets/api/guides/values
I have:
PHP Fatal error:
Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Request had insufficient authentication scopes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
My Google Sheet Doc has permission for redact/modify. I need have writing to a single range. What is mean this error? Please help me modify quickstart.php.
Change the scopes to Google_Service_Sheets::SPREADSHEETS check,
also try this
$params = array(
'valueInputOption' => $valueInputOption
);
to check
$params = array(
'valueInputOption' => 'USER_ENTERED'
);
<?php
include('lead1.php');
require_once __DIR__ . '/vendor/autoload.php';
global $link;
$emailmsgsql = "SELECT *
FROM psleads WHERE agreeid = '6'";
$msgreqsres = mysqli_query($link, $emailmsgsql); // or die(mysql_error()0);
$msgreqs = $msgreqsres->fetch_assoc();
$start = $msgreqs['contractbegindate'] . ' ' . $msgreqs['contractbegintime'];
$end = $msgreqs['contractenddate'] . ' ' . $msgreqs['contractendtime'];
$startDT = new DateTime($start, new DateTimeZone('Pacific/Honolulu'));
$endDT = new DateTime($end, new DateTimeZone('Pacific/Honolulu'));
$startDTw3c = $startDT->format(DateTime::W3C);
$endDTw3c = $endDT->format(DateTime::W3C);
putenv('GOOGLE_APPLICATION_CREDENTIALS=./service-account.json');
define('CREDENTIALS_PATH', '~/calendar-php.json');
define('CLIENT_SECRET_PATH', './client_secret.json');
//define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
$client = new Google_Client();
$client->setApplicationName("Paradise_Sound_Booking_Calendar");
$client->addScope('https://www.googleapis.com/auth/calendar');
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setClientId('532085378494-s908fs5mu4rf2e2s60cecgaprg9pem1p.apps.googleusercontent.com');
$client->setDeveloperKey("XXXXX");//flo.gd
$client->useApplicationDefaultCredentials();
// Load previously authorized credentials from a file.
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
//$authCode = trim(fgets(STDIN));
$authCode = 'Manually pasted return code into script here';
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
$service = new Google_Service_Calendar($client);
$event = new Google_Service_Calendar_Event(array(
'summary' => 'Booked Event ' . $msgreqs['contractbegindate'],
'start' => array(
'dateTime' => $startDTw3c,
//'dateTime' => '2015-05-28T09:00:00-07:00',
'timeZone' => 'Pacific/Honolulu',
),
'end' => array(
'dateTime' => $endDTw3c,
'timeZone' => 'Pacific/Honolulu',
)
));
$calendarId = 'iddnpsbinrifod2826eqo1kmoo#group.calendar.google.com';
$eventres = $service->events->insert($calendarId, $event);
echo json_encode($eventres);
?>
So here is my PHP code I am using to test event insertion into MY google calendar.
I thought I could use just an API key but google seems to have this convulted way of doing OAUTH that I just can't figure out. I can see all my 403 errors in my API Developers Console.
Does anyone have working code to do simple event inserts into my calendar.
CONTEXT:
I will recieve an IPN from paypal (done) and that will fire off this script that will insert an event into MY calendar, not the users. Can anyone help me without referring me to the google developer docs? They seem sparse and I have read them over and over and over again to no avail of solving my issue.
Here is the error I am getting:
Fatal error: Uncaught exception 'Google_Service_Exception' with
message '{ "error": { "errors": [ { "domain": "global", "reason":
"forbidden", "message": "Forbidden" } ], "code": 403, "message":
"Forbidden" } } ' in
/home/dahfrench/flo.gd/src/Google/Http/REST.php:118 Stack trace: #0
/home/dahfrench/flo.gd/src/Google/Http/REST.php(94):
Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response),
Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #1 [internal
function]: Google_Http_REST::doExecute(Object(GuzzleHttp\Client),
Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #2
/home/dahfrench/flo.gd/src/Google/Task/Runner.php(181):
call_user_func_array(Array, Array) #3
/home/dahfrench/flo.gd/src/Google/Http/REST.php(58):
Google_Task_Runner->run() #4
/home/dahfrench/flo.gd/src/Google/Client.php(789):
Google_Http_REST::execute(Object(GuzzleHttp\Client),
Object(GuzzleHttp\Psr7\Request), 'Google_Service_...', Array) #5
/home/dahfrench/flo.gd/src/Google/Service/Resource.php(232): Goo in
/home/dahfrench/flo.gd/src/Google/Http/REST.php on line 118
You may want to finalize what authentication you want to implement : user needs to login to perform/request to Google Services or delegate a domain-wide authority to the service account.
If you will be using OAuth 2.0:
Your application must use OAuth 2.0 to authorize requests.
Sample Code from Google:
<?php
require_once __DIR__ . '/vendor/autoload.php';
define('APPLICATION_NAME', 'Google Calendar API PHP Quickstart');
define('CREDENTIALS_PATH', '~/.credentials/calendar-php-quickstart.json');
define('CLIENT_SECRET_PATH', __DIR__ . '/client_secret.json');
// If modifying these scopes, delete your previously saved credentials
// at ~/.credentials/calendar-php-quickstart.json
define('SCOPES', implode(' ', array(
Google_Service_Calendar::CALENDAR_READONLY)
));
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient() {
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setScopes(SCOPES);
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setAccessType('offline');
// Load previously authorized credentials from a file.
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
// Store the credentials to disk.
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$client->setAccessToken($accessToken);
// Refresh the token if it's expired.
if ($client->isAccessTokenExpired()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($client->getAccessToken()));
}
return $client;
}
/**
* Expands the home directory alias '~' to the full path.
* #param string $path the path to expand.
* #return string the expanded path.
*/
function expandHomeDirectory($path) {
$homeDirectory = getenv('HOME');
if (empty($homeDirectory)) {
$homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH');
}
return str_replace('~', realpath($homeDirectory), $path);
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Calendar($client);
// Print the next 10 events on the user's calendar.
$calendarId = 'primary';
$optParams = array(
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c'),
);
$results = $service->events->listEvents($calendarId, $optParams);
if (count($results->getItems()) == 0) {
print "No upcoming events found.\n";
} else {
print "Upcoming events:\n";
foreach ($results->getItems() as $event) {
$start = $event->start->dateTime;
if (empty($start)) {
$start = $event->start->date;
}
printf("%s (%s)\n", $event->getSummary(), $start);
}
}
If you will be using Google Apps Domain-Wide Delegation of Authority:
Authorizing a service account to access data on behalf of users in a domain is sometimes referred to as "delegating domain-wide authority" to a service account.
Sample Code from a SO post:
function calendarize ($title, $desc, $ev_date, $cal_id) {
session_start();
/************************************************
Make an API request authenticated with a service
account.
************************************************/
set_include_path( '../google-api-php-client/src/');
require_once 'Google/Client.php';
require_once 'Google/Service/Calendar.php';
//obviously, insert your own credentials from the service account in the Google Developer's console
$client_id = '843319906820-xxxxxxxxxxxxxxxxxxxdcqal54p1he6.apps.googleusercontent.com';
$service_account_name = '843319906820-xxxxxxxxxxxxxxxxxxxdcqal54p1he6#developer.gserviceaccount.com';
$key_file_location = '../google-api-php-client/calendar-xxxxxxxxxxxx.p12';
if (!strlen($service_account_name) || !strlen($key_file_location))
echo missingServiceAccountDetailsWarning();
$client = new Google_Client();
$client->setApplicationName("Whatever the name of your app is");
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$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);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$calendarService = new Google_Service_Calendar($client);
$calendarList = $calendarService->calendarList;
//Set the Event data
$event = new Google_Service_Calendar_Event();
$event->setSummary($title);
$event->setDescription($desc);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($ev_date);
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($ev_date);
$event->setEnd($end);
$createdEvent = $calendarService->events->insert($cal_id, $event);
echo $createdEvent->getId();
}
?>
Note: If you plan on using only one calendar, I would recommend using a service account then sharing your calendar to the account in order to avoid 403 : Forbidden as said in the related SO post
Hope this helps.