Google indexing API wrong json file - php

Hi I am trying to use Google indexing API. I used this tutorial - https://developers.google.com/search/apis/indexing-api/v3/prereqs
I used this php library - different branch - v1-master because I dont use composer so I had to use autoload.php
https://github.com/googleapis/google-api-php-client/tree/master
Here is my code:
require_once($_SERVER["DOCUMENT_ROOT"] . '/assets/google-api-php-client/src/Google/autoload.php');
require_once($_SERVER["DOCUMENT_ROOT"] . '/assets/google-api-php-client/examples/templates/base.php');
$client = new Google_Client();
// service_account_file.json is the private key that you created for your service account.
$client->setAuthConfig($_SERVER["DOCUMENT_ROOT"] . '/assets/google-api-php-client/serviceAccount');
$client->addScope('https://www.googleapis.com/auth/indexing');
// Get a Guzzle HTTP Client
$httpClient = $client->authorize();
$endpoint = 'https://indexing.googleapis.com/v3/urlNotifications:publish';
// Define contents here. The structure of the content is described in the next step.
$content = '{
"url": "http://example.com/jobs/42",
"type": "URL_UPDATED"
}';
$response = $httpClient->post($endpoint, [ 'body' => $content ]);
$status_code = $response->getStatusCode();
I created service account
downloaded service account json file
This is how the json looks
added path to json as you can see above
I enabled Indexing API in console.developers.google.com for my project
json loads
But I got error Uncaught Google_Exception: Invalid client secret JSON file.
This topic is related to - google-api-php-client: Invalid client secret JSON file
But i just could not resolve it and I am stuck

Issue solved, according to issue here - https://github.com/googleapis/google-api-php-client/issues/2025#issuecomment-762634717, autoload has been removed and whole package depends on autoloader from composer (if you are using it).
If you are not using it, author pointed to the last usable version with autoloader here
https://github.com/googleapis/google-api-php-client/releases/tag/v2.8.2
Download this version and include only one autoload.php in your code
require_once($_SERVER["DOCUMENT_ROOT"] . '/assets/google-api-php-client/vendor/autoload.php');
Whole code is here
require_once($_SERVER["DOCUMENT_ROOT"] . '/assets/google-api-php-client/vendor/autoload.php');
$client = new Google_Client();
// service_account_file.json is the private key that you created for your service account.
$client->setAuthConfig($_SERVER["DOCUMENT_ROOT"] . '/assets/google-api-php-client/mykey-pre-10b793743427.json');
$client->addScope('https://www.googleapis.com/auth/indexing');
// Get a Guzzle HTTP Client
$httpClient = $client->authorize();
$endpoint = 'https://indexing.googleapis.com/v3/urlNotifications:publish';
// Define contents here. The structure of the content is described in the next step.
$content = '{
"url": "https://my-site.sk/news.php?ID=157",
"type": "URL_UPDATED"
}';
$response = $httpClient->post($endpoint, [ 'body' => $content ]);
$status_code = $response->getStatusCode();
return $status_code;
Also dont forget to add client_email from your json into Search Console owners by clicking on Settings - Users and Permission - click on dots next to you account - click Manage owners - add there new Owner (adding it to users in the previous site is not enough) - you would get 403 code.
If operation successful you would get Code 200, but in Search Console nothing would be changed because you initiated index job, that might run in few hours

Related

403 Forbidden error in Google Index API Using php

I am trying to integrate google index API with my website in order to index my side but i am getting 401 error.
I searched and got this solution for my problem.
Google Indexing API - 403 'Forbidden Response'
But this is also not working in my case since i have verified that i am owner in google search console plus integrating right JSON authentication file.
I am checking index matrics but and getting all number of calls in my console platform.
require_once 'google-api-php-client/vendor/autoload.php';
$client = new Google_Client();
// service_account_file.json is the private key that you created for your service account.
$client->setAuthConfig('service_account_file.json');
$client->addScope('https://www.googleapis.com/auth/indexing');
// Get a Guzzle HTTP Client
$httpClient = $client->authorize();
$endpoint = 'https://indexing.googleapis.com/v3/urlNotifications:publish';
// Define contents here. The structure of the content is described in the next step.
$content = '{
"url": "http://example.com/jobs/42",
"type": "URL_UPDATED"
}';
$response = $httpClient->post($endpoint, [ 'body' => $content ]);
$status_code = $response->getStatusCode();
any help will be appreciated.
Thank in advance

Fat Free Use Google OAuth + Google API

