From b7cf2d255350afde45cb1254ea1ddce76b024bd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sun, 27 Apr 2025 13:49:27 +0200 Subject: [PATCH 1/3] Implement mailing using sendgrid --- .../Common/Mail/Abstractions/IMailService.cs | 8 ++++ .../Common/Mail/Services/MailService.cs | 38 +++++++++++++++++++ TickAPI/TickAPI/Program.cs | 5 ++- TickAPI/TickAPI/TickAPI.csproj | 2 + TickAPI/TickAPI/appsettings.example.json | 6 +++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs create mode 100644 TickAPI/TickAPI/Common/Mail/Services/MailService.cs diff --git a/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs b/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs new file mode 100644 index 0000000..e709076 --- /dev/null +++ b/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs @@ -0,0 +1,8 @@ +using TickAPI.Common.Results; + +namespace TickAPI.Common.Mail.Abstractions; + +public interface IMailService +{ + public Task SendTicketAsync(string toEmail, string toLogin, string eventName, byte[] pdfData); +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Common/Mail/Services/MailService.cs b/TickAPI/TickAPI/Common/Mail/Services/MailService.cs new file mode 100644 index 0000000..f12bf51 --- /dev/null +++ b/TickAPI/TickAPI/Common/Mail/Services/MailService.cs @@ -0,0 +1,38 @@ +using System.Net; +using SendGrid; +using SendGrid.Helpers.Mail; +using TickAPI.Common.Mail.Abstractions; +using TickAPI.Common.Results; + +namespace TickAPI.Common.Mail.Services; + +public class MailService : IMailService +{ + private SendGridClient _client; + private EmailAddress _fromEmailAddress; + + public MailService(IConfiguration configuration) + { + var apiKey = configuration["SendGrid:ApiKey"]; + _client = new SendGridClient(apiKey); + var fromEmail = configuration["SendGrid:FromEmail"]; + var fromName = configuration["SendGrid:FromName"]; + _fromEmailAddress = new EmailAddress(fromEmail, fromName); + } + + public async Task SendTicketAsync(string toEmail, string toLogin, string eventName, byte[] pdfData) + { + var subject = $"Ticket for {eventName}"; + var toEmailAddress = new EmailAddress(toEmail, toLogin); + var htmlContent = "Download your ticket from attachments"; + var msg = MailHelper.CreateSingleEmail(_fromEmailAddress, toEmailAddress, subject, null, htmlContent); + var base64Content = Convert.ToBase64String(pdfData); + msg.AddAttachment("ticket.pdf", base64Content, "application/pdf"); + var response = await _client.SendEmailAsync(msg).ConfigureAwait(false); + if (response.IsSuccessStatusCode) + { + return Result.Success(); + } + return Result.Failure(500, "Error sending ticket"); + } +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Program.cs b/TickAPI/TickAPI/Program.cs index 59b7d54..40523e4 100644 --- a/TickAPI/TickAPI/Program.cs +++ b/TickAPI/TickAPI/Program.cs @@ -38,6 +38,8 @@ using TickAPI.Common.Claims.Services; using TickAPI.Common.Redis.Abstractions; using TickAPI.Common.Redis.Services; +using TickAPI.Common.Mail.Abstractions; +using TickAPI.Common.Mail.Services; // Builder constants const string allowClientPolicyName = "AllowClient"; @@ -120,6 +122,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); @@ -202,4 +205,4 @@ app.MapControllers(); -app.Run(); \ No newline at end of file +app.Run(); diff --git a/TickAPI/TickAPI/TickAPI.csproj b/TickAPI/TickAPI/TickAPI.csproj index 2f1a9cc..a4ca3a8 100644 --- a/TickAPI/TickAPI/TickAPI.csproj +++ b/TickAPI/TickAPI/TickAPI.csproj @@ -18,6 +18,8 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/TickAPI/TickAPI/appsettings.example.json b/TickAPI/TickAPI/appsettings.example.json index 04cae82..972d87b 100644 --- a/TickAPI/TickAPI/appsettings.example.json +++ b/TickAPI/TickAPI/appsettings.example.json @@ -25,5 +25,11 @@ "SecurityKey": "IH4xhBUKl3z51Gig5MFfg4kl0yLOulGk", "ExpirySeconds" : "3600" } + }, + + "SendGrid": { + "ApiKey": "ApiKey", + "FromEmail": "your_mail", + "FromName": "Resellio" } } From 2abe050db45f7b3a0160aba012ee38feb8e3e45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sun, 27 Apr 2025 14:40:40 +0200 Subject: [PATCH 2/3] Add abstraction --- .../Common/Mail/Models/MailAttachment.cs | 8 +++++ .../Common/Mail/Services/MailService.cs | 32 +++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 TickAPI/TickAPI/Common/Mail/Models/MailAttachment.cs diff --git a/TickAPI/TickAPI/Common/Mail/Models/MailAttachment.cs b/TickAPI/TickAPI/Common/Mail/Models/MailAttachment.cs new file mode 100644 index 0000000..d59be62 --- /dev/null +++ b/TickAPI/TickAPI/Common/Mail/Models/MailAttachment.cs @@ -0,0 +1,8 @@ +namespace TickAPI.Common.Mail.Models; + +public class MailAttachment +{ + public string fileName { get; set; } + public string base64Content { get; set; } + public string fileType { get; set; } +} \ No newline at end of file diff --git a/TickAPI/TickAPI/Common/Mail/Services/MailService.cs b/TickAPI/TickAPI/Common/Mail/Services/MailService.cs index f12bf51..05903c1 100644 --- a/TickAPI/TickAPI/Common/Mail/Services/MailService.cs +++ b/TickAPI/TickAPI/Common/Mail/Services/MailService.cs @@ -2,6 +2,7 @@ using SendGrid; using SendGrid.Helpers.Mail; using TickAPI.Common.Mail.Abstractions; +using TickAPI.Common.Mail.Models; using TickAPI.Common.Results; namespace TickAPI.Common.Mail.Services; @@ -23,11 +24,35 @@ public MailService(IConfiguration configuration) public async Task SendTicketAsync(string toEmail, string toLogin, string eventName, byte[] pdfData) { var subject = $"Ticket for {eventName}"; - var toEmailAddress = new EmailAddress(toEmail, toLogin); var htmlContent = "Download your ticket from attachments"; - var msg = MailHelper.CreateSingleEmail(_fromEmailAddress, toEmailAddress, subject, null, htmlContent); var base64Content = Convert.ToBase64String(pdfData); - msg.AddAttachment("ticket.pdf", base64Content, "application/pdf"); + List attachments = + [ + new MailAttachment + { + base64Content = base64Content, + fileName = "ticket.pdf", + fileType = "application/pdf" + } + ]; + var res = await SendMailAsync(toEmail, toLogin, subject, htmlContent, attachments); + return res; + } + + public async Task SendMailAsync(string toEmail, string toLogin, string subject, string content, + List? attachments = null) + { + var toEmailAddress = new EmailAddress(toEmail, toLogin); + var msg = MailHelper.CreateSingleEmail(_fromEmailAddress, toEmailAddress, subject, + null, content); + if (attachments != null) + { + foreach (var a in attachments) + { + msg.AddAttachment(a.fileName, a.base64Content, a.fileType); + } + } + var response = await _client.SendEmailAsync(msg).ConfigureAwait(false); if (response.IsSuccessStatusCode) { @@ -35,4 +60,5 @@ public async Task SendTicketAsync(string toEmail, string toLogin, string } return Result.Failure(500, "Error sending ticket"); } + } \ No newline at end of file From 9a12580f34df5ffcbdf5fa17f44d3f375dc0113e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stanis=C5=82aw?= <62651497+staszkiet@users.noreply.github.com> Date: Sun, 27 Apr 2025 16:10:04 +0200 Subject: [PATCH 3/3] fix kubapobke review --- TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs | 6 +++++- TickAPI/TickAPI/Common/Mail/Services/MailService.cs | 2 +- TickAPI/TickAPI/appsettings.example.json | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs b/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs index e709076..b7f3965 100644 --- a/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs +++ b/TickAPI/TickAPI/Common/Mail/Abstractions/IMailService.cs @@ -1,8 +1,12 @@ -using TickAPI.Common.Results; +using TickAPI.Common.Mail.Models; +using TickAPI.Common.Results; namespace TickAPI.Common.Mail.Abstractions; public interface IMailService { public Task SendTicketAsync(string toEmail, string toLogin, string eventName, byte[] pdfData); + + public Task SendMailAsync(string toEmail, string toLogin, string subject, string content, + List? attachments); } \ No newline at end of file diff --git a/TickAPI/TickAPI/Common/Mail/Services/MailService.cs b/TickAPI/TickAPI/Common/Mail/Services/MailService.cs index 05903c1..1e5a1c9 100644 --- a/TickAPI/TickAPI/Common/Mail/Services/MailService.cs +++ b/TickAPI/TickAPI/Common/Mail/Services/MailService.cs @@ -58,7 +58,7 @@ public async Task SendMailAsync(string toEmail, string toLogin, string s { return Result.Success(); } - return Result.Failure(500, "Error sending ticket"); + return Result.Failure(500, "Error sending email"); } } \ No newline at end of file diff --git a/TickAPI/TickAPI/appsettings.example.json b/TickAPI/TickAPI/appsettings.example.json index 972d87b..bbb517d 100644 --- a/TickAPI/TickAPI/appsettings.example.json +++ b/TickAPI/TickAPI/appsettings.example.json @@ -32,4 +32,4 @@ "FromEmail": "your_mail", "FromName": "Resellio" } -} +} \ No newline at end of file