Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to send too many emails in short time

I have a correspondence application where each user creates a correspondence and send it to multiple users (average send us between 2-30 user), with each send I open a new thread and send email to group of users in the following flow (connect to mail server > send > close connection) as follows:

public class EmailService {

    private String emailProtocol = null;
    private String emailHostSMTP = null;
    private String senderEmail = null;
    private String senderUser = null;
    private String senderPassword = null;
    private String senderDisplayName = null;
    private String emailPort = null;

    public void initConfig() {
        emailProtocol = GeneralServices.getConfig("emailProtocol");
        emailHostSMTP = GeneralServices.getConfig("emailHostSMTP");
        senderEmail = GeneralServices.getConfig("senderEmail");
        senderUser = GeneralServices.getConfig("senderUser");
        senderPassword = GeneralServices.getConfig("senderPassword");
        senderDisplayName = GeneralServices.getConfig("senderDisplayName");
        emailPort = GeneralServices.getConfig("emailPort");
        if (StringUtils.isBlank(emailPort))
            emailPort = "587";
    }

    public void setProps(Properties props) {

        props.put("mail.transport.protocol", emailProtocol);
        props.put("mail.smtp.host", emailHostSMTP);
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.port", emailPort);
        if (ConfigurationUtils.isEnableStartTlsInEmail())
            props.put("mail.smtp.starttls.enable", "true");
        if (ConfigurationUtils.isEnableDebugInEmail())
            props.put("mail.debug", "true");

    }

    public void sendEmail(String toUser, String subject, String emailHtmlBody, String bannerPath) throws Exception {
        try {
            if (StringUtils.isBlank(toUser)) {
                return;
            }
            List<String> toUsers = new ArrayList<String>(1);
            toUsers.add(toUser);
            sendEmail(toUsers, null, null, subject, emailHtmlBody, bannerPath);
        } catch (Exception e) {
            throw e;
        }
    }

    public void sendEmail(String fromEmail, String fromDisplayName, List<String> toList, List<String> ccList,
            String subject, String emailBody, String filePhysicalPath, String fileName, String fileContentType)
            throws Exception {

        Transport transport = null;

        try {

            initConfig();
            MimeMultipart multipart = new MimeMultipart();
            Authenticator authenticator = new SMTPAuthenticator();
            MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory();
            MimeBodyPart bodyPart = new MimeBodyPart();

            String html = "";

            Properties props = System.getProperties();
            setProps(props);

            sslSocketFactory.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.socketFactory", sslSocketFactory);

            Session session = Session.getInstance(props, authenticator);
            // session.setDebug(true);

            emailBody = emailBody + "<br/><br/>مرسل بواسطة : " + fromDisplayName;
            html = "<html><body style='text-align:right'> " + emailBody + " </body></html>";
            bodyPart.setContent(html, "text/html; charset=UTF-8");
            multipart.addBodyPart(bodyPart);

            MimeMessage message = new MimeMessage(session);

            message.setFrom(new InternetAddress(senderEmail, fromDisplayName));
            message.setReplyTo(new Address[] { new InternetAddress(fromEmail) });

            if (toList != null && toList.size() > 0) {
                for (String to : toList) {
                    message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
                }
            } else {
                throw new Exception("List of users to send email to is empty");
            }

            if (ccList != null && ccList.size() > 0) {
                for (String cc : ccList) {
                    message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc));
                }
            }

            // attach file
            BodyPart mimeBodyPart = new MimeBodyPart();
            DataSource source = new FileDataSource(filePhysicalPath);
            mimeBodyPart.setDataHandler(new DataHandler(source));
            mimeBodyPart.setFileName(MimeUtility.encodeText(fileName, "utf-8", "B"));

            multipart.addBodyPart(mimeBodyPart);
            // end of file attach

            message.setSubject(subject, "UTF-8");
            message.setContent(multipart);
            message.setSentDate(new Date());

            transport = session.getTransport(emailProtocol);
            transport.connect(senderEmail, senderPassword);
            transport.sendMessage(message, message.getAllRecipients());

        } catch (Exception ex) {
            throw ex;
        } finally {
            if (transport != null)
                transport.close();
        }

    }

    public void sendEmail(List<String> toList, List<String> ccList, List<String> bccList, String subject,
            String emailHtmlBody, String bannerPath) throws Exception {

        if ((toList == null || toList.size() == 0) && (ccList == null || ccList.size() == 0)
                && (bccList == null || bccList.size() == 0)) {
            return;
        }

        Transport transport = null;
        try {

            initConfig();
            MimeMultipart multipart = new MimeMultipart();
            Authenticator authenticator = new SMTPAuthenticator();
            MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory();
            MimeBodyPart bodyPart = new MimeBodyPart();

            String html = "";

            Properties props = System.getProperties();
            setProps(props);

            sslSocketFactory.setTrustAllHosts(true);
            props.put("mail.smtp.ssl.socketFactory", sslSocketFactory);

            Session session = Session.getInstance(props, authenticator);

            html = "<html><body> " + emailHtmlBody + " </body></html>";
            bodyPart.setContent(html, "text/html; charset=UTF-8");
            multipart.addBodyPart(bodyPart);

            // add banner path
            bodyPart = new MimeBodyPart();
            DataSource ds = new FileDataSource(bannerPath);
            bodyPart.setDataHandler(new DataHandler(ds));
            bodyPart.setHeader("Content-ID", "<MOAMALAT_LOGO>");
            multipart.addBodyPart(bodyPart);

            MimeMessage message = new MimeMessage(session);

            message.setFrom(new InternetAddress(senderEmail, senderDisplayName));
            message.setReplyTo(new Address[] { new InternetAddress(senderEmail) });

            if (toList != null && toList.size() > 0) {
                for (String email : toList)
                    message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
            }

            if (ccList != null && ccList.size() > 0) {
                for (String email : ccList)
                    message.addRecipient(Message.RecipientType.CC, new InternetAddress(email));
            }

            if (bccList != null && bccList.size() > 0) {
                for (String email : bccList)
                    message.addRecipient(Message.RecipientType.BCC, new InternetAddress(email));
            }

            message.setSubject(subject, "UTF-8");
            message.setContent(multipart);
            message.setSentDate(new Date());

            transport = session.getTransport(emailProtocol);
            transport.connect(senderEmail, senderPassword);
            transport.sendMessage(message, message.getAllRecipients());

        } catch (Exception ex) {
            throw ex;
        } finally {
            if (transport != null)
                transport.close();
        }

    }

    private class SMTPAuthenticator extends javax.mail.Authenticator {

        @Override
        public PasswordAuthentication getPasswordAuthentication() {
            String username = senderUser;

            String password = senderPassword;
            return new PasswordAuthentication(username, password);
        }
    }
}

