Can not access the Adsense Management API - php

Can not access the AdSense API no matter what I try. I have tried both service account and OAuth authentications.
What I am trying to accomplish:
Creating a bot that will grab the Adsense revenue earned and store it in an in-house database for tracking revenue over time. I do not want to have authentication issues, I want a server-to-server configuration.
What I do know is you can have access tokens and refresh tokens under OAuth. I've yet to be able to make them work under any available APIs with Adsense. Note: I have built an API to work with AdWords no problem.
Errors: (Between the types of authentication, I can not pass these)
"Account Not Found"
"Client is unauthorized to retrieve access tokens using this method."
What I have done so far:
The Adsense Management API is enabled.
Credentials Created: Service Account
Credentials Created: oAuth 2.0 Client ID
The GSuite account has access to APIs (includes "enabled api access" and "managed API client access")
Libraries (trying) to use:
https://developers.google.com/api-client-library/php/
https://github.com/google/google-api-php-client
https://github.com/google/google-api-php-client-services
(outdated) https://github.com/googleads/googleads-adsense-examples
Example code: (using the service account)
$client = new \Google_Client();
$client->setAuthConfig(WRITEPATH . 'auth/adsense-client.json');
$client->setIncludeGrantedScopes(true);
$client->addScope('https://www.googleapis.com/auth/adsense');
$client->setSubject('email#example.com');
// trying to fire the services
$service = new \Google_Service_AdSense($client);
$report = $service->accounts_reports->generate('clientId', $startDate, $endDate, $optParams);
This script fires the "Client is unauthorized to retrieve access tokens using this method." error message. However, the email address being used is able to access the adsense account, the APIs are enabled and configured on the admin domain level.
Is there an easier way? is there anyone who can lead me in the right direction?

Service account
I am not all that sure that Service accounts work with adsence. You can try by going to the adsence website and under manageUsers add the service account email address. The issue here is its going to sit there at pending i think because the service account needs to confirm that it has been added. There is no way to do that.
Admin domain level
If you are trying to add domain wide delegation to this i wouldn't bother with that either as far as i can see its not supported either.
Client is unauthorized to retrieve access tokens using this method.
As for that error i may be able to help. It means that you have taken the credentials file you downloaded for a service account and are trying to use it with the code for Oauth2. or visa versa. Download the credentials file again and try again.
I have some sample code that may help here

Related

Correct OAuth2.0 setup for Service Account to use Google Ads Api?

I have created my service account, following the Google documentation as best I can. I created a JSON Key File and have used it successfully to create and refresh my access token, but when I try to call the Google Ads API using that access token I get a 401 with the message "User in the cookie is not a valid Ads user."
I am using a PHP cURL request, not the Google Client library.
My suspicion is that I have something set up incorrectly somewhere between the Master Ad account, the service account and the project in the Google Cloud Console, but I am finding the documentation confusing and unhelpful.
I submitted a question to the Google Ads API google group, and the support person said that my setup looked OK, but also admitted that he cannot see all of it from his end.
I have created the following pieces of the puzzle:
Google Ads Master Account
Developer Token
Project in Google Cloud Console
Service Account in Project
Private Key for Service Account
Set email of Master Ads Account to role of Owner of Service Account
Enabled Domain-Wide Delegation for the Service Account with scope "https://www.googleapis.com/auth/adwords"
Requested and received Access Token with the private key in the JSON file
Please let me know what extra details I should provide to get my issue resolved. Thanks in advance.
My error was that when I created my Access Token, I passed the Gmail account that owns the Google Ads Manager Account to the parameter $sub, but to access Google Ads API the Service Account must impersonate a user in the domain that is registered with the Google Workspace. This point is made in the documentation, but is rather understated.
To fix the issue I granted access to the Google Ads Manager Account to an email account in the Workspace domain, and passed that email address to $sub; now I have made a successful test call to the Google Ads API.
I attach an anonymized summary of my configuration in case it helps anyone who might be reading this in the future.

Google Drive API PHP - unauthorized_client

