Google Cloud Translate: cryptic error 400 invalid value - php

I am using Google Translate (basic version) to translate some string. It was working fine a couple of minutes ago, but now it just returns error 400. The code is very simple:
function translatePhrase($text, $target, $source = 'it') {
$sourceLanguage = $source;
$targetLanguage = $target;
$translate = new TranslateClient();
$result = $translate->translate($text, [
'source' => $sourceLanguage,
'target' => $targetLanguage,
]);
$output = $result['text'];
return $output;
}
It returns:
Uncaught Google\Cloud\Core\Exception\BadRequestException: {
"error": {
"code": 400,
"message": "Invalid Value",
"errors": [
{
"message": "Invalid Value",
"domain": "global",
"reason": "invalid"
}
]
}
}
in \vendor\google\cloud-core\src\RequestWrapper.php:362
Stack trace:
#0 \vendor\google\cloud-core\src\RequestWrapper.php(206): Google\Cloud\Core\RequestWrapper->convertToGoogleException(Object(GuzzleHttp\Exception\ClientException))
#1 \translate\vendor\google\cloud-core\src\RestTrait.php(95): Google\Cloud\Core\RequestWrapper->send(Object(GuzzleHttp\Psr7\Request), Array)
#2 \translate\vendor\google\cloud-translate\src\V2\Connection\Rest.php(83): Google\Cloud\Translate\V2\Connection\Rest->send('translations', 'translate', Array)
#3 \translate\vendor\google\cloud-translate\src\V2\TranslateClient.php(248): Google\Cloud\Translate\V2\Connection\Rest->listTra
in [\translate\vendor\google\cloud-core\src\RequestWrapper.php riga 362]
Any thoughts ?

As one can see, it bugs out exactly here ...so the options array is at fault. It should rather look alike this (because no single example passes a source language-code, but instead an auto-detected $result['source'] is being returned):
function translatePhrase($text, $target) {
$translate = new TranslateClient();
$result = $translate->translate($text, [
'target' => $target
]);
return $result['text'];
}

I got the reason.
Basically, I was forcing a wrong source language. When I specified the correct source language it worked again.

Related

Updating spreadsheet data with Google Spreadsheet api and php suddenly not working with authentication error

In a form which takes input and updates the value in a spreadsheet. It was working fine before but suddenly stopped working with this error message:
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{ "error": { "code": 403, "message": "The caller does not have permission", "errors": [ { "message": "The caller does not have permission", "domain": "global", "reason": "forbidden" } ], "status": "PERMISSION_DENIED" } } ' in /google-api-php-client-2.2.2/src/Google/Http/REST.php:118
Stack trace:
#0 /google-api-php-client-2.2.2/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 /google-api-php-client-2.2.2/src/Google/Task/Runner.php(176): call_user_func_array(Array, Array)
#3 /google-api-php-client-2.2.2/src/Google/Http/REST.php(58): Google_Task_Runner->run()
#4 /html/form in /google-api-php-client-2.2.2/src/Google/Http/REST.php on line 118
According to other questions and answers it is because of authentication problem, but the form was working for 5 years with the same authentication so it is confusing. Is there any other reason for which the form is not updating?
here is the code included
<?php
ini_set("display_errors", 1);
ini_set("display_startup_errors", 1);
error_reporting(E_ALL);
date_default_timezone_set("US/Central");
// Autoload Composer.
if (file_exists(__DIR__ . "/google-api-php-client-2.2.2/vendor/autoload.php")) {
require_once __DIR__ . "/google-api-php-client-2.2.2/vendor/autoload.php";
$spreadsheetId = "********"; // TODO: Update placeholder value.
// The A1 notation of a range to search for a logical table of data.
// Values will be appended after the last row of the table.
$range = "A2"; // TODO: Update placeholder value.
// TODO: Assign values to desired properties of `requestBody`:
$values = [
[
date("Y-m-d H:i:s"),
$_POST["prop_type"],
$_POST["pstreet"],
$_POST["pcity"],
$_POST["pzip"],
],
];
$service_account_file = "service-account.json";
$client = new Google_Client();
$service = new Google_Service_Sheets($client);
if ($client) {
$client->setApplicationName("Google Sheet Update");
$client->setAuthConfig($service_account_file);
$client->setScopes(Google_Service_Sheets::SPREADSHEETS);
$client->setAccessType("online");
$redirect_uri =
"http://" . $_SERVER["HTTP_HOST"] . $_SERVER["PHP_SELF"];
$client->setRedirectUri($redirect_uri);
$guzzle = new GuzzleHttp\Client([
"verify" => false,
]);
$client->setHttpClient($guzzle);
$requestBody = new Google_Service_Sheets_ValueRange([
"values" => $values,
]);
$params = [
"valueInputOption" => "RAW",
];
$response = $service->spreadsheets_values->append(
$spreadsheetId,
$range,
$requestBody,
$params
);
//echo '<pre>', var_export($response, true), '</pre>', "\n";
} else {
echo "Not Valid Client";
echo "<pre>CLIENT", var_dump($client), "</pre>", "\n";
}
} else {
echo "Client File do not exist";
}
?>
The caller does not have permission
means exactly that. Which ever user you used to authorize this code does not have permission to access that sheet. Authorize your application with a user that has access or grant that user access.
Service accounts need to be preauthorized. The most common way to do that is to take the service account client id and share the file with it though the google drive web application. If someone removed the service accounts access to the file. The service account will no longer have access.
I would double check that it still has access.

