I tried to run query on Analytics Reporting using the "google/apiclient" and based on example on Google Analytics Reporting v4 documentation. It is returning records, but always only 10. NextPageToken is null in response. Response has only one report. Request has set PageSize for 100 records. I tried many configuration PageSize: 100/500/1000 and PageToken: 1/100/1000/abc and always return only 10 records.
I created the same report on page and it has 1169 pages for 10 records on page (for the same date range).
I looked on limit quotas for API and it has default value.
Did i miss something in code or may be there something problem with configuration service account (some limitation for service account)?
private function getReport($analytics, $VIEW_ID) {
$dateRange = new Google_Service_AnalyticsReporting_DateRange();
$dateRange->setStartDate("2020-04-01");
$dateRange->setEndDate("2020-04-12");
$quantityCheckedOut = new Google_Service_AnalyticsReporting_Metric();
$quantityCheckedOut->setExpression("ga:quantityCheckedOut");
$quantityCheckedOut->setAlias("itemQuantity");
$dimension1 = new Google_Service_AnalyticsReporting_Dimension();
$dimension1->setName("ga:productSku");
$pivots = new Google_Service_AnalyticsReporting_Pivot();
$pivots->setDimensions([$dimension1]);
$pivots->setMetrics($quantityCheckedOut);
$order = new Google_Service_AnalyticsReporting_OrderBy();
$order->setFieldName("ga:quantityCheckedOut");
$order->setSortOrder("ASCENDING");
$request = new Google_Service_AnalyticsReporting_ReportRequest();
$request->setViewId($VIEW_ID);
$request->setDateRanges($dateRange);
$request->setPageSize("100");
$request->setHideValueRanges(true);
$request->setMetrics([$quantityCheckedOut]);
$request->setPivots($pivots);
$request->setOrderBys([$order]);
$request->setSamplingLevel("LARGE");
return $request;
}
private function initializeAnalytics()
{
$KEY_FILE_LOCATION = $this->initFolder . '/google.json';
$filesystemAdapter = new Local($this->cacheFolder);
$filesystem = new Filesystem($filesystemAdapter);
$client = new Google_Client();
$client->setApplicationName("App Name");
$client->setAuthConfig($KEY_FILE_LOCATION);
$client->setIncludeGrantedScopes(true);
$cache = new FilesystemCachePool($filesystem);
$client->setCache($cache);
$client->addScope(Google_Service_AnalyticsReporting::ANALYTICS_READONLY);
$analytics = new Google_Service_AnalyticsReporting($client);
return $analytics;
}
private function printResults($reports)
{
$nextToken = 0;
/** #var Google_Service_AnalyticsReporting_Report $report */
foreach ($reports->getReports() as $report) {
$nextToken = $report->getNextPageToken();
}
return $nextToken
}
public function run(){
/** #var Google_Service_AnalyticsReporting $analytics */
$analytics = $this->initializeAnalytics();
$pageToken = 1;
$i = 0;
$request = $this->getReport($analytics, "VIEW_IDxxxx");
$body = new Google_Service_AnalyticsReporting_GetReportsRequest();
while($i < 1) {
$request->setPageToken((string)$i);
$body->setReportRequests($request);
$response = $analytics->reports->batchGet($body);
$pageToken = $this->printResults($response);
$i++;
}
}
It wasn't needed
$pivots = new Google_Service_AnalyticsReporting_Pivot();
$pivots->setDimensions([$dimension1]);
$pivots->setMetrics($quantityCheckedOut);
Instead of that i wrote
$request->setDimensions($dimension1);
Then google response was two columns in data: ProductSKU and itemQuantity. That is i wanted. Somehow Pivot removes nextPageToken and nextPageSize doesn`t affect on request.
Related
How can I create an event in google calendar and not have it on trash?
I was researching on Google Calendar API ( https://developers.google.com/calendar/v3/reference/events/insert ) how to create an event on the calendar, the insert works fine, the API returns with status: 'confirmed'.
But in the calendar, the event does not appear.
I looked at Google Calendar API and there the status is "canceled", so my events appear on the trash.
I'm not sure of what is happening, someone knows how to create an event on google calendar that does not goes to trash?
<?php
class Calendar
{
private $calendarId = 'primary';
private $service = null;
private $client = null;
public function __construct()
{
$this->client = new Client([
'scopes' => [
Google_Service_Calendar::CALENDAR,
Google_Service_Calendar::CALENDAR_READONLY,
Google_Service_Calendar::CALENDAR_EVENTS,
Google_Service_Calendar::CALENDAR_EVENTS_READONLY,
]
]);
$this->service = new Google_Service_Calendar($this->client->getClient());
}
public function eventAdd()
{
$email = 'seuemail#gmail.com';
$event = new Google_Service_Calendar_Event();
$event->setSummary('Vamos ver agora ;)');
$event->setStatus('confirmed');
$start_datetime = new Google_Service_Calendar_EventDateTime();
$start_datetime->setDateTime('2019-10-10T15:00:00.000-03:00');
$start_datetime->setTimeZone('America/Sao_Paulo');
$event->setStart($start_datetime);
$end_datetime = new Google_Service_Calendar_EventDateTime();
$end_datetime->setDateTime('2019-10-10T20:00:00.000-03:00');
$end_datetime->setTimeZone('America/Sao_Paulo');
$event->setEnd($end_datetime);
$reminder = new Google_Service_Calendar_EventReminder();
$reminder->setMethod('popup');
$reminder->setMinutes(10);
$reminders = new Google_Service_Calendar_EventReminders();
$reminders->setUseDefault(false);
$reminders->setOverrides(array($reminder));
$event->setReminders($reminders);
$attendee1 = new Google_Service_Calendar_EventAttendee();
$attendee1->setEmail($email);
$attendee1->setResponseStatus('accepted');
$attendees = array($attendee1);
$event->attendees = $attendees;
$optParams = array('sendNotifications' => true, 'maxAttendees' => 1);
$event = $this->service->events->insert($this->calendarId, $event, $optParams);
var_dump($event);
}
}
There is an open issue for this problem in Issue Tracker.
As a workaround, you can use your actual calendar ID instead of just 'primary'. This small change should solve your issue.
I hope this helps!
I'm trying to display the google analytics report in my web application which is to display top 10 pages and display browsers count,
i am using this link Hello Analytics Reporting API v4; PHP quickstart for service account to develop it. I am getting below error,
Error calling POST https://analyticsreporting.googleapis.com/v4/reports:batchGet: (401) Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential
CODE :
$analytics = initializeAnalytics();
$response = getReport($analytics);
printResults($response);
function initializeAnalytics()
{
// Use the developers console and download your service account
// credentials in JSON format. Place them in this directory or
// change the key file location if necessary.
$KEY_FILE_LOCATION = __DIR__ . '/preprod-b18917fe321f.json';
// Create and configure a new client object.
$client = new Google_Client();
$client->setApplicationName("Hello Analytics Reporting");
$client->setAuthConfig('{"web":{}}'); // provided the .json credentials
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$analytics = new Google_Service_AnalyticsReporting($client);
return $analytics;
}
function getReport($analytics) {
// Replace with your view ID, for example XXXX.
$VIEW_ID = "xxxxxx";
// Create the DateRange object.
$dateRange = new Google_Service_AnalyticsReporting_DateRange();
$dateRange->setStartDate("7daysAgo");
$dateRange->setEndDate("today");
// Create the Metrics object.
$sessions = new Google_Service_AnalyticsReporting_Metric();
$sessions->setExpression("ga:sessions");
$sessions->setAlias("sessions");
// Create the ReportRequest object.
$request = new Google_Service_AnalyticsReporting_ReportRequest();
$request->setViewId($VIEW_ID);
$request->setDateRanges($dateRange);
$request->setMetrics(array($sessions));
$body = new Google_Service_AnalyticsReporting_GetReportsRequest();
$body->setReportRequests( array( $request) );
return $analytics->reports->batchGet( $body );
}
/**
* Parses and prints the Analytics Reporting API V4 response.
*
* #param An Analytics Reporting API V4 response.
*/
function printResults($reports) {
for ( $reportIndex = 0; $reportIndex < count( $reports ); $reportIndex++ ) {
$report = $reports[ $reportIndex ];
$header = $report->getColumnHeader();
$dimensionHeaders = $header->getDimensions();
$metricHeaders = $header->getMetricHeader()->getMetricHeaderEntries();
$rows = $report->getData()->getRows();
for ( $rowIndex = 0; $rowIndex < count($rows); $rowIndex++) {
$row = $rows[ $rowIndex ];
$dimensions = $row->getDimensions();
$metrics = $row->getMetrics();
for ($i = 0; $i < count($dimensionHeaders) && $i < count($dimensions); $i++) {
print($dimensionHeaders[$i] . ": " . $dimensions[$i] . "\n");
}
for ($j = 0; $j < count($metrics); $j++) {
$values = $metrics[$j]->getValues();
for ($k = 0; $k < count($values); $k++) {
$entry = $metricHeaders[$k];
print($entry->getName() . ": " . $values[$k] . "\n");
}
}
}
}
}
Anyone please give me an idea to get rid of this error.
Error calling POST https://analyticsreporting.googleapis.com/v4/reports:batchGet: (401) Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential
Means that you are not logged in you are not properly authenticating the client before running the code.
posible issues with service accounts
Check $client->setAuthConfig('{"web":{}}'); make sure this is the correct path to the json key file. should probably be $KEY_FILE_LOCATION
Make sure that you created service account credentials on Google Developer console and not something else this code will only work with a service account key file.
Make sure that you granted the service account access to your google analytics account. Take the service account email address and add it as a user in Google analytics at the account level.
Issue with json file location
If you still have issues with the file you can put the location into an env
// Load the Google API PHP Client Library.
require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* #return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* #return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
ServiceAccount.php
The error tells us that a user needs be logged in. You simply need to add the authentication part.
I suggest you to look at a sample Google Oauth & Analytics v4 in PHP.
I'm working on a google Calendar sync with my application.
I'm using the latest google-api-php-client
Now I want to update all my event, so i want to use the batch operation.
The example code of the php client api is:
$client = new Google_Client();
$plus = new Google_PlusService($client);
$client->setUseBatch(true);
$batch = new Google_BatchRequest();
$batch->add($plus->people->get(''), 'key1');
$batch->add($plus->people->get('me'), 'key2');
$result = $batch->execute();
So when I "translate" it to the calendar API, I become the following code:
$client = new Google_Client();
$this->service = new Google_CalendarService($client);
$client->setUseBatch(true);
// Make new batch and fill it with 2 events
$batch = new Google_BatchRequest();
$gEvent1 = new Google_event();
$gEvent1->setSummary("Event 1");
$gEvent2 = new Google_event();
$gEvent2->setSummary("Event 2");
$batch->add( $this->service->events->insert('primary', $gEvent1));
$batch->add( $this->service->events->insert('primary', $gEvent2));
$result = $batch->execute();
But when I run this code, I get this error:
Catchable fatal error: Argument 1 passed to Google_BatchRequest::add()
must be an instance of Google_HttpRequest, instance of Google_Event given
And I do not think that "$plus->people->get('')" is a HttpRequest.
Does anybody know what I do wrong, or what method / object I should use to add in the batch?
Or what the correct use of the batch operation for the calendar is?
Thanks in advance!
I had the same problem while working with inserts to the MirrorService api, specifically with timeline items. What is happening is that the the Google_ServiceRequest object is seeing that you've set the useBatch flag on the client and is actually returning returning Google_HttpRequest object before executing the call to Google but the insert statement in the calendar service doesn't properly handle it as such and ends up returning the calendar event object instead.
It also looks like your params to batch->add are backwards. Should be:
$batch->add( $this->service->events->insert($gEvent1, 'primary'));
Here is my modification to the insert method (you'll need to do this in the calendar service with the proper object input to the method). Just a few lines to make it check what class is coming back from the ServiceRequest class:
public function insert(google_TimelineItem $postBody, $optParams = array()) {
$params = array('postBody' => $postBody);
$params = array_merge($params, $optParams);
$data = $this->__call('insert', array($params));
if ($this->useObjects()) {
if(get_class($data) == 'Google_HttpRequest'){
return $data;
}else{
return new google_TimelineItem($data);
}
} else {
return $data;
}
}
you can use this code to insert events in batch:
public function addEventInBatch($accessToken, $calendarId, array $events)
{
$client = new Google_Client();
$client->setAccessToken($accessToken);
$client->setUseBatch(true);
$service = new Google_Service_Calendar($client);
$batch = $service->createBatch();
collect($events)->each(fn ($event) => $batch->add($service->events->insert($calendarId, $event)));
return $batch->execute();
}
What is the best way I could add possibly 10,000 to 20,000 events at once to a Google Calendar with PHP?
If I try adding them separately I get a "limit exceeded" error far before the daily max.
I've also been looking at importing ICAL/ICS files but I also can't seem to find a function for this besides the calendar subscriptions. Calendar Subscriptions are great but I need to have almost "real-time" updates in my calendars when an event gets changed and it's unclear when calendar subscriptions get updated this could take as much as a day from the initial change in the ICS file.
Need to use Batch Requests. A batch request consists of multiple API calls combined into one HTTP request. Batch processing is a known feature request and is actively worked on. Read the following article about it: https://developers.google.com/google-apps/calendar/batch
See my multipleInsert function for example:
class My_google_calendar
{
...
/** Add single Event for Student */
function addEvent($lesson, $instructor, $return_request = false, $enable_attendees = false)
{
$calendar = $this->getGoogleCalendar(); // get calendar service variable
$lesson_from = date(DATE_RFC3339, $lesson->from);
$lesson_to = date(DATE_RFC3339, $lesson->from + $lesson->duration);
$event = new Google_Service_Calendar_Event();
$event->setSummary('Lesson with student: '$lesson->student_full_name);
$start = new Google_Service_Calendar_EventDateTime();
$start->setDateTime($lesson_from);
$start->setTimeZone($this->getGoogleCalendarTimeZone());
$event->setStart($start);
$end = new Google_Service_Calendar_EventDateTime();
$end->setDateTime($lesson_to);
$end->setTimeZone($this->getGoogleCalendarTimeZone());
$event->setEnd($end);
$event->setColorId(4);
$description = "...";
$event->setDescription($description);
if (isset($student->email) && $enable_attendees) {
$attendee1 = new Google_Service_Calendar_EventAttendee();
$attendee1->setResponseStatus('needsAction');
$attendee1->setEmail($student->email);
$attendees = array($attendee1);
$event->setAttendees($attendees);
}
$createdEvent = $this->calendar->events->insert($this->calendar_id, $event, array('fields' => 'id'));
return $return_request ? $createdEvent : $createdEvent->getId();
}
/** Push group of events to the Calendar */
function multipleInsert ($lessons, $instructor)
{
$this->use_batch = true;
$this->client->setUseBatch($this->use_batch);
$batch = new Google_Http_Batch($this->client);
foreach($lessons as $time => $lesson) {
$lesson = array_shift($group['lessons']);
$req = $this->addEvent($lesson, $instructor, true);
$batch->add($req, $time);
}
}
$results = $batch->execute();
return $results;
}
}
Can somebody provide working example of using the Bigquery API with PHP. I see there are examples for python and java but could not find anything for PHP.
Here is the bigquery browser https://bigquery.cloud.google.com/?pli=1
For e.g You can run this SQL in the browser
SELECT corpus,count(*) FROM publicdata:samples.shakespeare
group by corpus limit 5;
I want to simulate similar call via PHP.
Even a rough example of how to use the PHP API will help a lot.
Use the Google API Client for PHP. Here's a simple example of a script that does a single synchronous query job. This uses the class names found in the downloadable API client. Note: the source pulled from SVN features different class names. Note where you must add your own values for client secret, client id, redirect URI, and project id.
<?php
require_once 'google-api-php-client/src/apiClient.php';
require_once 'google-api-php-client/src/contrib/apiBigqueryService.php';
session_start();
$client = new apiClient();
// Visit https://developers.google.com/console to generate your
// oauth2_client_id, oauth2_client_secret, and to register your oauth2_redirect_uri.
$client->setClientId('XXXXXXXXXXXXXXX.apps.googleusercontent.com');
$client->setClientSecret('XXXXXXXXXXXXXXXXXXX');
$client->setRedirectUri('http://www_your_domain.com/somescript.php');
// Your project id
$project_id = 'XXXXXXXXXXXXXXXXXXXX';
// Instantiate a new BigQuery Client
$bigqueryService = new apiBigqueryService($client);
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
}
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$client->setAccessToken($client->authenticate());
$_SESSION['access_token'] = $client->getAccessToken();
}
if (isset($_GET['code'])) {
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
?>
<!doctype html>
<html>
<head>
<title>BigQuery API Sample</title>
</head>
<body>
<div id='container'>
<div id='top'><h1>BigQuery API Sample</h1></div>
<div id='main'>
<?php
$query = new QueryRequest();
$query->setQuery('SELECT TOP( title, 10) as title, COUNT(*) as revision_count FROM [publicdata:samples.wikipedia] WHERE wp_namespace = 0;');
$jobs = $bigqueryService->jobs;
$response = $jobs->query($project_id, $query);
// Do something with the BigQuery API $response data
print_r($response);
?>
</div>
</div>
</body>
</html>
The previous answers have outdated code. The following example should work with the more recent API (https://github.com/google/google-api-php-client/blob/master/src/Google/Service/Bigquery.php) :
require_once '../source/application/libraries/Google/autoload.php';
public function createGClient(){
define("CLIENT_ID", "{PROJECT_ID}.apps.googleusercontent.com");
define("SERVICE_ACCOUNT_NAME","{SERVICE_ACCOUNT EMAIL FROM CONSOLE}");
define("KEY_FILE",'../{FILENAME}.p12');
define("PROJECT_ID","{PROJECT_ID}");
define("DATASET_ID","{DATASET_ID}");
define("TABLE_ID","");
$this->client = new Google_Client();
$this->client->setApplicationName("{NAME}");
$key = file_get_contents(KEY_FILE);
$this->client->setAssertionCredentials(new Google_Auth_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.googleapis.com/auth/bigquery'), $key, "notasecret"));
$this->client->setClientId(CLIENT_ID);
$this->service = new Google_Service_Bigquery($this->client);
}
public function runQuery(){
// To see the a list of tables
print_r($this->service->tables->listTables(PROJECT_ID, DATASET_ID));
// To see details of a table
print_r($this->service->tables->get(PROJECT_ID, DATASET_ID, TABLE_ID));
// To query a table
$jobs = $this->service->jobs;
$query = new Google_Service_Bigquery_QueryRequest();
$query->setQuery("SELECT * FROM wherever;");
$response = $jobs->query(PROJECT_ID, $query);
print_r($response);
}
This is a modified version of the sample given at: http://michaelheap.com/using-the-php-sdk-with-google-bigquery/ for a service account. To use a client account you would need to use oauth2 and have a pingback address.
I had a lot of issues finding examples.
This is a basic async query, but can demonstrate current PHP API usage, you can see the Python/Java example of the API for async queries here: https://developers.google.com/bigquery/querying-data
Please note, I am not referencing how to setup $client credentials, as it is well documented elsewhere.
$bq = new Google_BigqueryService($client);
//build query
$sql = 'select * from example.table LIMIT 10';
$job = new Google_Job();
$config = new Google_JobConfiguration();
$queryConfig = new Google_JobConfigurationQuery();
$config->setQuery($queryConfig);
$job->setConfiguration($config);
$queryConfig->setQuery($sql);
$insert = new Google_Job($bq->jobs->insert(PROJECT_ID,$job));
$jr = $insert->getJobReference();
$jobId = $jr['jobId'];
$res = new Google_GetQueryResultsResponse($bq->jobs->getQueryResults(PROJECT_ID, $jobId));
//see the results made it as an object ok:
var_dump($results);
/**
* Executes and returns bigQuery response with 'INTERACTIVE' priority
* $this->service is the object of Google_Service_Bigquery
* $this->service = new Google_Service_Bigquery($this->client);
* #param String $sql
* #return Google_Service_Bigquery_GetQueryResultsResponse
*/
public function execute($sql) {
$job = new Google_Service_Bigquery_Job();
$config = new Google_Service_Bigquery_JobConfiguration();
$queryConfig = new Google_Service_Bigquery_JobConfigurationQuery();
$queryConfig->setQuery($sql);
/**
* Priority is set to INTERACTIVE for faster response options are 'BATCH'/'INTERACTIVE'
*/
$queryConfig->setPriority("INTERACTIVE");
$config->setQuery($queryConfig);
$job->setId(md5("$sql_{microtime()}"));
$job->setConfiguration($config);
$running = $this->service->jobs->insert('divine-builder-586', $job);
/* #var $running Google_Service_Bigquery_Job */
$jr = $running->getJobReference();
$jobId = $jr['jobId'];
$res = $this->service->jobs->getQueryResults('divine-builder-586', $jobId);
/* #var $res Google_Service_Bigquery_GetQueryResultsResponse */
return $res;
}