0


my application need to send and receive email so using business GSuite I created an account my-app@mydomain.com and I want to use java gmail api to send and receive email. I followed the google documentation to create and authorise the service account as follow:

  • I created a service account
  • I enabled G Suite Domain-wide Delegation(I think this is not needed as I'm not impersonate another user)
  • I generated and downloaded the key in credentials.json
  • Authorised the client in the admin console for scopes:

    https://mail.google.com/
    https://www.googleapis.com/auth/gmail.compose
    https://www.googleapis.com/auth/gmail.insert
    https://www.googleapis.com/auth/gmail.labels
    https://www.googleapis.com/auth/gmail.metadata
    https://www.googleapis.com/auth/gmail.modify
    https://www.googleapis.com/auth/gmail.readonly
    https://www.googleapis.com/auth/gmail.send
    https://www.googleapis.com/auth/gmail.settings.basic
    https://www.googleapis.com/auth/gmail.settings.sharing

Then try to send the email as follow:


    public Credential getCredentials(final Set<String> scopes) throws IOException, GeneralSecurityException {
        return GoogleCredential
               .fromStream(GoogleCredentialServices.class.getResourceAsStream("credentials.json"))
               .createScoped(scopes);
    }

    public void init() throws GeneralSecurityException, IOException {
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        gmailServices = new Gmail.Builder(
               HTTP_TRANSPORT, 
               JSON_FACTORY,
               googleCredentialServices.getCredentials(GmailScopes.all()))
               .setApplicationName(applicationName)
               .build();
    }

    public MimeMessage createEmail(final String to, final String from, final String subject, final String bodyText) throws MessagingException {
        final Properties props = new Properties();
        final Session session = Session.getDefaultInstance(props, null);
        final MimeMessage email = new MimeMessage(session);
        email.setFrom(new InternetAddress(from));
        email.addRecipient(javax.mail.Message.RecipientType.TO, new InternetAddress(to));
        email.setSubject(subject);
        email.setText(bodyText);
        return email;
    }

    public Message createMessageWithEmail(final MimeMessage emailContent) throws MessagingException, IOException {
        final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        emailContent.writeTo(buffer);
        final byte[] bytes = buffer.toByteArray();
        final String encodedEmail = Base64.encodeBase64URLSafeString(bytes);
        final Message message = new Message();
        message.setRaw(encodedEmail);
        return message;
    }

    public Message sendMessage(final MimeMessage emailContent) throws MessagingException, IOException {
        final Message message = createMessageWithEmail(emailContent);
        return gmailServices.users().messages().send("mail@mydomain.com", message).execute();
    }

    @Test
    public void createAndSendGMailTest() throws MessagingException, IOException {
       final MimeMessage emailContent = createEmail("dest@domain.com", "my-app@mydomain.com", "subject", "message body");
       final Message message = sendMessage(emailContent);
       System.out.println("message: " + message);
    }

When I run the test I got this error

com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Bad Request",
    "reason" : "failedPrecondition"
  } ],
  "message" : "Bad Request"
}
at com.google.api.client.googleapis.json.GoogleJsonResponseException.from(GoogleJsonResponseException.java:150)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1108)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)

Anyone can help me to understand what causing this error?

ippul
  • 1
  • 1
  • Service accounts only work with gsuite domain accounts. So yes you need to set up domain wide delegation to your gsuite. – Linda Lawton - DaImTo Apr 24 '20 at 13:43
  • GmailScopes.all <-- has your company considered what its going to cost to have that scope verified by google? – Linda Lawton - DaImTo Apr 24 '20 at 13:44
  • @DaImTo The [Gmail REST API : 400 Bad Request + Failed Precondition](https://stackoverflow.com/questions/29327846/gmail-rest-api-400-bad-request-failed-precondition) didn't answer the question: it use the .p12 approach instead of the .json one, and the code in the answer is not correct – ippul Apr 24 '20 at 16:29

0 Answers0