Can not send email when there are a lot of receivers - java

My email code works well when I just send an email to a few people, but when I sending to all users(177) in contact, I got this error:
[ERROR] - org.apache.commons.mail.EmailException: Sending the email to the following server failed : hlrdwd.com:25
The code is below:
HtmlEmail email = new HtmlEmail();
email.setCharset("utf-8");
if (vo.getContent() != null && vo.getContent().trim().length() > 0) {
email.setHtmlMsg(vo.getContent());
} else {
email.setHtmlMsg(" ");
}
email.setSubject(vo.getTitle());
email.setFrom(vo.getSender(), currentuname);
email.setHostName(Property.getSmtp());
List<Map<String, String>> toList = mm.formatAddress(vo
.getReceiver());
if (toList != null) {
for (int i = 0; i < toList.size(); i++) {
Map<String, String> tMap = toList.get(i);
email.addTo(tMap.get(mm.KEY_EMAIL), tMap.get(mm.KEY_NAME));
System.out.println(tMap.get(mm.KEY_EMAIL));
}
}
email.setAuthentication(currentuser, password);
String messageid = email.send();
I google this and add email.setTLS(true);, but still can not work. Waiting your help!

The problem is that the receiving mail server doesn't like messages being sent to too many people at the same time. As a reference, postfix by default rejects messages with more than 50 recipients.
The simplest solution is to send multiple messages, rather than sending to everyone at once. In the extreme, you could send a message per user -- then you get the opportunity to customise the messages if you want, which also makes them less likely to be filtered as spam.

Related

How To Detect An Email Address Is Real

IMPORTANT
I have been blocked by hotmail services. There is a control mechanism
called spamhaus which kicked me out. I'm stuck right now.
I am trying to detect an email address is valid and if its valid then check if this email address potentially used (I know that its not certain). For example, lets assume that there is a website with domain myimaginarydomain.com. If I run code below, I guess it won't fail because domain address is valid. But nobody can take an email address with that domain.
Is there any way to find out that email address is valid? (In this case its invalid)
I don't want to send confirmation email
Sending ping may be useful?
public class Application {
private static EmailValidator validator = EmailValidator.getInstance();
public static void main(String[] args) {
while (true) {
Scanner scn = new Scanner(System.in);
String email = scn.nextLine();
boolean isValid = validateEmail(email);
System.out.println("Syntax is : " + isValid);
if (isValid) {
String domain = email.split("#")[1];
try {
int test = doLookup(domain);
System.out.println(domain + " has " + test + " mail servers");
} catch (NamingException e) {
System.out.println(domain + " has 0 mail servers");
}
}
}
}
private static boolean validateEmail(String email) {
return validator.isValid(email);
}
static int doLookup(String hostName) throws NamingException {
Hashtable env = new Hashtable();
env.put("java.naming.factory.initial",
"com.sun.jndi.dns.DnsContextFactory");
DirContext ictx = new InitialDirContext(env);
Attributes attrs =
ictx.getAttributes(hostName, new String[]{"MX"});
Attribute attr = attrs.get("MX");
if (attr == null) return (0);
return (attr.size());
}
}
There is no failsafe way to do this in all cases, but, assuming the server uses SMTP then https://www.labnol.org/software/verify-email-address/18220/ gives quite a good tutorial on one method that may work.
The method used in the tutorial relies on OS tools, so you will need to ensure they exist before using them. a ProcessBuilder may help. Alternatively, you can open a socket directly in code and avoid using OS-dependent tools.
Essentially, you find out what the mail servers are (using nslookup), then telnet to one of the mail servers and start writing an email:
3a: Connect to the mail server:
telnet gmail-smtp-in.l.google.com 25
3b: Say hello to the other server
HELO
3c: Identify yourself with some fictitious email address
mail from:<labnol#labnol.org>
3d: Type the recipient’s email address that you are trying to verify:
rcpt to:<billgates#gmail.com>
The server response for rcpt to command will give you an idea whether an email address is valid or not. You’ll get an “OK” if the address exists else a 550 error
There really is no sensible way except trying to send a notification with a token to the address and ask the other party to confirm it, usually by visiting a web-page:
the recipients MX may be unavailable at the moment but come back online later, so you cannot rely on a lookup in real time;
just because the MX accepts the email doesn't mean that the address is valid, the message could bounce later down the pipe (think UUCP);
if this is some kind of registration service, you need to provide some confirmation step anyway as otherwise it'd become too easy to subscribe random strangers on the internet that do not want your service.

