Gmail SMTP Suitable For Production Messaging - java

I have some automated emailing tasks set up in my application. That is every day I send application specific email to customers to remind them of appointments etc. Is using Gmail's smtp suitable for production tasks beyond just a simple message here any there? Is there any benefit to implementing my own smtp server such as Apache James?

I agree with #Richthofen - Using gmail to send emails in a production environment is a bad (and unethical) idea; Amazon SES or Sendgrid are the best solutions here. If you want to run your own SMTP server then please keep in mind that it will share resources with your application and will probably slow it down.
However I use gmail to test development/testing environments using javamail API. Here's the code:
public class EmailSender{
public void send(){
//javamail code
Session mailSession = createSmtpSession();
//javamail code
}
private Session createSmtpSession() {
final Properties props = new Properties();
props.setProperty ("mail.host", "smtp.gmail.com");
props.setProperty("mail.smtp.auth", "true");
props.setProperty("mail.smtp.port", "" + 587);
props.setProperty("mail.smtp.starttls.enable", "true");
props.setProperty ("mail.transport.protocol", "smtp");
// props.setProperty("mail.debug", "true");
return Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(
"<gmail ID in user#domain format goes here>",
"<password goes here>");
}
});
}
}

Gmail TOS prohibits unsolicited commercial emails. In general I wouldn't deploy any service that relies on Gmail to the public. I think Gmail caps an email recipient list to 100 anyways so it would probably fail if you tried to send the same message to more than 100 people.
Usually you want your own IP for outgoing mail for reputation reasons. For most of my clients when I do freelance work I recommend affordable partner services like http://sendgrid.com/ ... Having your own IP means that you can manage your reputation as a bulk email sender legitimately. And you won't have to worry about Gmail shutting you down for breaking the TOS. Gmail also won't give you metrics about deliverability so you won't have any idea if you're being successful in sending these.
Having worked for a major email marketer, I can tell you that just sending a message to an SMTP server is not enough these days. All major mail service providers do things like require sender identification keys for bulk mail. They also meter messages and flag senders who end up submitting too many messages in a specific amount of time. If you want your mail delivered and not in the SPAM folder you need to do either a lot of work and spin up a dedicated server w/ a dedicated IP, or you should use a vendor who can do some of that work for you.

Related

Read sent mails using smtp java

I have been trying lot of things from multiple resources like Read Inbox Java2s
and How to get the list of available folders in a mail account using JavaMail
I am sending emails succesfully, but to be sure of mail is sent successfully, i need to read emails from sent items folder Is this possible with smtp? if yes, how?
Currently I am stuck even in connceting with stroe. I am finding no way to pass the steps
Store store = session.getStore(); and store.connect();
I have no idea about imap or pop3. They might not have been even configured at our server, but if smtp does not faicilitate then I am ready to process with those protocols, though I am sending mails using stmp yet. I have tried lot of edits in my following code, but nothing is helping
String host = "mysite.smtp.com";
Properties props = new Properties();
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.host", host);
props.put("mail.smtp.port", "myport");
props.put("mail.smtp.auth", "true");
Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
String user = "myname";
String password = "mypassword";
return new PasswordAuthentication(user, password);
}
});
Store store = session.getStore(); // had tried writing "imaps" here
store.connect(host, null, null);
//store.connect(); also tried this
Folder inbox = store.getFolder("INBOX"); //actually i need "SENT"
if (inbox == null) {
System.out.println("No INBOX");
System.exit(1);
}
inbox.open(Folder.READ_ONLY);
Message[] messages = inbox.getMessages();
for (int i = 0; i < messages.length; i++) {
System.out.println("Message " + (i + 1));
messages[i].writeTo(System.out);
}
inbox.close(false);
store.close();
You can't use smtp to read email, you need to use imap. pop3 won't help because it only lets you read the Inbox.
Depending on what you mean by "sent successfully", a successful return from the send method will tell you what you want to know.
Note also that depending on the mail server you're using, sent messages don't automatically appear in a "Sent Messages" folder; you might need to copy them their yourself after sending the message. (Gmail does this automatically, but not all other servers do.)
If what you really want to know is that the message was successfully delivered to the destination mail server(s) and all the addresses were valid, that's harder. The JavaMail FAQ has more information.
I know that I am answering late. I encountered quite similar problems while maintaining a software using extensively mail sending functionalities. I finally created a JUnit extension to write integration tests with a SMTP server emulation.
Please have a look to github.com/sleroy/fakesmtp-junit-runner/. By the way it's open-source.
Refer this link:
How to save sent items mail using the Java mail API?
Sent Mail Service using JAVAMAIL API
Note also that depending on the mail server you're using, sent messages don't automatically appear in a "Sent Messages" folder; you might need to copy them their yourself after sending the message. (Gmail does this automatically, but not all other servers do.)

