Google Calendar API - Forbidden - Error with Service Account - php

I try to use the Google Calendar API by php running server side.
I created a service account and use its credentials (via the json file). I am NOT using G Suite.
Now I am able to list events of my calendar but I get a Forbidden - Error, when I try to create a new event.
I shared my calendar with the service account's email address and gave it admin rights for the calendar. I don't know what I am doing wrong! I just can't get it working. I am also using the scope Google_Service_Calendar::CALENDAR.
The exception: 403 - Forbidden
I have no idea how to debug this problem and how to proceed further.
Can you help me?
Edit: here is my calling code:
putenv('GOOGLE_APPLICATION_CREDENTIALS=../google-service-account.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setScopes([Google_Service_Calendar::CALENDAR]);
$client->setRedirectUri('urn:ietf:wg:oauth:2.0:oob');
$service = new Google_Service_Calendar($client);
$event = new Google_Service_Calendar_Event([
'summary' => $name,
'location' => $location,
'description' => $desc,
'start' => [
'dateTime' => $start,
'timeZone' => $timezone,
],
'endTimeUnspecified' => true,
]);
$calendar = $service->calendars->get($calendarId);
$settings = $service->settings->listSettings();
$list = $service->acl->listAcl($calendarId);
$event = $service->events->insert($calendarId, $event);
The first three service calls ($calender = ..., $settings = ... and $list = ...) work fine and in the acl I can also see that the email address of my service account has all rights (role: owner). But the last line $event = ... gives the forbidden error...

'endTimeUnspecified' => true,
is causing your problem (its googles fault, but you cant tell them that)
if you change to
'end' => [
'dateTime' => $start2,
'timeZone' => $timezone,
],
it will work (i know it is not what you want and maybe you can figure out a way to adjust $start2 to give you what you want as an end time but the endTimeUnspecified is what is causing it to say 403 forbidden

Related

Add event on user shared calendar

I'm using Garethp/php-ews package to manage Exchange data.
I'm able to read Calendar that other user shared with me, but unless they gave me write access on their Calendar (Under web client, I can add event), I'm not able to add events trough php.
I think I have to use
$calendar = $api->getCalendar();
$userCalendar = $calendar->pickCalendar($displayName);
If I'm right, how to get his $displayName ?
Thanks
I think I found a solution:
$this->api = API::withUsernameAndPassword($server, $your_username, $your_password
$this->api->setPrimarySmtpEmailAddress('user_shared_calendar#test.com');
$folder = $this->api->getFolderByDistinguishedId('calendar');
$calendar = $this->api->getCalendar();
$calendar->setFolderId($folder->getFolderId());
$start = new \DateTime('now');
$start->setTimezone(new \DateTimeZone('Europe/Paris'));
$end = new \DateTime('now');
$end->add(new \DateInterval('PT1H'));
$calendar->createCalendarItems([
'Subject' => 'This is made by PHP',
'Body' => [
'BodyType' => API\Enumeration\BodyTypeType::HTML,
'_value' => 'This is <b>the</b> HTML body',
],
'Start' => $start->format('c'),
'End' => $end->format('c'),
]);
This script add event on a shared calendar.

Zoom Api - I can't update a meeting

I am trying to update a meeting using Zoom API but I can't get it to work. I'm trying to do a PATCH request using eleague oauth2 client like this:
require '../vendor/autoload.php';
require_once '../config.php';
$id = $_POST['id'];
$topic = $_POST['topic'];
$type = $_POST['type'];
$start_time = $_POST['start_time'];
$duration = $_POST['duration'];
$agenda = $_POST['agenda'];
$params = array(
'topic' => $topic,
'type' => $type,
'start_time' => $start_time,
'duration' => $duration,
'agenda' => $agenda,
'password' => '123456'
);
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => CONEXAO_API['clientId'],
'clientSecret' => CONEXAO_API['clientSecret'],
'redirectUri' => CONEXAO_API['redirect_url'],
'urlAuthorize' => 'https://zoom.us/oauth/authorize',
'urlAccessToken' => 'https://zoom.us/oauth/token',
'urlResourceOwnerDetails' => 'https://api.zoom.us/v2/users/me'
]);
$options['body'] = json_encode( $params );
$options['headers']['Content-Type'] = 'application/json';
$options['headers']['Accept'] = 'application/json';
$request = $provider->getAuthenticatedRequest( 'PATCH',
'https://api.zoom.us/v2/meetings/'.$id,
unserialize($_SESSION['token']),
$options
);
$retorno = $provider->getParsedResponse($request);
var_dump($retorno);
I'm getting an empty response, and I'm not sure what is missing. Can anyone help me?
basically the response given by the api is blank or just meeting updated which isn't in json format. So in case you want to check whether its working go to zoom meeting panel and open the meeting which you are updating using api and run the api and check the meeting is updated in zoom meeting panel.
The problem is that the method getParsedResponse for some reason is not returning any message. But the script is working, it's updating the meeting the way it supposed to.
If I get the response using the method getResponse I can see the statusCode 204, which means that everything went ok.

Calling Google API from localhost

I am trying to call the Google CSE Api from my localhost Docker container. Apparently, this is not working because of that.
I have defined CURLOPT_SSL_VERIFYPEER to false in order to prevent SSL certificate verification, but with no success.
If anyone has any thought on this, help would be appreciated.
My code:
// Create the google api client
$googleClient = new Google_Client();
// Set the google developer api key
$googleClient->setApplicationName('GoogleApi_Search');
$googleClient->setDeveloperKey(self::GOOGLE_SEARCH_API_KEY);
// for development purposes
$guzzleConfig = [
'curl' => [CURLOPT_SSL_VERIFYPEER => false],
'headers' => ['Referer' => 'localhost:8080'],
];
$guzzleClient = new Client($guzzleConfig);
$googleClient->setHttpClient($guzzleClient);
// The google custom search service client
$this->googleService = new Google_Service_Customsearch($googleClient);
// Define the search parameters
$this->searchParams = [
'cx' => self::GOOGLE_SEARCH_ENGINE_ID, // Custom search engine identifier
'gl' => 'en', // Location of results
'lr' => 'lang_en', // Language of results
'num' => 10, // Number of results (max. 10)
'start' => 0, // The current index (max. 10)
];
I solved my issue by setting the start parameter to 1 instead of 0. Apparently, setting it to be 0 trigger a fatal error on the server side which causes the error 400 Invalid Value and no other information.
Strange but working.

How can I authenticate Google Cloud Translate from PHP?

I'm trying to use the google/cloud-translate library (v ^1.5) in Laravel (v ^6.0).
In GoogleController.php:
public function translate(Request $request) {
$request->validate([
'source' => 'required|string|min:2|max:5',
'target' => 'required|string|min:2|max:5',
'q' => 'required|string',
]);
$translate = new TranslateClient([
'keyFile' => base_path(config('services.google.json_path')),
'projectId' => config('services.google.project_id'),
'suppressKeyFileNotice' => true,
]);
// Translate text from english to french.
$result = $translate->translate($request->q, [
'target' => explode($request->target, '-')[0],
'source' => explode($request->source, '-')[0],
]);
return $result;
}
But calling the route in Postman gives me the error:
Argument 2 passed to Google\Auth\CredentialsLoader::makeCredentials() must be of the type array, string given, called in /[...]/vendor/google/cloud-core/src/RequestWrapperTrait.php on line 155
I've checked that the projectId and the path to the keyFile is correct. Can anyone shed some light on how to get past this error?
You're specifying the path to the key file, so you should use the keyFilePath parameter instead.
Try this:
$translate = new TranslateClient([
'keyFilePath' => base_path(config('services.google.json_path')),
...
]);
From the TranslateClient.__construct docs:
keyFile: The contents of the service account credentials .json file retrieved from the Google Developer's Console. Ex: json_decode(file_get_contents($path), true).
keyFilePath: The full path to your service account credentials .json file retrieved from the Google Developers Console.

Used Google Cloud Translation API When return response 403 "Daily Limit Exceeded"

The following confirmation is done.
Credit card is registered
It does not exceed the upper limit of each threshold of API
So, I was able to run normally until yesterday.
But I will get an error all the time today.
I use "Cloud Translation API Client Libraries",
If there are other points to check, would you please teach me?
$translate = new TranslateClient([
'projectId' => 'xxxxxxx',
]);
$result = $translate->translate('I am playing Dragon Quest 11 ', [
'source' => 'en',
'target' => 'ja',
]);
solved it myself.
Used to authorized type 'authorized_user'.
Not so match authentication method.
My solution is:
Constructor add option 'keyFilePath' directory.
$translate = new TranslateClient([
'projectId' => 'xxxxxxx',
'keyFilePath' => env('GOOGLE_APPLICATION_CREDENTIALS')
]);

Categories