102 lines
2.6 KiB
Go
102 lines
2.6 KiB
Go
// Package gateway 定义消息网关的扩展接口与注册表。
|
|
//
|
|
// 与 drivers 的分工:driver 负责把一条规则执行出去(发邮件、发消息……),
|
|
// gateway 负责把外部系统投递进来的消息派发给绑定在网关上的规则。
|
|
// 新增一种网关只要实现 Gateway 并在 reg.go 里注册。
|
|
package gateway
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sort"
|
|
|
|
"github.com/ssdomei232/goodBaby/internal/meta"
|
|
"github.com/ssdomei232/goodBaby/model"
|
|
)
|
|
|
|
// Message 是外部系统投递进来的一条消息
|
|
type Message struct {
|
|
Title string
|
|
Content string
|
|
}
|
|
|
|
// Result 是一次投递的汇总结果
|
|
type Result struct {
|
|
Total int `json:"total"`
|
|
Failed []string `json:"failed"`
|
|
}
|
|
|
|
// Task 是一次投递所需的全部输入:网关与待触发的规则都由上层从数据库取出
|
|
type Task struct {
|
|
Gateway *model.MessageGateway
|
|
Rules []model.GatewayRule
|
|
Message Message
|
|
}
|
|
|
|
// Gateway 一种消息网关
|
|
type Gateway interface {
|
|
// GetType 获取网关类型标识
|
|
GetType() string
|
|
// Meta 返回给 WebUI 展示用的元数据
|
|
Meta() meta.GatewayMeta
|
|
// Deliver 把投递进来的消息派发给 task 里的规则
|
|
Deliver(ctx context.Context, task *Task) (*Result, error)
|
|
}
|
|
|
|
// Registry 网关注册表
|
|
type Registry struct {
|
|
gateways map[string]Gateway
|
|
}
|
|
|
|
// NewRegistry 创建新的网关注册表
|
|
func NewRegistry() *Registry {
|
|
return &Registry{
|
|
gateways: make(map[string]Gateway),
|
|
}
|
|
}
|
|
|
|
// Register 注册消息网关
|
|
func (r *Registry) Register(g Gateway) {
|
|
r.gateways[g.GetType()] = g
|
|
}
|
|
|
|
// Resolve 按类型取网关实现,类型为空时回退到默认类型
|
|
func (r *Registry) Resolve(gatewayType string) (Gateway, bool) {
|
|
if gatewayType == "" {
|
|
gatewayType = model.GatewayTypeWebhook
|
|
}
|
|
|
|
g, exists := r.gateways[gatewayType]
|
|
return g, exists
|
|
}
|
|
|
|
// Deliver 按网关类型派发一次投递
|
|
func (r *Registry) Deliver(ctx context.Context, gatewayType string, task *Task) (*Result, error) {
|
|
g, exists := r.Resolve(gatewayType)
|
|
if !exists {
|
|
return nil, fmt.Errorf("不支持的消息网关类型: %s", gatewayType)
|
|
}
|
|
|
|
return g.Deliver(ctx, task)
|
|
}
|
|
|
|
// GetSupportedTypes 获取所有支持的网关类型
|
|
func (r *Registry) GetSupportedTypes() []string {
|
|
types := make([]string, 0, len(r.gateways))
|
|
for t := range r.gateways {
|
|
types = append(types, t)
|
|
}
|
|
sort.Strings(types)
|
|
return types
|
|
}
|
|
|
|
// Metas 返回所有网关类型的元数据,按类型名排序
|
|
func (r *Registry) Metas() []meta.GatewayMeta {
|
|
metas := make([]meta.GatewayMeta, 0, len(r.gateways))
|
|
for _, g := range r.gateways {
|
|
metas = append(metas, g.Meta())
|
|
}
|
|
sort.Slice(metas, func(i, j int) bool { return metas[i].Type < metas[j].Type })
|
|
return metas
|
|
}
|