using System.Net.Mail;
using System.Net;
using Diligent.WebAPI.Contracts.Models;
namespace Diligent.WebAPI.Business.Services
{
///
/// Provieds an API for sending emails in both sync & async fashion, as well as sending emails with delays.
///
public class Emailer : IEmailer
{
private readonly MailSettings _settings;
public Emailer(IOptions mailSettings)
{
_settings = mailSettings.Value;
//_settings = new AuthorizationSettings
//{
// SmtpServer = "smtp.mailtrap.io",
// SmtpPort = 2525,
// SmtpUseSSL = true,
// SmtpUsername = "460e3c49f02e37",
// SmtpPassword = "66443869eaad55",
// SmtpFrom = "noreply@hrcenter.net",
// SmtpFromName = "HRCenter Team"
//};
}
///
/// Sends an email asynchronously and inserts a new record to the underlying database.
///
///
///
///
///
///
///
///
///
///
///
public async Task SendEmailAndWriteToDbAsync(List to, string subject, string body, bool isHtml = false, List cc = null)
{
var emailResult = await SendEmailAsync(to, subject, body, isHtml, cc);
var email = CreateEmail(to, subject, body, isHtml);
if (emailResult)
{
email.SentTime = DateTime.UtcNow;
}
//var dbResult = await WriteEmailToDbAsync(email);
return emailResult; // && dbResult > 0;
}
public async Task SendEmailAndWriteToDbAsync(string to, string subject, string body, bool isHtml = false, List cc = null)
{
return await SendEmailAndWriteToDbAsync(new List { to }, subject, body, isHtml, cc);
}
///
/// Sends an email synchronously and inserts a new record to the underlying database.
///
///
///
///
///
///
///
///
///
///
///
public bool SendEmailAndWriteToDb(List to, string subject, string body, bool isHtml = false,
List cc = null)
{
var emailResult = SendEmail(to, subject, body, isHtml, cc);
var email = CreateEmail(to, subject, body, isHtml);
if (emailResult)
{
email.SentTime = DateTime.UtcNow;
}
//var dbResult = WriteEmailToDb(email);
return emailResult; // && dbResult > 0;
}
public bool SendEmailAndWriteToDb(string to, string subject, string body, bool isHtml = false,
List cc = null)
{
return SendEmailAndWriteToDb(new List { to }, subject, body, isHtml, cc);
}
///
/// Sends an email synchronously.
///
///
///
///
///
///
///
///
///
///
///
public bool SendEmail(List to, string subject, string body, bool isHtml = false,
List cc = null)
{
try
{
using (var smtp = GetSmtpClient())
{
var message = GetMailMessage(to, subject, body, isHtml, cc);
smtp.Send(message);
return true;
}
}
catch (ArgumentException)
{
throw;
}
catch (Exception e)
{
throw new Exception("Failed to send email message.", e);
}
}
///
/// Sends an email asynchronously.
///
///
///
///
///
///
///
///
///
///
///
public async Task SendEmailAsync(List to, string subject, string body, bool isHtml = false, List cc = null)
{
try
{
using (var smtp = GetSmtpClient())
{
var message = GetMailMessage(to, subject, body, isHtml, cc);
await smtp.SendMailAsync(message);
return true;
}
}
catch (ArgumentException)
{
throw;
}
catch (Exception e)
{
throw new Exception("Failed to send email message.", e);
}
}
///
/// Creates a object and configures it.
///
///
public SmtpClient GetSmtpClient()
{
var smtp = new SmtpClient(_settings.SmtpServer) { Timeout = 1000000 };
if (!string.IsNullOrWhiteSpace(_settings.SmtpUsername))
{
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential(
_settings.SmtpUsername,
_settings.SmtpPassword);
smtp.EnableSsl = _settings.SmtpUseSSL;
smtp.Port = _settings.SmtpPort;
}
return smtp;
}
///
/// Creates a new from the specified arguments.
///
///
///
///
///
///
///
///
///
public MailMessage GetMailMessage(List to, string subject, string body, bool isHtml = false, List cc = null)
{
var message = new MailMessage
{
Sender = new MailAddress(_settings.SmtpFrom, _settings.SmtpFromName),
From = new MailAddress(_settings.SmtpFrom),
Subject = subject,
Body = body,
IsBodyHtml = isHtml
};
if (to.Any())
{
message.To.Add(string.Join(",", to.Where(email => !string.IsNullOrWhiteSpace(email))));
}
else
{
throw new ArgumentException("The list of recipient emails can not be empty");
}
if (cc != null && cc.Any())
{
message.CC.Add(string.Join(",", cc.Where(email => !string.IsNullOrWhiteSpace(email))));
}
return message;
}
///
/// Sends an email aysnchronously. If the "dont send before" argument is specified, then the email will be sent with a delay - after the specified time.
///
///
///
///
///
///
///
///
///
///
public async Task SendEmailWithDelayAsync(List to, string subject, string body, bool isHtml = false, DateTime? dontSendBefore = null)
{
try
{
var email = CreateEmail(to, subject, body, isHtml, dontSendBefore);
//var result = await WriteEmailToDbAsync(email);
return true;
}
catch (ArgumentException)
{
throw;
}
catch (Exception e)
{
throw new Exception("Error while attempting to send an email with delay.", e);
}
}
///
/// Creates a object with specified arguments.
///
///
///
///
///
///
///
///
///
public DiligEmail CreateEmail(List to, string subject, string body, bool isHtml = false,
DateTime? dontSendBefore = null)
{
if (!to.Any())
{
throw new ArgumentException("The list of recipient emails can not be empty");
}
var email = new DiligEmail
{
To = to.Aggregate((previous, next) => previous + ";" + next),
Subject = subject,
Body = body,
IsHtml = isHtml,
DontSendBefore = dontSendBefore,
CreateTime = DateTime.UtcNow
};
return email;
}
///
/// Fills the specified object with the specified list.
///
///
///
///
///
//public DiligEmail FillEmailAttachments(DiligEmail email)
//{
// if (email == null)
// {
// throw new ArgumentNullException(nameof(email), "Email can not be null");
// }
// if (attachments != null && attachments.Any())
// {
// attachments.ForEach(attachment =>
// {
// email.DiligEmailAttachments.Add(new DiligEmailAttachment
// {
// FileName = attachment.FileName,
// SourceFileName = attachment.SourceFileName,
// Type = attachment.Type,
// Disposition = attachment.Disposition
// });
// });
// }
// return email;
//}
///
/// Writes the specified object to the underlying database.
///
///
///
///
///
//public async Task WriteEmailToDbAsync(DiligEmail email)
//{
// try
// {
// if (email == null)
// {
// throw new ArgumentNullException(nameof(email), "Email can not be null");
// }
// _entities.DiligEmails.Add(email);
// var result = await _entities.SaveChangesAsync();
// return result;
// }
// catch (Exception e)
// {
// throw new Exception("Failed to write entry into the database", e);
// }
//}
///
/// Writes the specified object to the underlying database.
///
///
///
///
///
//public int WriteEmailToDb(DiligEmail email)
//{
// try
// {
// if (email == null)
// {
// throw new ArgumentNullException(nameof(email), "Email can not be null");
// }
// _entities.DiligEmails.Add(email);
// var result = _entities.SaveChanges();
// return result;
// }
// catch (ArgumentException)
// {
// throw;
// }
// catch (Exception e)
// {
// throw new Exception("Failed to write entry into the database", e);
// }
//}
}
}