You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/libs/sms_providers/provider.go

115 lines
3.0 KiB
Go

package sms_providers
import (
"context"
"fmt"
"github.com/veypi/OneAuth/cfg"
)
// SMSProvider 短信服务商接口
type SMSProvider interface {
// SendSMS 发送短信
SendSMS(ctx context.Context, req *SendSMSRequest) (id string, err error)
// GetName 获取服务商名称
GetName() string
}
var factory *ProviderFactory
var providers = make(map[string]SMSProvider)
func GetSMSProvider(region string) (SMSProvider, error) {
if factory == nil {
factory = NewProviderFactory()
// 初始化各区域的短信服务商
for region, regionConfig := range cfg.Config.SMS.Regions {
provider, err := factory.Create(regionConfig)
if err != nil {
return nil, fmt.Errorf("failed to create provider for region %s: %w", region, err)
}
providers[region] = provider
}
provider, err := factory.Create(cfg.Config.SMS.Default)
if err != nil {
return nil, fmt.Errorf("failed to create default provider: %w", err)
}
providers["default"] = provider
}
p, ok := providers[region]
if !ok {
p, ok = providers["default"]
if !ok {
return nil, fmt.Errorf("no SMS provider found for region %s", region)
}
}
return p, nil
}
// SendSMSRequest 发送短信请求
type SendSMSRequest struct {
Phone string `json:"phone"` // 手机号
TemplateID string `json:"template_id"` // 模板ID
Params map[string]string `json:"params"` // 模板参数
Region string `json:"region"` // 区域
Purpose string `json:"purpose"` // 用途
}
// SendSMSResponse 发送短信响应
type SendSMSResponse struct {
MessageID string `json:"message_id"` // 消息ID
Status string `json:"status"` // 发送状态
Cost float64 `json:"cost"` // 费用
Error string `json:"error"` // 错误信息
}
// ProviderFactory 服务商工厂
type ProviderFactory struct {
providers map[string]func(cfg.RegionConfig) (SMSProvider, error)
}
// NewProviderFactory 创建服务商工厂
func NewProviderFactory() *ProviderFactory {
factory := &ProviderFactory{
providers: make(map[string]func(cfg.RegionConfig) (SMSProvider, error)),
}
// 注册服务商
factory.Register("aliyun", NewAliyunProvider)
factory.Register("tencent", NewTencentProvider)
return factory
}
// Register 注册服务商
func (f *ProviderFactory) Register(name string, constructor func(cfg.RegionConfig) (SMSProvider, error)) {
f.providers[name] = constructor
}
// Create 创建服务商实例
func (f *ProviderFactory) Create(config cfg.RegionConfig) (SMSProvider, error) {
constructor, exists := f.providers[config.Provider]
if !exists {
return nil, &ProviderError{
Provider: config.Provider,
Message: "unsupported provider",
}
}
return constructor(config)
}
// ProviderError 服务商错误
type ProviderError struct {
Provider string
Message string
Err error
}
func (e *ProviderError) Error() string {
if e.Err != nil {
return e.Provider + ": " + e.Message + ": " + e.Err.Error()
}
return e.Provider + ": " + e.Message
}