75 lines
2.6 KiB
C#
75 lines
2.6 KiB
C#
using System.Net.Http.Headers;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using Socialize.Api.Infrastructure.Emailer.Configuration;
|
|
using Socialize.Api.Infrastructure.Emailer.Contracts;
|
|
using Microsoft.Extensions.Options;
|
|
|
|
namespace Socialize.Api.Infrastructure.Emailer.Services;
|
|
|
|
public class ResendEmailSender : IEmailSender
|
|
{
|
|
private static readonly Uri EndpointUri = new("https://api.resend.com/emails");
|
|
private readonly HttpClient _httpClient;
|
|
private readonly EmailerOptions _options;
|
|
|
|
public ResendEmailSender(
|
|
IHttpClientFactory httpClientFactory,
|
|
IOptions<EmailerOptions> options)
|
|
{
|
|
_httpClient = httpClientFactory.CreateClient();
|
|
_options = options.Value;
|
|
|
|
string apiKey = NormalizeApiKey(_options.ApiKey);
|
|
string fromEmail = _options.FromEmail?.Trim() ?? string.Empty;
|
|
|
|
if (string.IsNullOrWhiteSpace(apiKey))
|
|
{
|
|
throw new InvalidOperationException("Emailer:ApiKey is required when using Resend email delivery.");
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(fromEmail))
|
|
{
|
|
throw new InvalidOperationException("Emailer:FromEmail is required when using Resend email delivery.");
|
|
}
|
|
|
|
_options.ApiKey = apiKey;
|
|
_options.FromEmail = fromEmail;
|
|
|
|
_httpClient.DefaultRequestHeaders.Authorization =
|
|
new AuthenticationHeaderValue("Bearer", apiKey);
|
|
|
|
_httpClient.DefaultRequestHeaders.Accept.Add(
|
|
new MediaTypeWithQualityHeaderValue("application/json"));
|
|
}
|
|
|
|
public async Task SendEmailAsync(string toEmail, string subject, string htmlMessage)
|
|
{
|
|
var payload = new { from = _options.FromEmail, to = toEmail, subject, html = htmlMessage };
|
|
|
|
string json = JsonSerializer.Serialize(payload);
|
|
StringContent content = new(json, Encoding.UTF8, "application/json");
|
|
|
|
HttpResponseMessage response = await _httpClient.PostAsync(EndpointUri, content);
|
|
|
|
if (!response.IsSuccessStatusCode)
|
|
{
|
|
string body = await response.Content.ReadAsStringAsync();
|
|
throw new InvalidOperationException(
|
|
$"Resend email failed: {response.StatusCode} - {body}");
|
|
}
|
|
}
|
|
|
|
private static string NormalizeApiKey(string? apiKey)
|
|
{
|
|
string normalized = apiKey?.Trim().Trim('"', '\'') ?? string.Empty;
|
|
const string bearerPrefix = "Bearer ";
|
|
if (normalized.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase))
|
|
{
|
|
normalized = normalized[bearerPrefix.Length..].Trim();
|
|
}
|
|
|
|
return normalized;
|
|
}
|
|
}
|