Javamail error: SMTPAddressFailedException: 450 too many connections from your IP (rate controlled)

I have a Spring 4.1.1 web application in which the user can set some scheduled tasks. When these tasks complete the administrator will receive an automatic email sent with the SMTP method.
For the email I use the jars: javax.mail-api-1.5.2.jar and mail-1.5.0-b01.jar
The email are sent correctly at first, but when the frequency of the tasks goes up eventually I start to get the following exception and all subsequent emails fails. I can send about 30 emails in a 10 minutes window.
com.sun.mail.smtp.SMTPAddressFailedException: 450 too many connections from your IP (rate controlled)
at com.sun.mail.smtp.SMTPTransport.rcptTo(SMTPTransport.java:1862)
at com.sun.mail.smtp.SMTPTransport.sendMessage(SMTPTransport.java:1118)
at com.synaptic.email.MessageMail.sendMessage(MessageMail.java:152)
at com.synaptic.email.EmailManagerImpl.sendGeneralEmail(EmailManagerImpl.java:423)
The code snippet from which I send the emails is:
public void sendMessage(Brand brand, String timeout) throws MessagingException
{
try {
// Prepare message
Properties props = new Properties();
props.put("mail.smtp.host", mailHost);
props.put("mail.smtp.connectiontimeout", timeout);
props.put("mail.smtp.timeout", timeout);
props.put("mail.smtp.writetimeout", timeout);
props.put("mail.smtp.port", Integer.parseInt(brand.getBrandProperties().getEmailPort()));
Session session = Session.getInstance(props);
message = new MimeMessage(session);
createMessage();
if (brand.getBrandProperties().getEmailUsername().isEmpty() && brand.getBrandProperties().getEmailPassword().isEmpty()) {
// Send email message to SMTP server without auth
Transport.send(message);
} else {
// Send message with auth
Transport.send(message,brand.getBrandProperties().getEmailUsername(),brand.getBrandProperties().getEmailPassword());
}
} catch (MessagingException e) {
log.error("Failed to send email message.", e);
throw e;
}
}
From the javamail documentation and source code seems clear that the transport connection are closed on a finally statement, so no connection should be hanging open, but still I hit this exception.
I checked online but I can't find a way to increase this limit.
Am I doing something wrong sending the message? is there a way to monitor the email connections? or is an email server issue?
Your server is telling you that you're making too many connections in too short a time. It's rate-limiting you to prevent you from abusing the server. You may need to pay for a higher quality of service to be allowed to send more messages. Contact your ISP for details.
BTW, you say you're using javax.mail-api-1.5.2.jar and mail-1.5.0-b01.jar. You should not mix and match versions like that. You only need one jar file - the javax.mail-1.5.2.jar file. You can get it on the JavaMail project page.

Too much time to send mail with MS exchange SMTP server

Hi all and thanks for your help
I use javamail to send mail throhght office365 SMTP server ( smtp.office365.com) , but for some reason it keeps about 60-80 seconds to send mail.
stringaHost = "mail.smtp.host";
stringaUser = "mail.smtp.user";
Security.setProperty("ssl.SocketFactory.provider","com.ibm.jsse2.SSLSocketFactoryImpl");
Security.setProperty("ssl.ServerSocketFactory.provider","com.ibm.jsse2.SSLServerSocketFactoryImpl");
InitialContext initialContext = null;
initialContext = new InitialContext();
session = (Session)initialContext.lookup(nomeJndi);
session.getProperties().put("mail.smtp.auth", "true");
session.getProperties().put("mail.smtp.socketFactory.port", 465);
session.getProperties().put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
MimeMessage MsgEmail = new MimeMessage( session );
com.sun.mail.smtp.SMTPTransport t =(com.sun.mail.smtp.SMTPTransport)session.getTransport("smtp");
t.setStartTLS(true);
t.connect( smtp.office365.com,myUser,myPassword);
t.sendMessage( MsgEmail, MsgEmail.getAllRecipients());
t.close();
java mail spend more than 60 sec to evaluate instruction : t.connect(....) .
Any clue about what can happen and how can this time interval can be reduced ?
P.S. i tried to use t.connect() without parameters, by system technical says that this instruction use SMTP transport protocol from operating system and don't use Office365 server transport protocol
thanks
First, you shouldn't need all those socket factory properties.
If the delay is on the connect call, the possibilities are:
Your name service is slow in looking up the IP address for the server's host name.
The SSL negotiation is slow, perhaps due to certificate management on the client or server.
The server is slow authenticating you.
You can test #1 by seeing how long it takes InetAddress to look up the host name for your server.
You can test #2 by seeing how long it takes SSLSocket to make a connection to the server.
You can test #3 by either watching the JavaMail debug output in real time to see where the delay is, or getting time-stamped log messages from JavaMail.

