Google Contact Api PHP - Server Account (server to server): Empty contacts array - php

When I use "this solution" I get a blank contacts array.
I'm using "google-api-php-client-0.6.7" with a serviceAccount.php into the examples/contacts folder, and a Google_ContactsService into src/contrib folder.
I have configured the Google Apis Access, with OAUTH 2 as Server Account. I have the p12 file, a client id and a cliend mail address. The project name is "Google Contacts Sample".
serviceAccount.php:
<?php
require_once '../../src/Google_Client.php';
require_once '../../src/contrib/Google_ContactsService.php';
const CLIENT_ID = 'xxxxxxxxxxxxx.apps.googleusercontent.com';
const SERVICE_ACCOUNT_NAME = 'xxxxxxxxxxxxx#developer.gserviceaccount.com';
const KEY_FILE = '/absolute_path/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-privatekey.p12';
$client = new Google_Client();
$client->setApplicationName("Google Contacts Sample");
session_start();
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
$key = file_get_contents(KEY_FILE);
$client->setAssertionCredentials(new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.googleapis.com/auth/contacts'), $key));
$client->setClientId(CLIENT_ID);
if ($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion();
}
$token = $client->getAccessToken();
$service = new Google_ContactsService($client);
$result = $service->all();
print '<h2>Contacts Result:</h2><pre>' . print_r($result, true) . '</pre>';
Google_ContactsService.php:
<?php
class Google_ContactsService
{
const SCOPE = "https://www.google.com/m8/feeds";
/**
* #var Google_Client
*/
private $client;
public function __construct($pClient)
{
$this->client = $pClient;
$this->client->setScopes(self::SCOPE);
}
public function all()
{
$result = $this->execute('default/full?max-results=999');
$contacts = array();
foreach($result["feed"]["entry"] as $entry)
{
if(!isset($entry['gd$email']))
$entry['gd$email'] = array();
if(!isset($entry['gd$phoneNumber'])||empty($entry['gd$phoneNumber']))
continue;
$phones = array();
$emails = array();
foreach($entry['gd$phoneNumber'] as $phone)
{
$phone['$t'] = preg_replace('/\+33/', "0", $phone['$t']);
$phone['$t'] = preg_replace('/\-/', '', $phone['$t']);
$phones[] = $phone['$t'];
}
foreach($entry['gd$email'] as $email)
{
$emails[] = $email['address'];
}
$contacts[] = array(
"fullName"=>utf8_decode($entry['title']['$t']),
"phones"=>$phones,
"emails"=>$emails
);
}
return $contacts;
}
private function execute($pUrl)
{
$oauth = Google_Client::$auth;
$request = new Google_HttpRequest("https://www.google.com/m8/feeds/contacts/".$pUrl."&alt=json");
$oauth->sign($request);
$io = Google_Client::$io;
$result_json = $io->makeRequest($request)->getResponseBody();
$result = json_decode($result_json, true);
return $result;
}
}
When I go to "http://server.com/packs/googleapi/examples/contacts/serviceAccount.php" I don't see any contact.
The function Execute return empty.
What can I do?
Thanks.

I realize this is old so you have probably moved on but for other's finding this I believe the reason you don't see any contacts is that you are not delegating to a specific user. Not counting shared contacts on Google Apps Premier and Education Editions domains, contacts are private to that user.
I would change this line
$client->setAssertionCredentials(new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.googleapis.com/auth/contacts'), $key));
to be more like this
$auth = new Google_AssertionCredentials(SERVICE_ACCOUNT_NAME, array('https://www.google.com/m8/feeds'), $key);
$auth->sub = 'user#domain.com'; //whoever's contacts you want to see
$client->setAssertionCredentials($auth);
You could keep the first two lines together if you look at Google_AssertionCredentials method signature, but I think this makes it more explicit. Depending on what you are trying to achieve, user#domain.com will likely be a variable that is set from some kind of input, database, etc.

Related

"Login with Google" in PHP - Google+ API shutdown migration - how to migrate away from plus.people.get?

I got a warning email from Google reminding me of Google+'s EOL which is supposed to break my current "Login with Google", but I am unsure what exactly should I change.
Let me show you my (simplified) login code:
google-login.php
new class {
public function __construct() {
$state = mt_rand();
$client = new Google_Client();
$client->setApplicationName(Config::Google['app_name']);
$client->setClientId(Config::Google['id']);
$client->setClientSecret(Config::Google['secret']);
$client->setRedirectUri(sprintf('https://%s/members/google-callback.php', $_SERVER['HTTP_HOST']));
$client->setScopes(['profile', 'email']);
$client->setState($state);
$_SESSION['state'] = $state;
$url = $client->createAuthUrl(); // $url = https://accounts.google.com/o/oauth2/auth?response_type=code&access_type=online&client_id=CLIENT_ID.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fread2me.online%2Fmembers%2Fgoogle-callback.php&state=1588245f23f2a&scope=profile%20email&approval_prompt=auto
header ("location: $url");
}
};
google-callback.php
new class {
private $newUser = false;
public function __construct() {
if (!isset($_GET['state']) || $_GET['state'] != $_SESSION['state'])
die('State mismatch.');
$client = new Google_Client();
$client->setApplicationName(Config::Google['app_name']);
$client->setClientId(Config::Google['id']);
$client->setClientSecret(Config::Google['secret']);
$client->setRedirectUri(sprintf('https://%s/members/google-callback.php', $_SERVER['HTTP_HOST']));
$client->setScopes(['profile', 'email']);
$plus = new Google_Service_Plus($client);
if (isset($_GET['code'])) {
$client->fetchAccessTokenWithAuthCode($_GET['code']);
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if (!$client->getAccessToken() || $client->isAccessTokenExpired()) {
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$url = $client->createAuthUrl();
header ("location: $url");
}
try {
$me = $plus->people->get('me');
} catch (Google_Exception $e) {
\Rollbar::report_message($e->getMessage());
print_r($e->getMessage());
return;
}
$accessToken = $client->getAccessToken()['access_token'];
$email = $me->getEmails()[0]->getValue();
$name = $me->getDisplayName();
$avatar = $me->getImage()->getUrl();
$id = $me->getId();
if ($this->isEmailInSystem($email) === false) {
$this->newUser = true;
$this->addUser($email, $name, 'google', $accessToken, $id, $avatar);
}
header ("location: " . '/');
}
};
Now, I'm going through at what seems to be the up-to-date Sign In guide for PHP, but I am not sure what to change - any ideas?
Thanks
The best migration is to move from the Plus API to the People API, which provides access to the user's profile in a similar (tho not quite identical) way.
You would replace the creation of the $plus object with a new Goolge_Service_PeopleService object. Something like
$people = new Google_Service_PeopleService( $client );
Getting the profile is more involved since you need to specify which fields from the profile you want to get. But you might do it something like
$profile = $people->people->get(
'people/me',
array('personFields' => 'names,emailAddresses,photos')
);
The first parameter needs to be "people/me" to specify that you're requesting the authorized user's profile.
The second is an array of query parameters. You need to specify the "personFields" that you want from the list of what is available (scroll down on this page till you see the description of the available fields) and specify this as a comma separated list in a string. In my example above, I illustrate getting the name, email addresses, and photos. But consult the list and experiment.
The exact fields you get from the result in $profile will be different than those you got from $plus, but they should match the fields you requested. Check the values and exactly how they're structured.
I ran into the same issue as Google+ APIs shutting down on March 7, 2019.
Make sure Google People API is enable in your google console
I used google-api-php-client Library.
Once you have an access token here is code to get the person object using people API
$accessToken = 'REPLACE_WITH_ACCESS_TOKEN';
$clientId = 'REPLACE_WITH_CLIENT_ID';
$clientSecret = 'REPLACE_WITH_CLIENT_SECRET';
$developerKey = 'REPLACE_WITH_DEVELOPER_KEY';
$client = new Google_Client();
$client->setApplicationName("Application Name");
$client->setClientId($clientId . '.apps.googleusercontent.com');
$client->setClientSecret($clientSecret);
$client->setDeveloperKey($developerKey);
$client->setScopes(['https://www.googleapis.com/auth/userinfo.email','https://www.googleapis.com/auth/userinfo.profile']);
$client->setAccessToken($accessToken);
$guzzleClient = new \GuzzleHttp\Client(array( 'curl' => array( CURLOPT_SSL_VERIFYPEER => false, ), ));
$client->setHttpClient($guzzleClient);
$people = new Google_Service_PeopleService( $client );
if ($client->getAccessToken()) {
try {
$me = $people->people->get(
'people/me',
array('personFields' => 'emailAddresses,names,photos')
);
$id = preg_replace('/[^0-9]/', '', $me->getResourceName());
$email = $me->getEmailAddresses()[0]->value;
$name = $me->getNames()[0]->displayName;
$avtar = $me->getPhotos()[0]->getUrl();
} catch (Google_Exception $e) {
// error
echo $e->getMessage();
}
}
I also disabled Google+ API to make sure the application is not using it anymore anywhere.
With latest version of Google API PHP Client you can fetch profile details from Google_Client object itself.
$token = $client->fetchAccessTokenWithAuthCode($_GET['code']);
$attributes = $client->verifyIdToken($token['id_token'], GOOGLE_CLIENT_ID);
print_r($attributes);
Refer this article.
Obviously, the lines
$plus = new Google_Service_Plus($client);
and
$me = $plus->people->get('me');
You need to use google email API, see https://developers.google.com/gmail/api/quickstart/php , so the first line will be
$service = new Google_Service_Gmail($client);
and second ... hmmm ... not sure there WILL be any avatar after removing of google plus ...

PHP Google Api Client SQL Admin not enable Auth IP

I have this code that updates my Google MySQL instance authorized IPs, connection is ok, the code prints me the current IP's but it cannot add a new IP to the settings I tried many ways but it still do not works it doesn't make any change to the Instance configuration.
$client = new Google_Client();
$client->setAuthConfig('../config/service-account.json');
$client->setApplicationName(env("APP_NAME"));
$projectName = env("GOOGLE_PROJECT_NAME");
$instanceName = env("SQL_INSTANCE_NAME");
$scopes = [
"https://www.googleapis.com/auth/sqlservice.admin",
"https://www.googleapis.com/auth/compute",
];
$client->addScope($scopes);
$sql = new Google_Service_SQLAdmin($client);
$sqlAdmin = new Google_Service_SQLAdmin_Settings($client);
$instanceSettings = $sql->instances->get($projectName, $instanceName)->getSettings();
$authNetworks = $instanceSettings->getIpConfiguration();
$newAuthNetwork = new Google_Service_SQLAdmin_AclEntry($client);
$newAuthNetwork->setName("tmp_ip_connection");
$newAuthNetwork->setKind("sql#aclEntry");
$authNetworks->setAuthorizedNetworks($newAuthNetwork);
$ipv4 = file_get_contents('https://api.ipify.org');
$newAuthNetwork->setValue($ipv4);
$ipConfiguration = new Google_Service_SQLAdmin_IpConfiguration($client);
$ipConfiguration->setIpv4Enabled(true);
$ipConfiguration->setAuthorizedNetworks([$newAuthNetwork]);
$instanceSettings->setIpConfiguration($ipConfiguration);
$sql->instances->get($projectName, $instanceName)->setSettings($instanceSettings);
//TODO why it is not working??
print_r($sql->instances->get($projectName, $instanceName)->getSettings()->getIpConfiguration()->getAuthorizedNetworks());
The main thing missing from yours is you never updated the instance after you made the change.
Working example:
$client = new Google_Client();
$client->setAuthConfig('../config/service-account.json');
$client->setApplicationName(env("APP_NAME"));
$projectName = env("GOOGLE_PROJECT_NAME");
$instanceName = env("SQL_INSTANCE_NAME");
$scopes = [
"https://www.googleapis.com/auth/sqlservice.admin",
"https://www.googleapis.com/auth/compute",
];
$client->addScope($scopes);
$sql = new Google_Service_SQLAdmin($client);
$instances = $sql->instances;
$instance = $instances->get('projectId', 'instanceId');
$networks = $instance->getSettings()->getIpConfiguration()->getAuthorizedNetworks();
$values = [];
foreach ($networks as $network) {
$values[$network->getName()] = $network;
}
$values['1.production'] = array_get($values, '1.production', clone head($values));
$external_ip = #file_get_contents('http://ipecho.net/plain');
$values['1.production']->setValue("$external_ip/32");
$values['1.production']->setName('1.production');
$instance->getSettings()->getIpConfiguration()->setAuthorizedNetworks(array_values($values));
$instances->update('projectId', 'instanceId', $instance);

Google Calendar API, getItem and getSummery returns nothing

I seem to have bumped into a google calendar api problem. and I can't really see where I have made the error so an extra set of eyes would be greatly appreciated. The problem in short is that the part of the code that should output the events.. doesn't (the "result" part of the code.
require_once "./google-api-php-client/src/Google/Client.php";
require_once "./google-api-php-client/src/Google/Service/Calendar.php";
// Service Account info
$client_id = "XXXXXX-XXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com";
$app_name = "Some-name";
$service_account_name = 'XXXXX-XXXXXXXXXXXXXXXXXXXXXXX#developer.gserviceaccount.com';
$key_file_location = 'google-api-php-client/Some-name-xxxxxxxxxx.p12';
$cal_id = "primary";
// Service Account info
$client_id = $client_id;
$service_account_name = $service_account_name;
$key_file_location = $key_file_location;
// Calendar id
$calName = $cal_id;
$client = new Google_Client();
$client -> setApplicationName($app_name);
$service = new Google_Service_Calendar($client);
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/calendar.readonly'),
$key
);
$client->setAssertionCredentials($cred);
$cals = $service->calendarList->listCalendarList();
print_r($cals);
echo "<br>events<br>";
$events = $service->events->listEvents($calName);
var_dump($events);
echo "<br>result:<br>";
// the following is what returns nothing, works fine until this point.
$i = 0;
foreach ( $events->getItems() as $event ) {
echo 'i:'.$i.' '.$event->getSummary();
$i++;
}
echo 'end';
Change $events to the below line:
$events = $service->events->listEvents('primary', $params);
Instead of primary, add $calName and also send $params in listEvents method.
Hope this works.

PHP Google Analytics API - Simple example

I am trying to set some basic example of using Google Analytics with this library: https://github.com/google/google-api-php-client
For starter I have:
<?php
require_once 'Google/Client.php';
require_once 'Google/Service/Analytics.php';
$client = new Google_Client();
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("MY_SECRET_API"); //security measures
$service = new Google_Service_Analytics($client);
$results = $service->data_ga;
echo '<pre>';
print_r($results);
echo '</pre>';
Q: How to get data from Google Analytics from this query ?
/*
https://www.googleapis.com/analytics/v3/data/
ga?ids=ga%123456
&dimensions=ga%3Acampaign
&metrics=ga%3Atransactions
&start-date=2013-12-25
&end-date=2014-01-08
&max-results=50
*/
$client->setDeveloperKey("MY_SECRET_API");
First of all, for as far as I experienced this won't work for authentication, you'll need to use a OAuth2 authentication. There are two options to do this, using client ID for web application or using a service account. Authorization api
After you have this, you can make a call like this.
(I use a service account here)
First authenticate:
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
$service_account_name,
array('https://www.googleapis.com/auth/analytics.readonly'),
$key
);
$client->setAssertionCredentials($cred);
Make a call:
$ids = 'ga:123456'; //your id
$startDate = '2013-12-25';
$endDate = '2014-01-08';
$metrics = 'ga:transactions';
$optParams = array(
'dimensions' => 'ga:campaign',
'max-results' => '50'
);
$results = $service->data_ga->get($ids, $startDate, $endDate, $metrics, $optParams);
//Dump results
echo "<h3>Results Of Call:</h3>";
echo "dump of results";
var_dump($results);
echo "results['totalsForAllResults']";
var_dump($results['totalsForAllResults']);
echo "results['rows']";
foreach ($results['rows'] as $item) {
var_dump($item);
}
You will need to do a http get to get the information from the url.
http://www.php.net/manual/en/function.http-get.php
Remember you will still need to add the Oauth2 auth code to the string before you can send that request. This link might help if you dont have auth code already.
https://developers.google.com/analytics/solutions/articles/hello-analytics-api#authorize_access
what you could do is create a new function...
function ga_campaign_transactions($gaEmail, $gaPass, $gProfile, $limit)
{
require_once('classes/google-analytics/gapi.class.php');
$gDimensions = array('campaign');
$gMetrics = array('transactions');
$gSortMetric = NULL;
$gFilter = '';
$gSegment = '';
$gStartDate = '2013-12-25';
$gEndDate = '2014-01-08';
$gStartIndex = 1;
$gMaxResults = $limit;
$ga = new gapi($gaEmail, $gaPass);
$ga->requestReportData($gProfile, $gDimensions, $gMetrics, $gSortMetric, $gFilter, $gSegment, $gStartDate, $gEndDate, $gStartIndex, $gMaxResults);
$gAnalytics_results = $ga->getResults();
//RETURN RESULTS
return $gAnalytics_results;
}
$gProfile = '123456'; // The Profile ID for the account, NOT GA:
$gaEmail = 'YOUR GOOGLE EMAIL'; // Google Email address.
$gaPass = 'YOUR GOOGLE PASSWORD'; // Google Password.
// NOTE: if 2 step login is turned on, create an application password.
$limit = 50;
$ga_campaign_transactions = ga_campaign_transactions($gaEmail, $gaPass, $gProfile, $limit)
//OUTPUT
if(!empty($ga_campaign_transactions))
{
$counter=0;
$gaCampResults= array(); // CREATE ARRAY TO STORE ALL RESULTS
foreach($ga_campaign_transactions as $row)
{
$dim_list = $row->getDimesions();
$met_list = $row->getMetrics();
$gaCampResults[$counter]['campaign'] = $dim_list['campaign'];
$gaCampResults[$counter]['transactions'] = $met_list['transactions'];
$counter++;
}
}
if(!empty($gaCampResults))
{
$totalCampTransactions = count($gaCampResults);
?>
<h2>We Found ( <?php echo number_format($totalCampTransactions,0);?> ) Results</h2>
<ul>
<?php
foreach($gaCampResults as $gaRow){
echo "<li>Campaign:".$gaRow['campaign']." | Transactions: ".$gaRow['transactions']."</li>";
}
?>
</ul>
<?php
}
find Analytics Profile ID
Create Google Application password
Hopefully that puts you on the right track :)
untested this, but similar to what I've been using...
Marty

Google Groups Directory API - Add user to group - PHP Function

How do I use this function?
I have a userid and a group id.
The error message I get when I try to add my fields has to do with the Google_Member instance. How would I use this in my PHP code?
BTW it is from the Google Apps API
/**
* Add user to the specified group. (members.insert)
*
* #param string $groupKey Email or immutable Id of the group
* #param Google_Member $postBody
* #param array $optParams Optional parameters.
* #return Google_Member
*/
public function insert($groupKey, Google_Member $postBody, $optParams = array()) {
$params = array('groupKey' => $groupKey, 'postBody' => $postBody);
$params = array_merge($params, $optParams);
$data = $this->__call('insert', array($params));
if ($this->useObjects()) {
return new Google_Member($data);
} else {
return $data;
}
}
Follow the instructions listed here to setup the application in Google Console and to enable Domain Delegation of Authority.
http://jamespeckham.com/wordpress/?p=9 (Thank you JDPeckham)
Download the client from: https://code.google.com/p/google-api-php-client/downloads/list
Here is my working code:
require_once "google-api-php-client/src/Google_Client.php";
require_once "google-api-php-client/src/contrib/Google_DirectoryService.php";
require_once "google-api-php-client/src/contrib/Google_Oauth2Service.php";
session_start();
const GROUP_SCOPE = 'https://www.googleapis.com/auth/admin.directory.group';
const SERVICE_ACCOUNT_EMAIL = '.....#developer.gserviceaccount.com';
const SERVICE_ACCOUNT_PKCS12_FILE_PATH = '/path/to/...privatekey.p12';
const CLIENT_ID = '....apps.googleusercontent.com';
$userEmail = 'email-address-with-admin-rights#domain.com';
$key = file_get_contents(SERVICE_ACCOUNT_PKCS12_FILE_PATH);
$auth = new Google_AssertionCredentials(SERVICE_ACCOUNT_EMAIL, array(GROUP_SCOPE), $key, 'notasecret', 'http://oauth.net/grant_type/jwt/1.0/bearer', $userEmail);
$client = new Google_Client();
$client->setClientId(CLIENT_ID); // from API console
$client->setApplicationName("Project Name from API Console");
$client->setUseObjects(true);
$client->setAssertionCredentials($auth);
$member = new Google_Member(array('email' => 'abc#testing.com',
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER'));
$service = new Google_DirectoryService($client);
$results = $service->members->insert('mailing-list-name#domain.com', $member);
print '<h2>Response Result:</h2><pre>' . print_r($results, true) . '</pre>';
require_once $_SERVER['DOCUMENT_ROOT'] . '/../vendor/autoload.php';
$updateName = $_POST["name"];
$updateEmail = $_POST["email"];
//USING A SERVICE ACCOUNT TO CALL GOOGLE CLIENT
putenv('GOOGLE_APPLICATION_CREDENTIALS=/home/myserver/mywebsite/credentialsfile.json');
$client = new Google\Client();
// MY ACCOUNT DATA HERE
$client_id = 'clientid';
$service_account_name = 'serviceaccountemailhere'; //Email Address
$key_file_location = '/home/myserver/mywebsite/mykeyfile.json'; //key.p12
$agencyAdminGroupKey = 'emailforGroupKey#gmial.com'; //agency admins group key
$memberKey = $updateEmail; //$memberemail
$domain = 'yourwebsite.com';
if (getenv('GOOGLE_APPLICATION_CREDENTIALS')) {
// use the application default credentials
$client->useApplicationDefaultCredentials();
} else {
echo missingServiceAccountDetailsWarning();
return;
}
// set the scope(s) that will be used
//$client->setScopes(array('https://www.googleapis.com/auth/admin.directory.group'));
$client->setScopes(array('https://www.googleapis.com/auth/admin.directory.group'));
// this is needed only if you need to perform
// domain-wide admin actions, and this must be
// an admin account on the domain; it is not
// necessary in your example but provided for others
$client->setSubject('yourgoogleaccountemail#domain.com');
$client->setApplicationName("Client_Library_Examples");
$client->setDeveloperKey("paste-your-developer-key");
$service = new Google_Service_Directory($client);
$member = new Google_Service_Directory_Member( array('email' => $updateEmail,
'kind' => 'admin#directory#member',
'role' => 'MEMBER',
'type' => 'USER',
"deliverySettings" => 'DAILY'));
//GET request to google groups server
// $results = $service->members->listMembers($groupKey);
$results = $service->members->insert($agencyAdminGroupKey, $member);
Here are some useful links:
https://github.com/googleapis/google-api-php-client
https://developers.google.com/admin-sdk/directory/v1/quickstart/php
https://developers.google.com/resources/api-libraries/documentation/admin/directory_v1/php/latest/class-Google_Service_Directory_Groups.html
https://developers.google.com/admin-sdk/directory/reference/rest/v1/members

Categories