Sourav Chatterjee
Sourav Chatterjee

Reputation: 179

How to use service account to send email through GMAIL API using Java?

I am trying to send emails from a google compute instance through GMAIL API using a service account. I have followed all the steps according to this documentation but still getting an error message saying 'com.google.api.client.auth.oauth2.TokenResponseException: 401 Unauthorized'.

Below is the code snippet for the same.

public static void main( String[] args ) throws GeneralSecurityException, IOException, MessagingException
{
    final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
    GoogleCredential credentialFromJson = GoogleCredential
            .fromStream(new FileInputStream(
                    "/Users/souravc/Documents/MySpaceSRV6100/Java_Samples/EmailTest/mail-auth.json"))
            .createScoped(Collections.singletonList(GmailScopes.GMAIL_SEND));

    GoogleCredential credential = new GoogleCredential.Builder()
            .setTransport(HTTP_TRANSPORT)
            .setJsonFactory(JSON_FACTORY)
            .setServiceAccountId(credentialFromJson.getServiceAccountId())
            .setServiceAccountPrivateKey(credentialFromJson.getServiceAccountPrivateKey())
            .setServiceAccountScopes(SCOPES)
            .setServiceAccountUser("exampleemail").build();         

    //credential.refreshToken();

    Gmail service = new Gmail.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(APPLICATION_NAME).build();

    String user = "me";
    Message123 obj = new Message123();
    obj.sendMessage(service, "me", obj.createEmail("exampleemail", "exampleemail",
            "Test", "Hi,\n\nTest Email\n\nThanks,\nSourav"));
}

In a class named 'Message123', I have written the sendMessage(). Below is the code for the same.

public Message sendMessage(Gmail service, String userId, MimeMessage emailContent) throws MessagingException, IOException 
{
    Message message = createMessageWithEmail(emailContent);
    message = service.users().messages().send(userId, message).execute();
    System.out.println("Message id: " + message.getId());
    System.out.println(message.toPrettyString());
    return message;
}

Note: Delegating domain-wide authority has not been granted to the service account

Could you please help with this? and here I would like to ask one more concern do we need to assign Delegating domain-wide authority to the service account even if I'm just sending email not reading/fetching any other user data?

Thanks for your help in advance

Upvotes: 1

Views: 2433

Answers (1)

guillaume blaquiere
guillaume blaquiere

Reputation: 75715

The problem come from this

Note: Delegating domain-wide authority has not been granted to the service account

In your use case, you want that the service account send an email on behalf of you. It's close to the description provided in the documentation

For example, an application that uses the Google Calendar API to add events to the calendars of all users in a G Suite domain would use a service account to access the Google Calendar API on behalf of users

The 401 error means that the service-account has been authenticated (either you will have a 403) but it's not authorize to perform the operation, to send an email on behalf of you

Upvotes: 3

Related Questions