feature/mail #3

Merged
daniel.w merged 3 commits from feature/mail into main 2024-08-20 15:56:23 +00:00
10 changed files with 189 additions and 14 deletions
Showing only changes of commit cef8a172e6 - Show all commits

140
.golangci.yaml Normal file
View File

@ -0,0 +1,140 @@
run:
timeout: 3m
# Exit code when at least one issue was found.
# Default: 1
issues-exit-code: 2
# Include test files or not.
# Default: true
tests: false
# Reference URL: https://golangci-lint.run/usage/linters/
linters:
# Disable everything by default so upgrades to not include new - default
# enabled- linters.
disable-all: true
# Specifically enable linters we want to use.
enable:
# - depguard
- errcheck
# - godot
- gofmt
- goimports
- gosimple
- govet
- ineffassign
- misspell
- revive
# - staticcheck
- typecheck
- unused
# - wsl
- asasalint
- asciicheck
- bidichk
- bodyclose
# - containedctx
- contextcheck
# - cyclop
# - varnamelen
# - gci
- wastedassign
- whitespace
# - wrapcheck
- thelper
- tparallel
- unconvert
- unparam
- usestdlibvars
- tenv
- testableexamples
- stylecheck
- sqlclosecheck
- nosprintfhostport
- paralleltest
- prealloc
- predeclared
- promlinter
- reassign
- rowserrcheck
- nakedret
- nestif
- nilerr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- decorder
- dogsled
# - dupl
- dupword
- durationcheck
- errchkjson
- errname
- errorlint
# - execinquery
- exhaustive
- exportloopref
- forbidigo
- forcetypeassert
# - gochecknoglobals
- gochecknoinits
- gocognit
- goconst
- gocritic
- gocyclo
# - godox
# - goerr113
# - gofumpt
- goheader
- gomoddirectives
# - gomodguard always failed
- goprintffuncname
- gosec
- grouper
- importas
- interfacebloat
# - ireturn
- lll
- loggercheck
- maintidx
- makezero
issues:
exclude-rules:
- path: _test\.go
linters:
- funlen
- goconst
- interfacer
- dupl
- lll
- goerr113
- errcheck
- gocritic
- cyclop
- wrapcheck
- gocognit
- contextcheck
linters-settings:
gci:
sections:
- standard # Standard section: captures all standard packages.
- default # Default section: contains all imports that could not be matched to another section type.
gocognit:
# Minimal code complexity to report.
# Default: 30 (but we recommend 10-20)
min-complexity: 40
nestif:
# Minimal complexity of if statements to report.
# Default: 5
min-complexity: 10
lll:
# Max line length, lines longer will be reported.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option.
# Default: 120.
line-length: 200
# Tab width in spaces.
# Default: 1
tab-width: 1

View File

@ -4,3 +4,13 @@ Etcd:
Hosts: Hosts:
- 127.0.0.1:2379 - 127.0.0.1:2379
Key: service.rpc Key: service.rpc
SMTP:
Host: smtp.mailgun.org
Port: 25
User: postmaster@code.30cm.net
Password: 9015592e10f385e4f16705e00a5e0d3d-2b91eb47-31205b4e
SMSSender:
User: daniel@30cm.net
Password : test123

3
go.mod
View File

