setup resend client for email service

This commit is contained in:
juancwu 2025-12-14 18:24:30 -05:00
commit 82ac33ec66
5 changed files with 56 additions and 9 deletions

View file

@ -11,10 +11,11 @@ import (
)
type App struct {
Cfg *config.Config
DB *sqlx.DB
UserService *service.UserService
AuthService *service.AuthService
Cfg *config.Config
DB *sqlx.DB
UserService *service.UserService
AuthService *service.AuthService
EmailService *service.EmailService
}
func New(cfg *config.Config) (*App, error) {
@ -28,16 +29,20 @@ func New(cfg *config.Config) (*App, error) {
return nil, fmt.Errorf("failed to run migrations: %w", err)
}
emailClient := service.NewResendClient(cfg.ResendKey)
userRepository := repository.NewUserRepository(database)
userService := service.NewUserService(userRepository)
authService := service.NewAuthService(userRepository)
emailService := service.NewEmailService(emailClient, cfg.EmailFrom, cfg.AppURL, cfg.AppName, cfg.AppEnv == "development")
return &App{
Cfg: cfg,
DB: database,
UserService: userService,
AuthService: authService,
Cfg: cfg,
DB: database,
UserService: userService,
AuthService: authService,
EmailService: emailService,
}, nil
}

View file

@ -20,6 +20,9 @@ type Config struct {
JWTSecret string
JWTExpiry time.Duration
EmailFrom string
ResendKey string
}
func Load() *Config {
@ -40,6 +43,9 @@ func Load() *Config {
JWTSecret: envRequired("JWT_SECRET"),
JWTExpiry: envDuration("JWT_EXPIRY", 168*time.Hour), // 7 days default
EmailFrom: envString("EMAIL_FROM", ""),
ResendKey: envString("RESEND_KEY", ""),
}
return cfg

View file

@ -1,6 +1,11 @@
package service
import "context"
import (
"context"
"log/slog"
"github.com/resend/resend-go/v2"
)
type EmailParams struct {
From string
@ -13,6 +18,34 @@ type EmailClient interface {
SendWithContext(ctx context.Context, params EmailParams) (string, error)
}
type ResendClient struct {
client *resend.Client
}
func NewResendClient(apiKey string) *ResendClient {
var client *resend.Client
if apiKey != "" {
client = resend.NewClient(apiKey)
} else {
slog.Warn("cannot initialize Resend client with empty api key")
return nil
}
return &ResendClient{client: client}
}
func (c *ResendClient) SendWithContext(ctx context.Context, params EmailParams) (string, error) {
res, err := c.client.Emails.SendWithContext(ctx, &resend.SendEmailRequest{
From: params.From,
To: params.To,
Subject: params.Subject,
Text: params.Text,
})
if err != nil {
return "", err
}
return res.Id, nil
}
type EmailService struct {
client EmailClient
fromEmail string