Google Analytics API using PHP with service account - google-analytics

I have been searching and looking this up for two days now and can't figure out where I am going wrong. I am attempting to pull data from my google analytics account using php. I have followed all the steps to set up a service account and downloaded the JSON file. Here is the code I am using:
// Load the Google API PHP Client Library
require_once ('/google-api-php-client-1-master/src/Google/autoload.php');
$KEY_FILE_LOCATION = '/inc/ac_key.json';
// Create and configure a new client object.
$client = new Google_Client();
$client->setApplicationName("Hello Analytics Reporting");
$client->setAuthConfig($KEY_FILE_LOCATION);
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$analytics = new Google_Service_Analytics($client);
function getResults($analytics, $profileId) {
// Calls the Core Reporting API and queries for the number of sessions
// for the last seven days.
return $analytics->data_ga->get(
'ga:' . $profileId,
'30daysAgo',
'today',
'ga:pageviews'
);
}
$profile = $r['google_analytics'];
$results = getResults($analytics, $profile);
$month = date('n');
$year = date('Y');
$results->setMonth($month,$year);
$visits = $results->getVisitors();
$views = $results->getPageviews();
/* build tables */
if(count($visits)) {
foreach($visits as $day=>$visit) {
$flot_datas_visits[] = '['.$day.','.$visit.']';
$flot_datas_views[] = '['.$day.','.$views[$day].']';
}
$flot_data_visits = '['.implode(',',$flot_datas_visits).']';
$flot_data_views = '['.implode(',',$flot_datas_views).']';
}
I am getting an error for an invalid client_secret.json file but I am attempting to authenticate using a service account so I am not sure what is going on here. I am then attempting to plot the data in a flot table but I am not worried about that part yet as I am still trying to get through this first hurdle. Any help would be appreciated!

I'm not quite up-to-date with the Google PHP API client, but apparently there are different versions on offer - when I cloned the repo I got the version that you app use and I did not get it to work with my credentials file. I then installed the current version of the library via composer:
composer require google/apiclient:^2.0
I was then able to access a Google Analytics with the following code:
<?php
include_once __DIR__ . '/vendor/autoload.php';
date_default_timezone_set('America/Los_Angeles');
$client = new Google_Client();
$client->setAuthConfig('/path/to/credentials.json');
$client->setApplicationName("Client_Library_Examples");
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$service = new Google_Service_Analytics($client);
function getResults($service, $profileId) {
return $service->data_ga->get(
'ga:' . $profileId,
'30daysAgo',
'today',
'ga:pageviews'
);
}
$profile= "80493610";
$results = getResults($service, $profile);
print_r($results);
With a bit of poking around I managend to get an instance of the analytics service with the old version from your example. Apparently you have to use the loadServiceAccountJson function rather than setAuthConfig
<?php
// Load the Google API PHP Client Library
require_once ('google-api-php-client/src/Google/autoload.php');
$KEY_FILE_LOCATION = '/path/to/credentials.json';
// Create and configure a new client object.
$client = new Google_Client();
$client->setApplicationName("Hello Analytics Reporting");
$scopes = ['https://www.googleapis.com/auth/analytics.readonly'];
$client->loadServiceAccountJson($KEY_FILE_LOCATION, $scopes);
$analytics = new Google_Service_Analytics($client);
print_r($analytics);

Related

Google analytics 4 API with authentication