How to read the UNREAD email using java mail api

I am trying to read the UNREAD mails from gmail account. I tried to filter the messages based on the Flags, but it did not work. I printed the Flags sent on each message, but nothing is set on it, because of which I could not filter the messages. I used the keyword Flags.Flag.SEEN to filter the messages.
After googling, I found out that it is something with the email client. For ex, we need to the change the configuration in gmail or any exchange mail server. Can you please tell me on what to change the configuration to read the UNREAD mails?
Also, end of day, I am going to implement the code into one of the smtp exchange servers. Please let me know if there needs a special configuration. So that I can inform the respective team and then implement my change.
// connects to the message store
Store store = session.getStore("pop3");
store.connect(userName, password);
// opens the inbox folder
Folder folderInbox = store.getFolder("INBOX");
System.out.println("unread count - " + folderInbox.getUnreadMessageCount());
folderInbox.open(Folder.READ_WRITE);
// folderInbox.search(new FlagTerm(new Flags(Flags.Flag.RECENT),
// false));
// fetches new messages from server
Message[] arrayMessages = folderInbox.search(new FlagTerm(new Flags(Flags.Flag.RECENT), false));
The POP3 protocol doesn't support any flags. Use IMAP.
See Retrieving all unread emails using javamail with POP3 protocol.
One comment suggests the use of Flags.Flag.SEEN for Gmail. There's another suggestion about changing settings in your test Gmail account.

Finding SMTP host and port knowing the e-mail address using JAVA API

I made a simple application to send e-mails using Java API and have a question:
Is there any way to find out the SMTP host knowing the e-mail address of the one who will login to send an e-mail? And also the port?
For example, if the sender's e-mail address is sender#gmail.com, the SMTP host is smtp.gmail.com and the port 465. If the sender's e-mail address is sender#yahoo.com, the SMTP host is smtp.yahoomail.com and the port 25.
Supposing I don't know this, is there any way to find this information using Java API classes? Please note that I'm new to java :)
Thanks in advance,
Andreea
Thanks for your answers. I've tried to do the following:
public static String getMXRecordsForEmailAddress(String eMailAddress) {
String returnValue = null;
try {
String hostName = getHostNameFromEmailAddress(eMailAddress);
Record[] records = new Lookup(hostName, Type.MX).run();
if (records == null) {
throw new RuntimeException("No MX records found for domain " + hostName + ".");
}
// return first entry (not the best solution)
if (records.length > 0) {
MXRecord mx = (MXRecord) records[0];
returnValue = mx.getTarget().toString();
}
} catch (TextParseException e) {
throw new RuntimeException(e);
}
System.out.println("return value = "+returnValue);
return returnValue;
}
But, regardless of the value of hostName (eg. gmail.com, yahoo.com )
Record[] records = new Lookup(hostName, Type.MX).run(); always return null.
I'm pretty sure that I missed something, but I don't know what.
Will you please help me with this? Can you tell me what I'm doing wrong?
Thank you very much,
Andreea
Unfortunately, there's no standard way to identify the correct outgoing SMTP server for an arbitrary email address, assuming what you're trying to do is let the user specify an email address/password and then send the mail using that account.
That's why email clients (e.g. Thunderbird, Outlook, etc.) generally require the user to configure the outgoing SMTP server name/port manually. You could assist in that process by recognizing a few popular ISPs (Google, Yahoo, etc.) and pre-configuring the proper values, but there's no general-purpose way to do that automatically.
You typically talk to an smtp server you own and it handles routing mail to the yahoo Gmail some random isp to server.
The normal API to use is http://javamail.kenai.com/nonav/javadocs/ javamail.
If you were writing your own smtp server:
1 please don't
2 the smtp info is stored in the DNS mxrecord http://en.m.wikipedia.org/wiki/MX_record
It seems you are trying to let the user type only the email and password to connect. If so, we had this same issue and the best way we've found was to get the domain name and:
If it is public like Gmail, Yahoo or Outlook then try their specific configuration for them.
If it is privte domain or something like it. Loop through outgoing servers smtp.domain.com and mail.domain.com using ports 587, 465 and 25. You'll probably have to check for TLS and authentication.
The process is a bit long, but if you have a couple of public emails and a dozend private ones you should be able to test most of the scenarios.

Categories