package service import ( "baron-sso-backend/internal/domain" "context" "fmt" "log/slog" "os" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/credentials" "github.com/aws/aws-sdk-go-v2/service/ses" "github.com/aws/aws-sdk-go-v2/service/ses/types" ) type SesServiceImpl struct { client *ses.Client sender string } func NewEmailService() domain.EmailService { region := os.Getenv("AWS_REGION") accessKey := os.Getenv("AWS_ACCESS_KEY_ID") secretKey := os.Getenv("AWS_SECRET_ACCESS_KEY") sender := os.Getenv("AWS_SES_SENDER") if region == "" || accessKey == "" || secretKey == "" { slog.Warn("[EmailService] AWS configuration missing, email service will not work") return nil } cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion(region), config.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")), ) if err != nil { slog.Error("Failed to load AWS config", "error", err) return nil } return &SesServiceImpl{ client: ses.NewFromConfig(cfg), sender: sender, } } func (s *SesServiceImpl) SendEmail(to, subject, body string) error { if s == nil || s.client == nil { return fmt.Errorf("email service not initialized") } input := &ses.SendEmailInput{ Destination: &types.Destination{ ToAddresses: []string{to}, }, Message: &types.Message{ Body: &types.Body{ Html: &types.Content{ Charset: aws.String("UTF-8"), Data: aws.String(body), }, }, Subject: &types.Content{ Charset: aws.String("UTF-8"), Data: aws.String(subject), }, }, Source: aws.String(s.sender), } _, err := s.client.SendEmail(context.TODO(), input) if err != nil { slog.Error("[EmailService] Failed to send email", "to", to, "error", err) } else { slog.Info("[EmailService] Email sent successfully", "to", to) } return err }