| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- using Application.Abstractions.Cache;
- using Application.Abstractions.Messaging.Email;
- using Application.Features.Config.Get;
- using Infrastructure.Persistence;
- using SharedKernel;
- using MailKit.Net.Smtp;
- using MailKit.Security;
- using MimeKit;
- using Microsoft.EntityFrameworkCore;
- using Microsoft.Extensions.Logging;
- using Microsoft.Extensions.Options;
- namespace Infrastructure.Messaging.Email
- {
- public class MailService : IMailService
- {
- private readonly ILogger<MailService> _logger;
- private readonly ICacheService _cache;
- private readonly AppSettings.SmtpSection _smtp;
- private readonly AppDbContext _db;
- // SMTP 정보
- public string Host { get; set; } = default!;
- public int Port { get; set; } = 587;
- public string? User { get; set; }
- public string? Password { get; set; }
- public bool UseStartTls { get; set; } = true;
- public string FromEmail { get; set; } = default!;
- public string FromName { get; set; } = "no-reply";
- public MailService(ILogger<MailService> logger, ICacheService cache, IOptions<AppSettings> options, AppDbContext db)
- {
- _logger = logger;
- _cache = cache;
- _smtp = options.Value.SMTP;
- _db = db;
- }
- public async Task SendAsync(SendData data, CancellationToken ct = default)
- {
- _logger.LogInformation("Sending email to {ToAddress} with subject {Subject}", data.ToAddress, data.Subject);
- // 1. Redis 캐시에서 Config 조회
- var config = await _cache.GetAsync<Response>(CacheKeys.Config, ct);
- if (config is null)
- {
- var entity = await _db.Config.AsNoTracking().OrderByDescending(x => x.ID).FirstOrDefaultAsync();
- if (entity is null)
- {
- Host = _smtp.Host;
- Port = _smtp.Port;
- User = _smtp.User;
- Password = _smtp.Password;
- UseStartTls = _smtp.UseStartTls;
- FromEmail = _smtp.FromEmail;
- FromName = _smtp.FromName;
- }
- else
- {
- Host = entity.Basic.SmtpServer ?? "";
- Port = entity.Basic.SmtpPort ?? 587;
- UseStartTls = entity.Basic.SmtpEnableSSL;
- User = entity.Basic.SmtpUsername;
- Password = entity.Basic.SmtpPassword;
- FromEmail = entity.Basic.FromEmail ?? "";
- FromName = entity.Basic.FromName ?? "";
- }
- }
- else
- {
- Host = config.Basic.SmtpServer!;
- Port = config.Basic.SmtpPort! ?? 587;
- UseStartTls = config.Basic.SmtpEnableSSL;
- User = config.Basic.SmtpUsername;
- Password = config.Basic.SmtpPassword;
- FromEmail = config.Basic.FromEmail!;
- FromName = config.Basic.FromName!;
- }
-
- var message = new MimeMessage();
- message.From.Add(new MailboxAddress(FromName, FromEmail));
- message.To.Add(MailboxAddress.Parse(data.ToAddress));
- message.Subject = data.Subject;
- var body = new BodyBuilder
- {
- HtmlBody = data.MessageHtml,
- TextBody = data.MessageText
- };
- message.Body = body.ToMessageBody();
- using var client = new SmtpClient();
- var secure = UseStartTls ? SecureSocketOptions.StartTls : SecureSocketOptions.Auto;
- await client.ConnectAsync(Host, Port, secure, ct);
- if (!string.IsNullOrWhiteSpace(User))
- {
- await client.AuthenticateAsync(User, Password, ct);
- }
- await client.SendAsync(message, ct);
- await client.DisconnectAsync(true, ct);
- _logger.LogInformation("Email sent to {ToAddress} with subject {Subject}", data.ToAddress, data.Subject);
- }
- }
- }
|