Google Search Console Issue with permission - php

Hello fellow developers,
I am working with a friend on a Search Console Application. We are using Laravel and google/apiclient package.
I did implement the login with google with authenticating with OAuth2, and all workes fine.
The main issue here is that when i query search console i was able to get some websites data, but for some reasons for other websites i get this error.
Google\Service\Exception: {
"error": {
"code": 403,
"message": "User does not have sufficient permission for site 'https://example-site.com'. See also: https://support.google.com/webmasters/answer/2451999.",
"errors": [
{
"message": "User does not have sufficient permission for site 'https://examplesite.com'. See also: https://support.google.com/webmasters/answer/2451999.",
"domain": "global",
"reason": "forbidden"
}
]
}
}
https://example-site.com i used my real website.
Here are the steps that i did:
I created a project in google cloud api, activate the google search console api, i have project permission as owner, i got the credentials in json format.
In Laravel i implemented the apis (Controller and Api Routes) for google authentications(code exchange), refresh token , etc.
I also set the scope like this.
$client->setScopes(
[
\Google\Service\Oauth2::USERINFO_PROFILE,
\Google\Service\Oauth2::USERINFO_EMAIL,
\Google\Service\Oauth2::OPENID,
\Google\Service\SearchConsole::WEBMASTERS
]
);
This is the method that i used to query Analitics
public function getSearchConsoleData(Request $request)
{
$client = GoogleController::getUserClient();
$service = new \Google\Service\Webmasters($client);
$request = new \Google\Service\Webmasters\SearchAnalyticsQueryRequest;
$request->setStartRow(0);
$request->setStartDate('2022-11-01');
$request->setEndDate('2022-11-15');
$request->setSearchType('web');
$request->setDimensions(array('query','country','device','country','device',));
$query_search = $service->searchanalytics->query("https://website-that-i-own.com", $request);
$rows = $query_search->getRows();
return $rows;
}
All the site are verified, i did check in Search Console Site.
I also searched online, looked at documentation from google search console api, google api issue forum.
All the site are verified, i did check in Search Console Site.
I also searched online, looked at documentation from google search console api, google api issue forum.
Please let me know what i missed here.
Thank you so much for you help in advance.

Related

How to write to a sheet with Google Sheets API without oAuth consent screen

I'm writing a script in PHP to automate the process of grabbing data from a Database and inserting it into a google sheet.
Since it's going to be running at 15 minute intervals and Oauth consent screen isn't really the best option.
Is there another option to get the necessary authorization to write to the sheet without the need of signing in via browser?
Most of the examples I've seen in the documentation and online use a consent screen.
If I try this:
$client = new Google_Client();
$service = new Google_Service_Sheets($client);
Which would work with the Text-to-Speech API I get this (naturally):
> PHP Fatal error: Uncaught Google\Service\Exception: { "error": {
> "code": 401,
> "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid
> authentication credential. See
> https://developers.google.com/identity/sign-in/web/devconsole-project.",
> "errors": [
> {
> "message": "Login Required.",
> "domain": "global",
> "reason": "required",
> "location": "Authorization",
> "locationType": "header"
> }
> ],
> "status": "UNAUTHENTICATED" } }
The link in the error message just guides you through making a consent screen. From what I could find online if i were to only be reading a file there wouldn't be a problem, but writing to it, even if i set the sheet to public, requires authentication.
Note: This is all running in a Gcloud VM instance
You can use a service account and then share the sheet with that service account.
Go to console.cloud.google.com and login with the account containing the sheet
Add the Google Sheets API (go to APIs and Services, look up Google Sheets API, add it)
Go back to APIs and Services and click on Credentials
Click on Create credentials -> Service account
Fill in required stuff (mainly Service account name, and give it Owner role) and press done
Click on the service account you just created
Go to keys tab -> Add key -> Create new key -> JSON
This should give you a key to use. This is your client_secret.json. Use
$client->setAuthConfig('./client_secret.json') or
$client->setAuthConfigFile('./client_secret.json')
depending on the version of the php google api client you are using.
Also, make sure you set the appropriate scope using
$client->setScopes([\Google_Service_Sheets::SPREADSHEETS]);
Share the sheet from your drive with the created service account and give it editorial permissions

