template-monorepo/internal/model/notification/usecase/factory.go

141 lines
4.0 KiB
Go
Raw Permalink Normal View History

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
}
2026-05-26 06:05:33 +00:00
func buildEmailChain(cfg notifconfig.Config, rc *redislib.Client) (*email.Chain, error) {
senders, err := collectEmailSenders(cfg)
if err != nil {
return nil, err
}
if len(senders) == 0 {
switch cfg.Email.Provider {
case "", notifconfig.ProviderMock:
2026-05-26 06:05:33 +00:00
opts := []email.MockSenderOption{email.WithMockName(notifconfig.ProviderMock)}
if r := rc.Zero(); r != nil {
opts = append(opts, email.WithMockRedis(r, 0))
}
return email.NewChain(email.NewMockSender(opts...)), 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
}
2026-05-26 06:05:33 +00:00
func buildSMSChain(cfg notifconfig.Config, rc *redislib.Client) (*sms.Chain, error) {
senders, err := collectSMSSenders(cfg)
if err != nil {
return nil, err
}
if len(senders) == 0 {
switch cfg.SMS.Provider {
case "", notifconfig.ProviderMock:
2026-05-26 06:05:33 +00:00
opts := []sms.MockSenderOption{sms.WithMockName(notifconfig.ProviderMock)}
if r := rc.Zero(); r != nil {
opts = append(opts, sms.WithMockRedis(r, 0))
}
return sms.NewChain(sms.NewMockSender(opts...)), 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}
}