app-cloudep-notification-se.../pkg/repository/aws_ses_mailer.go

110 lines
2.9 KiB
Go

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
}