Is there any way to check email status when I'm sending email? I know at least 3 statuses: sent, deferred, denied, and I want to do some logic depends on it. I've tried a lot of libraries like javax.mail, simpejavamail and didn't find any way to get status.
My last attempt was:
String from = "********";
String pass = "*********";
// String[] to = { "to_mail_address#****.com" };
String host = "smtp.yandex.ru";
Properties props = System.getProperties();
props.put("mail.smtp.host", host);
props.put("mail.smtp.user", from);
props.put("mail.smtp.password", pass);
props.put("mail.smtp.port", "465");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.ssl.enable", "true");
props.put("mail.smtp.quitwait", "false");
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.debug", "true");
Session session = Session.getDefaultInstance(props, null);
SMTPTransport transport = (SMTPTransport) session.getTransport("smtp");
transport.connect(from,pass);
SMTPMessage message = new SMTPMessage(session);
message.setReturnOption(2);
message.setNotifyOptions(7);
message.setFrom(new InternetAddress("******"));
message.setRecipients(
Message.RecipientType.TO, InternetAddress.parse("******"));
message.setSubject("Test mail");
String msg = "This is my first email using JavaMailer";
MimeBodyPart mimeBodyPart = new MimeBodyPart();
mimeBodyPart.setContent(msg, "text/html; charset=utf-8");
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(mimeBodyPart);
message.setContent(multipart);
transport.sendMessage(message,InternetAddress.parse("zcaxc#inbox.ua"));
var i1 = transport.getLastReturnCode();
var i2 = transport.getReportSuccess();
return transport.getLastServerResponse();
}
I get response from server like this:
250 2.0.0 Ok: queued on vla5-3832771863b8.qloud-c.yandex.net
1656683490-NIUBgcx5PS-pUSKMoc1
It does not change if I send email to an invalid address.
So, I have a couple of questions
What is the best way to do it
Do all SMTP servers do response and what to do if they don't
Sending email is asynchronous, your SMTP server accepted the message, and will try to deliver it. If delivery fails (from your SMTP to the next SMTP server, or from an intermediate SMTP server to the final SMTP server), a bounce message will be generated, which will be sent to the envelope sender address of the message.
If you want to know about delivery failures, you need to monitor the mailbox of the envelope sender address, and parse the received bounces (e.g. using JakartaMail's dsn.jar, specifically com.sun.mail.dsn.DeliveryStatus). See also RFC 3464.
In theory, you can track successful delivery by requesting delivery status notification (which are basically "positive" bounces, delivered in the same way), but in my experience, a lot of mail servers do not honor requests for DSNs. So, in general it is better to simply assume successful delivery as long as you haven't received a bounce.
Related
When I try to send mail in java from my personal email like (sp#gmail.com) it is sent successfully.
But when I am using my company email(sp#example.com) it throws Authentication failed exception. I am using TLS authentication and it is successfully connected to host.
When I am manually login on my email it will always ask for Two Step
verification. Even if I have disabled my two step verification and have also done the change to make it less secure, it still asks for two step verification as it is showing this message after putting my username and password:
2-Step Verification
Based on your organization's policy, you need to turn on 2-step verification. Contact your administrator to learn more.
Enter one of your 8-digit backup codes
In this situation what should I do? As this is my first task in this company, I would be so happy if you could help me. How I can solve this problem?
My code :
String to = "abc#example.com";
String user = "sp#example.com";
String pass = "1234";
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.example.com");
props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
Session session = Session.getInstance(props,new javax.mail.Authenticator()
{
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(user,pass);
}
});
session.setDebug(true);
try
{
/* Create an instance of MimeMessage,
it accept MIME types and headers
*/
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(user));
message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
message.setSubject(sub);
message.setText(msg);
/* Transport class is used to deliver the message to the recipients */
Transport.send(message);
}
catch(Exception e)
{
e.printStackTrace();
}
Error message:
535 5.7.3 Authentication unsuccessful javax.mail.AuthenticationFailedException at javax.mail.Service.connect(Service.java:319) at javax.mail.Service.connect(Service.java:169) at javax.mail.Service.connect(Service.java:118) at javax.mail.Transport.send0(Transport.java:188) at javax.mail.Transport.send(Transport.java:118) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
SMTP configuration:
configuration:props.put("mail.smtp.host", "smtp.oceaneering.com"); props.put("mail.smtp.port", "587");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");
First is need to turn on 2-Step Verification .(after that google script to give new option for creation app passwords) https://support.google.com/accounts/answer/185839?
Next you must to create the app passwords https://support.google.com/accounts/answer/185833?hl=en
Last step to replace this line in your code
String pass = "1234"; - with app specific password, (it must generate on step 2) Some like String pass = "djd5n7hsd";
And For future reader in may be useful to check network and firewall setting on your system and mail setting your ISP. To check if packet can to reach gmail server.
Try telnet command : telnet smtp.gmail.com 587
The code I am currently using is as follows:
String to = "....#gmail.com";
String from = ".....#gmail.com";
String host = "127.0.0.1";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
Session session = Session.getDefaultInstance(properties);
try {
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
message.setSubject("This is the Subject Line!");
message.setText("This is actual message");
Transport.send(message);
System.out.println("Sent message successfully....");
} catch (MessagingException mex) {
mex.printStackTrace();
}
If I paste the above code in my Java servlet and run it, the following exception gets thrown:
javax.mail.NoSuchProviderException: smtp
I have also tried following the solutions outlined in these resources but to no avail: link1 link2 link3 link4.
It would help if you included the the full stacktrace for the javax.mail.NoSuchProviderException and JavaMail debug output. Because you are running this in a servlet container you could be running into Bug 6668 -skip unusable Store and Transport classes. Change your call to Transport.set to the following:
final ClassLoader ccl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(Session.class.getClassLoader());
try {
Transport.send(message);
} finally {
Thread.currentThread().setContextClassLoader(ccl);
}
That code will isolate which transport class the code is allowed to see. That will rule out that bug in your code.
NoSuchProviderException means something is messed up in your JavaMail API configuration. Where and how have you installed the JavaMail jar file?
Also, in case it's not clear from the other responses, the only way you're going to be able to send mail without authentication is if you're running your own mail server. You can't do it with general purpose online e-mail services (e.g. Gmail).
First of all, if you wanna use gmail to send emails from your program you need to define stmp host as gmail. Your current host "127.0.0.1" is localhost meaning your own computer? Do you have mail server running on your computer?
Here you can see some tutorial how to send an email using gmail: http://www.mkyong.com/java/javamail-api-sending-email-via-gmail-smtp-example/
If you're afraid to pass your normal gmail account details then create some kind of test email like kselvatest or something.
You are missing pretty much those:
final String username = "username#gmail.com";
final String password = "password";
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");
props.put("mail.smtp.port", "587");
So basicly all you need to add is:
1.login and password so JavaMail can use some gmail account
2.declare which mail server you wanna use
change String host = "127.0.0.1"; to String host = "smtp.gmail.com";
3.set mail port
For this code you should get javax.mail.MessagingException: Could not connect to SMTP host: 127.0.0.1, port: 25; exception
But I suspect you have a jre issue. May be smtp implementation has a problem. Why don't you download java mail implementation from http://www.oracle.com/technetwork/java/javamail/index-138643.html and add it to your project class path and try?
I am trying to send an email with javamail api, and then copy it to sent folder.
I am using yahoo mail.
I can send the email, but the copy to sent folder doesn't work.
Here is the code to copy to sent folder :
private void copyIntoSent(Session session,Message msg) throws MessagingException{
Store store = session.getStore("imap");
store.connect("imap.mail.yahoo.com", SMTP_AUTH_USER, SMTP_AUTH_PWD);
Folder folder = (Folder) store.getFolder("Inbox.Sent.Notifications");
if (!folder.exists()) {
folder.create(Folder.HOLDS_MESSAGES);
}
folder.open(Folder.READ_WRITE);
folder.appendMessages(new Message[]{msg});
}
I am getting this exception :
com.sun.mail.util.MailConnectException: Couldn't connect to host,
port: imap.mail.yahoo.com, 143; timeout -1; nested exception is:
java.net.ConnectException: Connexion terminée par expiration du délai
d'attente
I don't know if the problem only comes from my settings of IMAP or if the method to copy to sent folder is wrong.
Thanks in advance.
EDIT : send email code :
Properties properties = System.getProperties();
// Setup mail server
properties.put("mail.smtp.starttls.enable", "true");
properties.put("mail.smtp.host", host);
properties.put("mail.smtp.user", from);
properties.put("mail.smtp.password", pass);
properties.put("mail.smtp.port", "587");
properties.put("mail.smtp.auth", "true");
// Get the default Session object.
Session session = Session.getDefaultInstance(properties);
try{
// Create a default MimeMessage object.
MimeMessage message = new MimeMessage(session);
// Set From: header field of the header.
message.setFrom(new InternetAddress(from));
// Set To: header field of the header.
message.addRecipient(Message.RecipientType.TO,
new InternetAddress(to));
// Set Subject: header field
message.setSubject("This is the Subject Line!");
// Now set the actual message
MimeBodyPart messageBodyPart2 = new MimeBodyPart();
String filename = "SendAttachment.java";//change accordingly
File f = new File("/path_to_file/test.pdf");
MimeBodyPart attachmentPart = new MimeBodyPart();
attachmentPart.attachFile(f);
Multipart multipart = new MimeMultipart();
multipart.addBodyPart(attachmentPart);
message.setContent(multipart);
// Send message
Transport transport = session.getTransport("smtp");
transport.connect(host, from, pass);
transport.sendMessage(message, message.getAllRecipients());
copyIntoSent(session, message);
transport.close();
You need to use SSL with IMAP for Yahoo. Set "mail.imap.ssl.enable" to "true".
Also, since you're using transport.connect explicitly, you shouldn't need to set "mail.smtp.host" and "mail.smtp.user"; and there is no "mail.smtp.password" property so you don't need to set that either.
And you should probably change Sesion.getDefaultInstance to Session.getInstance.
From your exception it seems that your code is trying to connect to port 143 that's wrong use below settings for yahoo.
Incoming Mail (IMAP) Server
Server - imap.mail.yahoo.com
Port - 993
Requires SSL - Yes
And yes, imap allows 2-way synchronizing, which means everything you do remotely is reflected back in your Yahoo Mail account.so i don't think you externally need to move a mail to sent folder by default it will be reflected in sent mails of account
Instead of port 25 I want to be able to set the port to be whatever I want, along with the host. But I do not want to set the username or password because credentials will vary. My code base was working fine just using the static method Transport.send() to perform the task of sending out emails.
Transport has a connect method with no arguments or a method host/port/auth credentials.
There does not seem to be a way to set just the port and host without using the other two.
Transport seems to default to 25 no matter what I try. I am using a tool called smtp4dev to listen on ports that I am testing.
The important bits of the code are below:
Properties props = new java.util.Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.host", "localhost");//Just using localhost for testing
props.put("mail.smtp.port", 3500);//Whatever port
props.setProperty("mail.smtp.auth", "false");
session = Session.getInstance(props);
msg = new MimeMessage(session);
Transport transport = session.getTransport("smtp");
transport.connect(); //transport.connect("localhost", 3500, "","");
transport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
transport.close();
I can inspect session and see that it has the port property set in it, but when I inspect transport I only see the defaultPort as being set. I tried using a blank username, and password to no avail. Any ideas? Am I doing something dumb?
This is what fixed it, just use SMTPTransport instead and it works. I also used port as a string instead of an int.(I then had to unblock the port)
import com.sun.mail.smtp.SMTPTransport;
Properties props = new java.util.Properties();
props.setProperty("mail.transport.protocol", "smtp");
props.setProperty("mail.smtp.host", "localhost");//Just using localhost for testing
props.setProperty(SMTP_PORT_PROPERTY, String.valueOf(3500));//Whatever port
props.setProperty("mail.smtp.auth", "false");
session = Session.getInstance(props);
msg = new MimeMessage(session);
SMTPTransport transport = (SMTPTransport) session.getTransport("smtp");
transport.connect(); //transport.connect("localhost", 3500, "","");
transport.sendMessage(msg, msg.getRecipients(Message.RecipientType.TO));
transport.close();
The data type of the property value "mail.smtp.port" must be string.
Try changing this:
props.put ("mail.smtp.port", 3500);
to:
props.put ("mail.smtp.port", "3500");
I am trying to send mail using Java mail to distribution list(group mail id) and its a success. but thing is its recieved in junk box in MS Outlook by default. How to make it been delivered to Inbox?
Mail from donotreply#.com should be delivered to Inbox.
String host = "SMARTHOST.XXXX.COM";
Properties prop = new Properties();
prop.load(PDFGenerator.propLoad());
Properties properties = System.getProperties();
properties.put("mail.smtp.host", host); // smtp.gmail.com?
properties.put("mail.smtp.port", "25");
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session);
// From e-mail Id
message.setFrom(new InternetAddress("donotreply#example.com"));
message.addRecipients(Message.RecipientType.TO, "groupmailId#example.com");
In outlook add the sender's email to the safe senders list. This has nothing to do with java, sendmail, etc... It has to do with a spam filter.