chore(init): 初始化解忧商行项目并完成 Phase 0 基座
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
package sms
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrProviderConfigInvalid = errors.New("sms provider config invalid")
|
||||
ErrProviderRateLimited = errors.New("sms provider rate limited")
|
||||
)
|
||||
|
||||
// TemplateRequest 描述一条模板短信。SignName 留空时使用 Provider 自身配置的默认签名。
|
||||
type TemplateRequest struct {
|
||||
Phone string
|
||||
SignName string
|
||||
TemplateCode string
|
||||
Params map[string]string
|
||||
}
|
||||
|
||||
type Provider interface {
|
||||
SendLoginCode(ctx context.Context, phone string, code string) error
|
||||
// SendTemplate 发送模板短信,用于登录验证码以外的业务节点触达。
|
||||
// 阿里云要求模板必须提前报备审核,因此调用方只传模板 CODE 与变量,不拼接文案。
|
||||
SendTemplate(ctx context.Context, req TemplateRequest) error
|
||||
}
|
||||
|
||||
type ProviderError struct {
|
||||
Code string
|
||||
Message string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *ProviderError) Error() string {
|
||||
if e.Message != "" {
|
||||
return fmt.Sprintf("sms provider rejected: %s: %s", e.Code, e.Message)
|
||||
}
|
||||
if e.Code != "" {
|
||||
return fmt.Sprintf("sms provider rejected: %s", e.Code)
|
||||
}
|
||||
return "sms provider rejected"
|
||||
}
|
||||
|
||||
func (e *ProviderError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
func IsProviderRateLimited(err error) bool {
|
||||
return errors.Is(err, ErrProviderRateLimited)
|
||||
}
|
||||
Reference in New Issue
Block a user