Google Ads Api Developer Token Error - even though it is validated

I am developing an application which integrates with Google Ads and syncing Ad/Campaign etc. data into my servers. I am getting authorization related error when I try to request some data from Google Ads API. Here is the steps I have done by now:
Applied to Google in terms of validating an OAuth application and scopes (Done, we got verification from Google and can ask for AdWords scope)
Applied to Google Ads for getting a developer token and got it. (Basic Access)
We are able to connect test accounts and successfully getting the response. But when we try it with real accounts we get the error below.
The code is also from the original Google Ads API example. I have tried with tons of different accounts but none of them seems to be working. When I try to obtain those data with same parameters from AdWords API instead of Google Ads API, it works. But Google AdWords PHP SDK is no longer maintained so I have to keep trying with Google Ads API. I share my code below:
{
$this->customerId = $customerId;
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
$this->accessToken = $accessToken;
$oAuth2Credential = (new OAuth2TokenBuilder())
->withClientId($this->clientId)
->withClientSecret($this->clientSecret)
->withRefreshToken($this->accessToken)
->build();
$this->googleAdsClient = (new GoogleAdsClientBuilder())
->withOAuth2Credential($oAuth2Credential)
->withDeveloperToken(env("GOOGLE_DEVELOPER_TOKEN"))
->withLoginCustomerId((int) $this->customerId)
->build();
}
public function getCampaigns(): array
{
try {
$campaigns = [];
$services = $this->googleAdsClient->getGoogleAdsServiceClient();
$results = $services->search($this->customerId, $this->campaignQuery(), ['pageSize' => self::PAGE_SIZE]);
foreach ($results->iterateAllElements() as $row) {
$campaigns[] = (new Campaign())->transform($row);
}
return $campaigns;
} catch (GoogleAdsException $googleAdsException) {
// TODO add error log
return [];
}
}```
The error:
```Google\ApiCore\ApiException: {
"message": "The caller does not have permission",
"code": 7,
"status": "PERMISSION_DENIED",
"details": [
{
"#type": 0,
"data": "type.googleapis.com\/google.ads.googleads.v6.errors.GoogleAdsFailure"
},
{
"#type": 0,
"data": [
{
"errorCode": {
"authorizationError": "DEVELOPER_TOKEN_PROHIBITED"
},
"message": "Developer token is not allowed with project '691752477594'."
}
]
}
]}```
Are you using the same cloud console project credentials for the login on your site as you are for the API calls?
The very first call to the Google Ads API permanently associates a developer token to a cloud project. If this is different to the one you're using on your site, you may have to switch them.
some developer token is already associated with project that you are trying with,
to resolve this You have to create one more App project in console and re configure your secrate key, and client id with new project that you have created dont forget to use the latest developer token i.e (your current developer token) and make a first API call, then your developer token will get paired forever, once it get bound it will never be changed later on.
As said before you need to create a new google cloud project, this is related with how Google organises users through their products.
If you are a company that is advertising through Google Ads, Google wants you to organise all your campaigns under a single master user account. That master user account should have a single developer token which you use within the Google Cloud Project associated to the same company.
For Google you should not have multiple master user accounts for the same company and therefore multiple developer tokens.
Of course there are edge cases that do not fit this rule, like advertising agencies however there is not a large incentive for Google to change this.
You can follow this thread for updates, but I do not expect things to change any time soon, https://groups.google.com/g/adwords-api/c/O8_y2xt0nGo

Creating users using the Microsoft Graph API (PHP)

Issue
I'm trying to build an app to integrate with the Microsoft Graph API.
I have an admin account in Azure, and have set up a new app through the portal.
I've downloaded and installed the PHP SDK, and have managed to set everything up so that I can get a user successfully.
I can sign into the app and grant permissions to use my information (the permission I'm requesting is Directory.ReadWrite.All, but even just requesting User.ReadWrite.All is not working for me), however, my issue seems to be that I cannot access other users.
The following only returns my own user:
$graph = new Graph();
$graph->setAccessToken('/* SOMETOKEN */');
$users = $graph->createRequest('GET', '/users')
->setReturnType(User::class)
->execute();
POSTing a new user returns me a 404 error:
$newUser = new User();
$newUser->setAccountEnabled(true);
$newUser->setGivenName('first_name');
$newUser->setSurname('last_name');
$newUser->setUserPrincipalName('some.email#address.com');
$password = new PasswordProfile();
$password->setPassword('some_password');
$newUser->setPasswordProfile($password);
$user = $graph->createRequest('POST', '/users')
->attachBody($newUser)
->execute();
Returns:
{
"error": {
"code": "",
"message": "No HTTP resource was found that matches the request URI 'https://outlook.office365.com:444/profile/v1.0/users('CID:a8ef4446a149de4d')/profile?api-version=AGSV1-internal'.",
"innerError": {
"date": "/* timestamp */",
"request-id": "/* an id */",
"client-request-id": "/* an id */"
}
}
}
Even trying to use Microsoft's Graph Explorer is getting these same errors.
Am I right in thinking this could be an account setup issue?
Update
Here is the error message the Graph Explorer is returning
{
"error": {
"code": "",
"message": "No HTTP resource was found that matches the request URI 'https://outlook.office365.com:444/profile/v1.0/users('CID:a8ef4446a149de4d')/profile?api-version=AGSV1-internal'.",
"innerError": {
"date": "2020-11-30T16:51:41",
"request-id": "743030b4-8835-4a9f-9e3e-d35919a1c289",
"client-request-id": "c40cd440-d873-ba38-dce7-8669bc561e64"
}
}
}
I have resolved this.
Issue
The issue was in the permission request.
My app was set up to allow personal accounts as well as work/school ones.
Logging in with a personal account, my user was not able to grant the *.ReadWrite or *.All permissions.
While I was getting a token back from the auth request, it only had the User.Read permission.
Steps needed to get access to all users working
Change the app in Azure to only accept work/school accounts
When my app tries to authenticate, I needed to log in with a work/school account
Granting the permissions for User.Read.All should now work
Hitting the /users endpoint should return all users
To get write working, I needed to register for a Partner Center MPN ID and associate that with my app in Azure.

Seeking code example for OAuth 2.0 with Google Ad Exchange seller-API

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.

In Google API v2, why is the error "The project id used to call the Google Play Developer API has not been linked" happening?

When I'm using Google API v2, to get an inapp listing, I'm getting the following error when I'm making the API call:
{
"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 then researched this error and ended up seeing the suggestions on this page, this page, and on this page as well. I followed and double-checked the way the projects get linked there but it did not help.
This is what I did...
In Google Developer Console:
Used an existing project.
Went to APIs & auth > APIs.
Ensured "Google Play Android Developer API" was turned ON.
Used my existing credentials for CLIENT ID, CLIENT SECRET, and REDIRECT URIS. Application type was "native application".
Created an API KEY as well, but did not use it.
In Google Play Developer Console:
Went to SETTINGS > API access.
Under LINKED PROJECT, I ensured the above project from the Google Developer Console was linked.
In my PHP script:
<?php
require_once('/var/www/html/common/include.php');
require_once realpath(dirname(__FILE__) . '/lib/Google/autoload.php');
$refreshToken = '1/sometoken';
$packageName = 'com.somepackage';
$client_id = GOOGLE_CLIENT_ID;
$client_secret = GOOGLE_CLIENT_SECRET;
$redirect_uri = 'http://localhost';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setScopes(['https://www.googleapis.com/auth/androidpublisher']);
$client->refreshToken($refreshToken);
$service = new Google_Service_AndroidPublisher($client);
$response = $service->inappproducts->listInappproducts($packageName);
var_dump($service);
Which led to the above error.
Any other suggestions to resolve this error with using refresh tokens?
Hey I was having a similar issue as you, I figured out the problem was I was the authenticating a user did not have the right permissions.
First go into your Google Play Console, go under Settings> API Access. Make sure that you have a linked "Google Play Android Developer" (which is sounds like you do and I did as well).
Next go into Settings>User Accounts and Rights, make sure the user has the proper rights to view subscriptions or whatever you need it to. For testing purposes just give it all the rights.
Then make sure to Authenticate this user via Oauth(ie select their email from the list) and then get typical refresh/access token
Really seems so painfully obvious to me now, but it still took a day of frustration. I hope this solves your issue :)

Categories