How to send a mail to more than 15000 recipient?
Asked Answered
V

3

11

We are using asp.net 3.5 with c#.We have to make an powerful mailer module.This module can mail more than 15000 recipient or in short all records in DBMS.I would like to ask few things.

1)We have a code which sends a mail to single recipient.How will we send a mail to multiple recipient.I tried with our code to add more than one email id by ',' but it sends only first email id.Here is the code sample

 public bool Mail(string to, string subject, string body)
        {
            try
            {

                MailMessage objEmail = new MailMessage();
                objEmail.To =to;
                objEmail.From = "[email protected]";
                //objEmail.Priority =priority

                objEmail.Subject = subject;

                objEmail.Body = body;

                //enable the Html tag...

                objEmail.BodyFormat = MailFormat.Html;
                objEmail.Priority = MailPriority.High;

                SmtpMail.SmtpServer = "localhost";

                try
                {
                    SmtpMail.Send(objEmail);
                    return true;

                }
                catch(Exception ex)
                {
                    string error = ex.StackTrace;
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

2)What is the max limit to send mail at a time.Means how much value we can assign in string to that contains emailids?

3)One main thing our code is in button click so if we have more than 15000 records so will it able to send to mail all because What we are thinking is that page will have 60sec to render so it may send mails only those ids cover in 60 sec.

Lets suggest what is the best way to do that.

Thanks in advance.

Virtual answered 28/5, 2011 at 7:10 Comment(3)
Not necessarily directed towards you, but perhaps to someone reading this: in many countries, including the United States, sending spam is illegal, and punishable as mail fraud for up to 15+ years in prison.Revolt
Its not about spamming its about update information to our users.Virtual
Don't add several entries to the To or CC fields. Else you're giving your users the email addresses of other users.Deadly
M
10

Do not use System.Web.Mail. Use System.Net.Mail. See this blog.

System.Web.Mail is deprecated and not recommended.

You need to pass the work onto an actual mail server/service. A third party one is your best option. Do not send email directly from the web application code as request timeouts, authentication timeouts, etc will eventually halt your send loop. Also, this process will lock up the current page/session until it is done/halted and I have also experienced entire applications locking up for ALL visitors when pages are executing heavy tasks like this.

If all you want is a cheap email server that you can add emails to a queue and the server will just chug through them and send them, then Amazon SES is worth a look. If you want more user management and campaign management tools, then MailChimp or JangoMail might be your best options.

Amazon SES is definitely the cheapest as you only pay for what you use. I spend 4 bucks a month on average.

All of these provide APIs you can use in your code.

Aside: Do ensure that your recipients have somehow requested or are otherwise expecting these emails. Sending spam is illegal and the punishment is harsh.

Resources

Please also check out these questions:

Maimaia answered 28/5, 2011 at 7:14 Comment(8)
Remember, that in a lot of countries, you need to provide an unsubscription service by law. Also, for 15,000 addresses, you'll probably want to gather information about the emails that bounce back, and who is clicking on links within them. MailChimp is great, and handles all of this for you. www.campaignmonitor.com is also excellent.Spectrograph
@beejam, very true. Amazon SES shows you detailed information about bounce backs and their API is robust. Unsubscribing is simple.Maimaia
As many as you wish prateek (.net has no limit), but if you use a 3rd party API you are limited to certain amounts based on how much you want to pay. See the pricing for Amazon SES to see how many you are allowed to send with them and how much it will cost. Trust me when I tell you it's worth it. Writing your own email sending service on your server is a giant pain in the backside. SES does an AMAZING job at keeping you out of spam filters (as long as you're not sending spam :P) and it tracks your bounce backs very well.Maimaia
The real limit of TO addresses is the SMPT server sending them and the number of daily sends allowed varies by server. Like I said, save yourself a headache and use a 3rd party.Maimaia
"How many recipient i can add into "to" parameter?" You should only add a single one. Else you're compromising the privacy of your users.Deadly
@CodeInChaos, good point. Be sure to use BCC to protect them.Maimaia
You can use bouncely.com to get information from your bounces given that Amazon SES lacks that kind of statistics.Impignorate
@donald, that is incorrect. From the link I posted in my answer: codetunnel.com/content/bounces.jpgMaimaia
C
3

Apart from Chevex answer: If you send an email to multiple recipients then consider using BCC. If you use TO and CC each recipient will see the email addresses of the other recipients which they might not appreciate.

If you want to roll your own mail sendig module instead of using one of the available services then have a look at this question for some approaches of how to run longer lived background tasks in ASP.NET: Best way to run a background task in ASP.Net web app and also get feedback?

Crambo answered 28/5, 2011 at 7:32 Comment(1)
+1. Please also see these qustions: #5903143, #3906234Maimaia
D
0

This is my recommendation and it uses a database to manage the work load.

I'm gonna use SQL Server as an example here because that's what I've been using my self.

What you do is that you create a stored procedure and/or designate a table as the table for outgoing e-mail. This table, besides that which you need to send the email, has a the following metadata.

SendDate
IsSent
ErrorCount
Priority

At some point your going to need to fire up a thread or process that does the actual work, but how this is implemented is the interesting bit.

With SQL Server you can write a query like this:

DELCARE @now datetime; SET @now = GETDATE();

SELECT TOP (5) * 
FROM OutgoingEmail WITH (ROWLOCK, READPAST, UPDLOCK) 
WHERE SendDate < @now
    AND IsSent = 0 
    AND ErrorCount < 5
ORDER BY Priority
;

READPAST can only be specified in transactions operating at the READ COMMITTED or REPEATABLE READ isolation levels. You will set the isolation level when establishing a new connection.

Now what will happen is that when you use the SqlCommand object to create a DataReader SQL Server will lock those rows. No other instances will be able to get them. Which means you now effectively have a work queue for your outgoing email. It is however important to remember that you must keep the connection open while you do your processing otherwise the lock will be released.

A couple of things to note.

  • You fetch a bunch of rows and you send them. If you succeed your set the IsSent bit
  • If you crash (an exception is thrown somewhere) you don't discard the email you raise the ErrorCount. You don't delete it, you just raise the count. This is important because if the email for some reason contained input (as opposed to being caused by a network connectivty issue) it could keep crashing to send clients and this is called poisoning and it will prevent bad data from crashing your send clients. Therefore you should ignore email with a high ErrorCount
  • You can also empty a rolling schedule and move the SendDate forward as to not atempt the same thing every now and again.
  • The bottleneck will be the SmtpClient class but depending on the speed at which you want your emails to be sent you can spin up as many agents or threads as you need to process the emails in parallel.
  • The priority will ensure that if you need to send high priority email a full queue won't be an issue. e.g. if you wanna send all your e-mails this way, sending a password reset or registration e-mail won't be delayed just because the queue is full, as long as it has higher priority.

One thing to note though is that when errors happen the reason is unknown, I've seen the occasional network problem cause emails to not be sent. What generally will happen with this approach is that the email will just be sent at a later point when the network connectivity or SMTP server is back online. You can also have additional metadata to not send more than one email to a user who is trying to reset his or her password (just because for some unknown reason the emails are not being sent right now).

One last thing. You might want to split the table into two or three identical tables. The reason for this is that if you wanna log sent emails for a period of time you don't want them to interfere with your otherwise high performing send queue so you move them to a separate table, simply to maintain a history. It's the same deal with errors, if emails end up causing errors you might wanna log that and you can do that by then moving those emails you of the send queue into an error queue.

Delaine answered 28/5, 2011 at 7:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.