I'm trying the following thing for quite a while now and am heavily struggling...
On a website, I first want to authenticate a user with his Google Account using OAuth. Therefore, I'm using this library. In order to get it working, I used $f3->set('AUTOLOAD','vendor/ikkez/f3-opauth/lib/opauth/'); to load the PHP files and then used the following code to create the routes and make the authentication possible:
$f3 = \Base::instance();
// load opauth config (allow token resolve)
$f3->config('vendor/ikkez/f3-opauth/lib/opauth/opauth.ini', TRUE);
// init with config
$opauth = OpauthBridge::instance($f3->opauth);
// define login handler
$opauth->onSuccess(function($data){
header('Content-Type: text');
//$data['credentials']['token'];
});
// define error handler
$opauth->onAbort(function($data){
header('Content-Type: text');
echo 'Auth request was canceled.'."\n";
print_r($data);
});
So far so good, thats all working fine, once permission is granted from Google I get the correct callback, also including the login token.
Now the next step is, that after user gave permission for that (by authenticating), I want to check, if the user subscribed to a specific channel on Youtube (and afterwards saving that information to my DB, printing it at the first step would be enough though).
Now I did my homework for multiple hours in trying to figuring out how it works...
What I (in general found) is that the following curl request should give me the desired result:
curl \
'https://youtube.googleapis.com/youtube/v3/subscriptions?part=snippet%2CcontentDetails&forChannelId=UC_x5XG1OV2P6uZZ5FSM9Ttw&mine=true&key=[YOUR_API_KEY]' \
--header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
--header 'Accept: application/json' \
--compressed
I then tried to sent this curl request with PHP, substituting the API KEY with my Google API Key and "YOUR_ACCESS_TOKEN" with the token I got from OAUTH.... However, it's throwing an error, saying "request had insufficient authentication scopes"... That seems to be because when checking the PHP example from Google, I have to provide the Scopes I'm using - in my case https://www.googleapis.com/auth/youtube.readonly.
The PHP code provided by Google is the following:
<?php
/**
* Sample PHP code for youtube.subscriptions.list
* See instructions for running these code samples locally:
* https://developers.google.com/explorer-help/guides/code_samples#php
*/
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new Exception(sprintf('Please run "composer require google/apiclient:~2.0" in "%s"', __DIR__));
}
require_once __DIR__ . '/vendor/autoload.php';
$client = new Google_Client();
$client->setApplicationName('API code samples');
$client->setScopes([
'https://www.googleapis.com/auth/youtube.readonly',
]);
// TODO: For this request to work, you must replace
// "YOUR_CLIENT_SECRET_FILE.json" with a pointer to your
// client_secret.json file. For more information, see
// https://cloud.google.com/iam/docs/creating-managing-service-account-keys
$client->setAuthConfig('YOUR_CLIENT_SECRET_FILE.json');
$client->setAccessType('offline');
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open this link in your browser:\n%s\n", $authUrl);
print('Enter verification code: ');
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Define service object for making API requests.
$service = new Google_Service_YouTube($client);
$queryParams = [
'forChannelId' => 'UC_x5XG1OV2P6uZZ5FSM9Ttw',
'mine' => true
];
$response = $service->subscriptions->listSubscriptions('snippet,contentDetails', $queryParams);
print_r($response);
This let's me run into a new issue... Trying to use this code, I'm getting the error, that Google_Client is not known as class... I then went ahead and installed Google Client with Composer and tried to use vendor/autoload.php in order to use the class.... However, when including the autoload.php, I get the error Fatal error: Cannot declare class Prefab, because the name is already in use... This seems to be the case, because the f3-opauth declares this Prefab class already and then the google apiclient tries to declare it again... However, I didn't manage to to include google apiclient without the autoload...
You see, I really tried a lot and I've been working on this for about 5-6 hours today, only getting that one API request to work and I don't know what else to try...
Any hint on how to get it working would be appreciated - if there's any hint on doing it a completely other way, I'd be willing to change it as well, as the project itself just started.
Summarizing, what I'm trying to do is the following:
-> User can log in on Website with his Youtube/Google Account
-> When authenticating, its checked, if the User is a Subscriber of a specific channel. Next step would be to also check, if he is a channel member of this speicific channel. Both information would need to be saved to database
-> after that, user can always log in into his account with Google again and in the database, you can find the information if the user is subscriber and/or channel member of this channel..
Thanks in advance!
I'm not sure if this will help with your exact use case, but I've worked with Google APIs in the past with Fat-Free. I couldn't get it to work right off the bat, so I installed and got it working with the Google Client/API/SDK. Once I got that working, then I worked backwards to see if I could make it work with Fat-Free. One of the things that I noticed I was running into was missing fields in the Oauth request. access_type was one that got me as well as approval_prompt. I know that you said you've gotten your access token thus far, so it may not apply, but it could for future requests. Here's some example code I've got working to generate an oauth URL for Google Sign in, and then to process the request and make the call to the userinfo portion.
<?php
class App_Auth {
public static function generateOauthUrl() {
$fw = Base::instance();
$Oauth = new \Web\OAuth2();
$Oauth->set('client_id', $fw->get('google.client_id'));
$Oauth->set('scope', 'profile email');
$Oauth->set('response_type', 'code');
$Oauth->set('access_type', 'online');
$Oauth->set('approval_prompt', 'auto');
$Oauth->set('redirect_uri', $fw->SCHEME.'://' . $_SERVER['HTTP_HOST'] . $fw->BASE.'/oauthRedirect');
return $Oauth->uri('https://accounts.google.com/o/oauth2/auth', true);
}
public static function processAuthCodeAndGetToken($auth_code) {
$fw = Base::instance();
$Oauth = new \Web\OAuth2();
$Oauth->set('client_id', $fw->get('google.client_id'));
$Oauth->set('client_secret', $fw->get('google.client_secret'));
$Oauth->set('scope', 'profile email');
$Oauth->set('access_type', 'online');
$Oauth->set('grant_type', 'authorization_code');
$Oauth->set('code', $auth_code);
$Oauth->set('approval_prompt', 'auto');
$Oauth->set('redirect_uri', $fw->SCHEME.'://' . $_SERVER['HTTP_HOST'] . $fw->BASE.'/oauthRedirect');
return $Oauth->request('https://oauth2.googleapis.com/token', 'POST');
}
public static function getOauthUserInfo($access_token) {
$Oauth_User_Info = new \Web\OAuth2();
return $Oauth_User_Info->request('https://www.googleapis.com/oauth2/v2/userinfo', 'GET', $access_token);
}
One other error that has bitten me in the backside was we would get our access token from Google and then store it in the database for subsequent requests. We would get that scopes error you mentioned request had insufficient authentication scopes. We eventually figured out that the access_token was longer than our database field (VARCHAR(32) if I remember right) so we needed to make our database field longer so it would store the whole thing.
Hopefully one of those triggers something for you to figure out your issue.

How to create project in Google Console Cloud platform using PHP Lib programmatically?

I am trying to create a project in the Google console cloud using the PHP client library.
I copied this sample code from https://cloud.google.com/resource-manager/reference/rest/v1/projects/create#php
Steps taken/ Got the issue:
This line " $requestBody = new \Google_Service_CloudResourceManager_Project(); ".
Throwing error : 'Class Google_Service_CloudResourceManager_Project not found'.
Then I checked in the "Try this API" menu, we can pass the JSON to API with Google API Explorer. I tested with Google API Explorer and the results are working fine. (See screenshot)
Commenting this line "$requestBody = new \Google_Service_CloudResourceManager_Project();"
and trying to pass the json required to create method ( as i have checked in "Try this API" menu).
Throwing error : Call to a member function create() on null at this line "$response = $service->projects->create($requestBody);".
My Google OAuth script is working fine, only issue with this project create script
PHP Script:
$client = new \Google_Client();
$client->setApplicationName('Google-CloudResourceManagerSample/0.1');
//$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/cloud-platform');
$service = new \Google_Service_CloudResourceManager($client);
// TODO: Assign values to desired properties of `requestBody`:
//$requestBody = new \Google_Service_CloudResourceManager_Project();
$requestBody = '{
"name": "bob kris project 2",
"projectId": "bk-project-290016"
}';
$response = $service->projects->create($requestBody);
// TODO: Change code below to process the `response` object:
echo '<pre>', var_export($response, true), '</pre>', "\n";
die;
It seems that this is a Google internal issue. I recreated your scenario and have the same result. I contacted a Cloud App Engine engineering team and redirected your request. Also, we have already opened a public ticket, and all communication with Google will continue there.

How to authenticate google-indexing with a service account on a Drupal site

I'm trying to use the google indexing API on a Drupal site. I keep getting a 403 permission denied error.
I've enabled the API, created a service account, verified the site ownership using a meta tag, set owner permission to the service account and have downloaded the google-api-php-client library to make things easier. I put the php file on the server. When I go to the page, I get a 403 error. Permission denied.
require_once DRUPAL_ROOT . '/google-api-php-client/vendor/autoload.php';
//Set up service account credentials
putenv('GOOGLE_APPLICATION_CREDENTIALS='. DRUPAL_ROOT . '/myjsonfile.json');
$client = new Google_Client();
// service_account_file.json is the private key that you created for your service account.
//-----USING DEFAULT CREDENTIALS SET BY JSON FILE INSTEAD-----
$client->useApplicationDefaultCredentials();
$client->addScope('https://www.googleapis.com/auth/indexing');
// Get a Guzzle HTTP Client
$httpClient = $client->authorize();
$endpoint = 'https://indexing.googleapis.com/v3/urlNotifications:publish';
// Define contents here. The structure of the content is described in the next step.
$content = "{
\"url\": \"urlToUpdate\",
\"type\": \"URL_UPDATED\"
}";
$response = $httpClient->post($endpoint, [ 'body' => $content ]);
$status_code = $response->getStatusCode();
Edit: I have also tried using the $client->setAuthConfig() method as shown on googles documentation shown here: Google indexing api
Here is alternate code following google api
require_once DRUPAL_ROOT . '/google-api-php-client/vendor/autoload.php';
$client = new Google_Client();
// service_account_file.json is the private key that you created for your service account.
$client->setAuthConfig('myjsonfile.json');
$client->addScope('https://www.googleapis.com/auth/indexing');
// Get a Guzzle HTTP Client
$httpClient = $client->authorize();
$endpoint = 'https://indexing.googleapis.com/v3/urlNotifications:publish';
// Define contents here. The structure of the content is described in the next step.
$content = "{
\"url\": \"urlToUpdate\",
\"type\": \"URL_UPDATED\"
}";
$response = $httpClient->post($endpoint, [ 'body' => $content ]);
$status_code = $response->getStatusCode();
I've found the answer to my problem a while back, so I'm going to post the answer here. To my ire, the reason it wasn't authenticating, was because I registered the http://url instead of the https://url in the google console. So it did not recognize me as an owner of the site. The code is fine, just quadruple check to make sure you register the service account correctly.

Error 500 when using Google_PredictionService Google API sample

Updated:
My project is to be able to provide a web based application which allows the visitor to upload/download/delete files using GoogleDrive. The project requires it to be server based, which does not require credentials from the user to be able to perform these functions.
In a nutshell, the web application stores the files on a single dedicated google drive account, instead of storing the files on the server.
I researched Google's developer site, and was directed to using the example below as a starting point, to configure the PHP application to use the Drive Account I set up.
I followed the instructions per Google's page:
https://code.google.com/p/google-api-php-client/wiki/OAuth2#Service_Accounts
When I execute this script, I am receiving the following 500 error:
PHP Catchable fatal error: Argument 3 passed to
Google_HostedmodelsServiceResource::predict() must be an instance of
Google_Input, none given, called in
/data/sites/scott/htdocs/dfs_development/drive/serviceAccount.php on
line 62 and defined in
/data/sites/scott/htdocs/dfs_development/apis/google-api-php-client/src/contrib/Google_PredictionService.php
on line 36
What am I doing wrong here? I am uncertain what $project variable should hold, and it seems the predict() function needs 3 args, however I am at a loss to know what it should be.
Here is my code, which I obtained from the URL above. Thank you in advance for your response.
require_once '../apis/google-api-php-client/src/Google_Client.php';
require_once '../apis/google-api-php-client/src/contrib/Google_PredictionService.php';
// Set your client id, service account name, and the path to your private key.
// For more information about obtaining these keys, visit:
// https://developers.google.com/console/help/#service_accounts
const CLIENT_ID = '##########.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = '#########developer.gserviceaccount.com';
// Make sure you keep your key.p12 file in a secure location, and isn't
// readable by others.
const KEY_FILE = 'pathto/secretlystored/######-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName("My Google Drive");
// Set your cached access token. Remember to replace $_SESSION with a
// real database or memcached.
session_start();
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
// Load the key in PKCS 12 format (you need to download this from the
// Google API Console when the service account was created.
$key = file_get_contents(KEY_FILE);
$client->setAssertionCredentials(new Google_AssertionCredentials(
SERVICE_ACCOUNT_NAME,
array('https://www.googleapis.com/auth/prediction'),
$key)
);
$client->setClientId(CLIENT_ID);
$service = new Google_PredictionService($client);
// Prediction logic:
$id = 'dfslocalhost';
$predictionData = new Google_InputInput();
$predictionData->setCsvInstance(array('Je suis fatigue'));
$input = new Google_Input();
$input->setInput($predictionData);
$result = $service->hostedmodels->predict($id, $input); ## 500 ERROR occurs here..
print '<h2>Prediction Result:</h2><pre>' . print_r($result, true) . '</pre>';
// We're not done yet. Remember to update the cached access token.
// Remember to replace $_SESSION with a real database or memcached.
if ($client->getAccessToken()) {
$_SESSION['token'] = $client->getAccessToken();
}
thats because Google_PredictionService API has not actived in your google API console dev.

Categories