133 lines
3.7 KiB
Go
133 lines
3.7 KiB
Go
package usecase
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"gateway/internal/library/mongo"
|
|
redislib "gateway/internal/library/redis"
|
|
notifconfig "gateway/internal/model/notification/config"
|
|
domtpl "gateway/internal/model/notification/domain/template"
|
|
domusecase "gateway/internal/model/notification/domain/usecase"
|
|
"gateway/internal/model/notification/provider/email"
|
|
"gateway/internal/model/notification/provider/sms"
|
|
)
|
|
|
|
// FactoryParam wires notification module dependencies for production or tests.
|
|
type FactoryParam struct {
|
|
MongoConf *mongo.Conf
|
|
Redis *redislib.Client // process-wide client from svc; nil → memory idempotency/quota, no async worker
|
|
Config notifconfig.Config
|
|
}
|
|
|
|
// NewNotifierUseCaseFromParam builds NotifierUseCase when Mongo is configured.
|
|
func NewNotifierUseCaseFromParam(param FactoryParam) (domusecase.NotifierUseCase, error) {
|
|
mod, err := NewModuleFromParam(param)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return mod.Notifier, nil
|
|
}
|
|
|
|
func buildEmailChain(cfg notifconfig.Config) (*email.Chain, error) {
|
|
senders, err := collectEmailSenders(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(senders) == 0 {
|
|
switch cfg.Email.Provider {
|
|
case "", notifconfig.ProviderMock:
|
|
return email.NewChain(email.NewMockSender(email.WithMockName(notifconfig.ProviderMock))), nil
|
|
default:
|
|
return nil, fmt.Errorf("notification: no email senders enabled and provider %q is not mock", cfg.Email.Provider)
|
|
}
|
|
}
|
|
|
|
opts := []email.ChainOption{}
|
|
if cfg.Email.SES.Enable {
|
|
opts = append(opts, email.WithTimeout(90*time.Second))
|
|
}
|
|
if len(opts) == 0 {
|
|
return email.NewChain(senders...), nil
|
|
}
|
|
return email.NewChainWithOptions(senders, opts...), nil
|
|
}
|
|
|
|
func collectEmailSenders(cfg notifconfig.Config) ([]email.Sender, error) {
|
|
var senders []email.Sender
|
|
|
|
if cfg.Email.SMTP.Enable {
|
|
s, err := email.NewSMTPSender(email.SMTPSettings{
|
|
Sort: cfg.Email.SMTP.Sort,
|
|
Host: cfg.Email.SMTP.Host,
|
|
Port: cfg.Email.SMTP.Port,
|
|
Username: cfg.Email.SMTP.Username,
|
|
Password: cfg.Email.SMTP.Password,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("notification: smtp: %w", err)
|
|
}
|
|
senders = append(senders, s)
|
|
}
|
|
|
|
if cfg.Email.SES.Enable {
|
|
s, err := email.NewSESSender(email.SESSettings{
|
|
Sort: cfg.Email.SES.Sort,
|
|
Region: cfg.Email.SES.Region,
|
|
AccessKey: cfg.Email.SES.AccessKey,
|
|
SecretKey: cfg.Email.SES.SecretKey,
|
|
SessionToken: cfg.Email.SES.SessionToken,
|
|
})
|
|
if err != nil {
|
|
return nil, fmt.Errorf("notification: ses: %w", err)
|
|
}
|
|
senders = append(senders, s)
|
|
}
|
|
|
|
return senders, nil
|
|
}
|
|
|
|
func buildSMSChain(cfg notifconfig.Config) (*sms.Chain, error) {
|
|
senders, err := collectSMSSenders(cfg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if len(senders) == 0 {
|
|
switch cfg.SMS.Provider {
|
|
case "", notifconfig.ProviderMock:
|
|
return sms.NewChain(sms.NewMockSender(sms.WithMockName(notifconfig.ProviderMock))), nil
|
|
default:
|
|
return nil, fmt.Errorf("notification: no sms senders enabled and provider %q is not mock", cfg.SMS.Provider)
|
|
}
|
|
}
|
|
return sms.NewChain(senders...), nil
|
|
}
|
|
|
|
func collectSMSSenders(cfg notifconfig.Config) ([]sms.Sender, error) {
|
|
var senders []sms.Sender
|
|
|
|
if cfg.SMS.Mitake.Enable {
|
|
s, err := sms.NewMitakeSender(sms.MitakeSettings{
|
|
Sort: cfg.SMS.Mitake.Sort,
|
|
User: cfg.SMS.Mitake.User,
|
|
Password: cfg.SMS.Mitake.Password,
|
|
}, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("notification: mitake: %w", err)
|
|
}
|
|
senders = append(senders, s)
|
|
}
|
|
|
|
return senders, nil
|
|
}
|
|
|
|
func fallbackLocales(defaultLocale string) []string {
|
|
if defaultLocale == "" {
|
|
return []string{domtpl.LocaleZhTW, domtpl.LocaleEnUS}
|
|
}
|
|
if defaultLocale == domtpl.LocaleZhTW {
|
|
return []string{domtpl.LocaleZhTW, domtpl.LocaleEnUS}
|
|
}
|
|
return []string{defaultLocale, domtpl.LocaleZhTW, domtpl.LocaleEnUS}
|
|
}
|