backend/pkg/notification/repository/aws_ses_mailer.go

103 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repository
import (
"backend/pkg/notification/config"
"backend/pkg/notification/domain"
"backend/pkg/notification/domain/repository"
"context"
"fmt"
"backend/pkg/library/errs"
"backend/pkg/library/errs/code"
"github.com/aws/aws-sdk-go-v2/credentials"
"github.com/aws/aws-sdk-go-v2/service/ses/types"
"github.com/zeromicro/go-zero/core/logx"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/ses"
)
// AwsEmailDeliveryParam 傳送參數配置
type AwsEmailDeliveryParam struct {
Conf *config.AmazonSesSettings
}
type AwsEmailDeliveryRepository struct {
Client *ses.Client
Timeout int // 超時時間(秒),預設 30
}
func MustAwsSesMailRepository(param AwsEmailDeliveryParam) repository.MailRepository {
// 手動指定 AWS 配置,不使用默認配置
cfg := aws.Config{
Region: param.Conf.Region, // 自定義的 AWS 區域
Credentials: credentials.NewStaticCredentialsProvider(
param.Conf.AccessKey, // AWS Access Key
param.Conf.SecretKey, // AWS Secret Key
"",
),
}
// 創建 SES 客戶端
sesClient := ses.NewFromConfig(cfg)
// 設置默認超時時間
timeout := 30
if param.Conf.PoolSize > 0 {
timeout = param.Conf.PoolSize // 可以復用這個配置項,或新增專門的 Timeout 配置
}
return &AwsEmailDeliveryRepository{
Client: sesClient,
Timeout: timeout,
}
}
func (repo *AwsEmailDeliveryRepository) SendMail(ctx context.Context, req repository.MailReq) error {
// 檢查 context 是否已取消
if ctx.Err() != nil {
return ctx.Err()
}
// 設置郵件參數
to := make([]string, 0, len(req.To))
to = append(to, req.To...)
input := &ses.SendEmailInput{
Destination: &types.Destination{
ToAddresses: to,
},
Message: &types.Message{
Body: &types.Body{
Html: &types.Content{
Charset: aws.String("UTF-8"),
Data: aws.String(req.Body),
},
},
Subject: &types.Content{
Charset: aws.String("UTF-8"),
Data: aws.String(req.Subject),
},
},
Source: aws.String(req.From),
}
// 發送郵件(直接使用傳入的 context不創建新的 context
_, err := repo.Client.SendEmail(ctx, input)
if err != nil {
return errs.ThirdPartyErrorL(
code.CloudEPNotification,
domain.FailedToSendEmailErrorCode,
logx.WithContext(ctx),
[]logx.LogField{
{Key: "req", Value: req},
{Key: "func", Value: "AwsEmailDeliveryRepository.SendEmail"},
{Key: "err", Value: err.Error()},
},
fmt.Sprintf("failed to send mail by aws ses: %v", err)).Wrap(err)
}
logx.WithContext(ctx).Infof("Email sent successfully via AWS SES to %v", req.To)
return nil
}