I've been having an issue with the Webmaster Tools API. I am trying to make the script have no user interaction and get information that I need. I've got Google Analytics working with Service Accounts but this isn't supported for the Webmaster Tools.
I'm currently trying to use a API Server Key however when I try to query the API it returns :
Code 403:
"User does not have sufficient permission for site"
However I am owner of the site I am trying to query. I have checked www.google.com/webmasters/tools/home and the site is verified.
So I'm asking is my code correct?
$KEY_FILE_LOCATION = "privateKey.json";
$viewID = "view id"; //Website View ID - including ga:
$scopes = array(
"https://www.googleapis.com/auth/analytics.readonly",
"https://www.googleapis.com/auth/webmasters.readonly"
);
$emailAddr = 'Email'; //Got off google developer console
$apiKey = 'API Server Key'; //Got off google developer console
//Create Google Client
$client = new Google_Client();
$client->setApplicationName('Logging in Attempt');
$client->setAuthConfig($KEY_FILE_LOCATION);
$client->setScopes($scopes);
$client->setAccessType('offline');
$client->setDeveloperKey($apiKey);
//Creating Webmaster Service
$webmastersService = new Google_Service_Webmasters($client);
//Creating Request
$request = new Google_Service_Webmasters_SearchAnalyticsQueryRequest();
$request->setStartDate('2016-07-01');
$request->setEndDate('2016-07-10');
$request->setDimensions( array('query') );
$requestWebsite = 'Website'; //The website I have access to
//Querying Webmaster
$qsearch = $webmastersService->searchanalytics->query($requestWebsite, $request);
$rows = $qsearch->getRows();
echo "<pre>",print_r($rows),"</pre>";
Found out where I went wrong. The code was fine, the problem was that on the search console. The website was verified however I needed to add the email address from the Service Account into the website and gave it restricted access. Once that was in there the script worked.
Related
I have created my google service account and using it to make API calls. I am submitting site via API call at search console, call successfully completed with status 204 but site is not coming up in google search console UI.
Request URL is here
https://www.googleapis.com/webmasters/v3/sites/siteUrl
Here is my code
$client = new Google_Client();
$client->setAuthConfig('google-meta-search.json'); //Using service account credentials
$client->addScope('https://www.googleapis.com/auth/webmasters');
$request = new Google_Service_Webmasters($client);
$resultsGoogle = $request->sites->add('https://whatyouplay.com');
//List the added sites - check out the attached screenshot
$list = $googlerequest->sites->listsites();
OUTPUT:
I'm creating an AI Assistant using Dialogflow and I need to use Google APIs (google calendar and gmail). The APIs were working perfectly (I used this as reference). However, when I integrated my code with the dialogflow webhook, it returns Webhook Call failed. Error: 500 Internal Server Error.
here is a code snippet:
$client = new Google_Client();
$client->addScope(Google_Service_Gmail::GMAIL_READONLY); //view your emails and settings
$client->addScope(Google_Service_Gmail::GMAIL_COMPOSE); //manage drafts and send emails
$client->addScope(Google_Service_Gmail::GMAIL_MODIFY);
$client->addScope(Google_Service_Gmail::GMAIL_SEND); //send email on your behalf
$client->addScope(Google_Service_Calendar::CALENDAR); //manage calendar
$client->setAuthConfig('client_secret.json');
$client->setAccessType('offline');
$client->setApprovalPrompt('auto');
if($_SERVER['REQUEST_METHOD'] == 'POST'){
if(isset($_SESSION['access_token']) && $_SESSION['access_token']){
$client->setAccessToken($_SESSION['access_token']);
$gmail = new Google_Service_Gmail($client);
$user = "emailaddress#gmail.com";
$calendar = new Google_Service_Calendar($client);
$intent = $json->queryResult->intent->displayName;
$location_any = $json->queryResult->parameters->location_any;
$text = $json->queryResult->parameters->text;
$name = $json->queryResult->parameters->name;
$choice = $json->queryResult->parameters->choice;
$subject = $json->queryResult->parameters->subject;
$location = $json->queryResult->parameters->location;
$description = $json->queryResult->parameters->description;
$startDateTime = $json->queryResult->parameters->startDateTime;
$endDateTime = $json->queryResult->parameters->endDateTime;
if($intent== "UnreadMessages"){
$unread = unReadMessages($gmail, $user);
$speech = "You have ".$unread." messages";
}
else if($intent == "GetSchedule"){
$events = get_event($calendar);
if($events){
$reply = "You have the following events coming up:";
foreach($events as $event){
$eventName = $event['eventName'];
$eventTime = $event['time'];
$reply .= $eventName."is at".$eventTime;
}
$speech = $reply;
}
else{
$speech = "You don't have any events coming up.";
}
}
}
I'm suspecting it may be because of the authentication process that's required everytime I try to run the app, since the error only starts popping up whenever I check for session tokens. My problem now is how do I remove this authentication process?
You have several serious issues with your approach here, but most of them result from you treating the interaction with the Google Assistant like it was a browser hitting your web page. Although Actions on Google uses HTTPS and a webhook, it is otherwise not really like a browser at all.
For example, you check $_SESSION to see if an access token has already been set. $_SESSION is typically implemented by setting a session ID in the browser with a session cookie. The Assistant doesn't use cookies at all. Although it has a userStorage object which can be used it similar ways, this is accessed very differently.
It isn't clear if this is what is causing the error, or if the problem is related here somewhere. If you do have error logs, this would be useful to include in the question.
There is a lot that remains unclear. Primarily - where does the auth token come from in the first place in your code.
In a purely web-based OAuth scheme, you'll direct the user to log in using Google Sign In and, as part of that process, request authorization to access their Drive and GMail. Google Sign In for the Assistant doesn't allow you to do that - all it gives you is an Identity Token.
You can use Account Linking to link the Assistant account to your system - but this requires you to have an OAuth server that generates the auth token that the Assistant will give back to you. This is your OAuth token - not one that comes from Google (unless you're proxying it).
If you have a web-based way to get authorization, you can leverage this to provide access through the Assistant as well using Google Sign In for the Assistant.
I have created service account and below is my code:
$client = new Google_Client();
$client->setApplicationName("Console_Client");
$client->setAuthConfigFile('xxaax.json');
$scopes = [
//"https://www.googleapis.com/auth/webmasters",
//"https://www.googleapis.com/auth/webmasters.readonly"
Google_Service_Webmasters::WEBMASTERS_READONLY,
Google_Service_Webmasters::WEBMASTERS,
];
$client->setScopes($scopes);
$client->setAccessType('offline');
$service = new Google_Service_Webmasters($client);
$request = new Google_Service_Webmasters_SearchAnalyticsQueryRequest();
$optParams = array('siteUrl' => 'https://www.test.co/');
$request->startDate = "2018-01-01";
$request->endDate = "2018-01-02";
$results = $service->searchanalytics->query($optParams, $request);
I'm receiving this error message in response:
PHP Fatal error: Uncaught Google_Service_Exception
"reason": "insufficientPermissions"
I have enabled this api in my account and am also able to hit it when trying google API explorer.
Why is this occurring?
For this we need to create service account. This is preferable in the case when you are hitting API from console and you don't have any web UI for OAuth2.0.
For this particular case, there is service account Id (looks like long string email). Copy this and add it to your google account.
Doing above solved my problem.
This step was not clear in google API docs.
Hope this helps someone in future.
I have managed to obtain info from an "view" using php in the google analytics, however it only works if i authenticate with the google account, otherwise it displays the following error:
"Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST https://analyticsreporting.googleapis.com/v4/reports:batchGet: (403) User does not have sufficient permissions for this profile.'"
what i need basically is to find a way of obtaining the "view info" without authenticating, since i have a custom cms and i need to show this info in the cms admin section
Here is my code:
<?php
session_start();
require_once 'google-api-php-client/src/Google/autoload.php';
$client = new Google_Client();
$client->setAuthConfigFile('pathToFile.json');
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
// If the user has already authorized this app then get an access token
// else redirect to ask the user to authorize access to Google Analytics.
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
// Create an authorized analytics service object.
$analytics = new Google_Service_AnalyticsReporting($client);
// Call the Analytics Reporting API V4.
$response = getReport($analytics);
// Print the response.
$info = printResults($response);
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/api/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
function getReport(&$analytics) {
// Replace with your view ID. E.g., XXXX.
$VIEW_ID = "VIEW_ID_NUMBER";
// Create the DateRange object.
$dateRange = new Google_Service_AnalyticsReporting_DateRange();
$dateRange->setStartDate("2016-01-01");
$dateRange->setEndDate("today");
// Create the Metrics object.
$sessions = new Google_Service_AnalyticsReporting_Metric();
$sessions->setExpression("ga:goalCompletionsAll");
$sessions->setAlias("objetivos");
//Create the Dimensions object.
$medium = new Google_Service_Analyticsreporting_Dimension();
$medium->setName("ga:medium");
$minute = new Google_Service_Analyticsreporting_Dimension();
$minute->setName("ga:minute");
$hour = new Google_Service_Analyticsreporting_Dimension();
$hour->setName("ga:hour");
$date = new Google_Service_Analyticsreporting_Dimension();
$date->setName("ga:date");
$day = new Google_Service_Analyticsreporting_Dimension();
$day->setName("ga:day");
$goals = new Google_Service_Analyticsreporting_Metric();
$goals->setExpression("ga:goalStartsAll");
// Create the ReportRequest object.
$request = new Google_Service_AnalyticsReporting_ReportRequest();
$request->setViewId($VIEW_ID);
$request->setDateRanges($dateRange);
$request->setDimensions(array($medium, $date, $hour, $minute));
$request->setMetrics(array($sessions, $goals));
$body = new Google_Service_AnalyticsReporting_GetReportsRequest();
$body->setReportRequests( array( $request) );
return $analytics->reports->batchGet( $body );
}
?>
any info regarding this subject is greatly appreciated.
thanks
You can use a service account to access Google Analytics data without the Google authentication screen.
Create a service account and key
In the Google API Console (https://console.developers.google.com/), navigate to the Credentials tab. Under Create credentials, select Service account key. Choose a nice name and under Role I selected Project-->Viewer, which I can confirm to work. Under Key type, select JSON and click the Create button. A JSON file is downloaded to your system which you should look after since it's the only copy. You can't download it again later, so losing it will render that service account useless.
Give the account access to the Google Analytics view's data
The JSON file contains the Google Account (an e-mail address ending with iam.gserviceaccount.com). Copy that e-mail address and give it Read and analyze permissions on the Google Analytics view you want to have access to.
To get any information about GA you need to authenticate yourselfself.
If you do not want to use authentification path with the pop up windows you can use the "p12 key" to workaround this issue. The p12 files need to be attached to you request and there is no need to be logged (this is the solution for server side application), but this only work with your own data, so the ownder of the p12 key need to have access The desired account
https://developers.google.com/analytics/devguides/reporting/core/v4/authorization
Check this to know how to get the p12
https://webapps.stackexchange.com/questions/58411/how-where-to-obtain-a-p12-key-file-from-the-google-developers-console
I want my server to access a gmail account with php code. And the following is what I created with the examples I can find online.
<?php
session_start();
require_once dirname(dirname(__FILE__)) . '/utility/google-api-php-client/src/Google/autoload.php';
$json_file_location = 'Gmail-YQXB-7c754a18211a.json';
$client = new Google_Client();
$service = new Google_Service_Books($client);
$sgmail = new Google_Service_Gmail($client);
$scopes = array('https://www.googleapis.com/auth/books', 'https://mail.google.com');
if (isset($_SESSION['service_token'])) {
$client->setAccessToken($_SESSION['service_token']);
}
$cred = $client->loadServiceAccountJson($json_file_location, $scopes);
$client->setAssertionCredentials($cred);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$_SESSION['service_token'] = $client->getAccessToken();
$optParams = array('filter' => 'free-ebooks');
$results = $service->volumes->listVolumes('Henry David Thoreau', $optParams);
echo "<h3>Results Of Call:</h3>";
foreach ($results as $item) {
echo $item['volumeInfo']['title'], "<br /> \r\n";
}
$msg = $sgmail->users_messages->listUsersMessages('me');
var_dump($msg);
?>
The code works except the last request, which will throw something like:
PHP Fatal error: Uncaught exception 'Google_Service_Exception' with
message 'Error calling GET
https://www.googleapis.com/gmail/v1/users/me/messages: (400) Bad
Request' in
C:\inetpub\wwwroot\utility\google-api-php-client\src\Google\Http\REST.php:110
$msg = $sgmail->users_messages->listUsersMessages('me');
This account is a Service Account. I could make it working if I use a Web application type Client ID. Just don't know what is wrong here.
You should not be using a service account if you just want to access one account (your own). Service accounts are their own account and they're not Gmail accounts. They work well for APIs that don't need a user (e.g. maps, search) or when you are using a Google Apps for Work domain and want delegation enabled for all users in the domain (by domain admin, so you don't need individual user authorization).
You want to use standard oauth2 web auth flow. If you want to make sure it's usable offline (e.g. by some script/service/cron job) then make sure you add the offline flag on your oauth2 authorization web flow request and that'll make sure you get a permanent refresh token (can be used to request an access token). If you don't set offline, then it's an access token which is only good for an hour. See https://developers.google.com/gmail/api/auth/web-server for more details.