8

I have a Web Service deployed on Openshift. Currently what I'm developing is a kind of sending an automated email at a certain point, using my Gmail account.

So I have been documenting myself for two or three days and I've concluded that I've two options:

1) Using JavaMail library. 2) Using Gmail API.

For the first option What I've used is the following classes:

public class EmailSenderService {  
private final Properties properties = new Properties();  

private String password = "*******";  

private Session session;  

private void init() {  

    //ssl
    properties.put("mail.smtp.host", "smtp.gmail.com");
    properties.put("mail.smtp.socketFactory.port", "465");
    properties.put("mail.smtp.socketFactory.class",
            "javax.net.ssl.SSLSocketFactory");
    properties.put("mail.smtp.auth", "true");
    properties.put("mail.smtp.port", "465");

    session = Session.getDefaultInstance(properties,
        new javax.mail.Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("eu***@gmail.com",password);
            }
        });
}  

public void sendEmail(){  

    init();  

    //ssl
    try {
        Message message = new MimeMessage(session);
        message.setFrom(new InternetAddress("eu***@gmail.com"));
        message.setRecipients(Message.RecipientType.TO,
                InternetAddress.parse("c***6@gmail.com"));
        message.setSubject("Testing Subject");
        message.setText("Dear Mail Crawler," +
                "\n\n No spam to my email, please!");
        Transport t = session.getTransport("smtp");
        t.connect("smtp.gmail.com", "eu***@gmail.com", password);
        t.sendMessage(message, message.getAllRecipients());

        System.out.println("Done");

    } catch (MessagingException e) {
        e.printStackTrace();
    }   
}  
} 

And calling them using this:

EmailSenderService ess = new EmailSenderService();
        ess.sendEmail();

2) The second option I'm using is the following:

public class EmailSenderGmailApi {

/*
 * Atributos
 */
// Check https://developers.google.com/gmail/api/auth/scopes for all available scopes
private static final String SCOPE = "https://www.googleapis.com/auth/gmail.compose";
private static final String APP_NAME = "eu***l";
// Email address of the user, or "me" can be used to represent the currently authorized user.
private static final String USER = "eu***@gmail.com";
// Path to the client_secret.json file downloaded from the Developer Console
private static final String CLIENT_SECRET_PATH = "../app-root/data/eu***.json";

private static GoogleClientSecrets clientSecrets;


/*
 * Metodos
 */

public static Gmail init() throws IOException{

    System.out.println("***Working Directory = " + System.getProperty("user.dir"));


    HttpTransport httpTransport = new NetHttpTransport();
    JsonFactory jsonFactory = new JacksonFactory();

    clientSecrets = GoogleClientSecrets.load(jsonFactory,  new FileReader(CLIENT_SECRET_PATH));

    // Allow user to authorize via url.
    GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
        httpTransport, jsonFactory, clientSecrets, Arrays.asList(SCOPE))
        .setAccessType("online")
        .setApprovalPrompt("auto").build();

    String code = "***";

    // Generate Credential using retrieved code.
    GoogleTokenResponse response = flow.newTokenRequest(code)
        .setRedirectUri(GoogleOAuthConstants.OOB_REDIRECT_URI).execute();
    GoogleCredential credential = new GoogleCredential()
        .setFromTokenResponse(response);

    // Create a new authorized Gmail API client
    return new Gmail.Builder(httpTransport, jsonFactory, credential)
        .setApplicationName(APP_NAME).build();


}

