I am using the following code in a PHP server to update values in cells A4 & A7 of a Google Sheet:
$values = array(
array('1234'),
array('abcd')
);
$range = array(array('Sheet1!A4'),array('Sheet1!A7'));
$data = [];
$data[] = new Google_Service_Sheets_ValueRange([
'range' => $range,
'values' => $values
]);
// Additional ranges to update ...
$body = new Google_Service_Sheets_BatchUpdateValuesRequest([
'valueInputOption' => $valueInputOption,
'data' => $data
]);
$result = $service->spreadsheets_values->batchUpdate($spreadsheetId, $body);
On running this request, the following error is received:
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"range\" at 'data[0]': Proto field is not repeating, cannot start list.",
"errors": [
{
"message": "Invalid JSON payload received. Unknown name \"range\" at 'data[0]': Proto field is not repeating, cannot start list.",
"reason": "invalid"
}
],
"status": "INVALID_ARGUMENT"
}
}
What is the correct way to make a Google Sheets API request to update multiple discontinuous cells at once in PHP?
Solved the issue by posting the data in the following format:
$data = [
[
'range'=> 'Sheet1!A4',
'values'=> array(
array('1234')
)
],[
'range'=> 'Sheet1!A7',
'values'=> array(
array('abcd')
)
]
];
// Additional ranges to update ...
$body = new Google_Service_Sheets_BatchUpdateValuesRequest([
'valueInputOption' => 'USER_ENTERED',
'data' => $data
]);
$result = $service->spreadsheets_values->batchUpdate($spreadsheetId, $body);
Related
I am trying to hit a POST API Endpoint with Guzzle in PHP (Wordpress CLI) to calculate shipping cost. The route expects a RAW JSON data in the following format:
{
"startCountryCode": "CH"
"endCountryCode": "US",
"products": {
"quantity": 1,
"vid": x //Variable ID
}
}
Link to the API I am consuming: https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate
$body = [
"endCountryCode" => "US",
"startCountryCode" => "CN",
"products" => [
'vid' => $vid,
'quantity' => 1
],
];
$request = $this->client->request(
'POST', 'https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate',
[
'headers' => [
'CJ-Access-Token' => $this->auth_via_cj(), // unnecessary, no auth required. Ignore this header
],
'body' => json_encode( $body )
],
);
I've also tried using 'json' => $body instead of the 'body' parameter.
I am getting 400 Bad Request error.
Any ideas?
Try to give body like this.
"json" => json_encode($body)
I spent so many hours on this to just realise that products is actually expecting array of objects. I've been sending just a one-dimensional array and that was causing the 'Bad Request' error.
In order to fix this, just encapsulate 'vid' and 'quantity' into an array and voila!
You don't need to convert data in json format, Guzzle take care of that.
Also you can use post() method of Guzzle library to achieve same result of request. Here is exaple...
$client = new Client();
$params['headers'] = ['Content-Type' => 'application/json'];
$params['json'] = array("endCountryCode" => "US", "startCountryCode" => "CN", "products" => array("vid" => $vid, "quantity" => 1));
$response = $client->post('https://developers.cjdropshipping.com/api2.0/v1/logistic/freightCalculate', $params);
$range = "2020!A92:L92";
$valueRange= new Google_Service_Sheets_ValueRange();
$valueRange->setValues(["values" => ["updatetest1", "updatetest2", "updatetest3", "updatetest4", "updatetest5", "updatetest6", "updatetest7", "updatetest8", "updatetest9", "updatetest10", "updatetest11", "updatetest12"]]);
$conf = ["valueInputOption" => "RAW"];
$service->spreadsheets_values->update($spreadsheetId, $range, $valueRange, $conf);
I have this snippet, but the problem is tha I need to modify B92, F92 and G92 only, so I would need to update those with the values updatetest2, updatetest6 and updatetest7. I could call it three times, but there's probably a better way. I know there's \Google_Service_Sheets_BatchUpdateSpreadsheetRequest, but the documentation is pretty parse.
https://developers.google.com/resources/api-libraries/documentation/sheets/v4/php/latest/class-Google_Service_Sheets_BatchUpdateSpreadsheetRequest.html#$responseIncludeGridData
$data = [];
array_push(
$data,
new Google_Service_Sheets_ValueRange([
'range' => 'B92',
'values' => [["BATCHUPDATE"]]
])
);
array_push(
$data,
new Google_Service_Sheets_ValueRange([
'range' => 'E92',
'values' => [["BATCHUPDATE"]]
])
);
array_push(
$data,
new Google_Service_Sheets_ValueRange([
'range' => 'F92',
'values' => [["BATCHUPDATE"]]
])
);
$body = new Google_Service_Sheets_BatchUpdateSpreadsheetRequest([
"valueInputOption" => "RAW",
"data" => $data
]);
$result = $service->spreadsheets->batchUpdate($spreadsheetId, $body);
I also tried the following and I am getting:
PHP Fatal error: Uncaught Google\Service\Exception: {
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"valueInputOption\"
: Cannot find field.\nInvalid JSON payload received. Unknown name \"data\": Cann
ot find field.",
"errors": [
{
"message": "Invalid JSON payload received. Unknown name \"valueInputOpti
on\": Cannot find field.\nInvalid JSON payload received. Unknown name \"data\":
Cannot find field.",
"reason": "invalid"
}
],
"status": "INVALID_ARGUMENT"
}
}
The error you are receiving is due to the fact that the spreadsheets.batchUpdate request does not expect a field named valueInputOption.
However, since you want to update the values from a sheet, you should use the
spreadsheets.values.batchUpdate request and make the following change:
$body = new Google_Service_Sheets_BatchUpdateValuesRequest([
"valueInputOption" => "RAW",
"data" => $data
]);
For further use, if needed, you can easily simulate the Sheets API requests by making use of the "Try this API!" from the documentation pages.
Reference
Class Google_Service_Sheets_BatchUpdateValuesRequest;
Sheets API spreadsheets.values.batchUpdate.
Trying to add data to a Google Sheet via the Google Sheets API and the BatchUpdate method, but I get this error (don't know what it refers to)
> PHP Fatal error: Uncaught Google\Service\Exception: { "error": {
> "code": 400,
> "message": "Invalid JSON payload received. Unknown name \"\": Root element must be a message.",
> "errors": [
> {
> "message": "Invalid JSON payload received. Unknown name \"\": Root element must be a message.",
> "reason": "invalid"
> }
> ],
> "status": "INVALID_ARGUMENT" } }
Here's my new code:
$spreadsheetId = 'myspreadsheetid';
$client = new Google_Client();
$client->setAuthConfig('mycredntials.json');
$client->setApplicationName('Sheet Automation');
$client->setScopes(Google_Service_Sheets::SPREADSHEETS);
$service = new Google_Service_Sheets($client);
$range = 'A2:L';
$valueInputOption = 'USER_ENTERED';
$body = new Google_Service_Sheets_ValueRange([
'values' => $row1
]);
$params = [
'valueInputOption' => $valueInputOption
];
$result = $service->spreadsheets_values->append($spreadsheetId, $range, $body, $params);
EDIT:
The data I get from the database is put into an array ($row1) that when echoed looks like this:
(
[cdr_id] => myid
[calldate] => 2021-05-27
[src] => mysource
[accountcode] => myaccountcode
[userfield] => disposition
[ivr_std_txn_full] =>
)
I then grab that info and use implode to put it all in one line (this may be the issue)
echo $line1 = implode(',', $row1)
I tried setting the values to be appended to both $row1 and $line1, but still get the payload issue.
in my condition, its because some data have null value, so make sure data you want send not null, you can change it to empty string or other.
example :
[ivr_std_txn_full] => null
change to :
[ivr_std_txn_full] => ''
The solution was pretty simple once I finally figured it out. If you won't be putting the values in manually and instead have an array filled with data you just need to reference each key in the array instead of just the array.
The request body ended up looking like this:
$body = new Google_Service_Sheets_ValueRange([
//'values' => $row1
'values' =>
[
[
$row1['cdr_id'], $row1['calldate'], $row1['src'], $row1['accountcode'], $row1['userfield'], $row1['ivr_std_txn_full']
]
]
]);
$params = [
'valueInputOption' => $valueInputOption
];
$result = $service->spreadsheets_values->append($spreadsheetId, $range, $body, $params);
I want write data to my sheet:
$spreadsheetId = 'xxx';
$range = 'Test!A1:D5';
$values = [
'range' => "A1",
'majorDimension' => 'DIMENSION_UNSPECIFIED',
'values' => [
["Item", "Cost", "Stocked", "Ship Date"],
["Wheel", "$20.50", "4", "3/1/2016"],
["Door", "$15", "2", "3/15/2016"],
["Engine", "$100", "1", "30/20/2016"],
],
];
$body = new Google_Service_Sheets_ValueRange(array(
'values' => $values
));
$params = array(
'valueInputOption' => 'RAW'
);
$result = $service->spreadsheets_values->update($spreadsheetId, $range, $body, $params);
But in log i see:
PHP Fatal error: Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 400,
"message": "Invalid JSON payload received. Unknown name \"range\" at 'data.values': Cannot find field.\nInvalid JSON payload received. Unknown name \"major_dimension\" at 'data.values': Cannot find field.",
"errors": [
{
"message": "Invalid JSON payload received. Unknown name \"range\" at 'data.values': Cannot find field.\nInvalid JSON payload received. Unknown name \"major_dimension\" at 'data.values': Cannot find field.",
"domain": "global",
"reason": "badRequest"
}
],
"status": "INVALID_ARGUMENT"
}
}
What am I doing wrong? I will be grateful for the example code that works for you :)
In the examples there is not enough information( https://developers.google.com/sheets/api/guides/values#writing_to_a_single_range)
You're almost there. Don't forget to include the sheet name
"range": "Sheet1!A1:D5"
Check the Basic Writing guide for more samples.
Try this:
$spreadsheetId = 'xxx';
$range = 'Test!A1:D5';
$values = [
["Item", "Cost", "Stocked", "Ship Date"],
["Wheel", "$20.50", "4", "3/1/2016"],
["Door", "$15", "2", "3/15/2016"],
["Engine", "$100", "1", "30/20/2016"],
];
$updateBody = new Google_Service_Sheets_ValueRange([
'range' => $range,
'majorDimension' => 'ROWS',
'values' => $values,
]);
$valueInputOption = 'USER_ENTERED'; // Or RAW
$params = [
'valueInputOption' => $valueInputOption
];
$result = $this->sheetsService->spreadsheets_values->update(
$spreadsheetID,
$updateRange,
$updateBody,
$params
);
Not the case here, but I have solved a similar issue by removing NULL values from the items inside of the values array.
Google's PHP library seems to have a hard time parsing these values and ends up generating an invalid JSON payload.
I'm using Google's Client API via Composer (https://packagist.org/packages/google/apiclient) and I have successfully authenticated and received an access token.
I am trying to add a row to a Google sheet in my drive, but I can't find any relevant documentation that specifically addresses PHP.
Here's what I've got so far:
$service = new Google_Service_Sheets($a4e->google); // my authenticated Google client object
$spreadsheetId = "11I1xNv8cHzBGE7uuZtB9fQzbgrz4z7lIaEADfta60nc";
$range = "Sheet1!A1:E";
$valueRange= new Google_Service_Sheets_ValueRange();
$service->spreadsheets_values->update($spreadsheetId,$range,$valueRange);
This returns the following error:
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{ "error": { "code": 400, "message": "Invalid valueInputOption: INPUT_VALUE_OPTION_UNSPECIFIED", "errors": [ { "message": "Invalid valueInputOption: INPUT_VALUE_OPTION_UNSPECIFIED", "domain": "global", "reason": "badRequest" } ], "status": "INVALID_ARGUMENT" } } ' in /usr/share/nginx/vendor/google/apiclient/src/Google/Http/REST.php
I'm stuck as to the format of the "Google_Service_Sheets_ValueRange()" object, and also how to append a row to the end of the sheet, rather than having to specify a particular range.
I would greatly appreciate any help with this issue.
I had the same problem, there is a lack of documentation about this. But I found a solution. Here is a working example:
// ...
// Create the value range Object
$valueRange= new Google_Service_Sheets_ValueRange();
// You need to specify the values you insert
$valueRange->setValues(["values" => ["a", "b"]]); // Add two values
// Then you need to add some configuration
$conf = ["valueInputOption" => "RAW"];
// Update the spreadsheet
$service->spreadsheets_values->update($spreadsheetId, $range, $valueRange, $conf);
I think it's weird syntax, and I did not found clear documentation about it, I just tried some combination and now it works! Not sure it's the right way, hope it could help.
There is a new append method:
(I am using a service account.)
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setSubject($delegated_user);
$client->addScope(Google_Service_Sheets::SPREADSHEETS);
$service = new Google_Service_Sheets($client);
$range = 'Sheet1!A:E';
$values = [
["a", "b", "C", "D", "E"]
];
$body = new Google_Service_Sheets_ValueRange([
'values' => $values
]);
$params = [
'valueInputOption' => "RAW"
];
$result = $service->spreadsheets_values->append($spreadsheet_id, $range, $body, $params);
$client = $this->getClient();
$service = new Google_Service_Sheets($client);
$spreadsheetId = '1bFh8FYeez6c1snPCHZF_olsHOLRqEENJbChLKbE9xg0';
$range = 'A1:S1';
$values = [
['col 1', 'col 2', 'col 3'],
['col 1', 'col 2', 'col 3'],
['col 1', 'col 2', 'col 3']
];
$requestBody = new Google_Service_Sheets_ValueRange(array(
'values' => $values
));
$params = [
'valueInputOption' => 'RAW'
];
print_r($requestBody);
$response = $service->spreadsheets_values->update($spreadsheetId, $range, $requestBody, $params);