package repository import ( "code.30cm.net/digimon/app-cloudep-notification-service/pkg/config" "code.30cm.net/digimon/app-cloudep-notification-service/pkg/domain" "code.30cm.net/digimon/app-cloudep-notification-service/pkg/domain/repository" "context" "time" "code.30cm.net/digimon/library-go/errs/code" pool "code.30cm.net/digimon/library-go/worker_pool" "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 Pool pool.WorkerPool } 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) return &AwsEmailDeliveryRepository{ Client: sesClient, Pool: pool.NewWorkerPool(param.Conf.PoolSize), } } func (use *AwsEmailDeliveryRepository) SendMail(ctx context.Context, req repository.MailReq) error { err := use.Pool.Submit(func() { // 設置郵件參數 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), } // 發送郵件 // TODO 不明原因送不出去,會被 context cancel 這裡先把它手動加到100sec newCtx, cancel := context.WithTimeout(context.Background(), 100*time.Second) defer cancel() //nolint:contextcheck if _, err := use.Client.SendEmail(newCtx, input); err != nil { _ = domain.ThirdPartyErrorL( code.CloudEPNotification, domain.FailedToSendEmailErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "AwsEmailDeliveryU.SendEmail"}, {Key: "err", Value: err.Error()}, }, "failed to send mail by aws ses") } }) if err != nil { e := domain.ThirdPartyErrorL( code.CloudEPNotification, domain.FailedToSendEmailErrorCode, logx.WithContext(ctx), []logx.LogField{ {Key: "req", Value: req}, {Key: "func", Value: "AwsEmailDeliveryU.SendEmail"}, {Key: "err", Value: err.Error()}, }, "failed to send mail by aws ses") return e } return nil }