/**
   * Create a MimeMessage using the parameters provided.
   *
   * @param to Email address of the receiver.
   * @param from Email address of the sender, the mailbox account.
   * @param subject Subject of the email.
   * @param bodyText Body text of the email.
   * @return MimeMessage to be used to send email.
   * @throws MessagingException
   */
  public static MimeMessage createEmail(String to, String from, String subject,
      String bodyText) throws MessagingException {

      System.out.println("***Empezando a enviar email...");

    Properties props = new Properties();
    Session session = Session.getDefaultInstance(props, null);

    MimeMessage email = new MimeMessage(session);
    InternetAddress tAddress = new InternetAddress(to);
    InternetAddress fAddress = new InternetAddress(from);

    email.setFrom(new InternetAddress(from));
    email.addRecipient(javax.mail.Message.RecipientType.TO,
                       new InternetAddress(to));
    email.setSubject(subject);
    email.setText(bodyText);
    return email;
  }

  /**
   * Create a Message from an email
   *
   * @param email Email to be set to raw of message
   * @return Message containing base64 encoded email.
   * @throws IOException
   * @throws MessagingException
   */
  public static Message createMessageWithEmail(MimeMessage email)
      throws MessagingException, IOException {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    email.writeTo(bytes);
    String encodedEmail = Base64.encodeBase64URLSafeString(bytes.toByteArray());
    Message message = new Message();
    message.setRaw(encodedEmail);
    return message;
  }

  /**
   * Send an email from the user's mailbox to its recipient.
   *
   * @param service Authorized Gmail API instance.
   * @param userId User's email address. The special value "me"
   * can be used to indicate the authenticated user.
   * @param email Email to be sent.
   * @throws MessagingException
   * @throws IOException
   */
  public static void sendMessage(Gmail service, String userId, MimeMessage email)
      throws MessagingException, IOException {
    Message message = createMessageWithEmail(email);
    message = service.users().messages().send(userId, message).execute();

    System.out.println("Message id: " + message.getId());
    System.out.println(message.toPrettyString());
  }

}

The first option, when calling to it, the message which is shown in Openshift COnsole is the following:

javax.mail.AuthenticationFailedException
    at javax.mail.Service.connect(Service.java:306)
    at javax.mail.Service.connect(Service.java:156)
    at main.java.model.EmailSenderService.sendEmail(EmailSenderService.java:86)
    at main.java.model.AccessManager.renewPassStepOne(AccessManager.java:234)
    at main.java.webService.UsuarioService.renewPassStepOne(UsuarioService.java:192)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:302)
    ...

I've been trying to fix it by myself, looking at google, stackoverflow... But every change I introduce, the same message I get.

In option 2, I don't know how to use it. I'm trying something like that:

MimeMessage msg = EmailSenderGmailApi.createEmail("ca***@gmail.com", "eu***@gmail.com", "test", "holaaaaa");

        EmailSenderGmailApi.sendMessage(
                EmailSenderGmailApi.init(), 
                "cap***@gmail.com", 
                msg);

Anyway, to be honest I have investigated a lot of Java Mail, I hope someone can give me a hand solving any error I would have.

In relation to Gmail Api, on official documentation I haven't been able to figure out how to send an email. Neither there isn't so much documentation over the internet.

Could somebody lend me a hand?

Eric D
  • 6,901
  • 1
  • 15
  • 26
joninx
  • 1,775
  • 6
  • 31
  • 59

4 Answers4

6

The Gmail API public docs have a guide on sending email and it even has java sample code:

https://developers.google.com/gmail/api/guides/sending

Your code above doesn't seem that far off though. I'd first make sure you got Oauth2 working right by doing something simple like labels.list() and if that works then move on to something more complicated like sending an email. (You have the right idea constructing, turning into a string, base64url encoding and then sending it though.) What is the exact problem you're getting whist trying to send it with the Gmail API? Got some error output or missing something in your code?

Eric D
  • 6,901
  • 1
  • 15
  • 26
  • Thanks.I'll take a look to it this week. I'll inform you if I get it. My problem is that I don't know how to create the "Gmail service" parameter to use it in sendMessage. – joninx Oct 20 '14 at 12:03
  • Ah ok. Should be pretty standard with other Google APIs like calendar, drive, Plus so likely getting started/quickstarts for them that show it should work for Gmail with appropriate substitutions. I'll add some tags to hopefully help get more eyes on it. – Eric D Oct 20 '14 at 17:19
3

If you are using Java Mail API in your openshift application,

