I want to create a small bot, which can push G+ moments to G+ page under certain conditions. Want to try it with PHP. So I have: registered web app in Google Console, Google+ API turned on, small PHP-script on my Apache server and 401 Unathorized in result. I'm using google-api-php-client from https://github.com/google/google-api-php-client
I've searched answer through the Internet, but nothing've found. Everywhere everyone have had their own happy end and all worked, but I've try all of it - and only 401 came to me.
My script:
<?
header("Content-Type: text/html; charset=utf-8");
session_start();
ini_set("display_errors", 1);
require_once 'Google/Client.php';
require_once 'Google/Service/Plus.php';
$client = new Google_Client();
$client->setClientId("MY_CLIENT_ID");
$client->setClientSecret("MY_CLIENT_SECRET");
$client->setRedirectUri("REDIRECT_URL");
$client->setAccessType('offline');
$client->addScope("https://www.googleapis.com/auth/plus.login");
$client->addScope("https://www.googleapis.com/auth/plus.me");
$client->addScope("https://www.googleapis.com/auth/userinfo.profile");
$client->addScope("https://www.googleapis.com/auth/userinfo.email");
$requestVisibleActions = array('http://schemas.google.com/AddActivity');
$client->setRequestVisibleActions($requestVisibleActions);
if (!isset($_GET['code'])) {
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
$moment_body = new Google_Service_Plus_Moment();
$plus = new Google_Service_Plus($client);
$moment_body->setType("http://schemas.google.com/AddActivity");
$item_scope = new Google_Service_Plus_ItemScope();
$item_scope->setId("target-id-214wdefsadf1");
$item_scope->setType("http://schemas.google.com/AddActivity");
$item_scope->setName("The Google+ Platform");
$item_scope->setDescription("A page that describes just how awesome Google+ is!");
$item_scope->setImage("https://developers.google.com/+/plugins/snippet/examples/thing.png");
$moment_body->setTarget($item_scope);
$momentResult = $plus->moments->insert('me', 'vault', $moment_body);
} else {
$authUrl = $client->createAuthUrl();
header("Location: ".$authUrl);
exit;
}
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
header("Location: REDIRECT_URL");
exit;
}
So script succefully requests all needed access accordingly to scopes registered in client, gets a token, writes it into session, but when it try to insert new moment it gets Fatal error: Uncaught exception 'Google_Service_Exception' with message 'Error calling POST https://www.googleapis.com/plus/v1/people/me/moments/vault: (401) Unauthorized' in /var/www/rico/Google/Http/REST.php:79
What is wrong? And I've try some solutions placed here, on stackoveflow, but they didn't help. I also checked my authURL - it seems OK, with correct request_visible_actions and other... I don't know what is wrong...
You may be missing a few things. Maybe your example assumes you are putting the real values for some of these you have set. However you will want ApplicationName and DeveloperKey set. Many api calls will return not authorized if you don't have the developer key set for sure.
$client->setApplicationName($plApp->authenticationData->applicationName);
$client->setDeveloperKey($authData->apiKey);
I presume you are actually setting these below. Return url must match that which was set for the application on the google developer site for the specific application
$client->setClientId($authData->clientId);
$client->setClientSecret($authData->clientSecret);
$client->setRedirectUri($returnUrl);
Related
I have implemented sign-in with google for my client using google-api-php-client-2.4.0.
The implementation was quite straight forward from the documentations. I have used the following code and it is working fine. The flow is (a)set the credentials and the scopes, (b) redirect to google url, (c) google provides a code (d) get token from code (e) get the required info using the token.
require_once("../../plugins/server/google-api-php-client-2.4.0/vendor/autoload.php");
$client = new Google_Client();
$client->setClientId('*****');
$client->setClientSecret('*****');
$client->setRedirectUri("*****");
$client->addScope("email");
$client->addScope("profile");
if (isset($_GET['code']))
{
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
$client->setAccessToken($token['access_token']);
//get profile info
$google_oauth = new Google_Service_Oauth2($client);
$google_account_info = $google_oauth->userinfo->get();
print_r($google_account_info);
}
else
{
$authUrl = $client->createAuthUrl();
header('Location: ' . $authUrl);
exit;
}
Though the above code I used is working fine, I am not sure whether this is the correct approach. I am confused because, many code samples available in internet, uses the following approach to get the token. i.e., it does not use the token directly from the code. Instead, it is again redirecting to the same page and using the token.
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
exit;
}
if ($client->getAccessToken()) {
$token_data = $client->verifyIdToken();
}
Can you help me to confirm whether my approach is fine and I can go ahead with it. Thanks.
Note: I could see from the code of the library, authenticate is deprecated method. Therefore, may be the code samples available in internet are old.
I have a login script created which allows you to login through the Google API. Everything works fine and the redirect back to my website does also work.
Here is my script for the oauth callback:
<?php
require_once 'google-api-php-client-2.2.1/vendor/autoload.php';
session_start();
if (isset ($_GET["error"])) {
header('Location: #');
}
if (isset ($_GET["code"])) {
$client = new Google_Client();
$client->authenticate($_GET['code']);
$_SESSION['g_access_token'] = $client->getAccessToken();
$redirect = "http://".$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset ($_SESSION["g_access_token"])) {
$plus = new Google_Service_Plus($client);
$client->setAccesToken($_SESSION["g_access_token"]);
$me = $plus->people->get('me');
$_SESSION["unid"] = $me["id"];
$_SESSION["g_name"] = $me["displayName"];
$_SESSION["email"] = $me["emails"][0]["value"];
$_SESSION["g_profile_image_url"] = $me["image"]["url"];
$_SESSION["g_cover_image_url"] = $me["cover"]["coverPhoto"]["url"];
$_SESSION["g_profile_url"] = $me["url"];
}
?>
I dont get any error, but the session variables are still undefined. Where is the problem?
I just read and watched lots of tutorials, but still dont get it. Maybe somebody can help me here!
Thank you :)
EDIT
I just debugged my code and now I know that the Session Variable 'g_access_token' is empty after the login. So the main reason why it doesnt work should be the authentication. But I still dont know how to solve that...
I've just come from dealing successfully with Google OAuth API for PHP. So far, your code doesn't seem broke. Anyhow, it'd be nice to check your config file from which you get the class new Google_Client().
As that file is not posted in your question, i recommend you to follow this one, and call it through require_once to whenever you need it:
<?php
session_start();
require_once "GoogleAPI/vendor/autoload.php";
$gClient = new Google_Client();
$gClient->setClientId("your_client_id_comes_here");
$gClient->setClientSecret("your_client_secret");
$gClient->setApplicationName("CPI Login Tutorial");
$gClient->setRedirectUri("your_authorized_uri.php");
//addScope sets the permissions you'll have in your app, whether it is only for displaying them or to handle as you desire (e.g.: store account's information, such as email givenName and so on, into your own db
$gClient->addScope("https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/plus.me");
?>
Also, don't you forget to enable the Google + API in your Google console. Finally, check that in your credentials, the "Authorized redirect URIs" contains the redirect uri you want the google api to callback once the user is authenticated.
I am novice to Google Analytics Api. I just started working on a small project where I want to pull data from the API and display it on each user’s Dashboard, using one single Google Analytics Account. I tried to follow the tutorial provided by google and made adjustments where required due to update to the library.
I am working on a codeigniter based platform and I was able to create a Google Client Object and also to make use of a refresh token which is saved in the database. I use the refresh token in order to have the data available on the dashboard without having to manually login every time.
The access token is there every time when I am logged in, and I can use it to set the client access token and create a Google Service Analytics object ($service = new Google_Service_Analytics($client);). I am printing the service and I can see the client id, client secret, etc and the access token being passed to it; but other like Google_Service_Analytics_DataGa_Resource Object are empty ( I do not know if they should be like that or not at this particular step ?).
When I am trying to request the user accounts
$accounts = $analytics->management_accounts->listManagementAccounts();,
I get a blank screen and my view is not being rendered.
I could not find such a problem being encountered before, so I am a bit confused why is happening. I do not get any error messages or anything that might point me to the cause of it or the right direction.
Note: I did managed to make it work using the same credentials trough JavaScript, but in this case it is not what I am looking for. I was able to retrieve data, display data in charts,etc using JS. I am new to making posts, so if anything is required from my part in order for you to have a better idea of what is going on, please do let me know.
I would greatly appreciate it I could get any indication to why that might be happening, or anything that would put me on the right path.
Codeigniter controller Class as follows
// Step 1 - Load PHP Client Libraries
require_once APPPATH.'libraries/Google/Client.php';
require_once APPPATH.'libraries/Google/Analytics.php';
class GoogleTest extends CI_Controller {
public function index(){
$this->load->helper(array('url','form'));
$this->load->model('googleapi_model'); //used to get the refresh token
// Step 2 - Start a session to persist credentials
session_start();
// Step 3 - Create and configure a new client object
$client = new Google_Client();
$client->setApplicationName("API Project");
// Insert client id, api key, client secret, project scope and redirect uri
$client->setDeveloperKey("***************");
$client->setClientId('********************');
$client->setClientSecret('******************');
$client->setRedirectUri('****************');
$client->setScopes(array('https://www.googleapis.com/auth/analytics.readonly'));
// Check if refresh token exists, it is used to login users automatically & it is being generated only once when you login the first time from the created
// google analytics app, this will take precedence to Step 4 or 6 below ;
if(count($this->googleapi_model->getGoogleRefreshToken()) > 0){
$db_refresh_token = $this->googleapi_model->getGoogleRefreshToken();
$client->refreshToken($db_refresh_token[0]->refreshtoken);
$_SESSION['token'] = $client->getAccessToken();
}else{
if ($client->getAccessToken()) {
$token = $client->getAccessToken();
$authObj = json_decode($token);
$refreshToken = $authObj->refresh_token;
if(isset($refreshToken) && $refreshToken != null){
$this->googleapi_model->insertGoogleRefreshToken($refreshToken);
}
}
}
//Step 4 - Handle authorization flow from the server
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
// Step 5 - Retrieve and use stored credentials
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
// Stept 6 - Either prompt the user to login or run the demo
if(!$client->getAccessToken()){
$authUrl = $client->createAuthUrl();
$this->data['auth'] = $authUrl;
}else{ //Create analytics service object
echo 'authenticated';
$analytics = new Google_Service_Analytics($client);
//TILL HERE MY CODE WORKS FINE, NO ERRORS, VIEW BEING RENDERED
$accounts = $analytics ->management_accountSummaries->listManagementAccountSummaries();
// $accounts = $analytics->management_accounts->listManagementAccounts();
echo '<pre>';
print_r($analytics);
echo '</pre>';
}
$this->data['content'] = '/public/dashboard/google_test';
$this->load->view('template/template', $this->data);
}
Make sure you're logged into the google account that API app is in.
And that you have clicked 'connect'.
Then run the script.
Also turn on error reporting (including notices)
I have to implement a way to upload video from our site to youtube. I already registered the app in Google Cloud and got all the necessary client ID, client secret code, browser key, redirect uri and server key. I also did turn ON the Youtube Data API V3, Google+ API, Freebase API and YouTube Analytics API as suggessted by various sites.
Here is my code below:
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_YouTubeService.php';
$client = new Google_Client();
$client->setApplicationName('Application Name');
$client->setClientId('CLIENT_ID');
$client->setClientSecret('CLIENT_SECRET_CODE');
$client->setRedirectUri('REDIRECT_URI');
$client->setDeveloperKey('DEVELOPER_KEY');
$youtube = new Google_YouTubeService($client);
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])){
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()){
$path_to_video_to_upload = $_FILES["video"]["tmp_name"];
$mime_type = $_FILES["video"]["type"];
$snippet = new Google_VideoSnippet();
$snippet->setTitle('Highlights');
$snippet->setDescription('Description Of Video');
$snippet->setTags(array('training', 'Soccer'));
$snippet->setCategoryId(17);
$status = new Google_VideoStatus();
$status->privacyStatus = "private";
$video = new Google_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
try {
$obj = $youtube->videos->insert("status,snippet", $video,
array("data"=>file_get_contents($path_to_video_to_upload),
"mimeType" => $mime_type));
} catch(Google_ServiceException $e) {
print "Caught Google service Exception ".$e->getCode(). " message is ".$e->getMessage()." <br>";
}
$_SESSION['token'] = $client->getAccessToken();
}
else{
$authUrl = $client->createAuthUrl();
print "<a href='$authUrl'>Connect Me!</a>";
}
I was referencing these codes from:
Upload video to Youtube using Youtube API V3 and PHP
and
http://www.dreu.info/blog/uploading-a-video-to-youtube-through-api-version-3-in-php/
First time I ran this code, it had me connect to the youtube account (with a screen asking to let google manage my YT account) and then on the second try, I got this 401 Message response.
Here's the response from youtube server
Caught Google service Exception 401 message is Error calling POST https://www.googleapis.com/upload/youtube/v3/videos?part=status%2Csnippet&uploadType=multipart&key=AIzaSyCCySI5cToH3sICTmhCEFHW7QkIDptsjXg: (401) Unauthorized
I tried to search for various solutions but to no avail I cant seem to find it.
Any help is appreciated, thanks!
follow-up question: Is the developer key the browser key or the server key? I am confused as to which should I use in my code. I've tried switching the keys and it also didn't work.
I had the exact same problem.
Check your youtube account. Do you have a channel created? If you don't you wont be able to add videos (via API or even in youtube).
After creating the channel in youtube it worked. no need for new code or new keys.
For Those who are getting the problem of Access Not Configured. Please use Google Developers Console to activate the API for your project,
code by #justine1234 is working perfectly fine. Just remove
$client->setDeveloperKey('DEVELOPER_KEY');
and run it.
Thanks a lot for the code #justine1234.
Regards
I want to write a PHP script that imports web stats data from GA. The script is accessible through a web front end (for triggering the import) and resides on a local server (127.0.0.1).
As I understood from the documentation is that there are two options for authenticating and using the core API:
API key - grants only access to statistics
OAuth2 - full authorization
If I understand the mechanics of OAuth2 correctly then this is not an option in my scenario because I cannot specify a callback URL. Hacky solutions come to my mind - like establishing a web profile authentication directly connecting to GA from the browser and then fetching the data by JavaScript and feeding it to the import script - but I would prefer to refrain from such solutions. Also because the browser interaction triggering the import process might be substituted with a cron job in the future.
The API key seems to be exactly what I want but the GET request from the browser fails.
GET request:
https://www.googleapis.com/analytics/v3/data/ga
?ids=ga:[profile ID]
&start-date=2013-01-01&end-date=2013-01-05
&metrics=ga:visits
&key=[the API key]
Response:
{
error: {
errors: [
{
domain: "global",
reason: "required",
message: "Login Required",
locationType: "header",
location: "Authorization"
}
],
code: 401,
message: "Login Required"
}
}
The URL though should be fine. Except for the key parameter it is the same as the one generated with http://ga-dev-tools.appspot.com/explorer/ which is also working (AOuth2 is used in that case). The API key is fresh.
Then again generating a new API key confronts me with the next inconveniency which is that apparently the key is only valid for a day.
So at the end of the day my question is this:
Is it possible to fetch data in the above described scenario without having to authenticate manually or generate API keys on a daily basis?
As already suggested, use this library: https://code.google.com/p/google-api-php-client/
but, instead of using oauth, create a service account from the api console (just select server application). This will provide you with a client id, an email that identify the service account, and *.p12 file holding the private key.
You then have to add the service account (the email) to your analytics as an admin user in order to get the data you need.
To use the service:
$client = new Google_Client();
$client->setApplicationName('test');
$client->setAssertionCredentials(
new Google_AssertionCredentials(
EMAIL,
array('https://www.googleapis.com/auth/analytics.readonly'),
file_get_contents(PRIVATE_KEY_FILEPATH)
)
);
$client->setClientId(CLIENT_ID);
$client->setAccessType('offline_access');
$analytics = new Google_AnalyticsService($client);
To get some data:
$analytics->data_ga->get(PROFILE_ID, $date_from, $date_to, $metrics, $optParams)
For the details check api docs. Also, be careful, there is a query cap (unless you pay)
I think to get this working, you need to use OAuth but with a slight modification to run it from server. Google calls this auth method "Using OAuth 2.0 for Web Server Applications"
As described on that page, you can use a PHP client library to get the authentication done. The client library is located here.
An example example on how to use this client library are on the same project's help pages. Note that you'll have to make some modifications to the code as the comments say to store the token in db and to refresh it regularly.
<?php
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_PlusService.php';
// Set your cached access token. Remember to replace $_SESSION with a
// real database or memcached.
session_start();
$client = new Google_Client();
$client->setApplicationName('Google+ PHP Starter Application');
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('insert_your_oauth2_client_id');
$client->setClientSecret('insert_your_oauth2_client_secret');
$client->setRedirectUri('insert_your_oauth2_redirect_uri');
$client->setDeveloperKey('insert_your_simple_api_key');
$plus = new Google_PlusService($client);
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$activities = $plus->activities->listActivities('me', 'public');
print 'Your Activities: <pre>' . print_r($activities, true) . '</pre>';
// We're not done yet. Remember to update the cached access token.
// Remember to replace $_SESSION with a real database or memcached.
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a href='$authUrl'>Connect Me!</a>";
}
I have a similar setup. The thing that you don't realize is that you can specify a http://localhost or http://127.0.0.1 or anything else as an origin and callback URL. You need to setup some web interface on your local server that initiates an OAuth setup for the user with the GA access. Note that this is one time. The callback handler must be something like this:
Note: The libraries used here are the same as the previous answer, the detailed code is in the wrapper.
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . '/content/business-intelligence';
if (isset($_GET['code'])) {
require_once 'GAPI.php';
$client = GAPI::init(); //create client instance of Google_Client
$client->authenticate(); //convert auth code to access token
$token = $client->getAccessToken();
$retVal = CF_GAPI::persistToken($token); //save token
if($retVal)
$redirect .= "?new_token";
else
$redirect .= "?bad_token";
}
header('Location: ' . $redirect); //redirect to bi index
Once you have saved the token saved, you must set it in the client before making requests to GA to get your analytics data. Like:
try {
$token = GAPI::readToken(); //read from persistent storage
} catch (Exception $e) {
$token = FALSE;
}
if($token == FALSE) {
$logger->crit("Token not set before running cron!");
echo "Error: Token not set before running cron!";
exit;
}
$client = GAPI::init(); //instance of Google_Client
$client->setAccessToken($token);
The GAPI::init() is implemented as follows:
$client = new Google_Client();
$client->setApplicationName(self::APP_NAME);
$client->setClientId(self::CLIENT_ID);
$client->setClientSecret(self::CLIENT_SECRET);
$client->setRedirectUri(self::REDIRECT_URI);
$client->setDeveloperKey(self::DEVELOPER_KEY);
//to specify that the token is stored offline
$client->setAccessType('offline');
//all results will be objects
$client->setUseObjects(true);
//tell that this app will RO from Analytics
$client->setScopes('https://www.googleapis.com/auth/analytics.readonly');
return $client;
My mysql table has columns like id, title, send_to_emails, frequency, dimensions, metrics, filters, profile_id which completely define each report to the generated from GA. You can play around with them using the documentation, list of metrics & dimensions and the sandbox tester that you already know about.