feature/mail #3
			
				
			
		
		
		
	|  | @ -3,4 +3,4 @@ go.sum | ||||||
| account/ | account/ | ||||||
| gen_result/ | gen_result/ | ||||||
| etc/service.yaml | etc/service.yaml | ||||||
| ./client | client/ | ||||||
|  | @ -22,11 +22,11 @@ type ( | ||||||
| 	SenderService interface { | 	SenderService interface { | ||||||
| 		// SendMail 寄信
 | 		// SendMail 寄信
 | ||||||
| 		SendMail(ctx context.Context, in *SendMailReq, opts ...grpc.CallOption) (*OKResp, error) | 		SendMail(ctx context.Context, in *SendMailReq, opts ...grpc.CallOption) (*OKResp, error) | ||||||
| 		// SendSMS 寄簡訊
 | 		// SendSms 寄簡訊
 | ||||||
| 		SendSms(ctx context.Context, in *SendSMSReq, opts ...grpc.CallOption) (*OKResp, error) | 		SendSms(ctx context.Context, in *SendSMSReq, opts ...grpc.CallOption) (*OKResp, error) | ||||||
| 		// SendMailByTemplateID 寄送模板信件
 | 		// SendMailByTemplateId 寄送模板信件
 | ||||||
| 		SendMailByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) | 		SendMailByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) | ||||||
| 		// SendSMSByTemplateID 寄送模板簡訊
 | 		// SendSmsByTemplateId 寄送模板簡訊
 | ||||||
| 		SendSmsByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) | 		SendSmsByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -47,19 +47,19 @@ func (m *defaultSenderService) SendMail(ctx context.Context, in *SendMailReq, op | ||||||
| 	return client.SendMail(ctx, in, opts...) | 	return client.SendMail(ctx, in, opts...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendSMS 寄簡訊
 | // SendSms 寄簡訊
 | ||||||
| func (m *defaultSenderService) SendSms(ctx context.Context, in *SendSMSReq, opts ...grpc.CallOption) (*OKResp, error) { | func (m *defaultSenderService) SendSms(ctx context.Context, in *SendSMSReq, opts ...grpc.CallOption) (*OKResp, error) { | ||||||
| 	client := notification.NewSenderServiceClient(m.cli.Conn()) | 	client := notification.NewSenderServiceClient(m.cli.Conn()) | ||||||
| 	return client.SendSms(ctx, in, opts...) | 	return client.SendSms(ctx, in, opts...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendMailByTemplateID 寄送模板信件
 | // SendMailByTemplateId 寄送模板信件
 | ||||||
| func (m *defaultSenderService) SendMailByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) { | func (m *defaultSenderService) SendMailByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) { | ||||||
| 	client := notification.NewSenderServiceClient(m.cli.Conn()) | 	client := notification.NewSenderServiceClient(m.cli.Conn()) | ||||||
| 	return client.SendMailByTemplateId(ctx, in, opts...) | 	return client.SendMailByTemplateId(ctx, in, opts...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendSMSByTemplateID 寄送模板簡訊
 | // SendSmsByTemplateId 寄送模板簡訊
 | ||||||
| func (m *defaultSenderService) SendSmsByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) { | func (m *defaultSenderService) SendSmsByTemplateId(ctx context.Context, in *SendByTemplateIDReq, opts ...grpc.CallOption) (*OKResp, error) { | ||||||
| 	client := notification.NewSenderServiceClient(m.cli.Conn()) | 	client := notification.NewSenderServiceClient(m.cli.Conn()) | ||||||
| 	return client.SendSmsByTemplateId(ctx, in, opts...) | 	return client.SendSmsByTemplateId(ctx, in, opts...) | ||||||
|  |  | ||||||
|  | @ -13,11 +13,13 @@ message SendMailReq { | ||||||
|   string to = 1; |   string to = 1; | ||||||
|   string subject = 2; |   string subject = 2; | ||||||
|   string body = 3; |   string body = 3; | ||||||
|  |   string from =4; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| message SendSMSReq { | message SendSMSReq { | ||||||
|   string to = 1; |   string to = 1; | ||||||
|   string body = 2; |   string body = 2; | ||||||
|  |   string recipient_name=3; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| message SendByTemplateIDReq { | message SendByTemplateIDReq { | ||||||
|  | @ -31,11 +33,11 @@ message SendByTemplateIDReq { | ||||||
| service SenderService { | service SenderService { | ||||||
|   // SendMail 寄信 |   // SendMail 寄信 | ||||||
|   rpc SendMail(SendMailReq) returns(OKResp); |   rpc SendMail(SendMailReq) returns(OKResp); | ||||||
|   // SendSMS 寄簡訊 |   // SendSms 寄簡訊 | ||||||
|   rpc SendSms(SendSMSReq) returns(OKResp); |   rpc SendSms(SendSMSReq) returns(OKResp); | ||||||
|   // SendMailByTemplateID 寄送模板信件 |   // SendMailByTemplateId 寄送模板信件 | ||||||
|   rpc SendMailByTemplateId(SendByTemplateIDReq) returns(OKResp); |   rpc SendMailByTemplateId(SendByTemplateIDReq) returns(OKResp); | ||||||
|   // SendSMSByTemplateID 寄送模板簡訊 |   // SendSmsByTemplateId 寄送模板簡訊 | ||||||
|   rpc SendSmsByTemplateId(SendByTemplateIDReq) returns(OKResp); |   rpc SendSmsByTemplateId(SendByTemplateIDReq) returns(OKResp); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										10
									
								
								go.mod
								
								
								
								
							|  | @ -4,9 +4,12 @@ go 1.22.3 | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
| 	code.30cm.net/digimon/library-go/errors v1.0.0 | 	code.30cm.net/digimon/library-go/errors v1.0.0 | ||||||
|  | 	code.30cm.net/digimon/library-go/validator v1.0.0 | ||||||
|  | 	github.com/minchao/go-mitake v1.0.0 | ||||||
| 	github.com/zeromicro/go-zero v1.7.0 | 	github.com/zeromicro/go-zero v1.7.0 | ||||||
| 	google.golang.org/grpc v1.65.0 | 	google.golang.org/grpc v1.65.0 | ||||||
| 	google.golang.org/protobuf v1.34.2 | 	google.golang.org/protobuf v1.34.2 | ||||||
|  | 	gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| require ( | require ( | ||||||
|  | @ -19,11 +22,15 @@ require ( | ||||||
| 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect | 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect | ||||||
| 	github.com/emicklei/go-restful/v3 v3.11.0 // indirect | 	github.com/emicklei/go-restful/v3 v3.11.0 // indirect | ||||||
| 	github.com/fatih/color v1.17.0 // indirect | 	github.com/fatih/color v1.17.0 // indirect | ||||||
|  | 	github.com/gabriel-vasile/mimetype v1.4.3 // indirect | ||||||
| 	github.com/go-logr/logr v1.4.2 // indirect | 	github.com/go-logr/logr v1.4.2 // indirect | ||||||
| 	github.com/go-logr/stdr v1.2.2 // indirect | 	github.com/go-logr/stdr v1.2.2 // indirect | ||||||
| 	github.com/go-openapi/jsonpointer v0.19.6 // indirect | 	github.com/go-openapi/jsonpointer v0.19.6 // indirect | ||||||
| 	github.com/go-openapi/jsonreference v0.20.2 // indirect | 	github.com/go-openapi/jsonreference v0.20.2 // indirect | ||||||
| 	github.com/go-openapi/swag v0.22.4 // indirect | 	github.com/go-openapi/swag v0.22.4 // indirect | ||||||
|  | 	github.com/go-playground/locales v0.14.1 // indirect | ||||||
|  | 	github.com/go-playground/universal-translator v0.18.1 // indirect | ||||||
|  | 	github.com/go-playground/validator/v10 v10.22.0 // indirect | ||||||
| 	github.com/gogo/protobuf v1.3.2 // indirect | 	github.com/gogo/protobuf v1.3.2 // indirect | ||||||
| 	github.com/golang/mock v1.6.0 // indirect | 	github.com/golang/mock v1.6.0 // indirect | ||||||
| 	github.com/golang/protobuf v1.5.4 // indirect | 	github.com/golang/protobuf v1.5.4 // indirect | ||||||
|  | @ -34,6 +41,7 @@ require ( | ||||||
| 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect | 	github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect | ||||||
| 	github.com/josharian/intern v1.0.0 // indirect | 	github.com/josharian/intern v1.0.0 // indirect | ||||||
| 	github.com/json-iterator/go v1.1.12 // indirect | 	github.com/json-iterator/go v1.1.12 // indirect | ||||||
|  | 	github.com/leodido/go-urn v1.4.0 // indirect | ||||||
| 	github.com/mailru/easyjson v0.7.7 // indirect | 	github.com/mailru/easyjson v0.7.7 // indirect | ||||||
| 	github.com/mattn/go-colorable v0.1.13 // indirect | 	github.com/mattn/go-colorable v0.1.13 // indirect | ||||||
| 	github.com/mattn/go-isatty v0.0.20 // indirect | 	github.com/mattn/go-isatty v0.0.20 // indirect | ||||||
|  | @ -66,6 +74,7 @@ require ( | ||||||
| 	go.uber.org/automaxprocs v1.5.3 // indirect | 	go.uber.org/automaxprocs v1.5.3 // indirect | ||||||
| 	go.uber.org/multierr v1.9.0 // indirect | 	go.uber.org/multierr v1.9.0 // indirect | ||||||
| 	go.uber.org/zap v1.24.0 // indirect | 	go.uber.org/zap v1.24.0 // indirect | ||||||
|  | 	golang.org/x/crypto v0.25.0 // indirect | ||||||
| 	golang.org/x/net v0.27.0 // indirect | 	golang.org/x/net v0.27.0 // indirect | ||||||
| 	golang.org/x/oauth2 v0.20.0 // indirect | 	golang.org/x/oauth2 v0.20.0 // indirect | ||||||
| 	golang.org/x/sys v0.22.0 // indirect | 	golang.org/x/sys v0.22.0 // indirect | ||||||
|  | @ -74,6 +83,7 @@ require ( | ||||||
| 	golang.org/x/time v0.5.0 // indirect | 	golang.org/x/time v0.5.0 // indirect | ||||||
| 	google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect | 	google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect | ||||||
| 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect | 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect | ||||||
|  | 	gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect | ||||||
| 	gopkg.in/inf.v0 v0.9.1 // indirect | 	gopkg.in/inf.v0 v0.9.1 // indirect | ||||||
| 	gopkg.in/yaml.v2 v2.4.0 // indirect | 	gopkg.in/yaml.v2 v2.4.0 // indirect | ||||||
| 	gopkg.in/yaml.v3 v3.0.1 // indirect | 	gopkg.in/yaml.v3 v3.0.1 // indirect | ||||||
|  |  | ||||||
|  | @ -4,4 +4,16 @@ import "github.com/zeromicro/go-zero/zrpc" | ||||||
| 
 | 
 | ||||||
| type Config struct { | type Config struct { | ||||||
| 	zrpc.RpcServerConf | 	zrpc.RpcServerConf | ||||||
|  | 
 | ||||||
|  | 	SMTP struct { | ||||||
|  | 		Host     string | ||||||
|  | 		Port     int | ||||||
|  | 		User     string | ||||||
|  | 		Password string | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	SMSSender struct { | ||||||
|  | 		User     string | ||||||
|  | 		Password string | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | package usecase | ||||||
|  | 
 | ||||||
|  | import "context" | ||||||
|  | 
 | ||||||
|  | type MailClientUseCase interface { | ||||||
|  | 	SendMail(ctx context.Context, req MailReq) error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type MailReq struct { | ||||||
|  | 	To      string | ||||||
|  | 	From    string | ||||||
|  | 	Subject string | ||||||
|  | 	Body    string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type MailUseCase interface { | ||||||
|  | 	GetMailTemplateByID(ctx context.Context, tid int64) ([]rune, error) | ||||||
|  | } | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | package usecase | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type SMSClientUseCase interface { | ||||||
|  | 	SendSMS(ctx context.Context, req SMSReq) error | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type SMSReq struct { | ||||||
|  | 	// RecipientAddress 接收者號碼
 | ||||||
|  | 	RecipientAddress string | ||||||
|  | 	// RecipientName 接收者姓名
 | ||||||
|  | 	RecipientName string | ||||||
|  | 	// Body 要傳送的訊息
 | ||||||
|  | 	Body string | ||||||
|  | } | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| package senderservicelogic | package senderservicelogic | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"app-cloudep-notification-service/internal/domain/usecase" | ||||||
|  | 	ers "code.30cm.net/digimon/library-go/errors" | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"app-cloudep-notification-service/gen_result/pb/notification" | 	"app-cloudep-notification-service/gen_result/pb/notification" | ||||||
|  | @ -23,9 +25,42 @@ func NewSendMailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendMail | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type sendMailReq struct { | ||||||
|  | 	// TO 收件者
 | ||||||
|  | 	To string `validate:"required,email"` | ||||||
|  | 	// Subject 信件主旨
 | ||||||
|  | 	Subject string `validate:"required,max=128"` | ||||||
|  | 	// Body 內容
 | ||||||
|  | 	Body string `validate:"required"` | ||||||
|  | 	// From 寄件者
 | ||||||
|  | 	From string `validate:"required"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // SendMail 寄信
 | // SendMail 寄信
 | ||||||
| func (l *SendMailLogic) SendMail(in *notification.SendMailReq) (*notification.OKResp, error) { | func (l *SendMailLogic) SendMail(in *notification.SendMailReq) (*notification.OKResp, error) { | ||||||
| 	// todo: add your logic here and delete this line
 | 	if err := l.svcCtx.Validate.ValidateAll(&sendMailReq{ | ||||||
|  | 		To:      in.GetTo(), | ||||||
|  | 		Subject: in.GetSubject(), | ||||||
|  | 		Body:    in.GetBody(), | ||||||
|  | 		From:    in.GetFrom(), | ||||||
|  | 	}); err != nil { | ||||||
|  | 		return nil, ers.InvalidFormat(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err := l.svcCtx.MailSender.SendMail(l.ctx, usecase.MailReq{ | ||||||
|  | 		To:      in.GetTo(), | ||||||
|  | 		Subject: in.GetSubject(), | ||||||
|  | 		From:    in.GetFrom(), | ||||||
|  | 		Body:    in.GetBody(), | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		logx.WithCallerSkip(1).WithFields( | ||||||
|  | 			logx.Field("func", "MailSender.SendMail"), | ||||||
|  | 			logx.Field("in", in), | ||||||
|  | 			logx.Field("err", err), | ||||||
|  | 		).Error(err.Error()) | ||||||
|  | 		return nil, ers.ArkInternal("MailSender.SendMail failed to send mail") | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return ¬ification.OKResp{}, nil | 	return ¬ification.OKResp{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| package senderservicelogic | package senderservicelogic | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"app-cloudep-notification-service/internal/domain/usecase" | ||||||
|  | 	ers "code.30cm.net/digimon/library-go/errors" | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"app-cloudep-notification-service/gen_result/pb/notification" | 	"app-cloudep-notification-service/gen_result/pb/notification" | ||||||
|  | @ -23,9 +25,38 @@ func NewSendSmsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendSmsLo | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendSMS 寄簡訊
 | type sendSMSReq struct { | ||||||
|  | 	// RecipientAddress 收件者
 | ||||||
|  | 	RecipientAddress string `validate:"required,phone"` | ||||||
|  | 	// Body 內容
 | ||||||
|  | 	Body string `validate:"required"` | ||||||
|  | 	// RecipientName 收件者信名
 | ||||||
|  | 	RecipientName string `validate:"required"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // SendSms 寄簡訊
 | ||||||
| func (l *SendSmsLogic) SendSms(in *notification.SendSMSReq) (*notification.OKResp, error) { | func (l *SendSmsLogic) SendSms(in *notification.SendSMSReq) (*notification.OKResp, error) { | ||||||
| 	// todo: add your logic here and delete this line
 | 	if err := l.svcCtx.Validate.ValidateAll(&sendSMSReq{ | ||||||
|  | 		RecipientName:    in.GetTo(), | ||||||
|  | 		Body:             in.GetBody(), | ||||||
|  | 		RecipientAddress: in.GetTo(), | ||||||
|  | 	}); err != nil { | ||||||
|  | 		return nil, ers.InvalidFormat(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	err := l.svcCtx.SMSSender.SendSMS(l.ctx, usecase.SMSReq{ | ||||||
|  | 		RecipientAddress: in.GetTo(), | ||||||
|  | 		RecipientName:    in.GetRecipientName(), | ||||||
|  | 		Body:             in.GetBody(), | ||||||
|  | 	}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		logx.WithCallerSkip(1).WithFields( | ||||||
|  | 			logx.Field("func", "SMSSender.SendSMS"), | ||||||
|  | 			logx.Field("in", in), | ||||||
|  | 			logx.Field("err", err), | ||||||
|  | 		).Error(err.Error()) | ||||||
|  | 		return nil, ers.ArkInternal("SMSSender.SendSMS failed to send sms") | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	return ¬ification.OKResp{}, nil | 	return ¬ification.OKResp{}, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -7,7 +7,6 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 
 | 
 | ||||||
| 	"app-cloudep-notification-service/gen_result/pb/notification" | 	"app-cloudep-notification-service/gen_result/pb/notification" | ||||||
| 	senderservicelogic "app-cloudep-notification-service/internal/logic/senderservice" |  | ||||||
| 	"app-cloudep-notification-service/internal/logic/senderservice" | 	"app-cloudep-notification-service/internal/logic/senderservice" | ||||||
| 	"app-cloudep-notification-service/internal/svc" | 	"app-cloudep-notification-service/internal/svc" | ||||||
| ) | ) | ||||||
|  | @ -29,19 +28,19 @@ func (s *SenderServiceServer) SendMail(ctx context.Context, in *notification.Sen | ||||||
| 	return l.SendMail(in) | 	return l.SendMail(in) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendSMS 寄簡訊
 | // SendSms 寄簡訊
 | ||||||
| func (s *SenderServiceServer) SendSms(ctx context.Context, in *notification.SendSMSReq) (*notification.OKResp, error) { | func (s *SenderServiceServer) SendSms(ctx context.Context, in *notification.SendSMSReq) (*notification.OKResp, error) { | ||||||
| 	l := senderservicelogic.NewSendSmsLogic(ctx, s.svcCtx) | 	l := senderservicelogic.NewSendSmsLogic(ctx, s.svcCtx) | ||||||
| 	return l.SendSms(in) | 	return l.SendSms(in) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendMailByTemplateID 寄送模板信件
 | // SendMailByTemplateId 寄送模板信件
 | ||||||
| func (s *SenderServiceServer) SendMailByTemplateId(ctx context.Context, in *notification.SendByTemplateIDReq) (*notification.OKResp, error) { | func (s *SenderServiceServer) SendMailByTemplateId(ctx context.Context, in *notification.SendByTemplateIDReq) (*notification.OKResp, error) { | ||||||
| 	l := senderservicelogic.NewSendMailByTemplateIdLogic(ctx, s.svcCtx) | 	l := senderservicelogic.NewSendMailByTemplateIdLogic(ctx, s.svcCtx) | ||||||
| 	return l.SendMailByTemplateId(in) | 	return l.SendMailByTemplateId(in) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SendSMSByTemplateID 寄送模板簡訊
 | // SendSmsByTemplateId 寄送模板簡訊
 | ||||||
| func (s *SenderServiceServer) SendSmsByTemplateId(ctx context.Context, in *notification.SendByTemplateIDReq) (*notification.OKResp, error) { | func (s *SenderServiceServer) SendSmsByTemplateId(ctx context.Context, in *notification.SendByTemplateIDReq) (*notification.OKResp, error) { | ||||||
| 	l := senderservicelogic.NewSendSmsByTemplateIdLogic(ctx, s.svcCtx) | 	l := senderservicelogic.NewSendSmsByTemplateIdLogic(ctx, s.svcCtx) | ||||||
| 	return l.SendSmsByTemplateId(in) | 	return l.SendSmsByTemplateId(in) | ||||||
|  |  | ||||||
|  | @ -1,13 +1,25 @@ | ||||||
| package svc | package svc | ||||||
| 
 | 
 | ||||||
| import "app-cloudep-notification-service/internal/config" | import ( | ||||||
|  | 	"app-cloudep-notification-service/internal/config" | ||||||
|  | 	domainUC "app-cloudep-notification-service/internal/domain/usecase" | ||||||
|  | 	"app-cloudep-notification-service/internal/usecase" | ||||||
|  | 	v "code.30cm.net/digimon/library-go/validator" | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| type ServiceContext struct { | type ServiceContext struct { | ||||||
| 	Config config.Config | 	Config config.Config | ||||||
|  | 
 | ||||||
|  | 	Validate   v.Validate | ||||||
|  | 	MailSender domainUC.MailClientUseCase | ||||||
|  | 	SMSSender  domainUC.SMSClientUseCase | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func NewServiceContext(c config.Config) *ServiceContext { | func NewServiceContext(c config.Config) *ServiceContext { | ||||||
| 	return &ServiceContext{ | 	return &ServiceContext{ | ||||||
| 		Config: c, | 		Config:     c, | ||||||
|  | 		MailSender: usecase.MustMailgunUseCase(usecase.MailUseCaseParam{Conf: c}), | ||||||
|  | 		SMSSender:  usecase.MustMitakeUseCase(usecase.SMSUseCaseParam{Conf: c}), | ||||||
|  | 		Validate:   v.MustValidator(), | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -0,0 +1,35 @@ | ||||||
|  | package usecase | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"app-cloudep-notification-service/internal/config" | ||||||
|  | 	"app-cloudep-notification-service/internal/domain/usecase" | ||||||
|  | 	"context" | ||||||
|  | 	"github.com/minchao/go-mitake" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type SMSUseCaseParam struct { | ||||||
|  | 	Conf config.Config | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type SMSUseCase struct { | ||||||
|  | 	Client *mitake.Client | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (s *SMSUseCase) SendSMS(_ context.Context, req usecase.SMSReq) error { | ||||||
|  | 	message := mitake.Message{ | ||||||
|  | 		Dstaddr:  req.RecipientAddress, | ||||||
|  | 		Destname: req.RecipientName, | ||||||
|  | 		Smbody:   req.Body, | ||||||
|  | 	} | ||||||
|  | 	_, err := s.Client.Send(message) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func MustMitakeUseCase(param SMSUseCaseParam) usecase.SMSClientUseCase { | ||||||
|  | 	return &SMSUseCase{ | ||||||
|  | 		Client: mitake.NewClient(param.Conf.SMSSender.User, param.Conf.SMSSender.Password, nil), | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,41 @@ | ||||||
|  | package usecase | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"app-cloudep-notification-service/internal/config" | ||||||
|  | 	"app-cloudep-notification-service/internal/domain/usecase" | ||||||
|  | 	"context" | ||||||
|  | 	"gopkg.in/gomail.v2" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type MailUseCaseParam struct { | ||||||
|  | 	Conf config.Config | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type MailUseCase struct { | ||||||
|  | 	Host     string | ||||||
|  | 	Port     int | ||||||
|  | 	User     string | ||||||
|  | 	Password string | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (mu *MailUseCase) SendMail(_ context.Context, req usecase.MailReq) error { | ||||||
|  | 	m := gomail.NewMessage() | ||||||
|  | 	m.SetHeader("From", req.From) | ||||||
|  | 	m.SetHeader("To", req.To) | ||||||
|  | 	m.SetHeader("Subject", req.Subject) | ||||||
|  | 	m.SetBody("text/html", req.Body) | ||||||
|  | 	d := gomail.NewDialer(mu.Host, mu.Port, mu.User, mu.Password) | ||||||
|  | 	if err := d.DialAndSend(m); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func MustMailgunUseCase(param MailUseCaseParam) usecase.MailClientUseCase { | ||||||
|  | 	return &MailUseCase{ | ||||||
|  | 		Host:     param.Conf.SMTP.Host, | ||||||
|  | 		Port:     param.Conf.SMTP.Port, | ||||||
|  | 		User:     param.Conf.SMTP.User, | ||||||
|  | 		Password: param.Conf.SMTP.Password, | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue