MailQueue
This commit is contained in:
@ -16,5 +16,6 @@ public class MailQueue : EntitaBase
|
|||||||
public enum MailFrom
|
public enum MailFrom
|
||||||
{
|
{
|
||||||
Invitation = 0,
|
Invitation = 0,
|
||||||
Confirmation = 1
|
Confirmation,
|
||||||
|
Registrazione
|
||||||
}
|
}
|
||||||
@ -1,20 +1,18 @@
|
|||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Net.Http.Json;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using StandManager.Domain.DTO;
|
using StandManager.Domain.DTO;
|
||||||
using StandManager.MailProcessor.Mail;
|
|
||||||
using StandManager.Service.Interfaces;
|
using StandManager.Service.Interfaces;
|
||||||
|
using StandManager.Service.Resolver;
|
||||||
|
|
||||||
public class MailProcessor
|
public class MailProcessor
|
||||||
{
|
{
|
||||||
private readonly IManagerService _managerService;
|
private readonly IManagerService _managerService;
|
||||||
private readonly EmailConfig _config;
|
private readonly EmailConfig _config;
|
||||||
|
private readonly IMailProcessorResolver _resolver;
|
||||||
|
|
||||||
public MailProcessor(IManagerService managerService, EmailConfig config)
|
public MailProcessor(IManagerService managerService, EmailConfig config, IMailProcessorResolver resolver)
|
||||||
{
|
{
|
||||||
_managerService = managerService;
|
_managerService = managerService;
|
||||||
_config = config;
|
_config = config;
|
||||||
|
_resolver = resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Process()
|
public async Task Process()
|
||||||
@ -23,54 +21,11 @@ public class MailProcessor
|
|||||||
x.Eliminato == false && x.Sent == false && string.IsNullOrEmpty(x.Error), solaLettura:false);
|
x.Eliminato == false && x.Sent == false && string.IsNullOrEmpty(x.Error), solaLettura:false);
|
||||||
|
|
||||||
using var httpClient = new HttpClient();
|
using var httpClient = new HttpClient();
|
||||||
foreach (var mailQueue in list)
|
foreach (var mailQueueByFrom in list.GroupBy(x => x.From))
|
||||||
{
|
{
|
||||||
var email = new Email()
|
var processor = _resolver.Resolve(mailQueueByFrom.Key);
|
||||||
{
|
|
||||||
From = _config.From,
|
|
||||||
Body = string.IsNullOrEmpty(mailQueue.Args) ? mailQueue.Body : string.Format(mailQueue.Body, mailQueue.Args?.Split(_config.MailSplitChar) ?? [""]),
|
|
||||||
Cc = null,
|
|
||||||
Subject = mailQueue.Subject,
|
|
||||||
To = new(){"g.vitari@oaservice.it"} // mailQueue.ToList.Split(";").ToList()
|
|
||||||
};
|
|
||||||
var messageJson = JsonSerializer.Serialize(email);
|
|
||||||
|
|
||||||
// multipart
|
|
||||||
using var form = new MultipartFormDataContent();
|
|
||||||
form.Add(
|
|
||||||
new StringContent(messageJson, Encoding.UTF8, "application/json"),
|
|
||||||
"messageJson"
|
|
||||||
);
|
|
||||||
|
|
||||||
//Attachments
|
|
||||||
/*var filePath = @"C:\temp\test.pdf";
|
|
||||||
var fileBytes = await File.ReadAllBytesAsync(filePath);
|
|
||||||
|
|
||||||
var fileContent = new ByteArrayContent(fileBytes);
|
|
||||||
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf");
|
|
||||||
|
|
||||||
form.Add(
|
|
||||||
fileContent,
|
|
||||||
"attachments",
|
|
||||||
Path.GetFileName(filePath)
|
|
||||||
);*/
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var response = await httpClient.PostAsync(
|
|
||||||
_config.ServerAddress,
|
|
||||||
form
|
|
||||||
);
|
|
||||||
response.EnsureSuccessStatusCode();
|
|
||||||
mailQueue.Sent = true;
|
|
||||||
await _managerService.MailQueueService.Salva(mailQueue);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
mailQueue.Sent = false;
|
|
||||||
mailQueue.Error = e.Message;
|
|
||||||
await _managerService.MailQueueService.Salva(mailQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
await processor.ProcessAsync(mailQueueByFrom.ToList(), _config, httpClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
var a = list;
|
var a = list;
|
||||||
|
|||||||
@ -5,10 +5,10 @@ using Microsoft.Extensions.DependencyInjection;
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using StandManager.Domain.DTO;
|
using StandManager.Domain.DTO;
|
||||||
using StandManager.Infrastructure.DAL.Context;
|
using StandManager.Infrastructure.DAL.Context;
|
||||||
using StandManager.MailProcessor.Mail;
|
|
||||||
using StandManager.Service;
|
using StandManager.Service;
|
||||||
using StandManager.Service.Interfaces;
|
using StandManager.Service.Interfaces;
|
||||||
using StandManager.Service.Repository;
|
using StandManager.Service.Repository;
|
||||||
|
using StandManager.Service.Resolver;
|
||||||
|
|
||||||
var host = Host.CreateDefaultBuilder(args)
|
var host = Host.CreateDefaultBuilder(args)
|
||||||
.ConfigureServices((context, services) =>
|
.ConfigureServices((context, services) =>
|
||||||
@ -36,6 +36,9 @@ var host = Host.CreateDefaultBuilder(args)
|
|||||||
services.AddScoped<IManagerService, ManagerService>();
|
services.AddScoped<IManagerService, ManagerService>();
|
||||||
|
|
||||||
services.AddScoped<MailProcessor>();
|
services.AddScoped<MailProcessor>();
|
||||||
|
//MailProcessor
|
||||||
|
services.AddScoped<IMailProcessor, RegistrazioneMailProcessor>();
|
||||||
|
services.AddScoped<IMailProcessorResolver, MailProcessorResolver>();
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
|
|||||||
10
StandManager.Service/Interfaces/IMailProcessor.cs
Normal file
10
StandManager.Service/Interfaces/IMailProcessor.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
using StandManager.Domain.DTO;
|
||||||
|
using StandManager.Domain.Entita;
|
||||||
|
|
||||||
|
namespace StandManager.Service.Interfaces;
|
||||||
|
|
||||||
|
public interface IMailProcessor
|
||||||
|
{
|
||||||
|
MailFrom MailFrom { get; }
|
||||||
|
Task ProcessAsync(List<MailQueue> mailQueueList, EmailConfig config, HttpClient httpClient);
|
||||||
|
}
|
||||||
@ -1,4 +1,4 @@
|
|||||||
namespace StandManager.MailProcessor.Mail;
|
namespace StandManager.Service.Mail;
|
||||||
|
|
||||||
public class Email
|
public class Email
|
||||||
{
|
{
|
||||||
72
StandManager.Service/RegistrazioneMailProcessor.cs
Normal file
72
StandManager.Service/RegistrazioneMailProcessor.cs
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
using System.Text;
|
||||||
|
using System.Text.Json;
|
||||||
|
using StandManager.Domain.DTO;
|
||||||
|
using StandManager.Domain.Entita;
|
||||||
|
using StandManager.Service.Interfaces;
|
||||||
|
using StandManager.Service.Mail;
|
||||||
|
|
||||||
|
namespace StandManager.Service;
|
||||||
|
|
||||||
|
public class RegistrazioneMailProcessor : IMailProcessor
|
||||||
|
{
|
||||||
|
private readonly IManagerService _managerService;
|
||||||
|
|
||||||
|
public RegistrazioneMailProcessor(IManagerService managerService)
|
||||||
|
{
|
||||||
|
_managerService = managerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailFrom MailFrom => MailFrom.Registrazione;
|
||||||
|
|
||||||
|
public async Task ProcessAsync(List<MailQueue> mailQueueList, EmailConfig _config, HttpClient httpClient)
|
||||||
|
{
|
||||||
|
foreach (var mailQueue in mailQueueList)
|
||||||
|
{
|
||||||
|
var email = new Email()
|
||||||
|
{
|
||||||
|
From = _config.From,
|
||||||
|
Body = string.IsNullOrEmpty(mailQueue.Args) ? mailQueue.Body : string.Format(mailQueue.Body, mailQueue.Args?.Split(_config.MailSplitChar) ?? [""]),
|
||||||
|
Cc = null,
|
||||||
|
Subject = mailQueue.Subject,
|
||||||
|
To = new(){"g.vitari@oaservice.it"} // mailQueue.ToList.Split(";").ToList()
|
||||||
|
};
|
||||||
|
var messageJson = JsonSerializer.Serialize(email);
|
||||||
|
|
||||||
|
// multipart
|
||||||
|
using var form = new MultipartFormDataContent();
|
||||||
|
form.Add(
|
||||||
|
new StringContent(messageJson, Encoding.UTF8, "application/json"),
|
||||||
|
"messageJson"
|
||||||
|
);
|
||||||
|
|
||||||
|
//Attachments
|
||||||
|
/*var filePath = @"C:\temp\test.pdf";
|
||||||
|
var fileBytes = await File.ReadAllBytesAsync(filePath);
|
||||||
|
|
||||||
|
var fileContent = new ByteArrayContent(fileBytes);
|
||||||
|
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf");
|
||||||
|
|
||||||
|
form.Add(
|
||||||
|
fileContent,
|
||||||
|
"attachments",
|
||||||
|
Path.GetFileName(filePath)
|
||||||
|
);*/
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var response = await httpClient.PostAsync(
|
||||||
|
_config.ServerAddress,
|
||||||
|
form
|
||||||
|
);
|
||||||
|
response.EnsureSuccessStatusCode();
|
||||||
|
mailQueue.Sent = true;
|
||||||
|
await _managerService.MailQueueService.Salva(mailQueue);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
mailQueue.Sent = false;
|
||||||
|
mailQueue.Error = e.Message;
|
||||||
|
await _managerService.MailQueueService.Salva(mailQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
StandManager.Service/Resolver/IMailProcessorResolver.cs
Normal file
9
StandManager.Service/Resolver/IMailProcessorResolver.cs
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
using StandManager.Domain.Entita;
|
||||||
|
using StandManager.Service.Interfaces;
|
||||||
|
|
||||||
|
namespace StandManager.Service.Resolver;
|
||||||
|
|
||||||
|
public interface IMailProcessorResolver
|
||||||
|
{
|
||||||
|
IMailProcessor Resolve(MailFrom mailFrom);
|
||||||
|
}
|
||||||
22
StandManager.Service/Resolver/MailProcessorResolver.cs
Normal file
22
StandManager.Service/Resolver/MailProcessorResolver.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using StandManager.Domain.Entita;
|
||||||
|
using StandManager.Service.Interfaces;
|
||||||
|
|
||||||
|
namespace StandManager.Service.Resolver;
|
||||||
|
|
||||||
|
public class MailProcessorResolver : IMailProcessorResolver
|
||||||
|
{
|
||||||
|
private readonly Dictionary<MailFrom, IMailProcessor> _processors;
|
||||||
|
|
||||||
|
public MailProcessorResolver(IEnumerable<IMailProcessor> processors)
|
||||||
|
{
|
||||||
|
_processors = processors.ToDictionary(p => p.MailFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IMailProcessor Resolve(MailFrom mailFrom)
|
||||||
|
{
|
||||||
|
if (!_processors.TryGetValue(mailFrom, out var processor))
|
||||||
|
throw new NotSupportedException($"MailFrom {mailFrom} non supportato");
|
||||||
|
|
||||||
|
return processor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
<AuthorizeView>
|
<AuthorizeView>
|
||||||
<Authorized>
|
<Authorized>
|
||||||
<AppHeader />
|
<AppHeader ShowNavigation="false" />
|
||||||
</Authorized>
|
</Authorized>
|
||||||
|
|
||||||
<NotAuthorized>
|
<NotAuthorized>
|
||||||
|
|||||||
@ -88,6 +88,14 @@
|
|||||||
Mail = iscrizione.Mail
|
Mail = iscrizione.Mail
|
||||||
};
|
};
|
||||||
await _managerService.IscrizioneEventoPerMailService.Salva(model);
|
await _managerService.IscrizioneEventoPerMailService.Salva(model);
|
||||||
|
|
||||||
|
var queue = new MailQueue()
|
||||||
|
{
|
||||||
|
ToList = iscrizione.Mail,
|
||||||
|
From = MailFrom.Registrazione
|
||||||
|
};
|
||||||
|
await _managerService.MailQueueService.Salva(queue);
|
||||||
|
|
||||||
_navManager.NavigateTo("/Grazie");
|
_navManager.NavigateTo("/Grazie");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -9,7 +9,8 @@
|
|||||||
@rendermode InteractiveServer
|
@rendermode InteractiveServer
|
||||||
|
|
||||||
<PageTitle>Iscrizione Evento</PageTitle>
|
<PageTitle>Iscrizione Evento</PageTitle>
|
||||||
<AppHeader />
|
<AppHeader ShowNavigation="false"/>
|
||||||
|
|
||||||
<div class="container my-5 py-3">
|
<div class="container my-5 py-3">
|
||||||
<ClienteToggle ValueChanged="onClienteToggleChanged" />
|
<ClienteToggle ValueChanged="onClienteToggleChanged" />
|
||||||
@if (showCodiceCliente)
|
@if (showCodiceCliente)
|
||||||
|
|||||||
@ -10,6 +10,7 @@ using StandManager.Service.Interfaces;
|
|||||||
using StandManager.Service.Repository;
|
using StandManager.Service.Repository;
|
||||||
using StandManager.Utils;
|
using StandManager.Utils;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using StandManager.Service.Resolver;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@ -50,6 +51,10 @@ builder.Services.AddScoped<IManagerService, ManagerService>();
|
|||||||
builder.Services.AddScoped<BodyClassService>();
|
builder.Services.AddScoped<BodyClassService>();
|
||||||
builder.Services.AddScoped<LayoutState>();
|
builder.Services.AddScoped<LayoutState>();
|
||||||
|
|
||||||
|
//MailProcessor
|
||||||
|
builder.Services.AddScoped<IMailProcessor, RegistrazioneMailProcessor>();
|
||||||
|
builder.Services.AddScoped<IMailProcessorResolver, MailProcessorResolver>();
|
||||||
|
|
||||||
builder.Services.AddRadzenComponents();
|
builder.Services.AddRadzenComponents();
|
||||||
builder.Services.AddHttpContextAccessor();
|
builder.Services.AddHttpContextAccessor();
|
||||||
|
|
||||||
|
|||||||
52
script.sql
52
script.sql
@ -1,27 +1,51 @@
|
|||||||
BEGIN TRANSACTION;
|
BEGIN TRANSACTION;
|
||||||
ALTER TABLE [Destinazione] ADD [ComuneIstatId] uniqueidentifier NULL;
|
CREATE TABLE [MailQueue] (
|
||||||
|
[Id] uniqueidentifier NOT NULL,
|
||||||
|
[Subject] nvarchar(max) NOT NULL,
|
||||||
|
[Body] nvarchar(max) NOT NULL,
|
||||||
|
[ToList] nvarchar(max) NOT NULL,
|
||||||
|
[Args] nvarchar(max) NULL,
|
||||||
|
[From] int NOT NULL,
|
||||||
|
[Sent] bit NOT NULL,
|
||||||
|
[Error] nvarchar(max) NULL,
|
||||||
|
[DataCreazione] datetime2 NOT NULL,
|
||||||
|
[DataModifica] datetime2 NULL,
|
||||||
|
[Eliminato] bit NOT NULL,
|
||||||
|
[IdUtenteCreazione] uniqueidentifier NULL,
|
||||||
|
[IdUtenteModifica] uniqueidentifier NULL,
|
||||||
|
CONSTRAINT [PK_MailQueue] PRIMARY KEY ([Id]),
|
||||||
|
CONSTRAINT [FK_MailQueue_Utente_IdUtenteCreazione] FOREIGN KEY ([IdUtenteCreazione]) REFERENCES [Utente] ([Id]),
|
||||||
|
CONSTRAINT [FK_MailQueue_Utente_IdUtenteModifica] FOREIGN KEY ([IdUtenteModifica]) REFERENCES [Utente] ([Id])
|
||||||
|
);
|
||||||
|
|
||||||
ALTER TABLE [Destinazione] ADD [ProvinciaIstatId] uniqueidentifier NULL;
|
CREATE INDEX [IX_MailQueue_IdUtenteCreazione] ON [MailQueue] ([IdUtenteCreazione]);
|
||||||
|
|
||||||
CREATE INDEX [IX_Destinazione_ComuneIstatId] ON [Destinazione] ([ComuneIstatId]);
|
CREATE INDEX [IX_MailQueue_IdUtenteModifica] ON [MailQueue] ([IdUtenteModifica]);
|
||||||
|
|
||||||
CREATE INDEX [IX_Destinazione_ProvinciaIstatId] ON [Destinazione] ([ProvinciaIstatId]);
|
|
||||||
|
|
||||||
ALTER TABLE [Destinazione] ADD CONSTRAINT [FK_Destinazione_ComuneIstat_ComuneIstatId] FOREIGN KEY ([ComuneIstatId]) REFERENCES [ComuneIstat] ([Id]);
|
|
||||||
|
|
||||||
ALTER TABLE [Destinazione] ADD CONSTRAINT [FK_Destinazione_Province_ProvinciaIstatId] FOREIGN KEY ([ProvinciaIstatId]) REFERENCES [Province] ([Id]);
|
|
||||||
|
|
||||||
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
|
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
|
||||||
VALUES (N'20260107093044_CittaEProv', N'9.0.11');
|
VALUES (N'20260109133732_MailQueue', N'9.0.11');
|
||||||
|
|
||||||
ALTER TABLE [ComuneIstat] ADD [ProvinciaIstatId] uniqueidentifier NULL;
|
CREATE TABLE [IscrizioneEventoPerMail] (
|
||||||
|
[Id] uniqueidentifier NOT NULL,
|
||||||
|
[Mail] nvarchar(max) NOT NULL,
|
||||||
|
[Processata] bit NOT NULL,
|
||||||
|
[Inviata] bit NOT NULL,
|
||||||
|
[DataCreazione] datetime2 NOT NULL,
|
||||||
|
[DataModifica] datetime2 NULL,
|
||||||
|
[Eliminato] bit NOT NULL,
|
||||||
|
[IdUtenteCreazione] uniqueidentifier NULL,
|
||||||
|
[IdUtenteModifica] uniqueidentifier NULL,
|
||||||
|
CONSTRAINT [PK_IscrizioneEventoPerMail] PRIMARY KEY ([Id]),
|
||||||
|
CONSTRAINT [FK_IscrizioneEventoPerMail_Utente_IdUtenteCreazione] FOREIGN KEY ([IdUtenteCreazione]) REFERENCES [Utente] ([Id]),
|
||||||
|
CONSTRAINT [FK_IscrizioneEventoPerMail_Utente_IdUtenteModifica] FOREIGN KEY ([IdUtenteModifica]) REFERENCES [Utente] ([Id])
|
||||||
|
);
|
||||||
|
|
||||||
CREATE INDEX [IX_ComuneIstat_ProvinciaIstatId] ON [ComuneIstat] ([ProvinciaIstatId]);
|
CREATE INDEX [IX_IscrizioneEventoPerMail_IdUtenteCreazione] ON [IscrizioneEventoPerMail] ([IdUtenteCreazione]);
|
||||||
|
|
||||||
ALTER TABLE [ComuneIstat] ADD CONSTRAINT [FK_ComuneIstat_Province_ProvinciaIstatId] FOREIGN KEY ([ProvinciaIstatId]) REFERENCES [Province] ([Id]);
|
CREATE INDEX [IX_IscrizioneEventoPerMail_IdUtenteModifica] ON [IscrizioneEventoPerMail] ([IdUtenteModifica]);
|
||||||
|
|
||||||
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
|
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
|
||||||
VALUES (N'20260107093529_ProvSuComune', N'9.0.11');
|
VALUES (N'20260120130758_IscrizioneEventoPerMail', N'9.0.11');
|
||||||
|
|
||||||
COMMIT;
|
COMMIT;
|
||||||
GO
|
GO
|
||||||
|
|||||||
Reference in New Issue
Block a user