I have problem using Service Account to authenticate:
putenv('GOOGLE_APPLICATION_CREDENTIALS='/path/to/google.json');
$client = new \Google_Client();
$client->addScope(\Google_Service_Drive::DRIVE);
$client->useApplicationDefaultCredentials();
$client->setAccessType('offline');
$client->setSubject('xxx#xxx.com');
But it display error like this:
{
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method."
}
When I removed
$client->setSubject('xxx#xxx.com');
It works(I have access), but there is other problem, I can't see any files created through application in my google drive(using UI). From what I heard it's just because I use Service Account and it's creating files on his own space where I can have access only through API. I need to have access to files from API and from google drive application too.
Also I need to have access to my google drive without login to my google account(without redirecting user to google login page).
If you could help me with this problem and show some examples I would be very thankful.
You need to remember that a service account is not you. A service account is a dummy user it has its own google drive account. There will be no files on the service acccounts google drive account until you upload them.
There is no web view for a service account.
You can share a folder on your personal google drive account with the service account like you would any other user using the email address. Just make sure to have the serivce account update the permissions or you will have files on your drive account you dont have access to.
the service account can create a folder on its google drive account and share it with you. You should then be able to see it in the web view of your google drive account.
Storage limit of a service account is linked to the owner of the service account not the account it is uploading to.
Service accounts is used to act on behalf a user. You can set the user to be your account. This way, the service account is acting on your behalf and you can see everything (using the UI) got created via you app.
To avoid the error you are facing, ensure that the following is done:
Create Service account using the instructions in the link below. Please note that step number 6 is an important step and don't ignore it. https://support.google.com/a/answer/7378726?hl=en
Once a service account is created, you need to grant that account permissions using G-suite.
Copy the client_id. You can find it in the json file (service account credential file) or Using the Api Console, by going to Credentials > Manage Service Account then 'View Client ID'. Copy the client_id to clipboard
Launch the G-Suite Admin Console
Go to Security>Advanced Settings>Mange API client access.
Paste the client_id in the Client Name field, add the following API scopes and click Authorize:
https://www.googleapis.com/auth/admin.directory.group,
https://www.googleapis.com/auth/admin.directory.user,
https://www.googleapis.com/auth/calendar.readonly,
https://www.googleapis.com/auth/drive
Note: If step 3 is not done, you will get the error you are getting
References:
https://support.google.com/a/answer/7378726?hl=en
https://github.com/sazaamout/gDrive

PHP Google_Client insert youtube playlistItem (2-leg-oauth)

My web using the PHP Google_Client to insert the youtube playlistItem in my playlist (2-leg-oauth),
and get the error
Client is unauthorized to retrieve access tokens using this method.
Where can I setting the server using my-account#gmail.com to have the same permission to access google api
such like insert playlistItem,
or is there having another way without using my-account#gmail.com to get same permission?
PHP Code:
putenv('GOOGLE_APPLICATION_CREDENTIALS=client_secret.json');
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/youtube');
$client->setSubject('my-account#gmail.com');
If you have delegated domain-wide access to the service account and
you want to impersonate a user account, specify the email address of
the user account use
$client->setSubject($user_to_impersonate);
The YouTube API doesn't support delegated domain-wide access or service accounts. You will need to authenticate with Oauth2.
see PHP Code Samples
You're hitting a common problem. Many developers think that a Service Account is the correct way for server apps to communicate to Google's API services for a given Google account. It isn't! A Service Account, as its name implies, is a brand new account (actually a kind of half-account since you can't actually log in to it) that is dedicated to your app.
What you need to do is a one-time procedure to generate a Refresh Token, which you will store securely. Thereafter, whenever you need to access a Google API such as YouTube, you will use that Refresh Token to generate an Access Token, which you will include in each API request. The steps are enumerated How do I authorise an app (web or installed) without user intervention? (canonical ?) and https://www.youtube.com/watch?v=hfWe1gPCnzc

How to access Google Spreadsheets with a service account credentials?