PHP Google_Service_Dataflow not finding file in bucket

I've come across an issue using the googleapis/google-api-php-client library, specifically the Dataflow Service that I cannot solve.
When I try to use the library I set up the request like so:
$this->client = new \Google_Client();
$this->client->setAuthConfig(config_path('google-service-account.json'));
$this->client->setIncludeGrantedScopes(true);
$this->client->addScope(\Google_Service_Dataflow::CLOUD_PLATFORM);
$body = [
"gcsPath" => "gs://{$this->bucket}/{$this->template}",
"location" => "us-central1",
];
$parameters = new \Google_Service_Dataflow_LaunchTemplateParameters;
$parameters->setJobName($this->jobname);
$parameters->setParameters($body);
$service = new \Google_Service_Dataflow($this->client);
$request = $service->projects_templates->launch($this->project, $parameters);
And I get the following error:
{
"error": {
"code": 400,
"message": "(11f8b78933fc59c3): Bad file name: , expected
'gs://\u003cbucket\u003e/\u003cpath\u003e'",
"errors": [
{
"message": "(11f8b78933fc59c3): Bad file name: , expected
'gs://\u003cbucket\u003e/\u003cpath\u003e'",
"domain": "global",
"reason": "badRequest"
}
],
"status": "INVALID_ARGUMENT"
}
}
It seems that the path is getting corrupted along the way, I've checked and it gets fine until the Guzzle object is instantiated to send the request inside the library.
I'm pretty lost at this point so any suggestion or clue is welcome.
Thank you in advance.
No gcsPath is given in the query params for the request constructed by the SDK.
This is because gcsPath is set to be an option for Google_Service_Dataflow_LaunchTemplateParameters.
It is documented that request query parameters be given as optional params
(See https://github.com/googleapis/google-api-php-client-services/blob/v0.81/src/Google/Service/Dataflow/Resource/ProjectsTemplates.php#L73.)
$opt_params = [
"gcsPath" => "gs://{$this->bucket}/{$this->template}",
"location" => "us-central1",
];
$template_params = [
// Keep template params here.
];
$launch_params = new \Google_Service_Dataflow_LaunchTemplateParameters;
$launch_params->setJobName($this->jobname);
$parameters->setParameters($template_params);
$service = new \Google_Service_Dataflow($this->client);
$request = $service->projects_templates->launch($this->project, $parameters, $opt_params);

invalid api keys permission denied error in google api using php

I am using google api first time my code execute perfectly even give me data using people service api...but second time it give me following error
Type: Google_Service_Exception
Message: { "error": { "code": 403, "message": "The request is missing
a valid API key.", "errors": [ { "message": "The request is missing a
valid API key.", "domain": "global", "reason": "forbidden" } ],
"status": "PERMISSION_DENIED" } }
i am using codeignitor and this is redirected uri controller function...thanks in advance and sorry for poor english..
$client = $this->google_client_setup();
$client->authenticate($this->input->get('code'));
$access_token = $client->getAccessToken();
$people_service = new Google_Service_PeopleService($client);
$profile = $people_service->people->get(
'people/me', array('personFields' => 'names,emailAddresses'));
$access_token = $access_token['access_token'];
$email = $profile['emailAddresses'][0]['value'];
$name = $profile['names'][0]['displayName'];
$user = [
'email' => $email,
'name' => $name,
'is_admin' => 0
];
It's hard to tell, but I would think that if it says it's missing valid api key, you should treat that as answer ;)
Are you being redirected somewhere after first run? That could explain problem Javier commented on.
I'd suggest to dump two things to debug the code:
$this->input->get('code')
and if this is ok, then
$access_token
this should give you idea what your problem is :)
Good luck!