Sometimes I get the error:

com.sun.mail.smtp.SMTPSendFailedException: 421 4.4.2 Message submission rate for this client has exceeded the configured limit

but after reviewing with the Exchange Server Admin, he said the I have not send emails above the limit.

Sometimes also I get the error:

java.net.SocketException: Connection reset

Also sometimes I get:

javax.mail.MessagingException: Can't send command to SMTP host,Caused by: java.net.SocketException: Connection closed by remote host

I read that some people make the transport object static and make connection to exchange server only once and then reuse it, will that help to solve the issue, and for how long will the connection be open?

Also I have thought of a solution to save the emails details in a database table and make a job class to send the emails in a batch periodically.

like image 351
Mahmoud Saleh Avatar asked Apr 18 '17 08:04

Mahmoud Saleh


People also ask

Is there a limit to how many emails can be sent at once?

What is the daily Gmail sending limits? Gmail officially claims that with a regular Gmail account you can send 500 emails/day. And with paid services like G Suite(Google Workspace), you can send over 2,000 emails/day.

How can I send a lot of emails at once?

You can send a mass email to more than one recipient using the BCC feature. Click the compose box, after composing your message, click on BCC and add all your recipients.

How do I increase email sending limit in Outlook?

If you wanted to send more than 10,000 emails in a 24-hour period, you would need a third-party app dedicated to mass email sending. The other limit is for Outlook maximum recipients for a single email or newsletter. The Outlook recipient limit for a single email is 500 people.


1 Answers

I edited your secondly declared sendEmail method (as follows). If you liked it, apply same technic to other sendEmail method.

As a solution, i grabbed sendMessage part into for loop of cc list. So, for each "to" email and for each corresponding "cc" email, email will be sent. Absence of cc list must also be evaluated by you. Code might not be compiling, but you should see the point.

public void sendEmail(String fromEmail, String fromDisplayName, List<String> toList, List<String> ccList,
        String subject, String emailBody, String filePhysicalPath, String fileName, String fileContentType)
        throws Exception {

    Transport transport = null;

    try {

        initConfig();
        MimeMultipart multipart = new MimeMultipart();
        Authenticator authenticator = new SMTPAuthenticator();
        MailSSLSocketFactory sslSocketFactory = new MailSSLSocketFactory();
        MimeBodyPart bodyPart = new MimeBodyPart();

        String html = "";

        Properties props = System.getProperties();
        setProps(props);

        sslSocketFactory.setTrustAllHosts(true);
        props.put("mail.smtp.ssl.socketFactory", sslSocketFactory);

        Session session = Session.getInstance(props, authenticator);
        // session.setDebug(true);

        emailBody = emailBody + "<br/><br/>مرسل بواسطة : " + fromDisplayName;
        html = "<html><body style='text-align:right'> " + emailBody + " </body></html>";
        bodyPart.setContent(html, "text/html; charset=UTF-8");
        multipart.addBodyPart(bodyPart);

        MimeMessage message = new MimeMessage(session);

        // attach file
        BodyPart mimeBodyPart = new MimeBodyPart();
        DataSource source = new FileDataSource(filePhysicalPath);
        mimeBodyPart.setDataHandler(new DataHandler(source));
        mimeBodyPart.setFileName(MimeUtility.encodeText(fileName, "utf-8", "B"));

        multipart.addBodyPart(mimeBodyPart);
        // end of file attach

        message.setSubject(subject, "UTF-8");
        message.setContent(multipart);



        message.setFrom(new InternetAddress(senderEmail, fromDisplayName));
        message.setReplyTo(new Address[] { new InternetAddress(fromEmail) });

        transport = session.getTransport(emailProtocol);
        transport.connect(senderEmail, senderPassword);

        if (toList != null && toList.size() > 0) {
            for (String to : toList) {
                message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

                if (ccList != null && ccList.size() > 0) {
                    for (String cc : ccList) {
                        message.addRecipient(Message.RecipientType.CC, new InternetAddress(cc));
                        message.setSentDate(new Date());
                        transport.sendMessage(message, message.getAllRecipients());
                    }
                }


            }
        } else {
            throw new Exception("List of users to send email to is empty");
        }

    } catch (Exception ex) {
        throw ex;
    } finally {
        if (transport != null)
            transport.close();
    }

}
like image 118
yılmaz Avatar answered Sep 21 '22 13:09

yılmaz