I want to download mailbox by using the Admin SDK, but I can't get it working. I can't find what's the Scope I need to define. I'm using a service account.
In order to prepare a download, you have to do a POST request to https://apps-apis.google.com/a/feeds/compliance/audit/mail/export/{domain name}/{source user name}, but there is no audit.mail scope or something like that.
Here is my request:
<?php
$client = new \Google_Client();
$cred = new \Google_Auth_AssertionCredentials(
'***#developer.gserviceaccount.com',
array(
'https://apps-apis.google.com/a/feeds/compliance/audit',
),
file_get_contents($path)
);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
$url = "https://apps-apis.google.com/a/feeds/compliance/audit/publickey/" . $domain;
$req = new \Google_Http_Request($url, 'POST');
$req->setPostBody($xml);
$token = json_decode($client->getAccessToken(), true);
$req->setRequestHeaders(
array(
'Content-Type'=> 'application/atom+xml; charset=utf-8',
'Authorization'=> 'Bearer ' . $token['access_token'] . '',
)
);?>
But I get a 403 error: You are not authorized to access this API..
What's the best way to download a mailbox using the PHP API with a service account?
The email audit api scope is: https://apps-apis.google.com/a/feeds/compliance/audit/
Did you grant third party client access in your admin console for your service account with the appropriate scope? The scope setting have to be set within your code and also in admin console.
Here is complete instruction on how to correctly set up a service account (the example is in drive, so you should change the scope for email audit api in your case)
https://developers.google.com/drive/web/delegation
Make sure you complete the steps for 'Delegate domain-wide authority to your service account'.
Finally, if you take a look at the PHP code sample, you can see that you will need the scope, the user you are trying to impersonate and your service account.
Related
I understand that there were already similar questions here, but the answers to them did not help me.
Trying to connect through a service account to the calendars of users who are part of the domain. For connection I use Google API PHP Client (https://github.com/googleapis/google-api-php-client)
Account setup followed the instructions (https://developers/admin-sdk/directory/v1/guides/delegation)
Here's my code:
<?php
require '/vendor/autoload.php';
$client = new Google_Client();
putenv('GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json');
$client->useApplicationDefaultCredentials();
$client->authorize();
$scopes = implode(' ', [Google_Service_Calendar::CALENDAR, Google_Service_Calendar::CALENDAR_EVENTS]);
$client->setScopes($scopes);
$client->setSubject('user#email.com');
$service = new Google_Service_Calendar($client);
$optParams = [
'maxResults' => 10,
'orderBy' => 'startTime',
'singleEvents' => TRUE,
'timeMin' => date('c')
];
$results = $service->events->listEvents('root#email.com', $optParams);
$events = $results->getItems();
And then I get an authorization error:
Error: {
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
}
Can you tell me if someone 's already faced a mistake like this? Should the root#email.com be mail or mail that was generated during access setup? Or is the problem somewhere else at all?
Thank you in advance for any help!
Your code is actually correct. Be sure you authorized your service account to use the same scopes you are trying to use in your code. This is a common issue with service accounts.
Here a walk-through from the docs:
Go to your G Suite domain’s Admin console.
Select Security from the list of controls. If you don't see Security listed, select More controls from the gray bar at the bottom of the page, then select Security from the list of controls.
Select Advanced settings from the list of options.
Select Manage API client access in the Authentication section.
In the Client name field, enter the client ID obtained from the service account creation steps above.
In the One or More API Scopes field enter the scopes required for your application (for a list of possible scopes, see Authorize requests).
For example, if you require domain-wide access to Calendar and Calendar Events: https://www.googleapis.com/auth/calendar, https://www.googleapis.com/auth/calendar.events
Click the Authorize button.
I'm having a problem connecting through the google apiclient 2.0.0 as installed via composer.
Here's what I've done so far:
I installed apiclient via composer.
I went to https://console.cloud.google.com/apis/credentials?my-project and navigated to the API manager > Credentials page.
I created credentials for a Service Account and downloaded the json. I then uploaded the json to my server.
I enabled Domain Wide Delegation for the account by managing my service accounts.
I verified my domain name under the 'Domain Verification' tab.
Next I navigated to my calendar and shared the calendar with the email address associated with my service account, granting manage access.
Then I shared my calendar with the email address of the service account.
Now I'm trying to use the api to connect and running into authorization problems.
$json_file = '/path/to/service-account-credentials.json';
$scopes = [
Google_Service_Calendar::CALENDAR,
Google_Service_Calendar::CALENDAR_READONLY
];
// create a new client and authorize
$client = new Google_Client();
// set the basic information of the client
$client->setApplicationName("Apointments");
$client->setSubject( email-address-to-masquerade-as#mycompany.com );
$client->setAccessType('offline');
// load the json credential file
$client->setAuthConfig( $json_file );
$client->setScopes( $scopes );
// check to see if the token is stored in the session
if( isset( $_SESSION['service_token'] ) )
{
// token was stored, use it with the cilent
$client->setAccessToken( $_SESSION['service_token'] );
}
// test the authorization to see if it is expired
if( $client->isAccessTokenExpired() )
{
// Failed authorization, get a new token
$client->refreshTokenWithAssertion();
}
// store the token in the session
$_SESSION['service_token'] = $client->getAccessToken();
From a stacktrace, I've identified the offending line of code to be:
$client->refreshTokenWithAssertion();
Which yields an error message:
Client error response [url] https://www.googleapis.com/oauth2/v4/token [status code] 401 [reason phrase] Unauthorized
Any thoughts as to where I've gone awry?
Thanks in advance,
Adam
The way you are using Service account is only valid to access data related to your application or to your service account itself. Since you wish to access Google Calendar data, you must be a Google Apps domain administrator with privileges to access any of your domain user's data. Google Calendar data belong to users so you need to specify which user you are trying to access.
You need to authenticate the user, need to get an access token and pass that. If you are getting an access token, you can call token info passing access token to get more information about who the user is associated with it.
Here's a Quick start demo app, use this as your reference: https://developers.google.com/+/web/samples/php
I am using youtube API for scheduling live events for user in my application.
Once the user logged in my application i need to logged in the same user to our business google account(One google account for all user) without giving login credentials. and to get access token for scheduling the live events.
Is it possible to login the user into google account without giving login credentials(User will not feel he is login to another account).
Is it feasible with PHP?.Please give one example to get access token for youtube API access.
I used the following code for getting access token but service account can't access the youtube service.
My code for getting access token using service account:
<?php
require_once 'Google/autoload.php';
session_start();
$client_id = '395540674667-p64tdfqdsfsdfdsf#dsfd.com';
$Email_address = '54564-drgfdg1#developer.gserviceaccount.com';
$key_file_location = 'Youtube API-5czxczxc86.p12';
$client = new Google_Client();
$client->setApplicationName("Youtube API");
$key = file_get_contents($key_file_location);
// seproate additional scopes with a comma
$scopes = array('https://www.googleapis.com/auth/sqlservice.admin','https://www.googleapis.com/auth/plus.login','https://www.googleapis.com/auth/youtube');
$cred = new Google_Auth_AssertionCredentials($Email_address,
$scopes,
$key);
$client->setAssertionCredentials($cred);
if($client->getAuth()->isAccessTokenExpired()) {
$client->getAuth()->refreshTokenWithAssertion($cred);
}
//print_r($client);
echo $client->getAccessToken();
?>
I am expecting the answer is something like this.Any one please help
you example about Youtube api, first:
select credentials to your api project from here:
https://console.cloud.google.com/home/dashboard?project= with your project
also you need to have the api enable because google told us "Some APIs are enabled automatically."
when you select:
https://console.cloud.google.com/apis/api/youtube/ with Go to Credentials you have some option into modal window this will help
also.
the php code seem to be ok but also I think you will change after you learn more about Credentials settings.
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.
I am trying to read a feed from a Google Sites account (Google apps).
I don't need my app to require every user to login so i created my ClientID as a "Service Account" in the "Google API console".
I have added this Client ID and the scope (https://sites.google.com/feeds/) to the "Mange API client access" page in my google apps control panel.
I connect using the code below, all constants are defined in my code with the right values.
// api dependencies
require_once(GOOGLE_API_PATH);
// create client object and set app name
$client = new Google_Client();
$client->setApplicationName(GOOGLE_API_NAME);
// set assertion credentials
$client->setAssertionCredentials(
new Google_AssertionCredentials(
GOOGLE_API_EMAIL,
array(GOOGLE_API_SCOPE),
file_get_contents(GOOGLE_API_PK)
));
$client->setClientId(GOOGLE_API_CLIENTID);
// create service
$req = new Google_HttpRequest("https://sites.google.com/feeds/content/<herismydomainname.com>/intranet");
$val = $client->getIo()->authenticatedRequest($req);
// The contacts api only returns XML responses.
$response = json_encode($val->getResponseBody());
print "<pre>" . print_r(json_decode($response, true), true) . "</pre>";
The response i get is "Not authorized to access this feed "
When i try to get this feed in the OAuth2.0 playground logging in using my google apps account i get the expected response.
What am i overlooking here?
Service accounts and Google Sites can't be used together currently. Google Apps provides a consumer secret that can be used to access data across your domain as Two-Legged OAuth within OAuth 1.0a.
Check out http://support.google.com/a/bin/answer.py?hl=en&answer=162105 for how to configure your Apps account, and the sample code at https://developers.google.com/gdata/docs/auth/oauth#2LeggedOAuth.