137 lines
3.9 KiB
Go
137 lines
3.9 KiB
Go
package sms_tool
|
||
|
||
import (
|
||
"context"
|
||
"errors"
|
||
"fmt"
|
||
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||
dysmsapi20170525 "github.com/alibabacloud-go/dysmsapi-20170525/v5/client"
|
||
util "github.com/alibabacloud-go/tea-utils/v2/service"
|
||
"github.com/alibabacloud-go/tea/tea"
|
||
"github.com/redis/go-redis/v9"
|
||
"time"
|
||
)
|
||
|
||
type SmsClient struct {
|
||
SmsConfig
|
||
Cache ICacheAdapter
|
||
client *dysmsapi20170525.Client
|
||
}
|
||
|
||
type SmsConfig struct {
|
||
AccessKeyId string `json:"accessKeyId"`
|
||
AccessKeySecret string `json:"accessKeySecret"`
|
||
Endpoint string `json:"endpoint"`
|
||
}
|
||
|
||
func NewSmsClient(smsConfig *SmsConfig) (smsClient SmsClient, err error) {
|
||
config := &openapi.Config{}
|
||
if smsConfig.AccessKeyId == "" {
|
||
return SmsClient{}, errors.New("AccessKeyId 不能为空")
|
||
}
|
||
if smsConfig.AccessKeySecret == "" {
|
||
return SmsClient{}, errors.New("AccessKeySecret 不能为空")
|
||
}
|
||
if smsConfig.Endpoint == "" {
|
||
smsConfig.Endpoint = "dysmsapi.aliyuncs.com"
|
||
}
|
||
config.AccessKeyId = tea.String(smsConfig.AccessKeyId)
|
||
config.AccessKeySecret = tea.String(smsConfig.AccessKeySecret)
|
||
// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
|
||
config.Endpoint = tea.String(smsConfig.Endpoint)
|
||
|
||
smsClient.client = &dysmsapi20170525.Client{}
|
||
smsClient.client, err = dysmsapi20170525.NewClient(config)
|
||
return smsClient, err
|
||
}
|
||
|
||
// SendSms 发送短信
|
||
func (c *SmsClient) SendSms(params *SendSmsParams) (res *dysmsapi20170525.SendSmsResponse, err error) {
|
||
smsParams := &dysmsapi20170525.SendSmsRequest{
|
||
OutId: tea.String(params.OutId),
|
||
OwnerId: tea.Int64(params.OwnerId),
|
||
PhoneNumbers: tea.String(params.PhoneNumbers),
|
||
ResourceOwnerAccount: tea.String(params.ResourceOwnerAccount),
|
||
ResourceOwnerId: tea.Int64(params.ResourceOwnerId),
|
||
SignName: tea.String(params.SignName),
|
||
SmsUpExtendCode: tea.String(params.SmsUpExtendCode),
|
||
TemplateCode: tea.String(params.TemplateCode),
|
||
TemplateParam: tea.String(params.TemplateParam),
|
||
}
|
||
runtime := &util.RuntimeOptions{}
|
||
return c.client.SendSmsWithOptions(smsParams, runtime)
|
||
}
|
||
|
||
// GetCode 获取验证码
|
||
func (c *SmsClient) GetCode(ctx context.Context, key string) (code string, err error) {
|
||
if c.Cache == nil {
|
||
return "", errors.New("缓存不能为空")
|
||
}
|
||
value, err := c.Cache.Get(ctx, key)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
return value.(string), nil
|
||
}
|
||
|
||
// SaveCode 保存验证码
|
||
func (c *SmsClient) SaveCode(ctx context.Context, key string, code string, expire time.Duration, frequency time.Duration) (err error) {
|
||
if c.Cache == nil {
|
||
return errors.New("缓存不能为空")
|
||
}
|
||
frequencyKey := fmt.Sprintf(CodeFrequencyKey, key)
|
||
if frequency != 0 {
|
||
// 判断验证码是否频繁
|
||
frequencyValue, err := c.Cache.Get(ctx, frequencyKey)
|
||
if err != nil {
|
||
if errors.Is(err, redis.Nil) {
|
||
// 缓存中没有数据
|
||
fmt.Printf("缓存中没有数据")
|
||
} else {
|
||
return err
|
||
}
|
||
}
|
||
if frequencyValue != nil && frequencyValue.(string) == CodeFrequencyValue {
|
||
return errors.New("code发送频繁,请稍后再试")
|
||
}
|
||
}
|
||
//保存code
|
||
err = c.Cache.Set(ctx, key, code, expire)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if frequency != 0 {
|
||
// 保存验证码发送频率
|
||
err = c.Cache.Set(ctx, frequencyKey, CodeFrequencyValue, frequency)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
// DeleteCode 删除验证码
|
||
func (c *SmsClient) DeleteCode(ctx context.Context, key string) (err error) {
|
||
if c.Cache == nil {
|
||
return errors.New("缓存不能为空")
|
||
}
|
||
err = c.Cache.Del(ctx, key)
|
||
return err
|
||
}
|
||
|
||
// VerifyCode 校验验证码
|
||
func (c *SmsClient) VerifyCode(ctx context.Context, key string, verifyCode string) (ok bool, err error) {
|
||
//获取验证码
|
||
code, err := c.GetCode(ctx, key)
|
||
if err != nil {
|
||
return false, err
|
||
}
|
||
//校验验证码
|
||
if code != verifyCode {
|
||
return false, errors.New("code不一致")
|
||
}
|
||
//删除验证码
|
||
_ = c.DeleteCode(ctx, key)
|
||
return true, nil
|
||
}
|