Browse Source

refactor: emailing for event reminder and new event

pull/18/head
Berkan 6 years ago
parent
commit
36088724d5
  1. 2
      src/EventHub.Application/Emailing/Templates/EventReminder.tpl
  2. 2
      src/EventHub.Application/Emailing/Templates/NewEventCreated.tpl
  3. 1
      src/EventHub.Application/EventHub.Application.csproj
  4. 1
      src/EventHub.Application/EventHubApplicationModule.cs
  5. 17
      src/EventHub.Application/Events/EventAppService.cs
  6. 35
      src/EventHub.Application/Events/EventReminderNotifier.cs
  7. 39
      src/EventHub.Application/Events/EventReminderWorker.cs
  8. 50
      src/EventHub.Application/Events/NewEventDetectorWorker.cs
  9. 31
      src/EventHub.Application/Events/NewEventNotifier.cs

2
src/EventHub.Application/Emailing/Templates/EventReminder.tpl

@ -79,7 +79,7 @@
Hi {{model.user_name}},
</p>
<p>
See you in 30 minutes at the "{{model.title}}" event
The "{{model.title}}" event will start very soon.
</p>
<div>
<table border="0" cellpadding="0" cellspacing="0" style=" border-collapse: separate; vertical-align: top; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">

2
src/EventHub.Application/Emailing/Templates/NewEventCreated.tpl

@ -79,7 +79,7 @@
Hi {{model.user_name}},
</p>
<p>
A new event was created by "{{model.organization_name}}" under the title of "{{model.title}}".
A new event called "{{model.title}}" has been created.
</p>
<div>
<table border="0" cellpadding="0" cellspacing="0" style=" border-collapse: separate; vertical-align: top; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">

1
src/EventHub.Application/EventHub.Application.csproj

@ -13,7 +13,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.2" />
<PackageReference Include="Volo.Abp.Account.Application" Version="4.2.0-rc.1" />
<PackageReference Include="Volo.Abp.Identity.Application" Version="4.2.0-rc.1" />
<PackageReference Include="Volo.Abp.PermissionManagement.Application" Version="4.2.0-rc.1" />

1
src/EventHub.Application/EventHubApplicationModule.cs

@ -23,6 +23,7 @@ namespace EventHub
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
context.AddBackgroundWorker<EventReminderWorker>();
context.AddBackgroundWorker<NewEventDetectorWorker>();
}
public override void ConfigureServices(ServiceConfigurationContext context)

17
src/EventHub.Application/Events/EventAppService.cs

@ -3,7 +3,6 @@ using System.Linq;
using System.Threading.Tasks;
using EventHub.Organizations;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
@ -16,18 +15,15 @@ namespace EventHub.Events
private readonly EventManager _eventManager;
private readonly IRepository<Organization, Guid> _organizationRepository;
private readonly IRepository<Event, Guid> _eventRepository;
private readonly NewEventNotifier _newEventNotifier;
public EventAppService(
EventManager eventManager,
IRepository<Organization, Guid> organizationRepository,
IRepository<Event, Guid> eventRepository,
NewEventNotifier newEventNotifier)
IRepository<Event, Guid> eventRepository)
{
_eventManager = eventManager;
_organizationRepository = organizationRepository;
_eventRepository = eventRepository;
_newEventNotifier = newEventNotifier;
}
[Authorize]
@ -51,20 +47,9 @@ namespace EventHub.Events
@event.IsOnline = input.IsOnline;
@event.Capacity = input.Capacity;
@event.IsEmailSentToMembers = true;
await _eventRepository.InsertAsync(@event);
try
{
await _newEventNotifier.NotifyAsync(organization, @event);
}
catch (Exception e)
{
@event.IsEmailSentToMembers = false;
Logger.LogError($"An error occurred while sending an email to the members of the {organization.Name} organization after the new event was created. Error message: {e.Message}");
}
return ObjectMapper.Map<Event, EventDto>(@event);
}

35
src/EventHub.Application/Events/EventReminderNotifier.cs