PHP - How to update/delete contact (google People) With PHP

for 3 days i'm frustated because google not have tutorial for php.
(sorry for my bad english)
i got an error while updating names :
$client=client_google();
$google_id="people/c3062123412341234";
if ($client->getAccessToken() == "") return null;
$people_service = new Google_Service_PeopleService($client);
$person = new Google_Service_PeopleService_Person();
if($tipenya == "Cancel"){
$name = new Google_Service_PeopleService_Name();
$name->SetFamilyName("Keluarga Cemara");
$name->SetGivenName("Tampan");
$person->setNames($name);
$profile = $people_service->people->get(
$google_id,
array('personFields' => 'metadata'));
$etag = $profile->etag;
$person->setEtag($etag);
$person->setResourceName($google_id);
if($google_id !=''){
//$people_service->people->updatePersonField("names");
$people_service->people->updateContact($google_id,$person);
}
}else if($tipenya=="Delete"){
if($google_id !=''){
$person->setResourceName($google_id);
$people_service->people->deleteContact($person);
}
}
Error when i execute:
exception 'Google_Service_Exception' with message '{
"error": {
"code": 400,
"message": "updatePersonFields mask is required. Please specify one or more valid paths. Valid paths are documented at https://developers.google.com/people/api/rest/v1/people/update.",
"errors": [
{
"message": "updatePersonFields mask is required. Please specify one or more valid paths. Valid paths are documented at https://developers.google.com/people/api/rest/v1/people/update.",
"domain": "global",
"reason": "badRequest"
}
],
"status": "INVALID_ARGUMENT" }}'
You need to specify the parameter updatePersonFields. Seems like the parameters are passed as the last argument by looking at the read examples in the documentation. It probably should look something like:
$params = array('updatePersonFields' => 'names,emailAddresses');
$people_service->people->updateContact($google_id,$person,$params);
I haven't tested the above, so that might not be the exact syntax.

The service is currently unavailable Google api

