refactor: notify module

This commit is contained in:
Fu Diwei 2025-09-04 09:52:59 +08:00
parent 476877991c
commit 34dd521efd
6 changed files with 97 additions and 113 deletions

25
internal/notify/client.go Normal file
View File

@ -0,0 +1,25 @@
package notify
import (
"log/slog"
)
type Client struct {
logger *slog.Logger
}
type ClientConfigure func(*Client)
func NewClient(configures ...ClientConfigure) *Client {
client := &Client{}
for _, configure := range configures {
configure(client)
}
return client
}
func WithLogger(logger *slog.Logger) ClientConfigure {
return func(c *Client) {
c.logger = logger
}
}

View File

@ -0,0 +1,49 @@
package notify
import (
"context"
"errors"
"fmt"
"github.com/certimate-go/certimate/internal/domain"
"github.com/certimate-go/certimate/internal/notify/notifiers"
)
type SendNotificationRequest struct {
// 提供商相关
Provider string
ProviderAccessConfig map[string]any
ProviderExtendedConfig map[string]any
// 通知相关
Subject string
Message string
}
type SendNotificationResponse struct{}
func (c *Client) SendNotification(ctx context.Context, request *SendNotificationRequest) (*SendNotificationResponse, error) {
if request == nil {
return nil, errors.New("the request is nil")
}
providerFactory, err := notifiers.Registries.Get(domain.NotificationProviderType(request.Provider))
if err != nil {
return nil, err
}
provider, err := providerFactory(&notifiers.ProviderFactoryOptions{
ProviderAccessConfig: request.ProviderAccessConfig,
ProviderExtendedConfig: request.ProviderExtendedConfig,
})
if err != nil {
return nil, fmt.Errorf("failed to initialize notification provider '%s': %w", request.Provider, err)
}
provider.SetLogger(c.logger)
if _, err := provider.Notify(ctx, request.Subject, request.Message); err != nil {
return nil, err
}
return &SendNotificationResponse{}, nil
}

View File

@ -1,75 +0,0 @@
package notify
import (
"context"
"fmt"
"log/slog"
"github.com/certimate-go/certimate/internal/domain"
"github.com/certimate-go/certimate/internal/repository"
"github.com/certimate-go/certimate/pkg/core"
)
type Notifier interface {
Notify(ctx context.Context) error
}
type NotifierWithWorkflowNodeConfig struct {
Node *domain.WorkflowNode
Logger *slog.Logger
Subject string
Message string
}
// TODO: refactor
func NewWithWorkflowNode(config NotifierWithWorkflowNodeConfig) (Notifier, error) {
if config.Node == nil {
return nil, fmt.Errorf("the node is nil")
}
if config.Node.Type != domain.WorkflowNodeTypeBizNotify {
return nil, fmt.Errorf("the node type is '%s', expected '%s'", string(config.Node.Type), string(domain.WorkflowNodeTypeBizNotify))
}
nodeCfg := config.Node.Data.Config.AsBizNotify()
options := &notifierProviderOptions{
Provider: domain.NotificationProviderType(nodeCfg.Provider),
ProviderAccessConfig: make(map[string]any),
ProviderExtendedConfig: nodeCfg.ProviderConfig,
}
accessRepo := repository.NewAccessRepository()
if nodeCfg.ProviderAccessId != "" {
access, err := accessRepo.GetById(context.Background(), nodeCfg.ProviderAccessId)
if err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeCfg.ProviderAccessId, err)
} else {
options.ProviderAccessConfig = access.Config
}
}
notifier, err := createNotifierProvider(options)
if err != nil {
return nil, err
} else {
notifier.SetLogger(config.Logger)
}
return &notifierImpl{
provider: notifier,
subject: config.Subject,
message: config.Message,
}, nil
}
type notifierImpl struct {
provider core.Notifier
subject string
message string
}
var _ Notifier = (*notifierImpl)(nil)
func (n *notifierImpl) Notify(ctx context.Context) error {
_, err := n.provider.Notify(ctx, n.subject, n.message)
return err
}

View File

@ -1,25 +0,0 @@
package notify
import (
"github.com/certimate-go/certimate/internal/domain"
"github.com/certimate-go/certimate/internal/notify/notifiers"
"github.com/certimate-go/certimate/pkg/core"
)
type notifierProviderOptions struct {
Provider domain.NotificationProviderType
ProviderAccessConfig map[string]any
ProviderExtendedConfig map[string]any
}
func createNotifierProvider(options *notifierProviderOptions) (core.Notifier, error) {
provider, err := notifiers.Registries.Get(options.Provider)
if err != nil {
return nil, err
}
return provider(&notifiers.ProviderFactoryOptions{
ProviderAccessConfig: options.ProviderAccessConfig,
ProviderExtendedConfig: options.ProviderExtendedConfig,
})
}

View File

@ -8,8 +8,8 @@ import (
)
const (
notifyTestTitle = "[Certimate] Notification Test"
notifyTestBody = "Welcome to use Certimate!"
notifyTestSubject = "[Certimate] Notification Testing"
notifyTestMessage = "Welcome to use Certimate!"
)
type NotifyService struct{}

View File

@ -11,6 +11,7 @@ import (
type bizNotifyNodeExecutor struct {
nodeExecutor
accessRepo accessRepository
settingsRepo settingsRepository
}
@ -26,20 +27,28 @@ func (ne *bizNotifyNodeExecutor) Execute(execCtx *NodeExecutionContext) (*NodeEx
return execRes, nil
}
// 初始化通知器
deployer, err := notify.NewWithWorkflowNode(notify.NotifierWithWorkflowNodeConfig{
Node: execCtx.Node,
Logger: ne.logger,
Subject: nodeCfg.Subject,
Message: nodeCfg.Message,
})
if err != nil {
ne.logger.Warn("failed to create notifier provider")
return execRes, err
// 读取部署提供商授权
providerAccessConfig := make(map[string]any)
if nodeCfg.ProviderAccessId != "" {
if access, err := ne.accessRepo.GetById(execCtx.ctx, nodeCfg.ProviderAccessId); err != nil {
return nil, fmt.Errorf("failed to get access #%s record: %w", nodeCfg.ProviderAccessId, err)
} else {
providerAccessConfig = access.Config
}
}
// 初始化通知器
notifyClient := notify.NewClient(notify.WithLogger(ne.logger))
// 推送通知
if err := deployer.Notify(execCtx.ctx); err != nil {
notifyReq := &notify.SendNotificationRequest{
Provider: nodeCfg.Provider,
ProviderAccessConfig: providerAccessConfig,
ProviderExtendedConfig: nodeCfg.ProviderConfig,
Subject: nodeCfg.Subject,
Message: nodeCfg.Message,
}
if _, err := notifyClient.SendNotification(execCtx.ctx, notifyReq); err != nil {
ne.logger.Warn("failed to send notification")
return execRes, err
}
@ -69,6 +78,7 @@ func (ne *bizNotifyNodeExecutor) checkCanSkip(execCtx *NodeExecutionContext) (_s
func newBizNotifyNodeExecutor() NodeExecutor {
return &bizNotifyNodeExecutor{
nodeExecutor: nodeExecutor{logger: slog.Default()},
accessRepo: repository.NewAccessRepository(),
settingsRepo: repository.NewSettingsRepository(),
}
}