Google Sheets API (PHP) Batch Update - php

I would like to use the Google Sheets API Batch Update because the calls to update individual cells are extremely slow. The problem is that cells that have no data do not come back as part of a cell feed, so I do not have the necessary edit URL to include those cells in the Batch Update. I have seen reference to a "return-empty" parameter in the Google .NET API which will supposedly return all cells, even empty cells, in a cell feed, but I cannot find any reference to that for the "Protocol" API I am using in PHP (here is an example of a reference to the "return-empty" parameter: Writing to an empty cell in Google Spreadsheets). Does anyone know how to get the cell feed request to return all cells (including empty cells)? Or am I doomed to using the abysmally slow cell update requests?

Quick Hack
If you're using the same API I am, then in googlespraedsheet/api.php at line 152 after
$cellRangeCriteriaQuerystringList = [];
You can add:
$cellRangeCriteriaQuerystringList[] = "return-empty=true";
Better Way
There's a better way, which I have added in my own fork. I created a pull request.
If you work with my fork (or if the pull request is accepted), then you can just add 'returnEmpty' => true to your $cellRange. For example:
$cellList = $spreadsheetAPI->getWorksheetCellList(
$spreadsheetKey,
$worksheetID,
['rowStart' => $rowStart,
'rowEnd' => $rowEnd,
'returnEmpty' => true]);

Related

Analytics track custom events in new Web+App

