DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/Email/EmailNotificationTransportService.cs
Степанов Дмитрий Александрович 1b560dd0a2 Изменение уведомлений
1. Изменил сущность уведомлений. Добавил дату регистрации уведомления.
2. Добавил миграцию.
3. Изменил репозитории. Убрал метод для обновления коллекции уведомлений.
4. Поправил запрос для отправки уведомлений и метод контроллера.
5. Поправил логику обновления уведомления. Теперь обновление состояния уведомления происходит в транспорте, после успешной отправки уведомления.
2023-07-25 13:36:09 +05:00

125 lines
4.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Mail;
using System.Threading;
using System.Threading.Tasks;
using AsbCloudApp.Data;
using AsbCloudApp.Exceptions;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services.Notifications;
using AsbCloudInfrastructure.Background;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace AsbCloudInfrastructure.Services.Email
{
public class EmailNotificationTransportService : INotificationTransportService
{
private readonly BackgroundWorker backgroundWorker;
private readonly bool IsConfigured;
private readonly string sender;
private readonly string smtpServer;
private readonly string smtpPassword;
public EmailNotificationTransportService(BackgroundWorker backgroundWorker,
IConfiguration configuration)
{
sender = configuration.GetValue("email:sender", string.Empty);
smtpPassword = configuration.GetValue("email:password", string.Empty);
smtpServer = configuration.GetValue("email:smtpServer", string.Empty);
var configError = string.IsNullOrEmpty(sender) ||
string.IsNullOrEmpty(smtpPassword) ||
string.IsNullOrEmpty(smtpServer);
IsConfigured = !configError;
this.backgroundWorker = backgroundWorker;
}
public int IdTransportType => 1;
public Task SendAsync(NotificationDto notification, CancellationToken cancellationToken)
{
if (!IsConfigured)
{
Trace.TraceWarning("smtp is not configured");
return Task.CompletedTask;
}
var workId = MakeWorkId(notification.User.Email, notification.Title, notification.Message);
if (!backgroundWorker.Contains(workId))
{
var workAction = MakeEmailSendWorkAction(notification);
var work = new WorkBase(workId, workAction);
backgroundWorker.Push(work);
}
return Task.CompletedTask;
}
public Task SendRangeAsync(IEnumerable<NotificationDto> notifications, CancellationToken cancellationToken)
{
var tasks = notifications
.Select(notification => SendAsync(notification, cancellationToken));
return Task.WhenAll(tasks);
}
private Func<string, IServiceProvider, CancellationToken, Task> MakeEmailSendWorkAction(NotificationDto notification)
{
if(!MailAddress.TryCreate(notification.User.Email, out var mailAddress))
Trace.TraceWarning($"Mail {notification.User.Email} is not correct.");
if (mailAddress is null)
throw new ArgumentInvalidException($"Mail {notification.User.Email} is not null.", nameof(notification.User.Email));
if (string.IsNullOrWhiteSpace(notification.Title))
throw new ArgumentInvalidException($"{nameof(notification.Title)} should be set", nameof(notification.Title));
return async (_, serviceProvider, token) =>
{
var from = new MailAddress(sender);
var message = new MailMessage
{
From = from
};
message.To.Add(mailAddress.Address);
message.BodyEncoding = System.Text.Encoding.UTF8;
message.Body = notification.Message;
message.Subject = notification.Title;
message.IsBodyHtml = true;
using var client = new SmtpClient(smtpServer);
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential(sender, smtpPassword);
await client.SendMailAsync(message, token);
notification.SentDate = DateTime.UtcNow;
var notificationRepository = serviceProvider.GetService<INotificationRepository>();
await notificationRepository!.UpdateAsync(notification, token);
Trace.TraceInformation($"Send email to {notification.User.Email} subj:{notification.Title} html body count {notification.Message.Length}");
};
}
private static string MakeWorkId(string address, string subject, string content)
{
var hash = address.GetHashCode();
hash ^= subject.GetHashCode();
hash ^= content.GetHashCode();
return hash.ToString("x");
}
}
}