I would like to send email using SMTP Server, but in the certain time.
Is there possibility to setup some option so it will be in the queue on SMTP Server until specific time and date?
Idea is to avoid using Windows Service or extra table in DB
MailMessage message = new MailMessage("no-reply#tttt.com", "xxxx#gmail.com");
message.BodyEncoding = System.Text.Encoding.UTF8;
message.IsBodyHtml = true;
message.Subject = "Publishing Notification";
message.Body = "tes";
message.DeliveryNotificationOptions = DeliveryNotificationOptions.Delay;
SmtpClient client = new SmtpClient("xxxx", Int32.Parse("25"));
client.Send(message);
Making something execute at a given time is an easy problem presuming you've got a process to host it. But it seems like your client is refusing to get there. Here are two ways to approach this without:
Use Sql Server Jobs to execute a database mail task. This could be a very easy on-ramp depending on where the data is coming from.
Use a scheduled task to execute a command line program. Or use the Sql Job Manager to execute the program for that matter if getting a sql job in there is easier than standing up a scheduled task.
Quartz.NET is a great library and we use it a lot but you still need a constantly running service to execute scheduled tasks there. So, if you can piggyback this on your web app Quartz would work but if not then you'd be looking at writing a service. And from there you'd be better off just making it a scheduled task since there is no reason for this to be a service other than scheduling.
Related
I am trying to find a way to run a piece of code (MS Bot Framework, C# hosted on Azure) every time a person is mentioned on Yammer or receives a direct message.
The two ways that I tried:
1) The best I came up with for now is to enable email notifications from Yammer, and watch a mailbox for emails from notifications#yammer.com. Microsoft's Bot Framework has a one-click setup for monitoring emails, so that works.
But notification emails arrive with a 15 minutes delay, which renders this pretty useless as I need near-instant performance.
Finally, it looks like this approach simply doesn't work because the MS Bot Framework seems to reply to the email address who sent the email, rather to the one that I specify:
if (activity.ChannelId == "email" && activity.From.Id == "notifications#yammer.com")
{
var newActivity = activity.CreateReply();
//doesn't work, sends email back to the activity.From.Id
newActivity.Recipient.Id = "k48#gmail.com";
newActivity.Text = "I got a message from " + activity.From.Name + "!";
BotUtils.SendActivityToChat(newActivity);
}
I could write my own code for sending emails to an arbitrary recipient, but then there is still the problem with 15 min delay.
2) Another approach I am using is to poll Yammer's API every minute to see if there are new messages, but this is still not instant, and I'm not sure if my account gets banned if I keep polling the API way too often. (Update: the official rate limit is 1 poll per minute, or else they ban you).
Is there something I missed? How else would you run a piece of code every time you get a message or mention on Yammer?
The BotFramework will not allow you to reply to a message to a different address than the sender. However, if the recipient is one that the bot has received a message from before, you can send them a Proactive Message. To send a proactive message, you can keep the ServiceUrl and the user’s ChannelAccount (extracted from one of the messages from that user) and use this data to send a new activity from your bot to that user.
Here is an example in C#
Here is an example in Node.js
We have an ASP.NET MVC application that sends a number of reports via e-mail to clients each month. Each e-mail attaches a monthly statement. Currently we have around 70 clients but this will hopefully increase over time. We have been seeing issues that a number of e-mails are not getting sent. We use the System.Net.Mail API.
Here is the code we are using, is there a better approach?
foreach(string client in clients){
SmtpClient client = new SmtpClient("server.com");
BackgroundWorker emailInvoker = new BackgroundWorker();
emailInvoker.DoWork += delegate
{
// Delay to prevent flow control, try later Relay error
Thread.Sleep(TimeSpan.FromSeconds(2));
client.Send(message);
}
emailInvoker.RunWorkerAsync();
}
We have been seeing issues that a number of e-mails are not getting
sent.
The larger (and more likely) problem than some of them aren't getting sent is that many of them are not getting delivered.
...is there a better approach?
In most cases. Jeff Atwood goes over many of the problems with sending email in this blog post. That post was almost 3 years ago and even then, the first comment recommends using postmark. I've used postmark and it reliably handles the problem of getting your emails out through code at a good price. That said, there are better solutions on the market now, the one my company is currently very tempted to switch to is mandrill. Slightly better pricing, awesome analytics.
Because this is an ASP.NET MVC application, you need to be aware of your application pool. Creating multiple threads will exhaust your app pool quickly, and IIS maybe doing some funky things to keep things from literally grinding to a halt while emails are being sent. I would take a look at Can I use threads to carry out long-running jobs on IIS? if you're interested on learning more.
If I were to rewrite that, I would create one thread with the foreach and email sending, instead of a thread for each customer.
BackgroundWorker emailInvoker = new BackgroundWorker();
emailInvoker.DoWork += delegate
{
// get your clients here somehow
foreach(string client in clients){
SmtpClient client = new SmtpClient("server.com");
// Delay to prevent flow control, try later Relay error
Thread.Sleep(TimeSpan.FromSeconds(2));
client.Send(message);
}
}
emailInvoker.RunWorkerAsync();
We are sending free newsletters to all users who have registered for this service. Since these newsletters are sent free of cost we expect at least 5000 subscribers within a month. I am worried whether bulk mailing using SMTP server concept will cause some issue. First we thought of developing a windows service which would automatically mail to subscribers on periodical basis but the business users have given requirement that the newsletters should be editable by the admin and then only mailed to users so we had to develop this functionality in website itself!. I get the subscribers for the particular user in data table and then mail to each user inside for loop, will this cause any performance issue?
The code is pasted below:
dsEmailds.Tables[0] has list of newsletter subscribers.
for (iCnt = 0; iCnt < dsEmailIds.Tables[0].Rows.Count; iCnt++)
{
MailMessage msg = new MailMessage();
msg.From = new MailAddress("newsletters#domainname.com", "test1");
msg.To.Add(dsEmailIds.Tables[0].Rows[iCnt]["mailid"]);
msg.IsBodyHtml = true;
msg.Subject = subject;
AlternateView av1 = AlternateView.CreateAlternateViewFromString(MailMsg, null, System.Net.Mime.MediaTypeNames.Text.Html);
av1.LinkedResources.Add(lnkResLogo);
av1.LinkedResources.Add(lnkResSalesProperty);
av1.LinkedResources.Add(lnkResLeaseProperty);
msg.AlternateViews.Add(av1);
SmtpClient objSMTPClient = new SmtpClient(System.Configuration.ConfigurationManager.AppSettings["mailserver"].ToString());
objSMTPClient.DeliveryMethod = SmtpDeliveryMethod.Network;
objSMTPClient.Send(msg);
}
Any suggestions would be great!
You should STOP and consider all sort of things:
Black List: with that amount you will for sure be balck listed in severeal ISP's / Mail Servers, and you need to prove that the received user asked for such email and wait 1 to 3 month process while they remove the flag
You need to send emails in blocks, not more than 250 at each time, use different IP's machines to send more emails (more blocks)
please read some nice guidelines for doing all this, you can find it in MailChimp and Campaign Monitor
Free Email Marketing Guides
You should use a service, like Mailchimp (now it's free to 1000 subscribes, 3000 sends a month) but prices are very cheap and they have an API that you can easily add, create, send and you will get all those nice reports on how opened, what did they do, etc ...
Campaign Monitor is fantastic as well, but a little bit more expensive but great as you can brand the entire UI and sell as a service to your customers (if you are thinking of doing such thing in the near future).
I hope it helps.
give them a try, I'm a happy customer.
The main problem i see is that you may encounter a page timeout. The best way to do it in my opinion would be to set up a service that will take care of mail-related uses (templating for example) by reading from a queue. Your website could just post the mails you expect to send in the queue, then offer a basic administration panel to manage the service and get some stats.
You can use open-source & xcopy-friendly systems for the queue like Rhino queue, or ServiceBus, and Topshelf for services if you want easy setup
But i'd recommend you not to send bulk emails in the webpage
There is a SendAsync method that will actually queue up these requests and send them async from your thread. This way you can prevent the timeout and you can probably send (ie. queue) 5000 emails within seconds.
Write to a pickup queue of an SMTP server running on the machine (IIS includes one). This is the fastest and most efficient method.
OR
Setup a custom thread pool in your code and offload the task to it. That way worker threads from ASP.NET thread pool are ready to serve incoming requests and won't be occupied with sending mails (that depends on how high your server load is, of course - go ahead with ASP.NET thread pool using async methods if you don't care about the load/can afford it).
This question already has answers here:
Email messages going to spam folder
(7 answers)
Closed 9 years ago.
I've got a C# application going that needs to send out an html email via smtp. The email gets sent just fine, but the default security setting on outlook (Low) classifies it as junk email.
It's not exactly a showstopper issue, but this is rather annoying, especially since the junk folder turns off html. I don't want to have to make everyone at my company do something special to receive these emails in a readable fashion, does anyone know what I could be doing that makes outlook think this is junk email?
Code that makes the email (basic stuff.) Config is an object that holds strings related to the configuration of this stuff, toList is a list of email addresses, body/subject are filled by other function calls.
Edit: To add, at the moment I'm just sending it out to myself. In the live version, we'll be looking at less than a hundred people being sent to in a worst-case.
Another Edit: It turned out to be happening much much more often for the longer emails I was generating the other day (~200-300 lines at the worst), and not the shorter emails I'm generating now. That's a reasonable enough filter criteria, I suppose.
SmtpClient smtp = new SmtpClient(config.SmtpServer);
NetworkCredential net = new NetworkCredential();
net.UserName = config.SmtpLogin;
net.Password = config.SmtpPass;
smtp.Credentials = net;
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.Priority = MailPriority.Normal;
msg.To.Add(String.Join(",", toList.ToArray()));
msg.From = new MailAddress(fromAddr, "Build Server");
msg.Body = "Blah html is here";
msg.Subject = "Build successful: #numberhere and stuff";
try
{
smtp.Send(msg);
}
catch (SmtpException)
{
//stuff
}
I think this is less of a programming issue and more of a configuration issue. The recipients need to add fromAddr to their “Safe Senders List”.
The thing is, if there were a way to configure an e-mail to bypass the junk mail filter then all the spammers will be doing it.
If it's a matter of crafting the perfect non-junk-looking e-mail then it may work sometimes and not others. And all the spammers will be doing it.
You're going to have to tell everyone to allow e-mails from that account. And you probably shouldn't start that e-mail with any unnecessary anatomical or medicinal references.
If your message To contains a large list it may be seen as spam. Try sending a unique email to each person instead of a mass email.
However:
If you're going to loop through your list and send an email for each user, you might want to consider creating a queue that will be processed that allows for failure and retry.
We had a similar issue in our system where after about 20,00 messages sent in quick succession (ie: within a foreach loop) the outgoing mail server rejected any further attempt to relay.
We instead added outgoing messages to a database table, and wrote a service that would process a specified number of emails at a time and then pause for a specified time before going again.
In addition this allowed us to capture failures, and then setup retry rules. After X attempts we mark the message as failed for good and report the issue. We found that this provided a much more reliable system of users getting their messages, plus they were no longer marked as spam.
If you are sending out several mails at a time send them in small batches so you're not flooding the server.
Check the text of the email for words and symbols likely to be considered spam by some filters.
You might also want to look into things such as SPF to reduce the chance that your mails will be marked as spam.
Add following line in your code while creating MailMessage
msg.BodyEncoding = System.Text.Encoding.GetEncoding("utf-8");
Just a thought, try looping through your to list and send a separate email. Also, try experimenting with different wording and html structures.
Using this code, I can send emails to people. However, every time I press the send button, I think I log back in, correct?
Is there a way to perpetuate my login session, or is the way it's always been done ("I'm making a newbie assumption")?
var client = new SmtpClient("smtp.gmail.com", 587)
{
Credentials = new NetworkCredential("papuccino1#gmail.com", "password"),
EnableSsl = true
};
client.Send("papuccino1#gmail.com", "stapia.gutierrez#gmail.com", "test", "testbody");
Console.WriteLine("Sent");
Console.ReadLine();
The code you have is fine. Yes, the smtp service is sending the credentials to the smtp server each time you send the email.
From a coding perspective, this is the preferred way of doing things. If you are batching emails, then you would simply put the .Send method call inside the loop while the new SmtpClient call is above it.
You only want to leave the connection open long enough to do the job then you close it. Otherwise you run the risk of the app blowing up or otherwise failing to close the connection later. Servers only have a limited number of connections that they can handle. If most apps left them open for long periods of time then other users would have a hard time getting in.
Most mail clients, open the connection, send any emails in the outbox, grab any new emails, then close the connection. When a timer goes off, it will do the process over again.
Outlook tied to Exchange works slightly differently because there is a push component (from the server).
Each SMTP session starts with authentication usually. As far as I know there is no way to keep a session open to a SMTP server. It is possble to send a number of emails in a batch though, this is probably what happens when you use an email client.