I want to fetch Google Analytics data for my website via Google Analytics API.
First, I went to developers console, I enabled Analytics API, then under credentials section I created new ClientID (Service account).
Now, this is my code
include "assets/src/templates/base.php";
require_once 'assets/src/Google/autoload.php';
$client_id = 'xxx.apps.googleusercontent.com'; //Client ID
$service_account_name = 'yyy#developer.gserviceaccount.com'; //Email Address
$key_file_location = 'zzz/key.p12'; //key.p12
echo pageHeader("Service Account Access");
if (strpos($client_id, "googleusercontent") == false
|| !strlen($service_account_name)
|| !strlen($key_file_location)) {
echo missingServiceAccountDetailsWarning();
exit;
}
$client = new Google_Client();
$client->setApplicationName("app");
$service = new Google_Service_Analytics($client);
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/analytics.readonly'),
$key
);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$result = $service->data_ga->get(
'ga:AAA',
'2015-03-03',
'2015-03-03',
'ga:sessions');
?>
where AAA is my ViewID.
So, my problem is this: When I access this script on server it says
*"Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET
https://www.googleapis.com/analytics/v3/data/ga?ids=ga%3A91249839&start-date=2015-03-03&end-date=2015-03-03&metrics=ga%3Asessions:
(403) User does not have any Google Analytics account.' in
C:\xampp\htdocs\test\assets\src\Google\Http\REST.php:110 Stack trace:
0 C:\xampp\htdocs\test\assets\src\Google\Http\REST.php(62): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request),
Object(Google_Client)) #1 [internal function]:
Google_Http_REST::doExecute(Object(Google_Client),
Object(Google_Http_Request)) #2
C:\xampp\htdocs\test\assets\src\Google\Task\Runner.php(174):
call_user_func_array(Array, Array) #3
C:\xampp\htdocs\test\assets\src\Google\Http\REST.php(46):
Google_Task_Runner->run() #4
C:\xampp\htdocs\test\assets\src\Google\Client.php(590):
Google_Http_REST::execute(Object(Google_Client),
Object(Google_Http_Request)) #5
C:\xampp\htdocs\test\assets\src\Google\Service\Resource.php(231):
Google_Client->execute(Object(Google_Htt in
C:\xampp\htdocs\test\assets\src\Google\Http\REST.php on line 110"*
Any suggestions?
Thank you in advance!
Regards,
golobich
Edit: I've tried Google Books api and auth is working ok. (I've changed that link in $cred ofcourse.
The key error is this:
(403) User does not have any Google Analytics account
You are logging in with a service account. You need to grant the service account access to your Google analytics account.
Solution:
Go to the google analytics website. On the admin section add a new user using the service account email address, at the ACCOUNT LEVEL it must be the ACCOUNT LEVEL give this new user read access only that's all it really needs.
Then try your script again.
Related
I am new to the Google APIs and also to somewhat to PHP. I know there has been quite some similar questions, but going through them all in the last few days I didn't manage to handle my problem.
I am building an app which reads from and writes to google sheets, and using a simple API key with a public sheet I am able to read without problems. I didn't manage to figure out the Service Account authorization though.
I have made the sheet private and authorized the service account e-mail address editor access to the sheet.
I double and triple checked the client_id, email address, sheet id.
Here is my code:
function update_stat($spreadsheet_range)
{
session_start();
$client_id = 'XXXXXXXXXX';
$email_address = 'xxx#xxxx.iam.gserviceaccount.com';
$service_account_file = __DIR__ . '/sheetsCS.json';
$spreadsheet_id = 'xxxxxxxxxxxxxxxxxxxxxx';
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . $service_account_file);
date_default_timezone_set("Europe/Rome");
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->setScopes(Google_Service_Sheets::SPREADSHEETS);
$service = new Google_Service_Sheets($client);
$result = $service->spreadsheets_values->get($spreadsheet_id, $spreadsheet_range);
return $result;
}
No matter what I try, I get the following error:
[25-Nov-2020 09:22:07 Europe/Rome] PHP Fatal error: Uncaught Google\Service\Exception: {"error":"invalid_grant","error_description":"Invalid JWT Signature."} in /home/usedbott/public_html/wp-content/themes/ubl-custom-theme/stat-interface/vendor/google/apiclient/src/Http/REST.php:128
Stack trace:
#0 /home/usedbott/public_html/wp-content/themes/ubl-custom-theme/stat-interface/vendor/google/apiclient/src/Http/REST.php(103): 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 /home/usedbott/public_html/wp-content/themes/ubl-custom-theme/stat-interface/vendor/google/apiclient/src/Task/Runner.php(181): call_user_func_array(Array, Array)
#3 /home/usedbott/public_html/wp-content/themes/ubl-custom-theme/stat-interface/vendor/google/apiclient/src/Http/REST.php(66): Google\Task\Runner->run()
#4 /home/usedbott/public_html/wp-content/themes/ubl-custom-theme/stat-int in /home/usedbott/public_html/wp-content/themes/ubl-custom-theme/stat-interface/vendor/google/apiclient/src/Http/REST.php on line 128
What am I missing to make this work?
You might also want to check this Quickstart guide for Google Sheets API in PHP
https://developers.google.com/sheets/api/quickstart/php
Contents:
Guidelines on how to enable Google Sheets API
How to install Google Client Library
Setup a sample code
Run the sample code
Sample Code:
<?php
require __DIR__ . '/vendor/autoload.php';
if (php_sapi_name() != 'cli') {
throw new Exception('This application must be run on the command line.');
}
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Sheets API PHP Quickstart');
$client->setScopes(Google_Service_Sheets::SPREADSHEETS_READONLY);
$client->setAuthConfig('credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// 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 = 'token.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;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Sheets($client);
// Prints the names and majors of students in a sample spreadsheet:
// https://docs.google.com/spreadsheets/d/1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms/edit
$spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms';
$range = 'Class Data!A2:E';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (empty($values)) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s\n", $row[0], $row[4]);
}
}
it have been 4 hours trying to troubleshoot this problem,it always return with (403) User does not have an AdSense account , I am trying to get report of my adsense on my website,
Ps:it's server to server connection
require_once realpath(dirname(__FILE__) . '/../src/Google/autoload.php');
require_once '../src/Google/Client.php';
require_once '../src/Google/Service/AdSense.php';
$client_email = 'xxx#xxx-1220.iam.gserviceaccount.com';
$private_key = file_get_contents('adsense-xxxxx.p12');
$scopes = array('https://www.googleapis.com/auth/adsense.readonly');
$credentials = new Google_Auth_AssertionCredentials(
$client_email,
$scopes,
$private_key,
'notasecret'
);
$client = new Google_Client();
$client->setAssertionCredentials($credentials);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$service = new Google_Service_AdSense($client);
Error Log:
PHP Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling GET https://www.googleapis.com/adsense/v1.4/accounts?maxResults=50: (403) User does not have an AdSense account.' in /var/www/geturl/ad/src/Google/Http/REST.php:110
#0 /var/www/geturl/ad/src/Google/Http/REST.php(62): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request), Object(Google_Client))
#1 [internal function]: Google_Http_REST::doExecute(Object(Google_Client), Object(Google_Http_Request))
#2 /var/www/geturl/ad/src/Google/Task/Runner.php(174): call_user_func_array(Array, Array)
#3 /var/www/geturl/ad/src/Google/Http/REST.php(46): Google_Task_Runner->run()
#4 /var/www/geturl/ad/src/Google/Client.php(593): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request))
#5 /var/www/geturl/ad/src/Google/Service/Resource.php(240): Google_Client->execute(Object(Google_Http_Request))
#6 /var/www/geturl/ad/src/Google/Service/AdSense.php(1106): Google_Service_Resource->call('list', Array, 'Google_Servic in /var/www/geturl/ad/src/Google/Http/REST.php on line 110
Did you wait for 24 hours after enabling the api?
Try testing the account to make sure that it works outside of code. Use the APIs explorer:
https://developers.google.com/adsense/management/v1.4/reference/accounts/list#try-it
Authenticate and try to fetch accounts list.
If that works, make sure you are connecting to the API using that account credentials.
Edit:
Perhaps one of these can help:
https://github.com/googleads/googleads-adsense-examples/tree/master/php-clientlib-1.x/v1.x
https://developers.google.com/adsense/management/libraries
http://www.binarytides.com/php-get-adsense-earnings-and-reports/
I have PHP code that Google PHP Mirror API to insert user account.
if(isset($_GET['userToken'])){
$userToken=$_GET['userToken'];
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
'service-email-here',
array('https://www.googleapis.com/auth/glass', 'https://www.googleapis.com/auth/glass.thirdpartyauth'),
$key
);
$client->setAssertionCredentials($cred);
$mirrorService = new Google_Service_Mirror($client);
$_SESSION['access_token'] = $client->getAccessToken();
insert_account($mirrorService, $userToken, $email, $api_email);
exit();
}
function insert_account($service,$userToken, $email, $api_email)
{
$accountType='package-name-here';
$accountName='service-email-here';
$authtoken=null;
$postBody = new Google_Service_Mirror_Account();
$postBody->setAuthTokens($authtoken);
$userdata=array("email"=>$email);
$postBody->setUserData($userdata);
try {
$account = $service->accounts->insert($userToken, $accountType, $accountName, $postBody);
return $account;
} catch (Exception $e) {
echo "exception: ".$e;
return null;
}
}
I get an error which says:
exception: exception 'Google_Service_Exception' with message 'Error calling POST https://www.googleapis.com/mirror/v1/accounts/usertokenhere/package-name-here/service-email-here: (403) Insufficient Permission' in app-path/Google/Http/REST.php:79
Stack trace:
#0 app-path/Google/Http/REST.php(44): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request))
#1 app-path/Google/Client.php(508): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request))
#2 app-path/Google/Service/Resource.php(195): Google_Client->execute(Object(Google_Http_Request))
#3 app-path/Google/Service/Mirror.php(409): Google_Service_Resource->call('insert', Array, 'Google_Service_...')
#4 app-path/util.php(52): Google_Service_Mirror_Accounts_Resource->insert('8ce7d2ffbe6f693...', 'com.tenpearls.l...', '568533774877-an...', Object(Google_Service_Mirror_Account))
#5 app-path/add-your-own-camera.php(59): insert_account(Object(Google_Service_Mirror), '8ce7d2ffbe6f693...', 'safdar.tp#gmail...', '568533774877-an...')
#6 {main}
Why am I getting the insufficient permission error? I added the scope https://www.googleapis.com/auth/glass.thirdpartyauth which is required to add accounts using mirror api.
I need to insert user account using mirror API.
You do not need the scope https://www.googleapis.com/auth/glass. In fact, this is not a valid scope at all.
The only scope you need for adding an account on the device using a service account is https://www.googleapis.com/auth/glass.thirdpartyauth.
Calling insert account method required separate service client object. Code can be viewed here: http://goo.gl/DVggO6
I use the Blogger library v3 for php,I can not insert a new post.
The error message was:
Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST https://www.googleapis.com/blogger/v3/blogs/3631076204866601722/posts: (403) We're sorry, but you don't have permission to access this resource.' in E:\xampp\htdocs\Udemy2Blogger\libs\Google\Http\REST.php:79
Stack trace:
#0 E:\xampp\htdocs\Udemy2Blogger\libs\Google\Http\REST.php(44): Google_Http_REST::decodeHttpResponse(Object(Google_Http_Request))
#1 E:\xampp\htdocs\Udemy2Blogger\libs\Google\Client.php(508): Google_Http_REST::execute(Object(Google_Client), Object(Google_Http_Request))
#2 E:\xampp\htdocs\Udemy2Blogger\libs\Google\Service\Resource.php(195): Google_Client->execute(Object(Google_Http_Request))
#3 E:\xampp\htdocs\Udemy2Blogger\libs\Google\Service\Blogger.php(1495): Google_Service_Resource->call('insert', Array, 'Google_Service_...')
#4 E:\xampp\htdocs\Udemy2Blogger\index.php(78): Google_Service_Blogger_Posts_Resource->insert('363107620486660...', Object(Google_Service_Blogger_Post), Array)
#5 {main} thrown inE:\xampp\htdocs\Udemy2Blogger\libs\Google\Http\REST.php on line 79
the code is:
<?php
session_start();
$path = "libs";
set_include_path(get_include_path() . PATH_SEPARATOR . $path);
require_once 'Google/Client.php';
require_once 'Google/Service/Blogger.php';
$blogId = 'xxxxxxxxxxxxxxxxxxxx';
$service_account_name = 'xxxxxxxxxxxxxxxxxxxx';
$key_file_location = 'udemy coupon free-e0de16bee449.p12';
$client = new Google_Client();
$client->setAccessType('offline');
$client->setApplicationName("Udemy coupon free");
$bloggerService = new Google_Service_Blogger($client);
/************************************************
If we have an access token, we can carry on.
Otherwise, we'll get one with the help of an
assertion credential. In other examples the list
of scopes was managed by the Client, but here
we have to list them manually. We also supply
the service account
************************************************/
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$key1 = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/blogger'),
$key1
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$newpost = new Google_Service_Blogger_Post();
$newpost->setTitle("test");
$newpost->setContent("test content");
$post = $bloggerService->posts->insert($blogId, $newpost, array());
print_r($post);
Enable Blogger Api v3:
Create client id (service account):
Please help me, thanks a lot!
I've successful after switching to use Client ID (Web application) instead of using Client ID (Service account).
Thanks!
Sometimes if the google blogger ID doesn't match then you might get this error. You can find the blogger ID in the URL of the blogger account.
I was trying the same via REST client. Seems like service account didn't have permission to add blogger posts.
The reason might be - Only an author/admin can create/edit Posts and
service email can't be added to this list.
Attached ARC screenshot
I would like to access google calendar using Service account. This is my code :
<NUMBER> is replace by the correct value take on Google API Console.
<?php
require_once 'googleapi/Google_Client.php';
require_once 'googleapi/contrib/Google_CalendarService.php';
const CLIENT_ID = '<NUMBER>.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = '<NUMBER>#developer.gserviceaccount.com';
const MY_EMAIL = '<MY NAME>#gmail.com';
const KEY_FILE = 'privatekey.p12';
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setApplicationName("<APP NAME>");
$key = file_get_contents(KEY_FILE);
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/calendar'),
$key,
'notasecret',
'http://oauth.net/grant_type/jwt/1.0/bearer',
MY_EMAIL)
);
$cal = new Google_CalendarService($client);
$calList = $cal->calendarList->listCalendarList();
print "<h1>Calendar List</h1><pre>" . print_r($calList, true) . "</pre>";
When I execute my code, I receive:
Fatal error: Uncaught exception 'Google_AuthException' with message
'Error refreshing the OAuth2 token, message: '{ "error" :
"access_denied" }'' in
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/googleapi/auth/Google_OAuth2.php:279
Stack trace: #0
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/googleapi/auth/Google_OAuth2.php(256):
Google_OAuth2->refreshTokenRequest(Array) #1
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/googleapi/auth/Google_OAuth2.php(209):
Google_OAuth2->refreshTokenWithAssertion() #2
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/googleapi/service/Google_ServiceResource.php(166):
Google_OAuth2->sign(Object(Google_HttpRequest)) #3
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/googleapi/contrib/Google_CalendarService.php(154):
Google_ServiceResource->__call('list', Array) #4
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/testService.php(32):
Google_CalendarListServiceResource->listCalendarList() #5 {main}
thrown in
/home/www/65683f67e3f0d94b14bba3c945014cda/web/intranet/googleapi/auth/Google_OAuth2.php
on line 279
If I change my code with :
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/calendar'),
$key));
I receive:
(403) Access Not Configured
What is going wrong here?
I have the solution.
First the good code is the last:
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/calendar'),
$key));
The problem is not the code, but my google account, I have mentioned a Referer in Google API Console. After erasing the field, the code works.
For information purposes, if you would like to access shared calendars, do not forget to share your calendar with your XXXXXX#developer.gserviceaccount.com (your SERVICE_ACCOUNT_NAME).
For more information, see:
https://groups.google.com/forum/?fromgroups=#!topic/google-ajax-search-api/kaKYuUstwB0/discussion