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 }