I'm using google slide API to connect to my project account, the connection worked perfectly, but sometime I get this error :
Fatal error: Uncaught Google_Service_Exception: { "error": { "code": 503, "message": "The service is currently unavailable.", "errors": [ { "message": "The service is currently unavailable.", "domain": "global", "reason": "backendError" } ], "status": "UNAVAILABLE" } } in /vendor/google/apiclient/src/Google/Http/REST.php:118 Stack trace: #0 /vendor/google/apiclient/src/Google/Http/REST.php(94): Google_Http_REST::decodeHttpResponse(Object(GuzzleHttp\Psr7\Response), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #1 /vendor/google/apiclient/src/Google/Task/Runner.php(181): Google_Http_REST::doExecute(Object(GuzzleHttp\Client), Object(GuzzleHttp\Psr7\Request), 'Google_Service_...') #2 /vendor/google/apiclient/src/Google/Http/REST.php(58): Google_Task_Runner->run in /vendor/google/apiclient/src/Google/Http/REST.php on line 118
This is my getClient function Google API:
function getClient(string $SCOPES,string $CLIENT_SECRET_PATH,string $CREDENTIALS_PATH,string $APPLICATION_NAME) {
$this->client->setApplicationName($APPLICATION_NAME);
$this->client->setScopes($SCOPES);
$this->client->setAuthConfig($CLIENT_SECRET_PATH);
$this->client->setAccessType('offline');
$this->client->setApprovalPrompt('force');
$credentialsPath = $this->expandHomeDirectory($CREDENTIALS_PATH);
if (file_exists($credentialsPath)) {
$accessToken = json_decode(file_get_contents($credentialsPath), true);
} else {
$authUrl = $this->client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
$accessToken = $this->client->fetchAccessTokenWithAuthCode($authCode);
if(!file_exists(dirname($credentialsPath))) {
mkdir(dirname($credentialsPath), 0700, true);
}
file_put_contents($credentialsPath, json_encode($accessToken));
printf("Credentials saved to %s\n", $credentialsPath);
}
$this->client->setAccessToken($accessToken);
if ($this->client->isAccessTokenExpired()) {
$this->client->fetchAccessTokenWithRefreshToken($this->client->getRefreshToken());
file_put_contents($credentialsPath, json_encode($this->client->getAccessToken()));
}
return $this->client;
}
This is the request the I send:
public function replaceAllShapesWithImage(array $data_images)
{
$requests =array();
if(isset($data_images)){
foreach ($data_images as $key => $value) {
$requests[] = new \Google_Service_Slides_Request(array(
'replaceAllShapesWithImage' => array(
'imageUrl' => $value['url'],
'replaceMethod' => $value['replaceMethod'],
'containsText' => array(
'text' => $value['text']
)
)
));
}
}
return $requests;
}
$data_image has this value:
'replaceAllShapesWithImage' => array(
0 => array(
'text'=>'{{LOGO}}',
'url'=>'http://www.16cafe.com/wp-content/themes/16cafe/css/images/logo.png',
'replaceMethod'=>'CENTER_INSIDE'
),
1 => array(
'text'=>'{{PHOTO}}',
'url'=>'http://localhost:9880/wp-content/uploads/2017/02/pla23.jpg',
'replaceMethod'=>'CENTER_INSIDE'
),
)
Every time I catch an API error my script waits 1 second. If the error occurs again the script waits 2 seconds. Then 4 seconds, 8 seconds, 16 seconds. In total I make 5 attempts. It works every time.
public function get_analytics_response()
{
$api_call_num_of_attempts = 5;
$api_call_attempts = 0;
$api_call_sleep = 1;
do {
try {
$response = $this->analytics->reports->batchGet();
}
catch (Google_Service_Exception $e) {
// Sleep 1s, 2s, 4s, 8s, 16s + random milliseconds
$sleep = ($api_call_sleep * 1000000) + rand(1000, 1000000);
usleep($sleep);
$api_call_attempts++;
$api_call_sleep = $api_call_sleep * 2;
$error_message_json = $e->getMessage();
$error_message = json_decode($error_message_json, true);
// Save errors...
continue;
}
break;
}
while ($api_call_attempts < $api_call_num_of_attempts);
return $response;
}
Slides can definitely give better error messaging, but I'm pretty sure the problem is that http://localhost:9880/wp-content/uploads/2017/02/pla23.jpg image URL you are trying to insert. I tried making a replaceAllShapesWithImage request with that image and also got a 503.
Slides downloads your images over the public internet, so a localhost domain wont work. Try hosting it on some publicly accessible URL, or you can use Google Drive to host the image.
I had the same error message (for a totally different reason).
For me, I waited 30 seconds and attempted the same thing again, and it worked.
Seems it may simply be a brief outage of the Google API.

Categories