I'm using the Google PHP API. The documentation is rather lackluster... I want to allow users to connect their Google+ information and also use it to sign the users up in my database. In order to do that I need to get the email they use for their google account. I can't seem to figure out how to. It's easy enough in Facebook by forcing the permission when the users connect to my app. Anyone have any idea? This is the code I'm using to grab the users google+ profile and it works fine, except users may not have their email listed there.
include_once("$DOCUMENT_ROOT/../qwiku_src/php/google/initialize.php");
$plus = new apiPlusService($client);
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$me = $plus->people->get('me');
print "Your Profile: <pre>" . print_r($me, true) . "</pre>";
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
Without the users email address, it sort of defeats the purpose of allowing users to signup with Google+ Anyone more familiar with the Google API know how I can get it?
The UserInfo API is now supported by the Google API PHP Client.
Here's a small sample application:
http://code.google.com/p/google-api-php-client/source/browse/trunk/examples/userinfo/index.php
The important bit of the sample is here:
$client = new apiClient();
$client->setApplicationName(APP_NAME);
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setDeveloperKey(DEVELOPER_KEY);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/plus.me')); // Important!
$oauth2 = new apiOauth2Service($client);
// Authenticate the user, $_GET['code'] is used internally:
$client->authenticate();
// Will get id (number), email (string) and verified_email (boolean):
$user = $oauth2->userinfo->get();
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
print $email;
I'm assuming this snippet was called with a GET request including the authorization code. Remember to include or require apiOauth2Service.php in order for this to work. In my case is something like this:
require_once 'google-api-php-client/apiClient.php';
require_once 'google-api-php-client/contrib/apiOauth2Service.php';
Good luck.
Updated with today's API:
$googlePlus = new Google_Service_Plus($client);
$userProfile = $googlePlus->people->get('me');
$emails = $userProfile->getEmails();
This assumes the following:
You've authenticated the current user with the proper scopes.
You've set up $client with your client_id and client_secret.
Forgive me if I'm missing something, but how do you know what Google account to link them with if you don't have their email address? Usually, you'd prompt the user to enter their Google Account's email in order to find their profile in the first place.
Using OAuth2, you can request permissions through the scope parameter. (Documentation.) I imagine the scopes you want are https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/userinfo.profile.
Then, it's a simple matter to get the profile info once you've obtained your access token. (I assume you've been able to redeem the returned authorization code for an access token?) Just make a get request to https://www.googleapis.com/oauth2/v1/userinfo?access_token={accessToken}, which returns a JSON array of profile data, including email:
{
"id": "00000000000000",
"email": "fred.example#gmail.com",
"verified_email": true,
"name": "Fred Example",
"given_name": "Fred",
"family_name": "Example",
"picture": "https://lh5.googleusercontent.com/-2Sv-4bBMLLA/AAAAAAAAAAI/AAAAAAAAABo/bEG4kI2mG0I/photo.jpg",
"gender": "male",
"locale": "en-US"
}
There's got to be a method in the PHP library to make that request, but I can't find it. No guarantees, but try this:
$url = "https://www.googleapis.com/oauth2/v1/userinfo";
$request = apiClient::$io->makeRequest($client->sign(new apiHttpRequest($url, 'GET')));
if ((int)$request->getResponseHttpCode() == 200) {
$response = $request->getResponseBody();
$decodedResponse = json_decode($response, true);
//process user info
} else {
$response = $request->getResponseBody();
$decodedResponse = json_decode($response, true);
if ($decodedResponse != $response && $decodedResponse != null && $decodedResponse['error']) {
$response = $decodedResponse['error'];
}
}
}
Anyway, in the code you posted, just pass the desired scope to createAuthUrl():
else {
$authUrl = $client->createAuthUrl("https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile");
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
Related
I've managed to set up a PHP script that grabs data from our Google Analytics account and can run this great in the browser but I'm struggling to figure out how to allow this to work inside of the cronjob script instead.
Here's my code:
<?php
// Load the Google API PHP Client Library.
require_once dirname(__FILE__) . '/analytics/google-api-php-client-2.2.0/vendor/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfig(dirname(__FILE__) . '/analytics/client_secrets.json');
$client->setAccessType("offline"); //offline access
$client->addScope(Google_Service_Analytics::ANALYTICS_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
print "<br />start: ".date("H:i:s")."<br />";
// Set the access token on the client.
$client->setAccessToken($_SESSION['access_token']);
$sessionid = $_SESSION['access_token']['access_token'];
// Create an authorized analytics service object.
$analytics = new Google_Service_AnalyticsReporting($client);
$view_id = urlencode("ga:XXXXXX");
$start_date = "yesterday"; //can be words or dates in Y-m-d
$end_date = "yesterday"; //can be words or dates in Y-m-d
$metrics = urlencode("ga:transactions");
$dimensions = urlencode("ga:transactionId,ga:date,ga:orderCouponCode");
$sort = "ga:date"; //for DESC use -FIELD e.g. -ga:date
$sampling = "HIGHER_PRECISION"; //https://developers.google.com/analytics/devguides/reporting/core/v3/reference#samplingLevel
$limit = "10000";
$filters = urlencode("ga:orderCouponCode!=(not set)");
$params = "ids=$view_id&start-date=$start_date&end-date=$end_date&metrics=$metrics&dimensions=$dimensions&filters=$filters&sort=$sort&samplingLevel=$sampling&max-results=$limit&access_token=$sessionid";
$data = file_get_contents("https://www.googleapis.com/analytics/v3/data/ga?$params");
$json_data = json_decode($data);
print "<pre>";
print_r($json_data);
print "</pre>";
} else {
// Handle authorization flow from the server.
if (! isset($_GET['code'])) {
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/cronjobs/ga_coupon_codes.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
}
print "<br />end: ".date("H:i:s")."<br />";
When my cronjob runs, the servers send me an email to say that it has finished running. I'm expecting to see both the "start" and "end" times printed in the response, as well as the JSON data, but the only thing that's coming back in the "end" time, leading me to believe it's not running through the main bit of it.
I know the main reason why it's not working is due to the authentication bit. In a cronjob I cannot use header('location: URL') but I can't figure out what to change this to in order to make it work.
When I set up the account, it was created as a service account and I can see from within the API console that I have a service account key.
I've also got an OAuth 2.0 client ID (which is what is in the client screts JSON file). If I run this in my browser I'm getting the connection to work, even after the hour runs out (where it's getting a new access token).
I've googled around for this for quite some time and found that adding "offline access" should help but obviously I'm still using the header() function. I can't find examples for me to use that are understandable to me and I'd really like to get this working in a cronjob.
I am trying to get the organizations from a user with Google+ API or Google+ Domains API. I am following the steps on the official documentation and the logic I'm using is this one:
<?php session_start();
require_once 'vendor/autoload.php'; //INCLUDE PHP CLIENT LIBRARY
$scopes = array(
"https://www.googleapis.com/auth/plus.profiles.read",
"https://www.googleapis.com/auth/plus.me"
);
// Create client object and set its configuraitons
$client = new Google_Client();
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/');
$client->setAuthConfig("creds.json");
$client->addScope($scopes);
if( isset($_SESSION["access_token"]) ) {
$client->setAccessToken($_SESSION["access_token"]);
$service = new Google_Service_PlusDomains($client);
$me = $service->people->get('me');
var_dump($me);
echo "<br><br>*********************************************<br><br>";
$orgs = $me->getOrganizations(); // (THIS IS EMPTY!!!) ????
var_dump($orgs);
} else {
if( !isset($_GET["code"]) ){
$authUrl = $client->createAuthUrl();
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
} else {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
}
?>
This perfectly works for G-Suite account I had before the transition of Google+ to Google+ Domains. When I use this same script on a newer G Suite account, it won't work. I have tried with $service = new Google_Service_Plus($client); and the result is the same thing. Any idea why it won't work with newer G Suite accounts? Is anybody else having the same issue?
Ok. I found the root cause of my problem. It happens that the User Resource and the People Resource are two different resources. Both of them have the "organization" attribute but the information of the user resource will not appear in your Google Plus profile and in order to populate the "organization" attribute of the people resource, the user is required to manually update the information from the "about me" page in Google Plus. At the moment, seems there is no way to programmatically update the information of the People Resource but users have to do it manually.
i am trying to create a token/refreshToken so my website will be able to submit data to Google Sheets without asking the end user for permissions and i am struggling with this for few hours now..
I tried many different codes i found on the web + Google's docs and i made some progress but i can't get it to work and i can't figure what i am missing..
At this point i get no error (neither in my logs) but also i don't get any redirect or new window for authorizing the app
<?php
session_start();
require_once('php-google-oauth/Google_Client.php');
include_once('lib/autoload.php');
include_once('php-google-oauth/auth/Google_OAuth2.php');
$CLIENT_ID = 'xxxxxxxxxxxx.apps.googleusercontent.com';
$SECRET = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$REDIRECT = 'http://mywebsite.com';
$APIKEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
// $KEY = file_get_contents('php-google-oauth/client_secret.json');
$client = new Google_Client();
$client->setApplicationName("Contacts to Google Sheets");
$client->setClientId($CLIENT_ID);
$client->setClientSecret($SECRET);
$client->setRedirectUri($REDIRECT);
$client->setScopes(array('https://spreadsheets.google.com/feeds'));
$client->setAccessType('offline'); // Gets us our refresh token
// Step 1: The user has not authenticated so we give them a link to login
if (!$client->getAccessToken() && !isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
}
// Step 2: The user accepted your access now you need to exchange it.
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: ' . filter_var($REDIRECT, FILTER_SANITIZE_URL));
}
// Step 3: We have access we can now create our service
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
$token = $client->getAccessToken();
}
echo '<script>console.log("TOKEN: '. $token .'");</script>';
?>
Thanks in advance!
I looked at my code and tried this-
// Step 1: The user has not authenticated so we give them a link to login
if (!$client->getAccessToken() && !isset($_SESSION['token'])) {
$authUrl = $client->createAuthUrl();
echo 'Click here';
}
and now i do get a token back from Google
i am trying to code an application system with youtube login. but i have an issue After i get required authorisation with oauth 2.0 i want to get choosen youtube channel id in a string but i could not do it can somebody please help me.
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setApplicationName("BYTNETWORK");
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/yt-analytics.readonly'
));
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
}
so after this i want a string like
$channelid = "xxxxx"; to use it in code below
$data = file_get_contents('http://gdata.youtube.com/feeds/api/users/$channelid?alt=json');
$data = json_decode($data, true);
$stats_data = $data['entry']['yt$statistics'];
$medya = $data['entry']['media$thumbnail'];
//yt$username kısmından kanal adı parse edilir
/**********************************************************/
echo "<img src='$medya[url]'></img><br>";
echo "Subscribers: $stats_data[subscriberCount]<br>";
echo "Views: $stats_data[totalUploadViews]<br>";
Using OAUTH 2, you can get a refresh_token and an access_token for the requested scope(s).
If you want to get the YouTube channel-id, for an authorized user, using his access_token, then you send the request:
https://www.googleapis.com/youtube/v3/channels?part=id&mine=true&access_token=HereYourAccessToken
In the request above you need to replace the string "HereYourAccessToken".
The respone is a JSON string. And the channel-id is in the field named: items['id'] (or items.id).
Note, that an access_token expires after 1 hour. If so, then use the refresh_token to obtain a new one,
The refresh_token is valid until revoked by the owner.
I'm currently working with the Google Calendar API.
I retrieve a list of EVENTS from the user's calendar, but at the moment the account of the user is given in my code.
I wan't to make this variable (It should retrieve EVENTS from the account you select).
This is my code:
<?php
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_CalendarService.php';
$client = new Google_Client();
$client->setApplicationName('Tryout for Google Calendar');
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('myid');
$client->setClientSecret('mysecret');
$client->setRedirectUri('http://localhost/gcal/done.php');
$client->setDeveloperKey('mykey');
$cal = new Google_CalendarService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$minCheck = date(DATE_ATOM);
$eventList = $cal->events->listEvents("phpkay#gmail.com", array('singleEvents' => 'true', 'timeMin' => $minCheck));
print "<h1>Calendar List</h1><pre>" . print_r($eventList, true) . "</pre>";
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
This is the part where I set the useraccount, namely: "phpkay#gmail.com"
$eventList = $cal->events->listEvents("phpkay#gmail.com", array('singleEvents' => 'true', 'timeMin' => $minCheck));
How can I retrieve the selected useraccount (the user gets a screen where he can select one of the Google accounts he owns to use for this APP) and use this instead of the set "phpkay#gmail.com"-account?
Sorry if my question is unclear, I have no clue how to phrase this in another way.
You can do this with the OAuth 2.0 API. Just include:
https://developers.google.com/admin-sdk/directory/v1/reference/users
in your list of OAuth scopes and then make an authenticated GET request to:
https://www.googleapis.com/oauth2/v2/userinfo
this will return the email address of the authenticated user. You can try this out in the Google API Explorer