之前用golang封装的一个发送阿里云短信的工具包,代码如下
client.go
go
package sms
import (
"context"
"github.com/go-playground/validator/v10"
"github.com/pkg/errors"
)
type Client interface {
// Send 发送短信
Send(ctx context.Context, opt *SendOpt) error
}
type SendOpt struct {
// 必填:待发送手机号
// 批量上限为1000个手机号码,批量调用相对于单条调用及时性稍有延迟,验证码类型的短信推荐使用单条调用的方式
PhoneNumbers []string `validate:"required,max=1000"`
SignName string
// 必填:短信模板-可在短信控制台中找到
TemplateCode string `validate:"required"`
// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为
// 友情提示:如果JSON中需要带换行符,请参照标准的JSON协议对换行符的要求,比如短信内容中包含\r\n的情况在JSON中需要表示成\\r\\n,
// 否则会导致JSON在服务端解析失败
TemplateParam string `validate:"required"`
// 可选-上行短信扩展码(扩展码字段控制在7位或以下,无特殊需求用户请忽略此字段)
SmsUpExtendCode string
// 可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
OutId string
}
func (p *SendOpt) Valid() error {
if err := validator.New().Struct(p); err != nil {
return errors.WithStack(err)
}
return nil
}
impl.go
go
package sms
import (
"context"
"strings"
"time"
"github.com/denverdino/aliyungo/sms"
"github.com/pkg/errors"
)
const (
defaultSignName = ""
)
var (
ErrBusinessLimitControl = errors.New("BUSINESS_LIMIT_CONTROL")
)
type ClientImpl struct {
aliyunSms *sms.DYSmsClient
}
type CodeStore interface {
Save(ctx context.Context, key, smsCode string, expire time.Duration) error
Get(ctx context.Context, key string) (string, error)
}
type ClientOpt struct {
Key string
Secret string
}
func NewClient(opt *ClientOpt) Client {
return &ClientImpl{
aliyunSms: sms.NewDYSmsClient(opt.Key, opt.Secret),
}
}
func (p *ClientImpl) Send(_ context.Context, opt *SendOpt) error {
if err := opt.Valid(); err != nil {
return err
}
s := defaultSignName
if opt.SignName != "" {
s = opt.SignName
}
res, err := p.aliyunSms.SendSms(&sms.SendSmsArgs{
PhoneNumbers: strings.Join(opt.PhoneNumbers, ","),
SignName: s,
TemplateCode: opt.TemplateCode,
TemplateParam: opt.TemplateParam,
SmsUpExtendCode: opt.SmsUpExtendCode,
OutId: opt.OutId,
})
if err != nil {
return errors.WithStack(err)
}
switch res.Code {
case "OK":
return nil
case "isv.BUSINESS_LIMIT_CONTROL":
return ErrBusinessLimitControl
default:
return errors.Errorf("send sms fail: %s, RequestId<%s>, Code<%s>, BizId<%s>",
res.Message, res.RequestId, res.Code, res.BizId)
}
}