@ -5,6 +5,7 @@ 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 code.30cm.net/digimon/library-go/validator v1.0.0
code.30cm.net/digimon/library-go/worker_pool v0.0.0-20240820153352-f9c90a90f5e2
github.com/minchao/go-mitake 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
@ -49,6 +50,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/openzipkin/zipkin-go v0.4.3 // indirect
github.com/panjf2000/ants/v2 v2.10.0 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_golang v1.19.1 // indirect
github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect
@ -77,6 +79,7 @@ require (
golang.org/x/crypto v0.25.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/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect golang.org/x/sys v0.22.0 // indirect
golang.org/x/term v0.22.0 // indirect golang.org/x/term v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect golang.org/x/text v0.16.0 // indirect

View File

@ -3,9 +3,10 @@ package senderservicelogic
import ( import (
"app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/gen_result/pb/notification"
"app-cloudep-notification-service/internal/svc" "app-cloudep-notification-service/internal/svc"
ers "code.30cm.net/digimon/library-go/errors"
"context" "context"
"fmt" "fmt"
ers "code.30cm.net/digimon/library-go/errors"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )

View File

@ -2,9 +2,10 @@ package senderservicelogic
import ( import (
"app-cloudep-notification-service/internal/domain/usecase" "app-cloudep-notification-service/internal/domain/usecase"
ers "code.30cm.net/digimon/library-go/errors"
"context" "context"
ers "code.30cm.net/digimon/library-go/errors"
"app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/gen_result/pb/notification"
"app-cloudep-notification-service/internal/svc" "app-cloudep-notification-service/internal/svc"
@ -47,6 +48,7 @@ func (l *SendMailLogic) SendMail(in *notification.SendMailReq) (*notification.OK
return nil, ers.InvalidFormat(err.Error()) return nil, ers.InvalidFormat(err.Error())
} }
// TODO 以後可以做換線
err := l.svcCtx.MailSender.SendMail(l.ctx, usecase.MailReq{ err := l.svcCtx.MailSender.SendMail(l.ctx, usecase.MailReq{
To: in.GetTo(), To: in.GetTo(),
Subject: in.GetSubject(), Subject: in.GetSubject(),

View File

@ -2,9 +2,10 @@ package senderservicelogic
import ( import (
"app-cloudep-notification-service/internal/domain/usecase" "app-cloudep-notification-service/internal/domain/usecase"
ers "code.30cm.net/digimon/library-go/errors"
"context" "context"
ers "code.30cm.net/digimon/library-go/errors"
"app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/gen_result/pb/notification"
"app-cloudep-notification-service/internal/svc" "app-cloudep-notification-service/internal/svc"
@ -44,6 +45,7 @@ func (l *SendSmsLogic) SendSms(in *notification.SendSMSReq) (*notification.OKRes
return nil, ers.InvalidFormat(err.Error()) return nil, ers.InvalidFormat(err.Error())
} }
// TODO 以後可以做換線
err := l.svcCtx.SMSSender.SendSMS(l.ctx, usecase.SMSReq{ err := l.svcCtx.SMSSender.SendSMS(l.ctx, usecase.SMSReq{
RecipientAddress: in.GetTo(), RecipientAddress: in.GetTo(),
RecipientName: in.GetRecipientName(), RecipientName: in.GetRecipientName(),

View File

@ -7,7 +7,7 @@ import (
"context" "context"
"app-cloudep-notification-service/gen_result/pb/notification" "app-cloudep-notification-service/gen_result/pb/notification"
"app-cloudep-notification-service/internal/logic/senderservice" senderservicelogic "app-cloudep-notification-service/internal/logic/senderservice"
"app-cloudep-notification-service/internal/svc" "app-cloudep-notification-service/internal/svc"
) )

View File

@ -4,6 +4,7 @@ import (
"app-cloudep-notification-service/internal/config" "app-cloudep-notification-service/internal/config"
domainUC "app-cloudep-notification-service/internal/domain/usecase" domainUC "app-cloudep-notification-service/internal/domain/usecase"
"app-cloudep-notification-service/internal/usecase" "app-cloudep-notification-service/internal/usecase"
v "code.30cm.net/digimon/library-go/validator" v "code.30cm.net/digimon/library-go/validator"
) )

View File

@ -4,6 +4,7 @@ import (
"app-cloudep-notification-service/internal/config" "app-cloudep-notification-service/internal/config"
"app-cloudep-notification-service/internal/domain/usecase" "app-cloudep-notification-service/internal/domain/usecase"
"context" "context"
"github.com/minchao/go-mitake" "github.com/minchao/go-mitake"
) )

View File

@ -3,7 +3,12 @@ package usecase
import ( import (
"app-cloudep-notification-service/internal/config" "app-cloudep-notification-service/internal/config"
"app-cloudep-notification-service/internal/domain/usecase" "app-cloudep-notification-service/internal/domain/usecase"
pool "code.30cm.net/digimon/library-go/worker_pool"
"github.com/zeromicro/go-zero/core/logx"
"context" "context"
"gopkg.in/gomail.v2" "gopkg.in/gomail.v2"
) )
@ -16,9 +21,12 @@ type MailUseCase struct {
Port int Port int
User string User string
Password string Password string
Pool pool.WorkerPool
} }
func (mu *MailUseCase) SendMail(_ context.Context, req usecase.MailReq) error { func (mu *MailUseCase) SendMail(_ context.Context, req usecase.MailReq) error {
// 用 goroutine pool 送,否則會超時
err := mu.Pool.Submit(func() {
m := gomail.NewMessage() m := gomail.NewMessage()
m.SetHeader("From", req.From) m.SetHeader("From", req.From)
m.SetHeader("To", req.To) m.SetHeader("To", req.To)
@ -26,9 +34,15 @@ func (mu *MailUseCase) SendMail(_ context.Context, req usecase.MailReq) error {
m.SetBody("text/html", req.Body) m.SetBody("text/html", req.Body)
d := gomail.NewDialer(mu.Host, mu.Port, mu.User, mu.Password) d := gomail.NewDialer(mu.Host, mu.Port, mu.User, mu.Password)
if err := d.DialAndSend(m); err != nil { if err := d.DialAndSend(m); err != nil {
return err logx.WithCallerSkip(1).WithFields(
logx.Field("func", "MailUseCase.SendMail"),
logx.Field("req", req),
logx.Field("err", err),
).Error("failed to send mail by mailgun")
} }
return nil })
return err
} }
func MustMailgunUseCase(param MailUseCaseParam) usecase.MailClientUseCase { func MustMailgunUseCase(param MailUseCaseParam) usecase.MailClientUseCase {
@ -37,5 +51,6 @@ func MustMailgunUseCase(param MailUseCaseParam) usecase.MailClientUseCase {
Port: param.Conf.SMTP.Port, Port: param.Conf.SMTP.Port,
User: param.Conf.SMTP.User, User: param.Conf.SMTP.User,
Password: param.Conf.SMTP.Password, Password: param.Conf.SMTP.Password,
Pool: pool.NewWorkerPool(2000),
} }
} }