Google-api-php-client: "Cannot determine user location for geographically restricted operation."

Created on 28 Feb 2019  路  4Comments  路  Source: googleapis/google-api-php-client

Since three days I get the above mentioned error message when trying to access google books api, although my IP didn't change. I can reproduce that on the command line with a simple
curl "https://www.googleapis.com/books/v1/volumes?q=frankenstein"

So it's not my code. It can be fixed adding a country code:
curl "https://www.googleapis.com/books/v1/volumes?q=frankenstein&country=DE"

Now how do I do that in the PHP client?

I tried adding country as an optional Parameter:

$client = new Google_Client();
$client->setApplicationName("My_Project");
$client->setDeveloperKey( $google_books_api_key );
$service = new Google_Service_Books($client);
$optParams = array(
    'country' => 'DE'
);
$results = $service->volumes->listVolumes($terms, $optParams);

but that just gives me
{ "error": { "errors": [ { "domain": "global", "reason": "backendFailed", "message": "Service temporarily unavailable.", "locationType": "other", "location": "backend_flow" } ], "code": 503, "message": "Service temporarily unavailable." } }
A solution I found somwhere to set the users IP to one I do have access from still gave me the 'geographically restricted' error message.

$optParams = array(
    'userIp' => '91.64.137.131'
);

I found solutions for clients other then PHP like Java? or Ruby or C# but they didn't seem helpful to me.

In the PHP client a _setCountry($country)_ method exists in _'class Google_Service_Books_VolumeAccessInfo extends Google_Model'_ but I don't know how to access that method. Does anyone know how to solve that?

question

All 4 comments

You can accomplish this in a manner similar to the other language examples you shared by using middlewares:

use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\Middleware;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Handler\CurlHandler;

// Set this value to the country you want.
$countryCode = 'DE';

$client = new Google_Client();
$client->setApplicationName("My_Project");
$client->setDeveloperKey( $google_books_api_key );
$service = new Google_Service_Books($client);
$optParams = [];

$handler = new CurlHandler;
$stack = HandlerStack::create($handler);
$stack->push(Middleware::mapRequest(function ($request) use ($countryCode) {
    $request = $request->withUri(Uri::withQueryValue(
        $request->getUri(),
        'country',
        $countryCode
    ));

    return $request;
}));
$guzzle = new Client([
    'handler' => $stack
]);

$client->setHttpClient($guzzle);

$results = $service->volumes->listVolumes($terms, $optParams);

Middleware is a set of functions which are used to modify requests and responses. This example adds a request middleware, which prior to dispatching the request, will add country=$countryCode to the URI query string.

This example is simplified to some extent, and you'll need to work on it a bit. The big issue is that this middleware will add the country code to every request sent from this instance of Google_Client. I suggest adding additional logic to limit the modification to this request only.

It's exactly how I thought it would need to work but really wouldn't have been able to accomplish it when I look at it now. Works out of the box! Thank you so much.

@jdpedrie Would you like to copy your answer to the exact same question over here. So more people find help to this rather popular problem and you get the fame ;)

Sure, thanks for the heads up.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

slaFFik picture slaFFik  路  5Comments

Fredyy90 picture Fredyy90  路  3Comments

DenisSokoloff picture DenisSokoloff  路  5Comments

upendtu picture upendtu  路  4Comments

unixkapl picture unixkapl  路  3Comments