Then adding any new libraries in the application, you have to add its maven-configuration in the pom.xml file. Or in other words, you have to add dependency in the pom.xml file.

this is the dependency for mail-1.4.7 Just add this code in the pom.xml file

<dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.7</version>
    </dependency>

Similarly, for any other integrations, not forget to add dependencies. You can search in google : "maven dependency for ________"

Parth Pithadia
  • 276
  • 1
  • 3
  • 18
0

In order to send email using a gmail account, we have to follow some most important points:

The google account using which you want to send email must have “app password” enabled

Go to your google account and click on “security”.

Scroll down to “How you sign in to Google'' section and enable 2-factor authentication.

Now refresh your google account page.

Search “app password” in the search bar of your google account. Select the option from dropdown. Note that you will not see the “app password” option if you have not enabled 2-factor authentication.

You will be asked for a password. After verification of password. You will see two options.

select “other(custom name)” from “select app” drop down. Provide any name of your choice.

A password will automatically be generated. Store that password in a safe place.

Now you are ready for the mail api.

Required Jar:

  1. angus-activation-1.0.0.jar
  2. jakarta.activation-api-2.1.1.jar
  3. jakarta.mail-1.0.0.jar
  4. jakarta.mail-api-2.1.1.jar

If you are working on maven then use the following dependency:

<dependency>
    <groupId>org.eclipse.angus</groupId>
    <artifactId>jakarta.mail</artifactId>
    <version>2.0.2</version>
</dependency>
import java.io.File;
import java.io.IOException;
import java.util.Properties;

import jakarta.mail.Authenticator;
import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.PasswordAuthentication;
import jakarta.mail.Session;
import jakarta.mail.Transport;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMessage;
import jakarta.mail.internet.MimeMultipart;

public class Email {
    // Method To Send Plain Text Email
    public void sendPlainTextEmail(String senderMailAddress,String recieverMailAddress,String password) throws MessagingException {
        Properties props = new Properties();
        props.put("mail.smtp.auth","true");
        props.put("mail.smtp.starttls.enable","true");
        props.put("mail.smtp.port","587");
        props.put("mail.smtp.host","smtp.gmail.com");
        
        Session session = Session.getInstance(props, new Authenticator() {
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(senderMailAddress, password);
            }
        });

        MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(senderMailAddress));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(recieverMailAddress));
            message.setSubject("Mail Subject");         
            message.setText("Enter your message here");

            Transport.send(message);
            
            System.out.println("Check your inbox");
    }
    
    // Method To Send Email With Attachments
    public void sendEmailWithAttachment(String senderMailAddress,String recieverMailAddress,String password) throws MessagingException, IOException {
        Properties props = new Properties();
        props.put("mail.smtp.auth","true");
        props.put("mail.smtp.starttls.enable","true");
        props.put("mail.smtp.port","587");
        props.put("mail.smtp.host","smtp.gmail.com");
        
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(senderMailAddress, password);
            }
        });
        MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(senderMailAddress));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(recieverMailAddress));
            message.setSubject("Mil gaya");         

            MimeBodyPart part1 = new MimeBodyPart();
            part1.setText("This is text");
            
            MimeBodyPart part2 = new MimeBodyPart();
            part2.attachFile(new File("E:\\R.jpeg"));
            part2.setContent("This is my content","text/html; charset=utf-8");
            
            MimeMultipart multipart = new MimeMultipart();
            multipart.addBodyPart(part2);
            multipart.addBodyPart(part1);
            
            message.setContent(multipart);
            Transport.send(message);            
            System.out.println("sent");
    }
    
    public static void main(String[] args) {
        Email e = new Email();
        try {
            // e.sendPlainTextEmail("sender@gmail.com", "reciever@gmail.com", "appPassword");
            e.sendEmailWithAttachment("sender@gmail.com", "reciever@gmail.com", "appPassword");
        } catch (MessagingException | IOException e1) {
            e1.printStackTrace();
        }
    }
}