Delivery Confirmation For Sent Mail - java

My requirement is to send E-Mail Alerts to various customers for our client for which, we're planning to use JavaMail API. However, once mail is sent, we need to update status in DB as Sent/Delivered/Failure depending on the status of the mail. Please tell me how do we get Delivery Notification for the mail reaching the Mail Server of the Receiver. It's not necessary to ensure whether the person has read the mail or not, however, it will be great if we'll be able to know that. The mandatory thing to check is for delivery. How can we get the status. What I read was that using 'SMTPMessage' we can get the status, however, I couldn't find a code sample for how to read the Notification. I am putting my code which is very sample of what I have done till now. Please let me know how I can achieve the thing which we are trying to fulfill.
public class MailSender {
private int port = 25;
private String host = "testmailsrvr";
private String from = "test#test.com";
private boolean auth = true;
private String username = "test";
private String password = "test#123";
private Protocol protocol = Protocol.SMTP;
private boolean debug = true;
public void sendEmail(String strMailID, String strSubject, String strBody) throws MessagingException{
Properties props = new Properties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", port);
switch (protocol) {
case SMTPS:
props.put("mail.smtp.ssl.enable", true);
break;
case TLS:
props.put("mail.smtp.starttls.enable", true);
break;
case SMTP:
props.put("mail.smtp.ssl.enable", false);
break;
}
Authenticator authenticator = null;
if (auth) {
props.put("mail.smtp.auth", true);
authenticator = new Authenticator() {
private PasswordAuthentication pa = new PasswordAuthentication(username, password);
#Override
public PasswordAuthentication getPasswordAuthentication() {
return pa;
}
};
}
Session session = Session.getInstance(props, authenticator);
session.setDebug(debug);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
InternetAddress[] toAddress = {new InternetAddress(strMailID)};
message.setRecipients(Message.RecipientType.TO, toAddress);
message.setSubject(strSubject);
message.setSentDate(new Date());
message.setText(strBody);
Transport.send(message);
}
}

You'll want to read these JavaMail FAQ entries:
If I send a message to a bad address, why don't I get a SendFailedException or TransportEvent indicating that the address is bad?
When a message can't be delivered, a failure message is returned. How can I detect these "bounced" messages?
Then read the javadocs for the com.sun.mail.smtp and com.sun.mail.dsn packages to learn about Delivery Status Notifications.

You will have to approach the issue differently. The Transport.send() method will throw a SendFailedException if it runs into problems sending to any of the recipients. The exception will give you information on which recipient addresses failed. You should catch that exception, get the failing addresses and record them.

You might want to look into http://www.ultrasmtp.com. This service will send a notice back to the recipient upon the message being accepted, deferred, or refused by the receiving mail server. There is also an option to setup alerts for opened messages.

Related

java- How to use services for sending email?

I have a simple web application where different users can log into it. One of the important feature is user can access a document and send email of it's content to an outsider like third party. Below is just how the email looks like to give an idea:
It's pretty self explanatory and I can send to multiple user if I want like abc#example.com,efg#hotmail.com,... in the field box shown.With all this, I am using Java Mail API to make it work and after hitting the send button,it sends directly to the recipient.No issue at all.
Now, I want to modify this by doing this email feature as a service.What this means is when I send the email,the content and info filled in will be stored in a table in MYSQL and the service(running in background) will pick up from the table and do the sending.
This is my function:
public void sendEmail(String recipient, String subject, String content,
String host, String port, final String senderaddress,
final String password) {
try {
System.out.println("Please Wait, sending email...");
/*Setup mail server */
Properties props = new Properties();
props.put("mail.smtp.host", host); //SMTP Host
props.put("mail.smtp.port", port); //TLS Port
props.put("mail.smtp.auth", "true"); //enable authentication
props.put("mail.smtp.starttls.enable", "true"); //enable STARTTLS
//create Authenticator object to pass in Session.getInstance argument
Authenticator auth = new Authenticator() {
//override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderaddress, password);
}
};
Session session = Session.getInstance(props, auth);
session.setDebug(true);
// Define message
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(senderaddress));
message.addRecipients(Message.RecipientType.TO,
InternetAddress.parse(recipient));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(content);
try {
Transport.send(message);
} catch (AddressException addressException) {
addressException.printStackTrace();
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
Can this be done in the way I want because I am unsure how to make it work?
1 ) After hitting Sending mail button from UI, You need to call a method for saving data like recipient, subject, content in DB
2)Write an email sender Service which retrieves non_delivered / pending mail from DB table and send it through Java Mail API
3)Scheduled email sender service with the help of ScheduledExecutorService

