From 900bb5e845c3ad44defbd427cae3d44a4a43321f Mon Sep 17 00:00:00 2001 From: ivarlovlie Date: Sat, 25 Feb 2023 13:15:44 +0100 Subject: feat: Initial commit --- code/api/src/Services/MailService.cs | 132 +++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 code/api/src/Services/MailService.cs (limited to 'code/api/src/Services/MailService.cs') diff --git a/code/api/src/Services/MailService.cs b/code/api/src/Services/MailService.cs new file mode 100644 index 0000000..a6f7db4 --- /dev/null +++ b/code/api/src/Services/MailService.cs @@ -0,0 +1,132 @@ +namespace IOL.GreatOffice.Api.Services; + +public class MailService +{ + private readonly ILogger _logger; + private static string _fromEmail; + private readonly HttpClient _httpClient; + + public MailService(VaultService vaultService, ILogger logger, HttpClient httpClient) { + var configuration = vaultService.GetCurrentAppConfiguration(); + _fromEmail = configuration.EMAIL_FROM_ADDRESS; + _logger = logger; + httpClient.DefaultRequestHeaders.Add("X-Postmark-Server-Token", configuration.POSTMARK_TOKEN); + _httpClient = httpClient; + } + + /// + /// Send an email. + /// + /// + /// + public async Task SendMailAsync(PostmarkEmail message) { + try { + if (message.MessageStream.IsNullOrWhiteSpace()) { + message.MessageStream = "outbound"; + } + + if (message.From.IsNullOrWhiteSpace() && _fromEmail.HasValue()) { + message.From = _fromEmail; + } else { + throw new ApplicationException("Not one from-email is available"); + } + + if (message.To.IsNullOrWhiteSpace()) { + throw new ArgumentNullException(nameof(message.To), "A recipient should be specified."); + } + + if (!message.To.IsValidEmailAddress()) { + throw new ArgumentException(nameof(message.To), "To is not a valid email address"); + } + + if (message.HtmlBody.IsNullOrWhiteSpace() && message.TextBody.IsNullOrWhiteSpace()) { + throw new ArgumentNullException(nameof(message), "Both HtmlBody and TextBody is empty, nothing to send"); + } +#if DEBUG + _logger.LogInformation("Sending email: {0}", JsonSerializer.Serialize(message, new JsonSerializerOptions() {WriteIndented = true})); +#endif + var response = await _httpClient.PostAsJsonAsync("https://api.postmarkapp.com/email", message); + _logger.LogInformation("Postmark returned with message: {0}", (await response.Content.ReadFromJsonAsync()).Message); + } catch (Exception e) { + _logger.LogError(e, "A silent exception occured while trying to send an email"); + } + } + + private class PostmarkSendResponse + { + /// + /// The Message ID returned from Postmark. + /// + public Guid MessageID { get; set; } + + /// + /// The message from the API. + /// In the event of an error, this message may contain helpful text. + /// + public string Message { get; set; } + + /// + /// The time the request was received by Postmark. + /// + public DateTime SubmittedAt { get; set; } + + /// + /// The recipient of the submitted request. + /// + public string To { get; set; } + + /// + /// The error code returned from Postmark. + /// This does not map to HTTP status codes. + /// + public int ErrorCode { get; set; } + } + + public class PostmarkEmail + { + /// + /// The message subject line. + /// + public string Subject { get; set; } + + /// + /// The message body, if the message contains + /// + public string HtmlBody { get; set; } + + /// + /// The message body, if the message is plain text. + /// + public string TextBody { get; set; } + + /// + /// The message stream used to send this message. + /// + public string MessageStream { get; set; } + + /// + /// The sender's email address. + /// + public string From { get; set; } + + /// + /// Any recipients. Separate multiple recipients with a comma. + /// + public string To { get; set; } + + /// + /// Any CC recipients. Separate multiple recipients with a comma. + /// + public string Cc { get; set; } + + /// + /// Any BCC recipients. Separate multiple recipients with a comma. + /// + public string Bcc { get; set; } + + /// + /// The email address to reply to. This is optional. + /// + public string ReplyTo { get; set; } + } +} \ No newline at end of file -- cgit v1.3