@ -1,9 +1,13 @@
using System.Collections.Generic;
using System;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Emailing;
using EventHub.Events.Registrations;
using EventHub.Users;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Emailing;
using Volo.Abp.Linq;
using Volo.Abp.TextTemplating;
namespace EventHub.Events
@ -12,25 +16,42 @@ namespace EventHub.Events
{
private readonly IEmailSender _emailSender;
private readonly ITemplateRenderer _templateRenderer;
private readonly IRepository<AppUser, Guid> _userRepository;
private readonly IRepository<EventRegistration, Guid> _eventRegistrationRepository;
private readonly IAsyncQueryableExecuter _asyncExecuter;
public EventReminderNotifier(
IEmailSender emailSender,
ITemplateRenderer templateRenderer)
ITemplateRenderer templateRenderer,
IRepository<AppUser, Guid> userRepository,
IRepository<EventRegistration, Guid> eventRegistrationRepository,
IAsyncQueryableExecuter asyncExecuter)
{
_emailSender = emailSender;
_templateRenderer = templateRenderer;
_userRepository = userRepository;
_eventRegistrationRepository = eventRegistrationRepository;
_asyncExecuter = asyncExecuter;
}
public async Task NotifyAsync(
Event @event,
IEnumerable<AppUser> users)
public async Task NotifyAsync(Event @event)
{
if (users is null || @event is null)
if (@event is null)
{
return;
}
var userQueryable = await _userRepository.GetQueryableAsync();
var eventRegistrationQueryable = await _eventRegistrationRepository.GetQueryableAsync();
var userQuery = from eventRegistration in eventRegistrationQueryable
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == @event.Id
select user;
foreach (var user in users)
var usersToBeNotified = await _asyncExecuter.ToListAsync(userQuery);
foreach (var user in usersToBeNotified)
{
var model = new
{

39
src/EventHub.Application/Events/EventReminderWorker.cs

@ -1,13 +1,11 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using EventHub.Events.Registrations;
using EventHub.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
@ -25,36 +23,27 @@ namespace EventHub.Events
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
var eventReminderNotifier = workerContext.ServiceProvider.GetRequiredService<EventReminderNotifier>();
var eventRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<Event, Guid>>();
var userRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<AppUser, Guid>>();
var eventRegistrationRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<EventRegistration, Guid>>();
var asyncExecuter = workerContext.ServiceProvider.GetRequiredService<IAsyncQueryableExecuter>();
var eventQueryable = await eventRepository.GetQueryableAsync();
var userQueryable = await userRepository.GetQueryableAsync();
var eventRegistrationQueryable = await eventRegistrationRepository.GetQueryableAsync();
var thirtyOneMinutesAfter = DateTime.Now.AddMinutes(31);
var twentyNineMinutesAfter = DateTime.Now.AddMinutes(29);
var thirtyOneMinutesAfter = DateTime.Now.AddMinutes(30);
var oneMinutesAfter = DateTime.Now.AddMinutes(1);
var eventsStartingAfterThirtyMinutes = await eventQueryable.Where(x =>
x.IsRemindingEmailSent == false &&
x.StartTime < thirtyOneMinutesAfter &&
x.StartTime > twentyNineMinutesAfter)
.ToListAsync();
var eventQuery = eventQueryable.Where(x =>
x.IsRemindingEmailSent == false &&
x.StartTime <= thirtyOneMinutesAfter &&
x.StartTime >= oneMinutesAfter);
var events = await asyncExecuter.ToListAsync(eventQuery);
foreach (var @event in eventsStartingAfterThirtyMinutes)
foreach (var @event in events)
{
var usersToBeNotified = await (from eventRegistration in eventRegistrationQueryable
join user in userQueryable on eventRegistration.UserId equals user.Id
where eventRegistration.EventId == @event.Id
select user).ToListAsync();
@event.IsRemindingEmailSent = true;
try
{
await eventReminderNotifier.NotifyAsync(@event, usersToBeNotified);
await eventReminderNotifier.NotifyAsync(@event);
@event.IsRemindingEmailSent = true;
}
catch (Exception e)
{

50
src/EventHub.Application/Events/NewEventDetectorWorker.cs

@ -0,0 +1,50 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Volo.Abp.BackgroundWorkers;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Linq;
using Volo.Abp.Threading;
using Volo.Abp.Uow;
namespace EventHub.Events
{
public class NewEventDetectorWorker : AsyncPeriodicBackgroundWorkerBase
{
public NewEventDetectorWorker(AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory)
: base(timer, serviceScopeFactory)
{
Timer.Period = 60_000;
}
[UnitOfWork]
protected override async Task DoWorkAsync(PeriodicBackgroundWorkerContext workerContext)
{
var newEventNotifier = workerContext.ServiceProvider.GetRequiredService<NewEventNotifier>();
var eventRepository = workerContext.ServiceProvider.GetRequiredService<IRepository<Event, Guid>>();
var asyncExecuter = workerContext.ServiceProvider.GetRequiredService<IAsyncQueryableExecuter>();
var eventQueryable = await eventRepository.GetQueryableAsync();
var eventQuery = eventQueryable.Where(x => x.IsEmailSentToMembers == false);
var newEvents = await asyncExecuter.ToListAsync(eventQuery);
foreach (var @event in newEvents)
{
try
{
await newEventNotifier.NotifyAsync(@event);
@event.IsEmailSentToMembers = true;
}
catch (Exception e)
{
@event.IsEmailSentToMembers = false;
Logger.LogError($"An error occurred while sending an email to the members of the organization after the new event was created. Error message: {e.Message}");
}
}
}
}
}

31
src/EventHub.Application/Events/NewEventNotifier.cs

@ -1,15 +1,13 @@
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using EventHub.Emailing;
using EventHub.Organizations;
using EventHub.Organizations.Memberships;
using EventHub.Users;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Emailing;
using Volo.Abp.Linq;
using Volo.Abp.TextTemplating;
namespace EventHub.Events
@ -20,33 +18,35 @@ namespace EventHub.Events
private readonly ITemplateRenderer _templateRenderer;
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipsRepository;
private readonly IRepository<AppUser, Guid> _userRepository;
private readonly IAsyncQueryableExecuter _asyncExecuter;
public NewEventNotifier(
IEmailSender emailSender,
ITemplateRenderer templateRenderer,
ITemplateRenderer templateRenderer,
IRepository<OrganizationMembership, Guid> organizationMembershipsRepository,
IRepository<AppUser, Guid> userRepository)
IRepository<AppUser, Guid> userRepository,
IAsyncQueryableExecuter asyncExecuter)
{
_emailSender = emailSender;
_templateRenderer = templateRenderer;
_organizationMembershipsRepository = organizationMembershipsRepository;
_userRepository = userRepository;
_asyncExecuter = asyncExecuter;
}
public async Task NotifyAsync(
Organization organization,
Event @event)
public async Task NotifyAsync(Event @event)
{
if (organization is null || @event is null)
if (@event is null)
{
return;
}
var organizationMemberQueryable = await _organizationMembershipsRepository.GetQueryableAsync();
var organizationMembers = await organizationMemberQueryable
.Where(x => x.OrganizationId == organization.Id)
.ToListAsync();
var organizationMembershipsQueryable = await _organizationMembershipsRepository.GetQueryableAsync();
var membershipQuery = organizationMembershipsQueryable
.Where(x => x.OrganizationId == @event.OrganizationId);
var organizationMembers = await _asyncExecuter.ToListAsync(membershipQuery);
foreach (var member in organizationMembers)
{
@ -60,7 +60,6 @@ namespace EventHub.Events
var model = new
{
UserName = user.GetFullNameOrUsername(),
OrganizationName = organization.Name,
Title = @event.Title,
StartTime = @event.StartTime,
EndTime = @event.EndTime,

Loading…
Cancel
Save