javax.mail.AuthenticationFailedException: 535 5.7.3 Cannot send mail

I'm having trouble with error
javax.mail.AuthenticationFailedException: 535 5.7.3
Authentication when trying to send an email. I've tried using two different email accounts. One using Office365 server details and the other using Gmail server details.
In both cases I get the same error. My code is below. Outside of my code the email addresses can send and receive email successfully without issue. This is my email class as it is the part that isn't working. All other aspects of my program work. Any help you can provide is greatly appreciated.
public class SPUREMAIL{
//CONSTANTS - Things that will never change
private static final String HOST = "smtp.office365.com";
private static final String PORT = "587";
private static final String SENDER = "EMAIL";
private static final String PASSWORD = "PASSWORD";
private static final String SUBJECT = "Spur Design has shared a file with you";
private static final String MESSAGE = "This email message was sent from an unmonitored address. Please contact your Spur Design representative for any questions or concerns";
//this item will change, its the direct link to the file
private String URLToFile;
private String recipient;
public SPUREMAIL(String URLToFile, String recipient){
this.URLToFile = URLToFile;
this.recipient = recipient;
}
//Properties for email
private Properties getProperties(){
Properties properties = new Properties();
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", HOST);
properties.put("mail.smtp.port", PORT);
properties.put("mail.smtp.user", SENDER);
properties.put("mail.smtp.password", PASSWORD);
return properties;
}
//Creating an email session so I can authenticate to server
Session session = Session.getInstance(getProperties(), new javax.mail.Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(SENDER, PASSWORD);
}
});
public void sendMail(){//This will actually attempt to send the email successfully
try{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject(SUBJECT);
message.setText(MESSAGE);
Transport.getTransport("smtp");
Transport.connect(HOST, SENDER, PASSWORD, pass);
Transport.sendMessage(MESSAGE, message.getAllRecipients());
}
catch(MessagingException e){
System.out.println("send failed, exception: " + e);
}
System.out.println("Sent!!!!");
}
}
Few suggestion which you can try and check if they work for you.
If you are trying outlook, I am assuming you are trying to connect your internal organization email servers. Try with port 25 and check if setting mail.smtp.starttls.enable to false make a difference.
I don't think you need to use username and password. You can remove it in case of outlook. You will need that in case of gmail.
You might want white-list your ip address by the firewall team. They have to allow connection from your machine.
Try installing a local email server, I have used papercut and it works like a charm.
Before sending your email using gmail you have to allow non secure apps to access gmail you can do this by going to your gmail settings.
Good luck.
have you checked this link -
javax.mail.AuthenticationFailedException: 535 5.7.3 Authentication unsuccessful
It says it could the mail server configuration issue for your organization where your email id is not allowed to send mail via code. May be your mail server administrator can help here.
Also, this link - https://confluence.atlassian.com/confkb/unable-to-send-email-due-to-javax-mail-authenticationfailedexception-error-message-151519398.html , says the cause could be the mail server configured incorrectly.
Sometimes a pretty change will make a huge response, this case is also like that. You have to give full mail address at username. Sender's mail id's username should be with #domain.com
username : ******_****#domain.com
The issue with my code was two-fold. One, the email class was not being compiled when I compiled the entirety of my project. This was causing my Transport calls to go unchecked. Changed the Transport calls to the bloc below and after manually compiling email class successfully I was able to send emails perfectly fine. All credit goes to Bill Shannon for pointing me in the right direction.
public void sendMail(){//This will actually attempt to send the email successfully
try{
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(SENDER));
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(recipient));
message.setSubject(SUBJECT);
message.setText(MESSAGE);
Transport.send(message, message.getAllRecipients());
}
catch(MessagingException e){
System.out.println("send failed, exception: " + e);
}
System.out.println("Sent!!!!");
}
}

SMTP measurement and evaluation