Plivo SMS is not being sent and getting error in Java

I am integrating Plivo SMS API with my java web application. I want to send messages through my application. I am referring to https://www.plivo.com/docs/getting-started/send-a-single-sms/ link.
Below is the code snippet:
String authId = "{my Auth_id}"; //Your Authentication ID
String authToken = "{my auth Token}"; //Your authentication code
RestAPI api = new RestAPI(authId, authToken, "v1");
LinkedHashMap<String, String> parameters = new LinkedHashMap<String, String>();
parameters.put("src", "+44*******"); // Sender's phone number with country code
parameters.put("dst", "+91*******"); // Receiver's phone number with country code
parameters.put("text", "Hi, text from Plivo"); // Your SMS text message
try {
// Send the message
MessageResponse msgResponse = api.sendMessage(parameters);
// Print the response
System.out.println(msgResponse);
// Print the Api ID
System.out.println("Api ID : " + msgResponse.apiId);
// Print the Response Message
System.out.println("Message : " + msgResponse.message);
if (msgResponse.serverCode == 202) {
// Print the Message UUID
System.out.println("Message UUID : " + msgResponse.messageUuids.get(0).toString());
} else {
System.out.println(msgResponse.error);
}
} catch (PlivoException e) {
System.out.println(e.getLocalizedMessage());
}
I tried to run this code using console application as well as web application.I am getting exception "com.plivo.helper.exception.PlivoException: Connection to https://api.plivo.com refused". What is wrong with my code? Am I missing anything here?
Plivo Sales Engineer here.
Please check your firewall settings to ensure that it's not blocking any traffic. Also, are you using a web proxy? If yes, make sure that your application is using this proxy to handle connections.

return a single message from array of messages

I just have requirement that i have an array of type Messages. so i want to return a Messages from them. Can anyone help me how to do that?
public static Message getContent(String user, String pswd, String sub, String to)
throws MessagingException, IOException {
Session imapSession1 = TestMail.greenMail.getImap().createSession();
Store store = imapSession1.getStore("imap");
store.connect("foo", "password");
Folder inbox = store.getFolder("INBOX");
inbox.open(Folder.READ_ONLY);
// Getting only unread messages.
Flags flags = new Flags();
flags.add(Flag.SEEN);
FlagTerm flagTerm = new FlagTerm(flags, false);
Message[] msgs = inbox.search(flagTerm);
Message ms = msgs[0];
return ms;
}
I tried to return first message as shown above, but it is throwing IndexOutOfBoundsException: 0
So can anyone help me with this. Thanks in advance.
Either there is a problem with your previous code or there are no unread messages but either way msgs is empty after you have search the inbox - you just need to check msgs.length > 0 first and if it is not then decide what you want to do. You could return an Optional (Java8 feature and you would need to change the method signature to match) or simply return null or throw an exception depending on your needs. All 3 scenarios then need appropriate handling in the calling code.
NOTE that it is unlikely that throwing an Exception is the correct approach unless the code is only called when there should be unread messages.

java getDisposition returns null on emails with attachments

