Sending Sms and Email Notification in Asp.Net

Alright, a friend of mine asked me to assist with codes for sending sms and email notification from a project he’s working on, I explained it to him thou but i felt it might worth it to post the codes here so that others could learn just a little  from it.

The use case here is that the admin should be able to send emails and sms notification to all staffs; informing them of their new posting. Sending sms and Emails to a single number and email respectively could be as easy as just calling the necessary web service methods, and that’s all. However, when notifications are to be sent to hundreds or thousands of staff members; lots of things could occur which could negatively affect the sms and emails that are being sent.

Such things include App Pool recycling, Server Restart for whatever reason. Therefore, a good approach would be to schedule the sms and notification using a task scheduler. The task scheduler would make sure the methods gets called at a particular time and of course gets executed. The Scheduler we’ll be using here is Hangfire. We’ll also use smslive247 for sms notification and Mailchimp for emails.

So let’s proceed by adding the nugget packages to our visual studio project. Open the Nuget Cosole and run the following commands.

 

Install-Package Hangfire.MemoryStorage

Install-Package mcapi.net

And the last is smslive247 Api. We’ll add it to our project in form of a service reference. Details of adding and using the web service can be found in their documentation. In case you run into issues with the service reference, you could follow this link to get it resolved.

The Method for sending the sms and email are highlighted below.

 

 public string SiteToken => ConfigurationManager.AppSettings.Get("smssubaccounttoken");

      
        public void SendMsg(SmsMessage smsMessage)
        {
            var sms = new SMSSiteAdminProxySoapClient();
            var newSms = new MessageInfo
            {
                CallBack = smsMessage.SenderId,
                Destination = new ArrayOfString {smsMessage.Number},
                DeliveryEmail = "me@tobiawe.com",
                Message = smsMessage.Message,
                MessageType = SMSTypeEnum.TEXT
            };


            var response = sms.SendSMS(SiteToken, newSms);

            if (response.ErrorCode != 0)
            {
                //log to db or logger
                //reschedule message to send in an hour
            }


        }

 

 public void SendMessage(SmsMessage msg)
        {
            SmsLiveProvider slp = new SmsLiveProvider();
            Thread.Sleep(200);
            ThreadPool.QueueUserWorkItem(stateObject => slp.SendMsg(msg));

        }

 

 public class MailPusher
    {
        public void SendMail(MailModel mm)
        {
            var api = new MandrillApi("your-key"); //you could as well store in web .config

            var recipients = new List<Mandrill.Messages.Recipient> {new Mandrill.Messages.Recipient(mm.To, mm.Name)};

            var message = new Mandrill.Messages.Message()
            {
                To = recipients.ToArray(),
                BccAddress = mm.Bcc,
                FromEmail = mm.From,
                Subject = mm.Subject,
                Html = mm.Message
            };

            api.Send(message);
        }

      
        public void SendEmail(string to, string bcc, string subject, string message)
        {
            var msg = new MailModel
            {
                From = "me@tobiawe.com",
                To = to,
                Bcc = bcc,
                Name = "YOU NEW POSTING",
                Message = message,
                Subject = subject
            };
            Thread.Sleep(200);
            ThreadPool.QueueUserWorkItem(stateObject => SendMail(msg));
        }
    }

 

 

If sending fails from the web service endpoint (we determine this by checking the response msg), then we reschedule again.

 

The next thing we’ll do from here is to schedule the notifications using hangfire. To initiate hangfire, we simply add the following to our startup file

 public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            GlobalConfiguration.Configuration.UseMemoryStorage();
            app.UseHangfireDashboard();
            app.UseHangfireServer();
            ConfigureAuth(app);
        }
    }

 

Then to schedule,we do it this way.

  public ActionResult NotifyStaffs()
        {
            var allPostings = _db.Postings.Include("Staff").ToList();
            if (allPostings.Any())
            {
                foreach (var posting in allPostings)
                {
                    //create a new msg object
                    var newmsg = new SmsMessage
                    {
                        Message = "You've been assigned to serve at " + posting.AssignedOffice + " between dates "    +
                                  posting.StartDate.ToShortDateString() + " and  " + posting.EndDate.ToShortDateString(),
                        Number = posting.Staff.ApplicationUser.PhoneNumber,
                        SenderId = "TOBIAWE"
                    };
                    //queue sms
                    BackgroundJob.Schedule(() => _messenger.SendMessage(newmsg), TimeSpan.FromMinutes(1));

                    //create a new email object
                    //queue email
                }
            }
            TempData["info"] = "Notification has been successfully queued";
            return RedirectToAction("Index");
        }

 

To check the status of our scheduled jobs(Task), we can simply  navigate to the dashboard url i.e localhost:port/hangfire. If anything goes wrong,we can easily  see it and reschedule. Kindly note that Hangfire.MemoryStorage is not recommended for production use; other form of persistence such as postgresql,Ms sql etc could be used. The list of available options can be found here. And of course, I would expect anyone to test properly before pushing to production. Furthermore, The Sms and Email Notification can be scheduled in Batches rather than just pulling the entire list and looping through at once.

The Entire Source could be downloaded from here.

Bookmark and Share

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
1 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Heyzed Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Heyzed
Guest
Heyzed

If you are using VS13 and below, change this code :
public string SiteToken => ConfigurationManager.AppSettings.Get(“smssubaccounttoken”);
to
public string SiteToken = “smssubaccounttoken”;