133 lines
5.6 KiB
C#
133 lines
5.6 KiB
C#
using Microsoft.AspNetCore.Hosting;
|
|
using Microsoft.Extensions.Logging;
|
|
using Microsoft.Extensions.Configuration; // Für Absender-Config
|
|
using Resend;
|
|
using System;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using Webshop.Application.Services.Public.Interfaces;
|
|
|
|
namespace Webshop.Application.Services.Public
|
|
{
|
|
public class EmailService : IEmailService
|
|
{
|
|
private readonly IResend _resend;
|
|
private readonly IWebHostEnvironment _env;
|
|
private readonly ILogger<EmailService> _logger;
|
|
private readonly IConfiguration _configuration;
|
|
|
|
public EmailService(
|
|
IResend resend,
|
|
IWebHostEnvironment env,
|
|
ILogger<EmailService> logger,
|
|
IConfiguration configuration)
|
|
{
|
|
_resend = resend;
|
|
_env = env;
|
|
_logger = logger;
|
|
_configuration = configuration;
|
|
}
|
|
|
|
public async Task SendEmailConfirmationAsync(string toEmail, string confirmationLink)
|
|
{
|
|
var subject = "Willkommen! Bitte bestätigen Sie Ihre E-Mail-Adresse";
|
|
var title = "E-Mail bestätigen";
|
|
var body = "Vielen Dank für Ihre Registrierung! Bitte klicken Sie auf den Button unten, um Ihr Konto zu aktivieren.";
|
|
var btnText = "Konto aktivieren";
|
|
|
|
await SendEmailInternalAsync(toEmail, subject, title, body, btnText, confirmationLink);
|
|
}
|
|
|
|
public async Task SendPasswordResetAsync(string toEmail, string resetLink)
|
|
{
|
|
var subject = "Passwort zurücksetzen";
|
|
var title = "Passwort vergessen?";
|
|
var body = "Wir haben eine Anfrage zum Zurücksetzen Ihres Passworts erhalten. Klicken Sie hier:";
|
|
var btnText = "Passwort zurücksetzen";
|
|
|
|
await SendEmailInternalAsync(toEmail, subject, title, body, btnText, resetLink);
|
|
}
|
|
|
|
public async Task SendOrderConfirmationAsync(Guid orderId, string toEmail)
|
|
{
|
|
// Link zur Bestellübersicht (anpassen an dein Frontend Routing)
|
|
var orderLink = $"{_configuration["App:FrontendUrl"]}/orders/{orderId}";
|
|
|
|
var subject = $"Bestellbestätigung #{orderId.ToString().Substring(0, 8).ToUpper()}";
|
|
var title = "Vielen Dank für Ihre Bestellung!";
|
|
var body = $"Wir haben Ihre Bestellung #{orderId} erhalten und bearbeiten sie umgehend.";
|
|
var btnText = "Bestellung ansehen";
|
|
|
|
await SendEmailInternalAsync(toEmail, subject, title, body, btnText, orderLink);
|
|
}
|
|
|
|
public async Task SendEmailChangeConfirmationAsync(string toEmail, string confirmationLink)
|
|
{
|
|
var subject = "Änderung Ihrer E-Mail-Adresse bestätigen";
|
|
var title = "Neue E-Mail bestätigen";
|
|
var body = "Sie haben eine Änderung Ihrer E-Mail-Adresse angefordert. Bitte bestätigen Sie dies:";
|
|
var btnText = "E-Mail bestätigen";
|
|
|
|
await SendEmailInternalAsync(toEmail, subject, title, body, btnText, confirmationLink);
|
|
}
|
|
|
|
// --- Interne Methode für Resend ---
|
|
private async Task SendEmailInternalAsync(string toEmail, string subject, string title, string body, string btnText, string btnLink)
|
|
{
|
|
try
|
|
{
|
|
// 1. Template laden
|
|
string htmlContent = await LoadAndFormatTemplate(title, body, btnText, btnLink);
|
|
|
|
// 2. Resend Message bauen
|
|
var message = new EmailMessage();
|
|
message.To.Add(toEmail);
|
|
// Hole Absender aus Config oder Fallback
|
|
message.From = _configuration["Resend:FromEmail"] ?? "noreply@deinwebshop.com";
|
|
message.Subject = subject;
|
|
message.HtmlBody = htmlContent;
|
|
|
|
// 3. Senden
|
|
await _resend.EmailSendAsync(message);
|
|
|
|
_logger.LogInformation($"E-Mail '{subject}' erfolgreich an {toEmail} gesendet via Resend.");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, $"Fehler beim Senden der E-Mail an {toEmail} via Resend.");
|
|
// Optional: Exception werfen, wenn der Prozess abbrechen soll.
|
|
// Meistens besser: Loggen und "Silent Fail", damit z.B. der Checkout nicht abbricht.
|
|
}
|
|
}
|
|
|
|
private async Task<string> LoadAndFormatTemplate(string title, string body, string btnText, string btnLink)
|
|
{
|
|
// Pfad: wwwroot/templates/email-template.html
|
|
var templatePath = Path.Combine(_env.WebRootPath ?? _env.ContentRootPath, "templates", "email-template.html");
|
|
|
|
string template;
|
|
|
|
if (File.Exists(templatePath))
|
|
{
|
|
template = await File.ReadAllTextAsync(templatePath);
|
|
}
|
|
else
|
|
{
|
|
// Fallback HTML, falls Datei fehlt
|
|
_logger.LogWarning($"Template nicht gefunden unter {templatePath}");
|
|
template = "<html><body><h1>{{ShopName}}</h1><h2>{{Titel}}</h2><p>{{Haupttext}}</p><p><a href='{{CallToActionLink}}'>{{CallToActionText}}</a></p></body></html>";
|
|
}
|
|
|
|
// Platzhalter ersetzen
|
|
var shopName = _configuration["ShopInfo:Name"] ?? "Webshop";
|
|
|
|
return template
|
|
.Replace("{{ShopName}}", shopName)
|
|
.Replace("{{Titel}}", title)
|
|
.Replace("{{Haupttext}}", body)
|
|
.Replace("{{CallToActionText}}", btnText)
|
|
.Replace("{{CallToActionLink}}", btnLink)
|
|
.Replace("{{Jahr}}", DateTime.UtcNow.Year.ToString());
|
|
}
|
|
}
|
|
} |