You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

218 lines
6.0 KiB

2 months ago
package msg
import (
"errors"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
dysmsapi20180501 "github.com/alibabacloud-go/dysmsapi-20180501/v2/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/patrickmn/go-cache"
uuid "github.com/satori/go.uuid"
"sync"
"time"
"wss-pool/config"
"wss-pool/internal"
"wss-pool/internal/data/mysqlbusiness"
"wss-pool/internal/redis"
"wss-pool/logging/applogger"
"wss-pool/pkg/model/sqlmodel"
)
type aLiYun struct {
verificationCodeReqCache *cache.Cache // You can only send the verification code once within a minute
}
var (
aLiYunOnce sync.Once
aLiYunEntity *aLiYun
)
// getALiYunEntity
func getALiYunEntity() *aLiYun {
aLiYunOnce.Do(func() {
aLiYunEntity = new(aLiYun)
aLiYunEntity.verificationCodeReqCache = cache.New(time.Minute, time.Minute)
})
return aLiYunEntity
}
// SendVerificationCode
func (al *aLiYun) SendVerificationCode(phoneNumber string) (code string, err error) {
// Verify if the verification code can be obtained (1-minute validity period)
_, found := al.verificationCodeReqCache.Get(phoneNumber)
if found {
err = errors.New("请勿重复发送验证码")
return
}
// Generate verification code
verifyCode := CreateRandCode()
// Generate Message Body
message := al.getVerifyCodeReq(phoneNumber, verifyCode)
// Write to database
applogger.Debug("send message info:%v", message)
if err = mysqlbusiness.SaveBoUserSms(sqlmodel.BoUserSms{
From: tea.StringValue(message.From),
To: tea.StringValue(message.To),
Message: tea.StringValue(message.Message),
TaskId: tea.StringValue(message.TaskId),
}); err != nil {
err = errors.New("add data db error")
return internal.ResultStr, err
}
// Sends sms
//result, _err := al.SendSms(message)
//if _err != nil {
// _err = errors.New("请输入正确的手机号")
// return internal.ResultStr, _err
//}
result := "发送短信之后的返回值"
applogger.Debug("Send the returned results:%v", tea.StringValue(util.ToJSONString(util.ToMap(result))))
// Update to database
if err = mysqlbusiness.UpdateBoUserSms(sqlmodel.BoUserSms{
From: tea.StringValue(message.From),
To: tea.StringValue(message.To),
Message: tea.StringValue(message.Message),
TaskId: tea.StringValue(message.TaskId),
MessageResult: tea.StringValue(util.ToJSONString(util.ToMap(result))),
UpdateTime: time.Now(),
}); err != nil {
err = errors.New("update data db error")
return internal.ResultStr, err
}
// Request valid within 1 minute
al.verificationCodeReqCache.SetDefault(phoneNumber, 1)
// Set SMS verification code cache to be valid within 5 minutes
err = redis.Set_Cache_Data(phoneNumber, verifyCode, 5)
if err != nil {
err = errors.New("cache key error")
return internal.ResultStr, err
}
return verifyCode, nil
}
// CheckVerificationCode
func (al *aLiYun) CheckVerificationCode(phoneNumber, verificationCode string) (err error) {
code, err := redis.Get_Cache_Data(phoneNumber)
if err != nil {
if err.Error() == "redis: nil" {
// init cache data
if err = redis.Set_Cache_Data(phoneNumber, verificationCode, 5); err != nil {
return errors.New("内部服务出错")
}
code = verificationCode
}
}
if len(code) == 0 {
err = errors.New("验证码已失效")
return
}
if verificationCode != code {
err = errors.New("验证码输入错误")
return
}
return err
}
// CheckVerificationCodeNew
func (al *aLiYun) CheckVerificationCodeNew(phoneNumber string) (string, error) {
code, err := redis.Get_Cache_Data(phoneNumber)
if err != nil {
if err.Error() == "redis: nil" {
code = ""
} else {
err = errors.New("内部服务错误")
return "", err
}
}
return code, nil
}
// getVerifyCodeReq
func (al *aLiYun) getVerifyCodeReq(phoneNumber, code string) (req dysmsapi20180501.SendMessageToGlobeRequest) {
verifyCodeFrom := CreateRandCodeTest()
req = dysmsapi20180501.SendMessageToGlobeRequest{
From: tea.String(verifyCodeFrom), // 发送方标识;支持SenderId的发送,只允许数字+字母,含有字母标识最长11位,纯数字标识支持15位
To: tea.String(phoneNumber), // 接收短信号码;号码格式为:国际区号+号码
Message: tea.String(code), // TODO: 修改短信内容
TaskId: tea.String(uuid.NewV4().String()), // 任务ID;长度不要超过255
}
return
}
// CreateClient Initialize the Client with the AccessKey of the account
func (al *aLiYun) CreateClient(accessKeyId *string, accessKeySecret *string) (_result *dysmsapi20180501.Client, _err error) {
configs := &openapi.Config{
// Required, your AccessKey ID
AccessKeyId: accessKeyId,
// Required, your AccessKey secret
AccessKeySecret: accessKeySecret,
}
// Endpoint
configs.Endpoint = tea.String(config.Config.ALiYun.EndPoint)
_result = &dysmsapi20180501.Client{}
_result, _err = dysmsapi20180501.NewClient(configs)
return _result, _err
}
// SendSms
func (al *aLiYun) SendSms(req dysmsapi20180501.SendMessageToGlobeRequest) (res *dysmsapi20180501.SendMessageToGlobeResponse, _err error) {
client, _err := al.CreateClient(tea.String(config.Config.ALiYun.AccessKeyId), tea.String(config.Config.ALiYun.AccessKeySecret))
if _err != nil {
return nil, _err
}
defer func() {
if r := tea.Recover(recover()); r != nil {
_err = r
}
}()
runtime := &util.RuntimeOptions{}
// Copy the code to run, please print the return value of the API by yourself.
result, _err := client.SendMessageToGlobeWithOptions(&req, runtime)
if _err != nil {
return nil, _err
}
if *result.Body.ResponseCode != "OK" {
_err = errors.New(result.String())
}
return result, _err
}
func RunSendSms(phoneNumber string) (string, error) {
sms := NewSms()
code, err := sms.CheckVerificationCodeNew(phoneNumber)
if err != nil {
return err.Error(), err
}
if len(code) > 0 {
return code, err
}
// Request verification code
codeMsg, err := sms.SendVerificationCode(phoneNumber)
if err != nil {
return internal.ResultStr, err
}
return codeMsg, nil
}