I have created a server side application in PHP that's supposed to work with Google Spreadsheets.
I'm able to authenticate successfully with OAuth 2.0 authentication, but when requesting the list of the spreadsheets from Google, I only get the spreadsheets shared with the service account by the spreadsheet owner.
Is there a way that service account could retrieve all the spreadsheets owned by my main account not the service one, including those not explicitly shared with the service account?
Also I still want to keep the spreadsheets private so noone can access them without my permission, but I need the service account to have full access to both existing and new spreadsheets.
Any advice is appreciated.
Here is a sample script that uses a service account to read the contents of a Google Spreadsheet's sheet. Have a look at the README for instructions to set it up:
https://github.com/juampynr/google-spreadsheet-reader
You have to change approach:
Create a service account in Drive. You can manage and use this account only with the API (not with the web interface as usually)
With the Drive API you can list, create, update, delete and change the permissions of the files. When you create a new file, you can share it - always with API - to the users you want, make the new file public or change the ownership.
Please take a look: https://developers.google.com/drive/v2/reference/permissions
I am assuming you use Google Apps and not a personal GMail account. You can use your service account to impersonate your main account.
Note that here I am talking of a service account in the way Google means it : a private key (in p12 format) and an identifier. This is not a Google Apps account used for technical purposes. More information here.
This is done by :
Authorizing your service account on your Google Apps domain
Modify the code you use to generate the API credentials
The steps are exactly the same for the Spreadsheet API and for the Drive API.
To first authorize your service account to impersonate the domain users, you can follow this documentation. Here are the basic steps. You must be a domain super administrator to perform this task.
Go to your Google Apps domain’s Admin console : https://admin.google.com
Select Security from the list of controls. If you don't see Security listed, select More
controls from the gray bar at the bottom of the page, then select
Security from the list of controls.
Select Advanced settings from
the list of options.
Select Manage third party OAuth Client access
in the Authentication section.
In the Client name field enter the
service account's Client ID. In the One or More API Scopes field
enter the list of scopes that your application should be granted
access to. In your case that would be at least the Spreadsheet API scope : https://spreadsheets.google.com/feeds
When this is done, you need to update your code so that it impersonates your main account :
$key = file_get_contents($SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(
'YOUR_SERVICE_ACCOUNT_EMAIL',
array('https://spreadsheets.google.com/feeds'),
$key);
$auth->sub = 'yourmainaccount#domain.com';
You can then use the $authvariable to generate the OAuth tokens you need to access the spreadsheet API. I am not sure which client you use for this so the way you inject the access token will depend on which client you use.
Also, note that this token will expire after 1 hour, and then the API will start returning Session Expired errors. If your client does not handle this automatically, you will need to catch the error and regenerate the token.

Google Analytics Core Reporting API Version 3.0 without client login

I want to access our Google Analytics account reporting using the newer v3.0, but it seems from everything that I read that in order to get a valid access token the user must log in.
We want direct access to our own account reporting, and not access a client's depending on their account. How do we accomplish this in PHP without having to send the browser to a Google login page? Is there no straight API authentication for v3.0?
EDIT
This seems to be the only method of accessing the API without end-user interaction, which they call "Server to Server":
https://developers.google.com/accounts/docs/OAuth2ServiceAccount
EDIT 2
Looks like it can't be done? ;(
Warning: Very few Google APIs currently support Service Accounts.
Service accounts are currently supported by the following Google
developer services:
Google Cloud Storage
Google Prediction API
Google URL Shortener
Google OAuth 2.0 Authorization Server
EDIT 3
There seems to be a solution after all, as I log in once and then use "Refresh Tokens" to keep gaining access without an additional user login.
I did end up using the refresh tokens, they work fine. I got a oauth token by using the google api console, and then saved it.
Then I just do this before each request:
require_once 'google-api-php-client/src/apiClient.php';
require_once 'google-api-php-client/src/contrib/apiAnalyticsService.php';;
$client = new apiClient();
$client->setApplicationName('My Analytics');
$client->setClientId($this->client_id);
$client->setClientSecret($this->client_secret);
$client->setDeveloperKey($this->api_key);
$client->setScopes(array('https://www.googleapis.com/auth/analytics.readonly'));
$client->refreshToken($this->refresh_token);
$this->service = new apiAnalyticsService($client);

Categories