matteo
matteo

Reputation: 3067

Google Webmaster Tools API - can't obtain permissions for a domain I own

I'm using this library: https://github.com/googleapis/google-api-php-client

I created a simple PHP script that fetches some information from Google Search Console / Webmaster Tools about the performance of a domain I own.

It is not intented to autentify on behalf of a user who visits the page and own their own website. It's intended to show information about MY website and it identifies via a fixed service account. More detail below.

Here's the PHP code:

<!DOCTYPE html>
<html>
<head>
<title>Google Webmaster Tools test</title>
</head>
<body>
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);

require_once ('./path/to/the/autoload.php');

echo "Instantiating client<br>";

$client = new Google_Client(); 

$credentials = file_get_contents ('./test_search_console_credentials.json', true) ; 

echo "Configuring client<br>";

$client->setAuthConfig(json_decode($credentials,true));

$client->setScopes(['https://www.googleapis.com/auth/webmasters.readonly']);

$client->setAccessType('offline');

echo "Instantiating Webmasters service <br>";

$service = new Google_Service_Webmasters($client); 


$query = new \Google_Service_Webmasters_SearchAnalyticsQueryRequest();
 
$date_now = date('Y-m-d');
$date_past = date('Y-m-d', time()-3600*24*30);


$query->setStartDate($date_past);
$query->setEndDate($date_now);
$query->setDimensions(['page','query']);
$query->setSearchType('web');


$pfilter=new \Google_Service_Webmasters_ApiDimensionFilter();
$pfilter->setDimension('page');
$pfilter->setOperator('equals');
$pfilter->setExpression('https://example.com/');


$fgroup= new Google_Service_Webmasters_ApiDimensionFilterGroup();
$fgroup->setFilters([$pfilter]);

$query->setDimensionFilterGroups([$fgroup]);

try {
    $u = $service->searchanalytics->query('https://example.com', $query); 
    echo '<table border=1>';
    echo '<tr>
        <th>#</th><th>Clicks</th><th>CTR</th><th>Imp</th><th>Page</th><th>KEYword</th><th>Avg. pos</th>';
        for ($i = 0; $i < count($u->rows); $i++) {
        echo "<tr><td>$i</td>";
        echo "<td>{$u->rows[$i]->clicks}</td>";
        echo "<td>{$u->rows[$i]->ctr}</td>";
        echo "<td>{$u->rows[$i]->impressions}</td>";
        echo "<td>{$u->rows[$i]->keys[0]}</td>";
        echo "<td>{$u->rows[$i]->keys[1]}</td>";
        echo "<td>{$u->rows[$i]->position}</td>";
        echo "</tr>";
        }             
    echo '</table>';
    } catch(\Exception $e ) {
    echo $e->getMessage();
    }  
?>


</body>
</html>

So I did the following:

enter image description here

enter image description here

enter image description here

That generated a JSON file which is the one I load from the PHP code above.

enter image description here

whose ownership I verified via DNS. As you can see, I can see the data in the web interface.

enter image description here

Yet, when I try the script above, I get the error:

{ "error": { "code": 403, "message": "User does not have sufficient permission for site 'https://********.com'. See also: https://support.google.com/webmasters/answer/2451999.", "errors": [ { "message": "User does not have sufficient permission for site 'https://*******.com'. See also: https://support.google.com/webmasters/answer/2451999.", "domain": "global", "reason": "forbidden" } ] } }

Obviously the linked Help Center page doesn't help.

I have done the exact same thing with half a dozen other websites, all with the exact same procedure, with the same project, Service Account and credentials, and it works with most of them.

The only difference I can see between the properties with which it works and those with which it doesn't, is that the ones that work are properties that have existed for years, way before I even created the Google Cloud Platform project; and they were not "domain" properties, but url-prefix-based ones, that is, properties that either start with https:// or plain http://, either with or without the www., and they only work with the proper protocol and the right www prefix or lack thereof. And in those, you verify the ownership by uploading a file with a given path and name that Google gives you. However, I have tried to create a property like that for the newer domain that I'm trying to get to work, and that doesn't work either.

It's almost as if Google's api refused to work with properties created after a certain date.

NOTE: don't tell me I need Owner permissions instead of Full. I have already tried that (which you can only do through an older interface difficult as hell to find) and it makes no difference whatsoever. The older websites work both with Full and Owner permissions; the newer one doesn't work with either.

Upvotes: 2

Views: 1477

Answers (1)

matteo
matteo

Reputation: 3067

I found the answer here: Webmasters API User does not have sufficient permission for site (MartijnvdB's answer in case the deep link to the specific answer breaks).

I needed to change this:

$u = $service->searchanalytics->query('https://example.com', $query);

to this:

$u = $service->searchanalytics->query('sc-domain:example.com', $query);

There are two types of Google Search Console properties: domain-type and prefix-type. For domain-type properties you need to pass the name of the property as https://www.example.com (with http or https, with or without the www matching the exact prefix of the property). For domain-based properties you need to pass it as sc-domain:example.com.

I had tried with just example.com without any kind of prefix, but that didn't work. I don't know why the API can't just accept that and prepend sc-domain: when needed.

The PHP library has no documentation whatsoever, and the documentation of the API itself is unbelievably poor too, as is usual for Google APIs.

Once you already know the answer, you can find it documented here:

https://developers.google.com/webmaster-tools/search-console-api-original/v3/searchanalytics/query

siteUrl string The URL of the property as defined in Search Console. Examples: http://www.example.com/ (for a URL-prefix property) or sc-domain:example.com (for a Domain property)

Note that it says "as defined in Search Console". When browsing the Search Console as a user, you never see the name of the property as sc-domain:... anywhere.

Upvotes: 4

Related Questions