I used to track custom events (API hits) with google analytics and PHP via cURL, but now analytics is deprecating this method. I understood that the new analytics Web+App is used to track this kind of events, but i cannot find anything that allows me to track those events.
my current code:
$response = $client->post('https://www.google-analytics.com/collect', [
'form_params' => [
'v' => 1,
't' => 'event',
'ec' => 'ap1-v1-xxx',
'ea' => 'invoke',
'el' => 'MY-API',
'tid' => 'XXXXXXXX',
'cid' => '555'
]
]);
Doing this, i was able to track every hit and have statistics about API usage, this is what the analytics panel looked-like:
But, as i said, analytics is deprecating this method, and it stopped tracking my hits:
https://support.google.com/firebase/answer/9167112?ref_topic=6386699
There is a way to keep track these custom events? I can't find anything alike in PHP or cURL whatsoever.
Thanks!
It's not so much the method (measurement protocol) has been deprecated, it's that it is using a new, as of yet apparently undocumented, version 2 of the measurement protocol.
That makes sense - you cannot sent hit type anymore (because there is now a single type event, whose name can be customized), and you cannot send event category, action and label, since those no longer exist, and have been replaced by event parameters.
Since there does not seem to be documentation yet, you can do a bit of reverse engineering. I looked at the request issued by the code from a web&app property (actually gtag.js) for a pageview:
https://www.google-analytics.com/g/collect? // endpoint, remains the same
v=2 // protocol version, v2
&tid=G-XXXXXXXXXX // tracking id
&_p=1253409603 // no idea, don't think this needs to be set
&sr=1920x1080 // screen resolution, not applicable to a serverside call
&ul=de-de // user agent language, probably not relevant for a serverside call
&cid=533127994.1575982871 // client id
&_s=1 // no idea
&en=pageview // event - this corresponds broadly to hit type t in the previous version
&dl=http://localhost/test2.html // document location
&dr= // document referrer, not relevant for a serverside call
&dt=Title // document title
&sid=1575982870 // no idea
&sct=1 // no idea
&seg=1 // no idea
I think for a serverside application you can ignore all parameters marked with "no idea" (I assume that is something determined by the Javascript tracking code).
Instead of "v=1" you need to set "v=2", and instead of "t" for hit type you need "en" for event name. I will see if I can work out how to sent event parameters (I am in the office and don't really have time to experiment), but in any case this should be enough to get you started (I tested a call via curl and it showed up in the realtime section of a web&app property, so it should work for you, too).

GAPI - Google Analytics Sampling.

I am using the GAPI API to access Google Analytics rather than do it myself directly (I know slightly lazy...). I've had a look at the class file but I can't see any built-in function for checking sampling. I was wondering if anyone who has used it has found a way to check if the results being returned are being sampled.
This is the code I am using.
$this->load->config('gapi');
$params = array('client_email' => $this->config->item('account_email'),
'key_file' => $this->config->item('p12_key'));
$this->load->library('gapi', $params);
$this->gapi->requestReportData(
$this->config->item('ga_profile_id'), //reportID
array('date', 'transactionId', 'campaign'), //Dimensions
array('transactionRevenue'), //Metrics
'', //Sort Metric
'medium==email', //Filters
date('Y-m-01'), //Start Date
date('Y-m-d'), //End Date
1,
500
);
$results = $this->gapi->getResults();
My plan is to run the report for a given date range, check to see if the data is sampled and if true, split the query into small parts to get around it.
The v3 API has 2 sampling-related response fields:
Sample Size: number of data entries used
Sample Space: number of data entries available
So if you do Sample Size / Sample Space you have your sampling ratio.
The v4 API has the same but named differently:
samplesReadCounts: number of data entries used
samplingSpaceSizes: number of data entries available
So if you do samplesReadCounts / samplingSpaceSizes you have your sampling ratio.
If gapi doesn't expose these fields in the response, then you should change API client (eg use the official client)

Google Drive PHP method listFiles and get return 'thumbnailLink' NULL

I'm using the PHP V2 API. I requested full access (scope: https://www.googleapis.com/auth/drive). I also tried adding all of the different scopes to no avail.
I'm fully able to retrieve all files and list them but the thumbnail link is always null. Same with 'hasThumbnail'.
I tried the API explorer on https://developers.google.com/drive/v2/reference/files/get#examples and it shows me the thumbnail links correctly.
The relevant code can be boiled down to this:
$drive = new Google_Service_Drive($this->client);;
$files = $drive->files->listFiles($parameters)->files;
This is the response from the API explorer.
The response from my code (for the same ID) is:
Found the solution. It took 5 hours to run into this such simple solution.
Not many fields show by default, you must specify which fields you want populated.
The modified basic query now is:
$this->drive->files->listFiles([
'fields' => 'nextPageToken, files(thumbnailLink, webViewLink)'
])->files;

parse foursquare json feed using php

Using Foursquare API it returns me the following JSON feed
{"meta":{"code":200},"notifications":[{"type":"notificationTray","item":{"unreadCount":1}},{"type":"message","item":{"message":"OK! We've got you # Place XXX. You've been here 2 times."}},{"type":"insights","item":{"insights":{"count":4,"items":[{"type":"pointsReward","image":"https://foursquare.com/img/points/discovery-venue3.png","title":"First of your friends to check into Place XXX!","shareable":false,"points":{"image":{"prefix":"https://foursquare.com/img/points/discovery-venue3_","sizes":[44,60,120],"name":".png"},"message":"First of your friends to check into Place XXX!","points":5}},{"type":"pointsReward","image":"https://foursquare.com/img/points/discovery-venue3.png","title":"First time at Place XXX.","shareable":false,"points":{"image":{"prefix":"https://foursquare.com/img/points/discovery-venue3_","sizes":[44,60,120],"name":".png"},"message":"First time at Place XXX.","points":5}},{"type":"pointsReward","image":"https://foursquare.com/img/points/category-outdoor.png","title":"First Plaza check-in of your friends!","shareable":false,"points":{"image":{"prefix":"https://foursquare.com/img/points/category-outdoor_","sizes":[44,60,120],"name":".png"},"message":"First Plaza check-in of your friends!","points":6}},{"type":"pointsReward","image":"https://foursquare.com/img/points/discovery-venue3.png","title":"First of your friends to check in here.","shareable":false,"points":{"image":{"prefix":"https://foursquare.com/img/points/discovery-venue3_","sizes":[44,60,120],"name":".png"},"message":"First of your friends to check in here.","points":2}}]}}},{"type":"leaderboard","item":{"total":18,"scores":[{"icon":"https://foursquare.com/img/points/discovery-venue3.png","message":"First of your friends to check into...
What I would like to do is to display the message "OK! We've got you # Place XXX. You've been here 2 times." which is embedded in the second "type" tag
I'm used to do get this kind of value using a foreach function but with this one I cannot get it.
I need help from an expert, thanks for your participation.
Code Im trying to use without success:
$data = json_decode($response, true); // return array not object
foreach($data['notifications']['type'][0] as $item) {
echo $item['item']['message'];
}
notifications is an array, so you can't hash into it with 'type' like you are trying to do. You should iterate through $data['notifications'] until you find an object with a "type" property of "message". Then dig into that object's "item" and get its "message". For more details about the notifications field in a response, see https://developer.foursquare.com/docs/responses/notifications.
In the sample JSON you provided, to directly access the content you want, you could use $data['notifications'][1]['item']['message']. The 1 may change depending on what API version you're passing in, but should be relatively stable as long as you keep using the same version.

Google Spreadsheets: Adding Columns using the GData API

Currently, newly created Google spreadsheets seem to default to having 20 columns.
I am able to create new column headers through the cell feed, but only for those existing 20 columns. Beyond that, I cannot create new columns, much less new column headers, as I get the following error:
Expected response code 200, got 403It looks like someone else already deleted this cell.
Using the Zend GData API, this is what I'm doing:
<?php
/*
* Given:
*
* $columnNames, e.g. array('FirstName', 'LastName', 'DateOfBirth')
* $lastColumnOnSpreadsheet, e.g. 20
* $spreadsheetService
* $spreadsheetKey
* $worksheetId
*/
foreach ($columnNames as $columnName)
{
if (!array_key_exists($columnName, $columnsAlreadyOnSpreadsheet))
{
$spreadsheetService->updateCell(1 /* first row */,
++$lastColumnOnSpreadsheet,
$columnName,
$spreadsheetKey,
$worksheetId);
}
}
?>
So, beyond $lastColumnOnSpreadsheet being 19, I get the aforementioned error. Currently, the only workaround is to manually insert columns to the right, one by one, which, besides being tedious, kind of destroys the purpose of automation via GData.
Is it possible to insert columns via the GData API? If so, how, in particular through the Zend framework?
Java/.net: This shows how to set the size of the sheet, you can use it to append rows and cols
https://developers.google.com/google-apps/spreadsheets/
But I found the OAuth hard. For OAuth I used the GDrive tutorial "DrEdit", is the best OAuth tutorial I have seen.

Categories