My website already has universal analytics and we are displaying different analytics profile data on our dashboard by authenticating users. Because each user will have access to a different analytics profile. So the steps we follow in UA are,
Ask the user to authenticate.
Get auth code and create an access token.
Passing access token to listManagementProfiles API to get the list of profiles for the authenticated user.
Based on the selected profile we display the analytics data. (we use google service analytics library)
sample code:
if (!class_exists('Google_Client')) {
require_once '/lib/google-api-php-client-master/src/Google/Client.php';
require_once '/lib/google-api-php-client-master/src/Google/Service/Analytics.php';
}
$this->client = new Google_Client();
$this->client->setApprovalPrompt('force');
$this->client->setAccessType('offline');
$this->client->setClientId('************');
$this->client->setClientSecret('*************');
$this->client->setRedirectUri('*****************');
$this->client->setScopes('https://www.googleapis.com/auth/analytics');
$this->client->setDeveloperKey('*************************');
$this->service = new Google_Service_Analytics($this->client);
$accessToken = $this->client->authenticate($authCode);
if ($accessToken) {
$this->client->setAccessToken($accessToken);
return true;
} else {
return false;
}
Where I'm stuck?
I've checked for the GA4 documentation and followed the steps provided in the doc. I have created the account/property for GA4 in one of my google accounts.
I then enabled the analytics service from google console.
Created service account.
Downloaded JSON file.
Downloaded the google admin client library from here
GA4 sample code:
require 'vendor/autoload.php';
use Google\Analytics\Admin\V1alpha\AnalyticsAdminServiceClient;
use Google\Analytics\Data\V1beta\BetaAnalyticsDataClient;
use Google\Analytics\Data\V1beta\DateRange;
use Google\Analytics\Data\V1beta\Dimension;
use Google\Analytics\Data\V1beta\Metric;
putenv('GOOGLE_APPLICATION_CREDENTIALS=config.json');
$client = new AnalyticsAdminServiceClient();
$accounts = $client->listAccountSummaries();
But this does not require the access_token and without an access token, it allows to fetch the accounts lists. I don't want the manual process of giving access to the service account for each analytics account.
I want my user to authenticate to my website and then only do the rest process based on it.
How can I achieve that?
I also read something that GA4 does not have profiles(views), then how can I access the profile data in GA4? do I need to list down the accounts/properties list to the user for selection?
I need the referral, organic search, users, and session data on my website. What endpoint of GA4 provides this data?
Any other library do I need to use?
I think you are close. You are just mixing oauth and service account.
With your UA analytics code you are using the Google analytics reporting api / google analytics management api to request access of the user to access their Google analytics accounts. You are currently using Oauth2 to request access of a user to access "their" google analytics accounts. These are accounts that they control.
With your GA4 accounts you are connecting to the google analytics admin api though you are currently using a service account.
Service accounts must be pre authorized. They are intended for use with accounts that the developer owns. You need to swtich it to use Oauth2 and not a service account. This way the users will be authenticated to their own account.
Google analytics admin Oauth2
Here is a sample with Oauth2.
<?php
// composer composer require google/analytics-admin
require 'vendor/autoload.php';
use Google\Client;
use Google\Analytics\Admin\V1alpha\AnalyticsAdminServiceClient;
putenv('GOOGLE_APPLICATION_CREDENTIALS=C:\YouTube\dev\credentials.json'); // Installed app credentials.
$credentials = getenv('GOOGLE_APPLICATION_CREDENTIALS');
$myfile = file_get_contents($credentials, "r") ;
$clientObj = json_decode($myfile);
$client = getClient();
$tokenResponse = $client->getAccessToken();
print_r($tokenResponse);
print_r($tokenResponse["access_token"]);
$service = new AnalyticsAdminServiceClient( [
'credentials' => Google\ApiCore\CredentialsWrapper::build( [
'scopes' => [
'https://www.googleapis.com/auth/analytics',
'openid',
'https://www.googleapis.com/auth/analytics.readonly',
],
'keyFile' => [
'type' => 'authorized_user',
'client_id' => $clientObj->installed->client_id,
'client_secret' => $clientObj->installed->client_secret,
'refresh_token' => $tokenResponse["refresh_token"]
],
] ),
] );
$accounts = $service->listAccounts();
foreach ($accounts as $account) {
print 'Found account: ' . $account->getName() . PHP_EOL;
}
function getClient()
{
$client = new Client();
$client->setApplicationName('Google analytics admin beta Oauth2');
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
$client->setAuthConfig(getenv('GOOGLE_APPLICATION_CREDENTIALS'));
$client->setAccessType('offline');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'tokenAdmin.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
Note this is a console app, not a web app. You may have to tweek it to work with web but you should just be able to copy your UA auth code and dump the tokens in as i have shown here.
Code shamelessly copied from Simple How to Integrate php with Google analytics admin api.
To fetch Account Summaries using Access Token, you can use Google APIs Client Library for PHP
Here is the working code
<?php
require_once 'vendor/autoload.php';
use Google\Client;
use Google\Service\GoogleAnalyticsAdmin;
$access_token = 'ya29.xxxxxxx';
// Init Google Client and Set Access Token
$client = new Client();
$client->setAccessToken($access_token);
// GA Admin Service
$service = new GoogleAnalyticsAdmin($client);
// Fetch Account Summaries
$summary = $service->accountSummaries->listAccountSummaries();
// Output
print_r($summary->toSimpleObject());
Output
stdClass Object
(
[accountSummaries] => Array
(
[0] => stdClass Object
(
[account] => accounts/XXXXXXX
[displayName] => XXXXXXX
[name] => accountSummaries/XXXXXXX
[propertySummaries] => Array
(
[0] => stdClass Object
(
[displayName] => XXXXXXX GA4 Property
[parent] => accounts/XXXXXXX
[property] => properties/XXXXXXX
[propertyType] => PROPERTY_TYPE_ORDINARY
)
)
)
[1] => stdClass Object
(
[account] => accounts/XXXXXX
[displayName] => XXXXXXX accounts
[name] => accountSummaries/XXXXXX
)
)
)

Fatal error: Class 'Client' not found in

I got an error while adding Twilio SMS APi to my website. My site is in wordpress and using Woo commerce.
Error : Fatal error: Class 'Client' not found in /var/www/html/++++/wp-content/themes/dokan-theme-v2.2.2-child/functions.php on line 4583
My code is below:
function wl8OrderPlacedTriggerSomething($order_id){
//do something...
//echo get_stylesheet_directory_uri(). '/twilio-php-master/Twilio/Rest/Client.php';
require_once( get_stylesheet_directory_uri(). '/twilio-php-master/Twilio/autoload.php');
require( get_stylesheet_directory_uri(). '/twilio-php-master/Twilio/Rest/Client.php');
// Use the REST API Client to make requests to the Twilio REST API
// use Twilio\Rest\Client;
// Your Account SID and Auth Token from twilio.com/console
$sid = 'xxxxxxxxxxxxxxxxxxxxxx';
$token = 'xxxxxxxxxxxxxxxx';
$client = new Client($sid, $token);
// Use the client to do fun stuff like send text messages!
$client->messages->create(
// the number you'd like to send the message to (xxxxxxx)
'xxxxxxxxx',
array(
// A Twilio phone number you purchased at twilio.com/console
'from' => '+xxxxxxx',
// the body of the text message you'd like to send
'body' => "Hey Jenny! Good luck on the bar exam!"
)
);
}
Please help me for the same.
Thank you,
Twilio developer evangelist here.
I think you may need to use the fully qualified namespace for the Client in this case. Try:
$client = new Twilio\Rest\Client($sid, $token);
Let me know if that helps.
Edit
OK, that didn't work. After reading around, I've found that it's not recommended to use require or require_once within a function. I'd recommend you require the autoload file outside of your function, use the namespace and then call the Client inside the function. Like this:
require_once( get_stylesheet_directory_uri(). '/twilio-php-master/Twilio/autoload.php');
use Twilio\Rest\Client;
function wl8OrderPlacedTriggerSomething($order_id){
$sid = 'xxxxxxxxxxxxxxxxxxxxxx';
$token = 'xxxxxxxxxxxxxxxx';
$client = new Client($sid, $token);
// and so on...
}
make sure that autoload.php and Client.php files are getting loaded properly.
its unable to load client call

Evernote PHP sdk integration with Symfony2

I am using this documentation to set up Evernote cloud sdk php into Symfony2 :
https://github.com/evernote/evernote-cloud-sdk-php/blob/master/documentation/Getting_Started.md
As they say, I installed it first with composer.
Then I am using this code
$sandbox = true;
$oauth_handler = new \Evernote\Auth\OauthHandler($sandbox);
$key = '%key%';
$secret = '%secret%';
$callback = 'http://host/pathto/evernote-cloud-sdk-php/sample/oauth/index.php';
$oauth_data = $oauth_handler->authorize($key, $secret, $callback);
echo "\nOauth Token : " . $oauth_data['oauth_token'];
I changed the parameters with mine, but the problem is inside Evernote\Auth\OauthHandler :
https://github.com/evernote/evernote-cloud-sdk-php/blob/master/src/Evernote/Auth/OauthHandler.php
The lib is using the function header(location: ...);
And the function is not executing.
I guess Symfony2 is not allowing the usage of this function.
Is there a way to force it ?
Or how can I change it in a good way (and to be able to push on my git repository) ?
Thanks,

Which PHP Script File is needed for ical() class in Google Calendar PHP API v3

I am getting an error in a PHP script I am building:
Fatal error: Class 'ical' not found in /home/abc/public_html/app/mods/googleCalendar_3.0/cache_events.php on line 74
Here is a snippet from my script file:
define('CLIENT_ID', 'ASDLJJLDSJLASDJLajdl;jdsljkASD;LKJASDLKJASD.apps.googleusercontent.com');
require_once('autoload.php'); // 2014-11-24 part of /usr/local/lib/php/google-api-php-client
require_once('/usr/local/lib/php/google-api-php-client/src/Google/Client.php'); // 2014-11-25
require_once('/usr/local/lib/php/google-api-php-client/src/Google/Service/Calendar.php'); // 2014-11-25
$ical = new ical('https://www.google.com/calendar/ical/CLIENT-ID/public/basic.ics');
$eventListArray = array_filter($ical -> events(), "locationfilter");
$eventCount = count($eventListArray);
print_r($eventListArray); echo "<br>";
echo "Event Count:" . $eventCount;echo "<br>";
exit;
I am simply trying to retrieve all events in my public calendar
Notes:
Calendar is publicly viewable
Just to make sure, I added my Auth & API's > Credentials > Service Account > Email Address to it just to be safe
If you want to use a service account your code is off quite a bit. I cant test this code my local webserver is acting up but it should be close you may have to tweek the $service->Events->list(); part it was kind of a guess. Make sure that you have the Service account email address added as a user on the calendar in question and it should work.
session_start();
require_once 'Google/Client.php';
require_once 'Google/Service/Calendar.php';
/************************************************
The following 3 values an befound in the setting
for the application you created on Google
Developers console. Developers console.
The Key file should be placed in a location
that is not accessable from the web. outside of
web root. web root.
In order to access your GA account you must
Add the Email address as a user at the
ACCOUNT Level in the GA admin.
************************************************/
$client_id = '1046123799103-nk421gjc2v8mlr2qnmmqaak04ntb1dbp.apps.googleusercontent.com';
$Email_address = '1046123799103-nk421gjc2v8mlr2qnmmqaak04ntb1dbp#developer.gserviceaccount.com';
$key_file_location = '629751513db09cd21a941399389f33e5abd633c9-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$key = file_get_contents($key_file_location);
// seproate additional scopes with a comma
$scopes ="https://www.googleapis.com/auth/calendar";
$cred = new Google_Auth_AssertionCredentials(
$Email_address,
array($scopes),
$key
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$service = new Google_Service_Calendar($client);
// you should only need to do this once print this and you will
// find the calendarId for the one you are looking for.
$calendars = $service->calendarList->list();
$events = $service->events->list($yourCalendarID);
Note: all you need is the Google Dir you can remove everything above that you dont really need it. Code was edited from the only tutorial i have that shows this in PHP.

Google Calendar :: Update Existing Attendee Status using PHP API

I am using google calendar API V3 . I want to update existing attendee status using PHP API. I am using following code. But it seems this code is not updating existing attendee. For example consider (shohag#test.com,enamul#test.com,test#test.com) are attendees of certain event and all of them event status are pending. After executing this code i see only test#test.com in accepted condition. Here is my code.
<?php
require_once '../../src/Google_Client.php';
require_once '../../src/contrib/Google_CalendarService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google Calendar PHP Starter Application");
$client->setClientId('MYCLIENT ID');
$client->setClientSecret('MY SECRET');
$client->setRedirectUri('MY RETURN URL');
$client->setDeveloperKey('MY DEV KEY');
$cal = new Google_CalendarService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
// First retrieve the event from the API.
$event = new Google_Event($cal->events->get('primary', 'EVENT ID'));
$attendee1 = new Google_EventAttendee();
$attendee1->setEmail('test#test.com');
$attendee1->setResponseStatus('accepted');
$attendees = array($attendee1);
$event->attendees = $attendees;
$updatedEvent = $cal->events->update('primary', $event->getId(), $event);
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
How can i change status of existing attendee? Here is update API link https://developers.google.com/google-apps/calendar/v3/reference/events/update .Let me know.
Just like in the Google Calendar UI, attendee status can only be modified by the attendee their self. If all of these users are in the same Google Apps domain, you can authorize as the attendee via a service account and change their status as them.

Resources