-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Scott Galloway
committed
Sep 27, 2024
1 parent
13fac2d
commit 83cef92
Showing
29 changed files
with
350 additions
and
298 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
127 changes: 91 additions & 36 deletions
127
Mostlylucid.SchedulerService/Services/NewsletterSendingService.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,56 +1,111 @@ | ||
using System.Diagnostics.CodeAnalysis; | ||
using Mostlylucid.DbContext.EntityFramework; | ||
using Mostlylucid.Services.Email; | ||
using Mostlylucid.Services.Email; | ||
using Mostlylucid.Services.EmailSubscription; | ||
using Mostlylucid.Shared; | ||
using Mostlylucid.Shared.Config; | ||
using Mostlylucid.Shared.Helpers; | ||
using Mostlylucid.Shared.Models.EmailSubscription; | ||
using Serilog; | ||
using Serilog.Events; | ||
using SerilogTracing; | ||
|
||
namespace Mostlylucid.SchedulerService.Services; | ||
|
||
public class NewsletterSendingService(IServiceScopeFactory scopeFactory) | ||
public class NewsletterSendingService( | ||
IServiceScopeFactory scopeFactory, | ||
NewsletterConfig newsletterConfig, | ||
ILogger<NewsletterSendingService> logger) | ||
{ | ||
public async Task SendNewsletter(SubscriptionType subscriptionType) | ||
private string GetPostUrl(string language, string slug) | ||
{ | ||
|
||
var scope = scopeFactory.CreateScope(); | ||
return language == Constants.EnglishLanguage ? $"{newsletterConfig.AppHostUrl}/post/{slug}" : $"{newsletterConfig.AppHostUrl}/{language}/post/{slug}"; | ||
} | ||
|
||
public async Task SendScheduledNewsletter(SubscriptionType subscriptionType) | ||
{ | ||
using var scope = scopeFactory.CreateScope(); | ||
var activity = Log.Logger.StartActivity("SendScheduledNewsletter"); | ||
var newsletterManagementService = scope.ServiceProvider.GetRequiredService<NewsletterManagementService>(); | ||
var emailSender = scope.ServiceProvider.GetRequiredService<IEmailSenderHostedService>(); | ||
|
||
var subscriptions =await newsletterManagementService.GetSubscriptions(subscriptionType); | ||
var posts =await newsletterManagementService.GetPostsToSend(subscriptionType); | ||
foreach (var subscription in subscriptions) | ||
{ | ||
// foreach (var post in posts) | ||
// { | ||
// | ||
// await emailSender.SendEmailAsync(subscription.Email, emailModel); | ||
// } | ||
await newsletterManagementService.UpdateLastSendForSubscription(subscription.Id, DateTime.Now); | ||
} | ||
var subscriptions = await newsletterManagementService.GetSubscriptions(subscriptionType); | ||
foreach (var subscription in subscriptions) | ||
{ | ||
logger.LogInformation("Sending newsletter for subscription {Subscription}", subscription); | ||
await SendNewsletterForSubscription(subscription, activity); | ||
} | ||
logger.LogInformation("Updating last send for subscription type {SubscriptionType}", subscriptionType); | ||
await newsletterManagementService.UpdateLastSend(subscriptionType, DateTime.Now); | ||
} | ||
|
||
public async Task SendImmediateEmailForSubscription(string token) | ||
private async Task<bool> SendNewsletterForSubscription(EmailSubscriptionModel subscription, LoggerActivity activity) | ||
{ | ||
var scope = scopeFactory.CreateScope(); | ||
var emailSubscriptionService = scope.ServiceProvider.GetRequiredService<EmailSubscriptionService>(); | ||
activity?.Activity?.SetTag("subscription", subscription); | ||
try | ||
{ | ||
|
||
using var scope = scopeFactory.CreateScope(); | ||
var newsletterManagementService = scope.ServiceProvider.GetRequiredService<NewsletterManagementService>(); | ||
var emailSender = scope.ServiceProvider.GetRequiredService<IEmailSenderHostedService>(); | ||
var emailSubscription = await emailSubscriptionService.GetByToken(token); | ||
if (emailSubscription == null) | ||
var posts = await newsletterManagementService.GetPostsToSend(subscription.SubscriptionType); | ||
var emailModel = new EmailTemplateModel() | ||
{ | ||
ToEmail = subscription.Email, | ||
Subject = "mostlylucid newsletter", | ||
Posts = posts.Select(p => new EmailPostModel() | ||
{ | ||
Title = p.Title, | ||
Language = p.Language, | ||
PlainTextContent = p.PlainTextContent.TruncateAtWord(200), | ||
Url = GetPostUrl(p.Language, p.Slug), | ||
PublishedDate = p.PublishedDate | ||
}).ToList(), | ||
}; | ||
await emailSender.SendEmailAsync(emailModel); | ||
activity?.Activity?.SetTag("email", subscription.Email); | ||
activity?.Complete(LogEventLevel.Information); | ||
await newsletterManagementService.UpdateLastSendForSubscription(subscription.Id, DateTime.Now); | ||
return true; | ||
} | ||
catch (Exception e) | ||
{ | ||
return; | ||
activity?.Complete(LogEventLevel.Error, e); | ||
logger.LogError(e, "Error sending newsletter for subscription {Subscription}", subscription); | ||
return false; | ||
} | ||
|
||
|
||
} | ||
|
||
public async Task SendEmail(SubscriptionType subscriptionType, DateTime fromDateTime, DateTime toDateTime, | ||
string email) | ||
|
||
public async Task<bool> SendImmediateEmailForSubscription(string token) | ||
{ | ||
|
||
var emailTemplageModel = new EmailTemplateModel | ||
using var activity = Log.Logger.StartActivity("SendImmediateEmailForSubscription"); | ||
try | ||
{ | ||
ToEmail = email | ||
}; | ||
var scope = scopeFactory.CreateScope(); | ||
var emailSubscriptionService = scope.ServiceProvider.GetRequiredService<EmailSubscriptionService>(); | ||
|
||
var emailSubscription = await emailSubscriptionService.GetByToken(token); | ||
activity.AddProperty("token", token); | ||
if (emailSubscription == null) | ||
{ | ||
logger.LogWarning("Email subscription not found for token {token}", token); | ||
activity.Complete(LogEventLevel.Warning); | ||
return false; | ||
} | ||
|
||
logger.LogInformation("Sending email for subscription {EmailSubscription}", emailSubscription); | ||
if (await SendNewsletterForSubscription(emailSubscription, activity)) | ||
{ | ||
activity.Complete(LogEventLevel.Information); | ||
} | ||
else | ||
{ | ||
return false; | ||
} | ||
return true; | ||
} | ||
catch (Exception e) | ||
{ | ||
logger.LogError(e, "Error sending email for subscription"); | ||
activity?.Complete(LogEventLevel.Error, e); | ||
return false; | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
45 changes: 45 additions & 0 deletions
45
Mostlylucid.Service.Test/IEmailServiceTests/EmailService_Send_Tests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System.Reflection; | ||
using FakeItEasy; | ||
using FluentEmail.Core; | ||
using FluentEmail.Core.Models; | ||
using Microsoft.Extensions.Logging.Testing; | ||
using Mostlylucid.Services.Email; | ||
using Mostlylucid.Shared.Config; | ||
using Mostlylucid.Shared.Models.Email; | ||
|
||
namespace Mostlylucid.Service.Test.IEmailServiceTests; | ||
|
||
public class EmailService_Send_Tests | ||
{ | ||
private readonly string _toEmail = "test@test.com"; | ||
private string _senderEmail = "test1@test.com"; | ||
private readonly CancellationToken ct = new CancellationToken(); | ||
private readonly string _senderName = "Test"; | ||
private SendResponse _sendResponse; | ||
private Fake<IFluentEmail> GetEmailService() | ||
{ | ||
var smtpSettings = new SmtpSettings(); | ||
smtpSettings.ToMail = _toEmail; | ||
var fluentEmail = new FakeItEasy.Fake<IFluentEmail>(); | ||
fluentEmail.CallsTo(x => | ||
x.UsingTemplateFromEmbedded(A<string>.Ignored, A<object>.Ignored, A<Assembly>.Ignored, true)).Returns(fluentEmail.FakedObject); | ||
fluentEmail.CallsTo(x => x.To(A<string>.Ignored)).Returns(fluentEmail.FakedObject); | ||
fluentEmail.CallsTo(x => x.SetFrom(A<string>.Ignored, A<string>.Ignored)).Returns(fluentEmail.FakedObject); | ||
fluentEmail.CallsTo(x => x.Subject(A<string>.Ignored)).Returns(fluentEmail.FakedObject); | ||
fluentEmail.CallsTo(x => x.SendAsync(ct)).Returns(_sendResponse); | ||
|
||
return fluentEmail; | ||
} | ||
|
||
[Fact] | ||
public async Task Test_Send() | ||
{ | ||
var fakeLogger =new FakeLogger<EmailService>(); | ||
var fluentMail = GetEmailService(); | ||
|
||
var emailService = new EmailService(new SmtpSettings(), fluentMail.FakedObject,fakeLogger); | ||
var emailModel = new BaseEmailModel(); | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>true</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="coverlet.collector" Version="6.0.0"/> | ||
<PackageReference Include="FakeItEasy" Version="8.3.0" /> | ||
<PackageReference Include="Microsoft.Extensions.Diagnostics.Testing" Version="8.9.1" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/> | ||
<PackageReference Include="xunit" Version="2.5.3"/> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Using Include="Xunit"/> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Mostlylucid.Services\Mostlylucid.Services.csproj" /> | ||
<ProjectReference Include="..\Mostlylucid.Shared\Mostlylucid.Shared.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.