SO i'm making a mail client for a homework assignment and one of the requirements is to handle incoming attachments. The first thing I want to do is just show if an email even has an attachment or not. I have a bunch of AWT lists that are side by side for From, Subject, Size, Date, Attachment.
For testing purposes, if the disposition returns null, i just put an x in the attachmentList. If its inline, it puts an i and for attachments it should show the filename. However, even on emails where there are attachments and looking at the headers in gmail webmail, which shows the content disposition as attachment (all lower case), the getDisposition of the email still returns null. I don't get why its not returning ATTACHMENT or attachment or something besides null. Here is the relevant code.
for (int i = 0; i < messages.length; i++) {
Address[] froms = messages[i].getFrom();
String email = froms == null ? null : ((InternetAddress) froms[0]).getAddress();
fromList.add(email);
subjectList.add(messages[i].getSubject());
sizeList.add("" + messages[i].getSize());
dateList.add(messages[i].getReceivedDate().toString());
String disposition = messages[i].getDisposition();
System.out.println("Disposition is " + disposition + ".");
if (disposition == null) {
attachmentList.add("x");
}
else if ("INLINE".equalsIgnoreCase(disposition)) {
attachmentList.add("i");
}
else if ("ATTACHMENT".equalsIgnoreCase(disposition)) {
String fileName = messages[i].getFileName();
if (fileName != null) {
attachmentList.add("attachment " + fileName);
}
}
}
You'll notice that it prints "the disposition is..." which is another testing code and it always prints either null or INLINE. The particular email i'm looking at is about 700k and contains 2 attachments.
Look at the raw MIME text of the message and make sure the Content-Disposition header is set as you expect.
Turn on JavaMail session debugging and examine the protocol trace in the debug output.
Are you using IMAP to read the message? If so, the IMAP server parses the message and returns the "disposition" information in the IMAP protocol message. The IMAP server may not be parsing the message correctly or may not be returning the disposition information correctly.

Someone knows a mail (SMTP) delivery library for Java?

I'd like to send mail without bothering with the SMTP-Server which is used for delivery.
So JavaMail API doesn't work for me because I have to specify a SMTP server to connect to.
I'd like the library to find out on its own which SMTP server is responsible for which email address by querying the MX record of the mail address domain.
I'm looking for something like Aspirin. Unfortunately I can't use Aspirin itself because the development stopped 2004 and the library fails to communicate with modern spam hardened servers correctly.
An embeddable version of James would do the task. But I haven't found documentation concerning whether this is possible.
Or does anyone know about other libraries I could use?
One possible solution: get the MX record on your own and use JavaMail API.
You can get the MX record using the dnsjava project:
Maven2 dependency:
<dependency>
<groupId>dnsjava</groupId>
<artifactId>dnsjava</artifactId>
<version>2.0.1</version>
</dependency>
Method for MX record retrieval:
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 + "."); }
if (log.isTraceEnabled()) {
// log found entries for debugging purposes
for (int i = 0; i < records.length; i++) {
MXRecord mx = (MXRecord) records[i];
String targetString = mx.getTarget().toString();
log.trace("MX-Record for '" + hostName + "':" + targetString);
}
}
// 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);
}
if (log.isTraceEnabled()) {
log.trace("Using: " + returnValue);
}
return returnValue;
}
private static String getHostNameFromEmailAddress(String mailAddress) throws TextParseException {
String parts[] = mailAddress.split("#");
if (parts.length != 2) throw new TextParseException("Cannot parse E-Mail-Address: '" + mailAddress + "'");
return parts[1];
}
Sending mail via JavaMail code:
public static void sendMail(String toAddress, String fromAddress, String subject, String body) throws AddressException, MessagingException {
String smtpServer = getMXRecordsForEmailAddress(toAddress);
// create session
Properties props = new Properties();
props.put("mail.smtp.host", smtpServer);
Session session = Session.getDefaultInstance(props);
// create message
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress(fromAddress));
msg.setRecipient(Message.RecipientType.TO, new InternetAddress(toAddress));
msg.setSubject(subject);
msg.setText(body);
// send message
Transport.send(msg);
}
This is completely the wrong way to handle this.
Anyone connected to the internet will have some kind of "legit" SMTP server available to them to take the submission of email -- your ISP, your office, etc.
You WANT to leverage because they do several things for you.
1) they take your message and the responsibility to handle that message. After you drop it off, it's not your problem anymore.
2) Any mail de-spamming technologies are handled by the server. Even better, when/if those technologies change (Domain keys anyone?), the server handles it, not your code.
3) You, as a client of that sending mail system, already have whatever credentials you need to talk to that server. Main SMTP servers are locked down via authentication, IP range, etc.
4) You're not reinventing the wheel. Leverage the infrastructure you have. Are you writing an application or a mail server? Setting up mail server is an every day task that is typically simple to do. All of those casual "dumb" users on the internet have managed to get email set up.
Don't.
Sending email is much more complex than it seems. Email servers excel at (or should excel at) reliable delivery.
Set up a separate email server if you need to- that will be essentially the same as implementing one in Java (I doubt you will find libraries for this task- they would be essentially complete mail servers), but much more simpler.

Categories

Resources