I've created a spreadsheet, which I managed to successfully update with some data using the google api library and by creating a service accounts credentials from Google console -> Api & Services -> Credentials.
My problem is to try to restrict the access of the spreadsheet file. If don't allow to be publicly available for everyone with Editor roles, it will not work. I m getting this message:
{
"error": {
"code": 403,
"message": "The caller does not have permission",
"errors": [
{
"message": "The caller does not have permission",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
If I allow for everyone to access my spreadsheet, like in the image below , it will work .
I am also running my script, which updates the spreadsheet via a cronjob. Also this is the code where I do the auth part and I'm using the data from my Service Contract:
$client = new Google_Client();
$client->setApplicationName('Google Sheets and PHP');
$configuration = '{
"type": "'.$apiConfig['keyFile']['type'].'",
"project_id": "'.$apiConfig['projectId'].'",
"private_key_id": "'.$apiConfig['keyFile']['private_key_id'].'",
"private_key": "'.$key.'",
"client_email": "'.$apiConfig['keyFile']['client_email'].'",
"client_id": "'.$apiConfig['keyFile']['client_id'].'",
"auth_uri": "'.$apiConfig['keyFile']['auth_uri'].'",
"token_uri": "'.$apiConfig['keyFile']['token_uri'].'",
"auth_provider_x509_cert_url": "'.$apiConfig['keyFile']['auth_provider_x509_cert_url'].'",
"client_x509_cert_url": "'.$apiConfig['keyFile']['client_x509_cert_url'].'"
}';
$client->setAuthConfig(json_decode($configuration, true));
$client->setScopes([Google_Service_Sheets::SPREADSHEETS]);
$client->setAccessType('offline');
return new Google_Service_Sheets($client);
Does anyone have any clue how can I restrict the access? and still have this work?
Thanks a lot for any suggestions
Finally I got it work by adding this email address :
To the Share with people and groups. See image from my post(question) .
Related
Calling Google API got this message:
{
"error": {
"errors": [
{
"domain": "androidpublisher",
"reason": "permissionDenied",
"message": "The current user has insufficient permissions to perform the requested operation."
}
],
"code": 401,
"message": "The current user has insufficient permissions to perform the requested operation."
}
}
or this error message (ADDED):
{
"error": {
"errors": [
{
"domain": "androidpublisher",
"reason": "projectNotLinked",
"message": "The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console."
}
],
"code": 403,
"message": "The project id used to call the Google Play Developer API has not been linked in the Google Play Developer Console."
}
}
I follow all indications I found and I keep having this error.
ON MY SYSTEM
My code
try {
ini_set('max_execution_time', 3000);
$client = new Google_Client();
if ($credentials_file = $this->checkServiceAccountCredentialsFilePlay()) {
// set the location manually
$client->setAuthConfig($credentials_file);
} elseif (getenv('GOOGLE_APPLICATION_CREDENTIALS')) {
// use the application default credentials
$client->useApplicationDefaultCredentials();
} else {
$rv= "missingServiceAccountDetailsWarning()";
return [$rv];
}
$client->addScope("https://www.googleapis.com/auth/androidpublisher");
$serviceAndroidPublisher = new \Google_Service_AndroidPublisher($client);
$servicePurchaseSubscription = $serviceAndroidPublisher->purchases_subscriptions;
$rv = $servicePurchaseSubscription->get(
"com.my.app",
"sub1month",
"ajgbkxxxxxxxxx.AO-J1OxTOKENTOKENTOKEN-"
);
} catch (\Exception $e) {
return $e->getMessage();
}
The credential file
{
"type": "service_account",
"project_id": "project-id",
"private_key_id": "abababababababababababababababababa",
"private_key": "-----BEGIN PRIVATE KEY-----KEYBASE64=\n-----END PRIVATE KEY-----\n",
"client_email": "google-play-account#project-id.iam.gserviceaccount.com",
"client_id": "123450000000000000000",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/google-play-account%40project-id.iam.gserviceaccount.com"
}
ON GOOGLE PLAY CONSOLE
I link the project to the google play console
I add the Service account to the google play console
It's present in the user menu of google play console
And I give him all permission:
ON GOOGLE API DEVELOPER CONSOLE
ADD FYI: my "project-id" is under an organization.
In google developer console I gave all possible permission to the service account:
And of course I've enabled the google Play Android Developer Api (showing my failures):
I had the same problem.
In my case, I was using the google app engine (python) as a backend service. In the beginning, I linked a new Google cloud project in the Google Play Console. I'm not entirely sure if it's the main reason that I got a 401 'insufficient permissions' error, but after switching the linked project to my cloud project (which I used for the app engine) it worked the next day. Right after switching accounts, I received the 403 'projects not linked' error. So, I'm guessing that Google doesn't recognize the change of the linked projects immediately and you need to wait for a few hours.
If you are using app engine, you have to make sure that your default service account for the app engine has a JSON credential file. It's not created by default.
Here is the python code:
if os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine/'):
# production environment
credentials = oauth2client.contrib.appengine.AppAssertionCredentials(scope='https://www.googleapis.com/auth/androidpublisher')
http = credentials.authorize(httplib2.Http(memcache))
response = googleapiclient.discovery.build('androidpublisher', 'v3').purchases().subscriptions()\
.get(packageName=package_name, subscriptionId=subscription.product_id, token=subscription.token)\
.execute(http)
else:
# local environment
# setting the scope is not needed because the api client handles everything automatically
credentials = google.oauth2.service_account.Credentials.from_service_account_file('local_dev.json')
response = googleapiclient.discovery.build('androidpublisher', 'v3', credentials=credentials).purchases().subscriptions()\
.get(packageName=package_name, subscriptionId=subscription.product_id, token=subscription.token)\
.execute()
I have created new YouTube account for test purposes. I got an accessToken for this account and tried to get my own subscriptions via YouTubeAPI.
I use Google APIs Client Library for PHP.
$data = $service->subscriptions->listSubscriptions('snippet', ['mine' => 'true']);
I get an error:
"domain": "youtube.subscription",
"reason": "subscriberNotFound",
"message": "The subscriber identified with the request cannot be found.",
"locationType": "parameter",
"location": "channelId"
"code": 404,
"message": "The subscriber identified with the request cannot be found."
I tried to change the YouTube account, and I got a successful result on my old account. But I want to get info on my new account.
What the problem?
I have to read an excel file on google drive. I need to connect automatically to google drive without prompt any form... a bot must read document... I have this code:
$service_account_file = dirname(__FILE__) . '/key-85ac95ab1e62.json';
$spreadsheet_id = 'the_id_inside_the_url_of_the_file';
$spreadsheet_range = 'Sheet1!A1:A1';
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . $service_account_file);
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope(Google_Service_Sheets::SPREADSHEETS);
$service = new Google_Service_Sheets($client);
$result = $service->spreadsheets_values->get($spreadsheet_id, $spreadsheet_range);
var_dump($result->getValues());
Something goes wrong... I explain how I generated the key-*.json file:
On Google Console Developer i clicked on Service Account, then i created a new one and downloaded the json.. this json is the key-*.json file. I have added this file in my project (as you can see on first row)... Here i copied the Account Service Idthat I will use later...
Now I explain how I get the spreadheet_id... I went on my google drive, right click on the file and I shared it with the Account Service Id (copied before) and an url has been generated... if I copy and past the url in the browser everything works but not in the project... i take the spreadsheet_id from url
this is the error I receive :
PHP Fatal error: Uncaught Google_Service_Exception: {
"error": {
"code": 404,
"message": "Requested entity was not found.",
"errors": [
{
"message": "Requested entity was not found.",
"domain": "global",
"reason": "notFound
}
],
"status": "NOT_FOUND
}
}
What's wrong? the file exists and i cann see it in the browser using the same url I use in the php file... so I think it is a connection or login problem...
any idea?
This is the usual problem with Service Accounts. Refer to any of these https://stackoverflow.com/search?q=404+service+account
In simple terms a Service Account is NOT the same as the Google Account that you used to create it. Either don't use Service Accounts, or share the file from its own account to the Service Account to give it access.
First things first:
The goal is to pull reports from via ADX seller API.
I followed the tutorial, created a Project in the GDC, activated the adx-seller-API and added an OAuth 2.0 client ID just to make sure both types, "Web application" and "Other".
The code is easy enough, I got the google-api-php-client via composer and used the minimal example:
<?php
require_once 'vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfigFile('client_secrets.json');
$client->addScope('https://www.googleapis.com/auth/adexcange.seller');
$service = new Google_Service_AdExchangeSeller($client);
$result = $service->accounts->listAccounts();
print_r($result);
?>
However running the code only yields an exception:
Google_Service_Exception: { "error": { "errors": [ { "domain": "global", "reason": "required", "message": "Login Required", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Login Required" } } in [SNIP]\vendor\google\apiclient\src\Google\Http\REST.php on line 105
So basically 401: Login required
I also used both generated JSON for client_secrets.json, only the "other" one works.
If I use the Google API Explorer it works just fine, oddly the accountId that is talked of everywhere seems to be the DFP-ADX Publisher ID in case anyone is ever wondering.
I've no idea why this isn't working? Am I missing something important or doing something wrong?
In case it helps, I tried the same with Python, for some reason I get as far as to the authentication via browser, the adexchangeseller.dat is created and then it pops a 403: User does not have an Ad Exchange Seller account. which is hilarious considering it does and works via Google API Explorer.
Any help, even a push towards a decent tutorial is appreciated a lot of researching only led to dead ends.
I am trying to get Google Play API subscription details using PHP and using following url to get purchase data :
https://www.googleapis.com/androidpublisher/v1/applications/[PACKAGE]/subscriptions/[SKU]/purchases/[PURCHASE_TOKEN]?access_token=[ACCESS_TOKEN]
I am getting the following error:
{
"error": {
"errors": [
{
"domain": "androidpublisher",
"reason": "developerDoesNotOwnApplication",
"message": "This developer account does not own the application."
}
],
"code": 401,
"message": "This developer account does not own the application."
}
}
Please help me sort out.
Just providing the URL does not help you get data of any application. How can you think so.? Isnt it insecure.? You have to get proper data by which you can at least prove ownership for the app..