Replace AWS SES with Resend for email delivery

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Andrew Gundersen 2026-03-01 22:08:26 -05:00
commit 4841986e0b
4 changed files with 33 additions and 43 deletions

View file

@ -4,63 +4,47 @@ import (
"context"
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ses"
sestypes "github.com/aws/aws-sdk-go-v2/service/ses/types"
resend "github.com/resend/resend-go/v2"
)
type Config struct {
ApiKey string
FromEmail string
BaseDomain string
}
type Client struct {
ses *ses.Client
cfg Config
resend *resend.Client
cfg Config
}
func NewClient(awsCfg aws.Config, cfg Config) *Client {
func NewClient(cfg Config) *Client {
return &Client{
ses: ses.NewFromConfig(awsCfg),
cfg: cfg,
resend: resend.NewClient(cfg.ApiKey),
cfg: cfg,
}
}
func (c *Client) SendWelcome(ctx context.Context, email, slug, password string) error {
func (c *Client) SendWelcome(_ context.Context, email, slug, password string) error {
url := fmt.Sprintf("https://%s.%s", slug, c.cfg.BaseDomain)
subject := "Your Crimata hub is ready"
text := fmt.Sprintf("Your hub is live at %s\n\nPassword: %s\n\nChange your password in Settings after logging in.\n\n— Crimata", url, password)
html := fmt.Sprintf(`<p>Your hub is live at <a href="%s">%s</a></p><p><strong>Password:</strong> <code>%s</code></p><p style="color:#555">Change your password in Settings after logging in.</p><p>— Crimata</p>`, url, url, password)
_, err := c.ses.SendEmail(ctx, &ses.SendEmailInput{
Source: aws.String(c.cfg.FromEmail),
Destination: &sestypes.Destination{ToAddresses: []string{email}},
Message: &sestypes.Message{
Subject: &sestypes.Content{Data: aws.String(subject)},
Body: &sestypes.Body{
Text: &sestypes.Content{Data: aws.String(text)},
Html: &sestypes.Content{Data: aws.String(html)},
},
},
_, err := c.resend.Emails.Send(&resend.SendEmailRequest{
From: c.cfg.FromEmail,
To: []string{email},
Subject: "Your Crimata hub is ready",
Text: fmt.Sprintf("Your hub is live at %s\n\nUsername: %s\nPassword: %s\n\nChange your password in Settings after logging in.\n\n— Crimata", url, slug, password),
Html: fmt.Sprintf(`<p>Your hub is live at <a href="%s">%s</a></p><p><strong>Username:</strong> <code>%s</code><br><strong>Password:</strong> <code>%s</code></p><p style="color:#555">Change your password in Settings after logging in.</p><p>— Crimata</p>`, url, url, slug, password),
})
return err
}
func (c *Client) SendDataExport(ctx context.Context, email, downloadURL string) error {
subject := "Your Crimata data export is ready"
text := fmt.Sprintf("Your data export is ready for download:\n\n%s\n\nThis link expires in 24 hours.\n\n— Crimata", downloadURL)
html := fmt.Sprintf(`<p>Your data export is ready: <a href="%s">Download</a></p><p style="color:#555">This link expires in 24 hours.</p><p>— Crimata</p>`, downloadURL)
_, err := c.ses.SendEmail(ctx, &ses.SendEmailInput{
Source: aws.String(c.cfg.FromEmail),
Destination: &sestypes.Destination{ToAddresses: []string{email}},
Message: &sestypes.Message{
Subject: &sestypes.Content{Data: aws.String(subject)},
Body: &sestypes.Body{
Text: &sestypes.Content{Data: aws.String(text)},
Html: &sestypes.Content{Data: aws.String(html)},
},
},
func (c *Client) SendDataExport(_ context.Context, email, downloadURL string) error {
_, err := c.resend.Emails.Send(&resend.SendEmailRequest{
From: c.cfg.FromEmail,
To: []string{email},
Subject: "Your Crimata data export is ready",
Text: fmt.Sprintf("Your data export is ready for download:\n\n%s\n\nThis link expires in 24 hours.\n\n— Crimata", downloadURL),
Html: fmt.Sprintf(`<p>Your data export is ready: <a href="%s">Download</a></p><p style="color:#555">This link expires in 24 hours.</p><p>— Crimata</p>`, downloadURL),
})
return err
}