Skip to content

Commit 5c444a2

Browse files
Copilotardalis
andauthored
Replace SendGrid with SMTP2Go for email delivery (#1385)
* Initial plan * Replace SendGrid with SMTP2Go email service Co-authored-by: ardalis <782127+ardalis@users.noreply.github.com> * Add SMTP2Go email service tests and update configuration templates Co-authored-by: ardalis <782127+ardalis@users.noreply.github.com> * Update to use the api * optimize for api instead of smtp * Adding config class --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: ardalis <782127+ardalis@users.noreply.github.com> Co-authored-by: Steve Smith <steve@kentsmiths.com>
1 parent 6b35c29 commit 5c444a2

13 files changed

Lines changed: 119 additions & 57 deletions

ApiMailSenderOptions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace DevBetterWeb.Infrastructure.Services;
2+
3+
public class ApiMailSenderOptions
4+
{
5+
public string? ApiBaseUrl { get; set; }
6+
public string? ApiKey { get; set; }
7+
public string? Sender { get; set; }
8+
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Head over to [devBetter.com](https://devbetter.com) to see the live site. Scroll
1515
- Register
1616
- Login
1717
- View Public Questions/Topics
18-
- Validate Accounts via Email (SendGrid)
18+
- Validate Accounts via Email (SMTP2Go)
1919

2020
### Members Only
2121

src/DevBetterWeb.Infrastructure/DevBetterWeb.Infrastructure.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
<PackageReference Include="Markdig" />
2121
<PackageReference Include="MediatR" />
2222
<PackageReference Include="NimblePros.Vimeo" />
23-
<PackageReference Include="Sendgrid" />
2423
<PackageReference Include="Ardalis.EFCore.Extensions" />
2524
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" />
2625
<PackageReference Include="Microsoft.AspNetCore.Identity.UI" />

src/DevBetterWeb.Infrastructure/InfrastructureServiceCollectionExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public static IServiceCollection AddInfrastructureServices(this IServiceCollecti
2626
}
2727
else
2828
{
29-
services.AddTransient<IEmailService, SendGridEmailService>();
29+
services.AddTransient<IEmailService, Smtp2GoEmailService>();
3030
}
3131

3232
// Common Dependencies
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace DevBetterWeb.Infrastructure.Services;
2+
3+
public class ApiMailSenderOptions
4+
{
5+
public string? ApiBaseUrl { get; set; }
6+
public string? ApiKey { get; set; }
7+
public string? Sender { get; set; }
8+
}

src/DevBetterWeb.Infrastructure/Services/AuthMessageSenderOptions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
public class AuthMessageSenderOptions
44
{
5-
public string? SendGridUser { get; set; }
6-
public string? SendGridKey { get; set; }
5+
public string? SmtpServer { get; set; }
6+
public int SmtpPort { get; set; } = 587;
7+
public string? ApiKey { get; set; }
78
}

src/DevBetterWeb.Infrastructure/Services/SendGridEmailService.cs

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using System;
2+
using System.Net.Http;
3+
using System.Text;
4+
using System.Text.Json;
5+
using System.Threading.Tasks;
6+
using Ardalis.GuardClauses;
7+
using DevBetterWeb.Core.Interfaces;
8+
using Microsoft.Extensions.Options;
9+
10+
namespace DevBetterWeb.Infrastructure.Services;
11+
12+
public class Smtp2GoEmailService : IEmailService
13+
{
14+
private readonly HttpClient _httpClient;
15+
public Smtp2GoEmailService(IOptions<AuthMessageSenderOptions> optionsAccessor)
16+
{
17+
Guard.Against.Null(optionsAccessor, nameof(optionsAccessor));
18+
Guard.Against.Null(optionsAccessor.Value, nameof(optionsAccessor.Value));
19+
Options = optionsAccessor.Value;
20+
_httpClient = new HttpClient();
21+
}
22+
23+
public AuthMessageSenderOptions Options { get; }
24+
25+
public async Task SendEmailAsync(string email, string subject, string message)
26+
{
27+
if (string.IsNullOrEmpty(Options.ApiKey)) throw new Exception("SMTP API Key not set.");
28+
29+
var request = new HttpRequestMessage(HttpMethod.Post, "https://api.smtp2go.com/v3/email/send");
30+
request.Headers.Add("Authorization", $"Bearer {Options.ApiKey}");
31+
32+
var payload = new
33+
{
34+
sender = "donotreply@devbetter.com",
35+
to = new[] { email },
36+
subject = subject,
37+
text_body = message,
38+
html_body = message
39+
};
40+
string json = JsonSerializer.Serialize(payload);
41+
request.Content = new StringContent(json, Encoding.UTF8, "application/json");
42+
43+
var response = await _httpClient.SendAsync(request);
44+
if (!response.IsSuccessStatusCode)
45+
{
46+
var error = await response.Content.ReadAsStringAsync();
47+
throw new Exception($"SMTP2GO API error: {response.StatusCode} - {error}");
48+
}
49+
}
50+
}

src/DevBetterWeb.Web/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060

6161
builder.Services.AddLogging();
6262

63-
builder.Services.Configure<AuthMessageSenderOptions>(builder.Configuration.GetSection("AuthMessageSenderOptions"));
63+
builder.Services.Configure<ApiMailSenderOptions>(builder.Configuration.GetSection("ApiMailSenderOptions"));
6464
builder.Services.Configure<DiscordWebhookUrls>(builder.Configuration.GetSection("DiscordWebhookUrls"));
6565
builder.Services.Configure<StripeOptions>(builder.Configuration.GetSection("StripeOptions"));
6666
builder.Services.Configure<SubscriptionPlanOptions>(builder.Configuration.GetSection("SubscriptionPlanOptions"));

src/DevBetterWeb.Web/appsettings.Template.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@
1414
"ApiSettings": {
1515
"ApiKey": "[api key string goes here]"
1616
},
17+
"ApiMailSenderOptions": {
18+
"ApiBaseUrl": "https://api.smtp2go.com/v3/",
19+
"ApiKey": "[smtp2go api key goes here]",
20+
"Sender": "donotreply@devbetter.com"
21+
},
1722
"Logging": {
1823
"ApplicationInsights": {
1924
"LogLevel": {

0 commit comments

Comments
 (0)