I'm trying to learn about how SMTP works (JAVAMAIL API).
I wrote a code that send message to a given list of adresses.
I used as properties for the SMTP server:
mail.smtp.auth= true
mail.smtp.starttls.enable= true
mail.smtp.host= smtp.gmail.com
mail.smtp.port= 587
the send email code is:
public void sendEmail(String emailRecip, String subject, String texte) {
boolean isMsgSent = false;
Session session = Session.getInstance(props,
new javax.mail.Authenticator() {
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(username, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress(username));
String address = emailRecip;
InternetAddress[] iAdressArray = InternetAddress.parse(address);
message.setRecipients(Message.RecipientType.TO,iAdressArray);
message.setSubject(subject);
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setText(texte);
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp1);
message.setContent(mp);
Transport.send(message);
isMsgSent = true;
} catch (MessagingException e) {
//...
}
}
This code works well, but i would like to know how can i:
1- calculate the avrage time of message delivery
2- calculate the impact of the size of the message
3- evaluate the impact of sending multiple messages on the same SMTP
I found many documentations that talke about those issus but i don't know how to put it in a code example, is there any other properties i must to add it to SMTP server?
JavaMail isn't going to do this for you. You're going to need some performance analysis tools. Find one you like and then apply it to this task. Or just do something simple yourself using System.currentTimeMillis() to measure the amount of time an operation takes.
See also this JavaMail FAQ entry for sending multiple messages with a single connection.

Mail API stopped to work

I have an automated java mail application that sends automated mail to users when some important update occur in our database. It was working fine. However it started to give me errors and I realized that it's not working.
The error says:
"Please log in via your web browser and then try again.
Learn more at https://support.google.com/mail/bin/answer.py?answer=78754 l10sm7526045oev.7 - gsmtp"
The java mail application that I write is huge and contains some confidential values(password etc.), I decided to write a sample demo to show you what's going on. It gives me the same error. Please assume that javax.MAIL API has been imported to the project. Here is what I have:
public class MailDemo {
public static void main(String[] args) {
final String userName = "dummyEmail#gmail.com";
final String password = "dummyPassword";
Properties props = new Properties();
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", "smtp.gmail.com");//Smtp server address
props.put("mail.smtp.port", "587");//port for the smtp server
Session session = Session.getInstance(props, new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication(){
return new PasswordAuthentication(userName, password);
}
});
try {
Message message = new MimeMessage(session);
message.setFrom(new InternetAddress("dummyEmail#gmail.com"));//from email address
message.setRecipients(Message.RecipientType.TO, InternetAddress.parse("dummyEmail#gmail.com"));//to email address
message.setSubject("My first Email");//Subject of the mail
message.setContent("<h1>This is a test email</h1>", "text/html; charset=utf-8");//Content of the mail
Transport.send(message);//send the message
System.out.println("Email Stiation:Done!");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Well, i found the problem. Actually the codes are correct. It's gmail. it blocks the sign in attempts.I think that gmail thinks the attempts are not real.

Email is sending but not receiving when use no authentication

I am sending email using
public void sendEmail(String fromEmailAddr, String toEmailAddr,String subject, String emailBody) {
String host = "xxx";
final String user = "user";
final String password = "password";
// Get system properties
Properties properties = new Properties();
// Setup mail server
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.port", "25");
// Get the default Session object.
Session session = Session.getDefaultInstance(properties, null);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(fromEmailAddr));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO, new InternetAddress(toEmailAddr));
// Set Subject: header field
message.setSubject(subject);
// Now set the actual message
message.setText(emailBody);
// Send message
Transport.send(message);
System.out.println("Sent message successfully....");
}catch (MessagingException mex) {
mex.printStackTrace();
}
}
When i try to send email using above code then it comes to message Sent message successfully.... but i got no email. On the other hand if i use authentication then i got the email
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(properties,
new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(user,password);
}
});
Why ? Is it necessary to provide userName and password for host ? Can i send email by just specifying host, no username and password provided ?
Thanks
I guess the port number might be the issue.
Try changing properties.put("mail.smtp.port", "25");
to properties.put("mail.smtp.port", "587");.
Further you can refer this.
It depends on the mail server you're using.
For example, some mail servers will let you send mail to anyone in the same company without authentication, but authentication is needed to send mail outside of the company. In the latter case, if you send the mail without authenticating, the mail server may accept the message and return a "mailer-daemon" failure message, or might just throw the message away.
Also, see this list of common JavaMail mistakes.

Categories