Gmail API domain-wide delegation - google-api

I am using Gmail API and I am trying to fetch emails from all users under company. But when I run code such as:
function runAPI(auth) {
var gmail = google.gmail('v1');
gmail.users.threads.list({auth: auth, userId: '108800016305523828361'},'',function(err, response){
if (err) {
console.log("The API returned an error: " + err);
return;
}
var threads = response.threads;
console.log(threads);
})
}
I get error:
The API returned an error: Error: Delegation denied for xxxx#xxxxx.com
In admin console I did this:
As client name I used id from the client_secret.json file. And for scope, I gave it all permissions.
How do I properly setup domain wide delegation for Gmail API ?

The setup is fine, however in your code you're doing it wrong.
This code:
gmail.users.threads.list({auth: auth, userId: '108800016305523828361'},'',function(err, response)
specifically.
userId should be "me" however before you can call the Gmail API you need to use the service account "JWT flow" in your code to retrieve an oauth2 credential for the Gmail user you want to access as described in the Preparing to make an authorized API call service account domain-wide delegation doc.
Specifically this uses your service account's private key to request to get a credential for the user you desire (set the user's email in your domain that you want to access in the setServiceAccountUser(user#example.com) function in the request). Then you can use that GoogleCredential in your call to the Gmail API.

For the question How do I properly setup domain wide delegation for Gmail API?
I think this documentation from Google can help you with this, just follow this steps to delegate domain-wide authority.
Go to your Google Apps 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. If you can't see the controls, make sure you're signed in as an administrator for the domain.
Select Show more and then Advanced settings from the list of options.
Select Manage API client access in the Authentication section.
In the Client Name field enter the service account's Client ID. You can find your service account's client ID in the Service accounts page.
In the One or More API Scopes field enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide access to the Google Drive API and the Google Calendar API, enter: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
In your case, use this scope for Gmail API.
Click Authorize.
For more information about the error 403 or Delegation denied for <user email>,check this related SO question:
Gmail API returns 403 error code and “Delegation denied for user email"
GMail API Super Admin access other users accounts via API?

Related

Cant authenticate to Doubleclick bid manager Api using a service account

i write some code to connect with google api Doubleclick bid manager
I download client_secrets.json at https://console.cloud.google.com/apis/credentials? then run some code like
require 'google/apis/doubleclickbidmanager_v1'
require 'google/api_client/client_secrets'
service = Google::Apis::DoubleclickbidmanagerV1::DoubleClickBidManagerService.new
service.authorization = Google::Auth.get_application_default(['https://www.googleapis.com/auth/doubleclickbidmanager'])
service.download_line_items
it response some errors like:
Sending HTTP post https://www.googleapis.com/doubleclickbidmanager/v1/lineitems/downloadlineitems?
403
#https://www.googleapis.com/doubleclickbidmanager/v1/lineitems/downloadlineitems == 403 (354 bytes) 1091ms>
Caught error unauthorizedApiAccess: You are not authorized to use DoubleClick Bid Manager API. Please contact dbm-support#google.com.
Error - #
Google::Apis::ClientError: unauthorizedApiAccess: You are not authorized to use DoubleClick Bid Manager API. Please contact dbm-support#google.com.
And when i run api at https://developers.google.com/apis-explorer, it return "You are not authorized to use DoubleClick Bid Manager API. Please contact dbm-support#google.com." too
Some one know this errors, plz check and help me
When your application requests private data, the request must be authorized by an authenticated user who has access to that data. Every request your application sends to the Google DoubleClick Bid Manager API must include an authorization token. The token also identifies your application to Google.
This is what the error means by
"You are not authorized to use DoubleClick Bid Manager API.
Make sure that you include the following scope when requesting authentication of the user.
https://www.googleapis.com/auth/doubleclickbidmanager
More info can be found here and there is documentation here on how to get it working with ruby you will need to alter the example there for your api as this is for calendar.
Note about service accounts.
Service accounts must be pre-authorized in order to work. In the case of Google drive you can take the service account email address and share a folder on your google drive with it. Basically you share data with the service account granting it access to the data. Not all google apis support service account authentication. Youtube api, Doubleclick, and blogger I think addsence or adWords as well, are a few that do not support service account authentication as there is no way to share the data with a user without them responding to the share request.

send emails from MY gmail account with OAuth2 and nodemailer

I want to send emails from my gmail address through my own server. I'm using nodemailer and using account credentials is flaky, and often times doesn't work and leads to this thread
I've implemented everything on that thread many times, and still it's flaky, and also I know OAuth2 is the way to go.
I have a project with cliendID and clientSecret in google developer console, as you can see:
But how do I get an access token WITHOUT any browser interaction?
I seem to be missing something trivial here ...
I've went through all google tutorials and docs I could find about OAuth2, tokens, and APIs, but all guides go through the browser in one point.
Go to the OAuth Playground, click the cog on the top right, check the Use your own OAuth credentials and insert your clientID and clientSecret.
Then select the Gmail API v1 scopes you want in the list to the left and follow the outlined steps and you will get an access_token and a refresh_token.
Google Oauth2 actually all Oauth2 implementations I am aware of require that a user grant an application access via a web browser.
There is an alternative type called service accounts this is more like oauth1 service accounts are preauthorized. You can grant a service account access to your google drive by sharing folders and files with the service account like you would any other user. Because they are preauthorized there is no browser window pop up with service accounts.
You can only user service accounts with Gmail if you have a Google domains account Gsuite. The admin can go in and grant the service account access to the Gmail account in question. Perform G Suite Domain-Wide Delegation of Authority
If this is a normal user Gmail account you cant use a service account. You will have to use Oauth2 popup the request and save the refresh token so that you can gain access at a later date.

Unauthorised access to Email Settings Google API

I am using both GAM and the Google API PHP client library to integrate with Google for Work.
I am using a service account and I have authorized the Client ID in the Admin console to access the following two scopes:
https://www.googleapis.com/auth/drive
https://apps-apis.google.com/a/feeds/emailsettings/2.0/
I have also enabled the Drive API and Admin SDK in the Developers Console. There is no Email Settings API that I can see.
I have followed this page and granted GAM access to all scopes during testing - which does include the Email Settings scope.
I can successfully use GAM and the PHP client library to access the Google Drive API. However, I always get a 403 - Unauthorised when trying to do any of the Email Settings API functions detailed in https://developers.google.com/admin-sdk/email-settings/
I am fairly confident that I have the authorised the right Client ID in the Admin Console. When I remove the scope https://www.googleapis.com/auth/drive from the Admin Console it blocks my access to Google Drive from both GAM and the PHP client library.
Any suggestions on what to try?
GAM does not use service accounts for email settings API, it uses standard OAuth 2.0 for installed apps. Be sure you used a super administrator to authorize GAM access to the email settings API. If you didn't, run
gam oauth revoke
And then another command like:
gam all users show imap
And this time make sure you are logged in as a super admin.
Jay's post led me to the answer - namely that I should be logged in as a super admin when accessing the Email Settings API.
I therefore created a super admin account and authenticated GAM using that. That gave GAM access.
In order to get the PHP client library working, I had to impersonate the super admin account when I created the OAuth2 token. The code to impersonate the admin account is below:
$credentials = new Google_Auth_AssertionCredentials(
$service_account_email,
$scopes,
$private_key,
'notasecret', // Default P12 password
'http://oauth.net/grant_type/jwt/1.0/bearer', // Default grant type
$admin_email
);
where
$service_account_email is the email address of the service account created in the Developer's console - not the super admin account.
$scopes is an array of the API URLs that you need to access
$private_key is the contents of the P12 certificate created from the Developer's console.
$admin_email is the email of the super admin account.
Hope this helps someone else.

Impersonate current user when calling a Google API using service account & delegation of authority

There is a marketplace requirement that if a Google Apps for Work domain admin installs our app for their domain, the admin and any users from their domain should thereafter not see a scope auth screen when accessing our app. The act of installing the app for the domain should implicitly delegate domain-wide authority for the service account associated with our app.
In order to achieve this behavior, I am trying to do delegation of authority to a service account to work on behalf of, AKA impersonate, the currently logged in user.
The code snippet below shows the various attempts that I've made to get this to work. The only one that does work is to pass a domain superuser's email address as the "sub" param (AKA prn) when creating the JWT. However, this essentially elevates a regular run of the mill domain user's privileges to those of super user which is not the desired effect.
var client = new googleapis.auth.JWT(
'<serviceaccount>#developer.gserviceaccount.com',
'localhost.pem',
null,
["https://www.googleapis.com/auth/admin.directory.user.readonly"],
// null - // 403 not auth
// {'userId' : 'domainsuperuser#email.com'} // 403 not auth
// {'userId' : 'me'} // 403 not auth
// "domainsuperuser#email.com" // works!
// "{domainsuperuser#email.com}" // not a valid email error
// 'me' // invalid impersonation prn email address
);
Does Google honor any other ID than just the email address of the person you want to impersonate such as the special 'me' value?
It feels like we are running into a chicken and egg problem here. Essentially we don't want to hardcode the email address (especially not an admin email), so it feels like we have to make an API call. But we can't make an API call without impersonating a user.
You don't need to use a service account and domain-wide delegation in this case. Instead, simply go through the normal OAuth2 flow with the user, and the approval screen will be skipped automatically.
When the admin installs the app and approves your scopes, they are essentially automatically granting you access to those scopes for all users in the domain. And while it is a requirement that users not see the approval screen, you still have to go through the OAuth2 flow with them in order get the OAuth2 token. If you launch an OAuth2 flow for the user, and don't request any scopes not already approved by the domain admin and don't set approval_prompt=force in the URL, then the OAuth2 approval screen will instantly redirect to your redirect URI, making the process invisible to the user.

Google Api - Get Users Email id

I am using Google API - PHP client to connect to Google Analytics API. Is there any way i can get the email Address of the User while Authenticating the user and Granting the permissions ?
Use the Google Management API for Analytics. When you make the authenticated call to https://www.googleapis.com/auth/analytics.readonly, you will receive back (among other things) a username which is defined as "Email address of the authenticated user".

Resources