Files
full/module/base/sender/internal/logic/sms/send.go

177 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package sms
import (
"context"
"encoding/json"
"errors"
"fmt"
"math/rand"
"regexp"
"strings"
"time"
"bsm/full/module/base/sender/internal/config"
"bsm/full/module/base/sender/internal/excode"
"bsm/full/module/base/sender/internal/impl"
pb "bsm/full/module/base/sender/pb"
"git.apinb.com/bsm-sdk/core/cache/redis"
"git.apinb.com/bsm-sdk/core/errcode"
AliYunClient "github.com/alibabacloud-go/darabonba-openapi/v2/client"
AliYunUtil "github.com/alibabacloud-go/darabonba-openapi/v2/utils"
"github.com/alibabacloud-go/tea/dara"
"github.com/alibabacloud-go/tea/tea"
"github.com/spf13/cast"
)
func Send(ctx context.Context, in *pb.SmsSendRequest) (reply *pb.SmsReply, err error) {
var smsCode string
if in.GetPhone() == "" || !VerifyPhone(in.GetPhone()) {
return nil, excode.ErrPhone
}
if in.GetTemplateCode() == "" {
return nil, excode.ErrTemplate
}
// 是否验证黑名单
if impl.RedisService.Client.SIsMember(impl.RedisService.Ctx, BlackListCacheKey, in.GetPhone()).Val() {
return nil, excode.ErrInBlackList
}
// 每天限制
limitKey := LimitCacheKey + time.Now().Format(FormatDay) + in.GetPhone()
// check limit
twice, err := impl.RedisService.Client.Get(impl.RedisService.Ctx, limitKey).Int()
if err != nil && !errors.Is(err, redis.Nil) {
return nil, errcode.ErrRedis
}
if twice > config.Spec.Code.MaxSentLimit {
return nil, excode.ErrSentLimit
}
// 从redis获取验证码如果没有重新生成
key := KeyPrefix + in.GetPhone()
if in.GetIsGenCode() {
//验证码最少4位最大10位。
if config.Spec.Code.Length < 4 || config.Spec.Code.Length > 10 {
config.Spec.Code.Length = 6
}
// 新生成验证码
smsCode = GenValidateCode(config.Spec.Code.Length)
//sms code write to redis
expire := time.Second * time.Duration(config.Spec.Code.Expire)
impl.RedisService.Client.SetNX(impl.RedisService.Ctx, key, smsCode, expire)
} else {
// 获取验证码
if code, ok := in.Paramters["code"]; ok {
smsCode = code
} else {
return nil, excode.ErrCode
}
}
var result map[string]interface{}
switch strings.ToLower(in.GetProvider()) {
case "aliyun":
if impl.Provider.Aliyun == nil {
return nil, excode.ErrProviderIsNil
}
result, err = AliyunSender(in, smsCode)
case "tencent":
if impl.Provider.Tencent == nil {
return nil, excode.ErrProviderIsNil
}
result, err = TencentSender(in)
default:
return nil, excode.ErrNotProvider
}
if err != nil {
return nil, err
}
jsonBytes, _ := json.Marshal(result)
fmt.Println("短信发送结果:", string(jsonBytes))
return &pb.SmsReply{
Reply: string(jsonBytes),
}, nil
}
func AliyunSender(args *pb.SmsSendRequest, code string) (map[string]any, error) {
// 构建发送参数
var templateParam = map[string]any{
"code": code,
}
for key, val := range args.Paramters {
templateParam[key] = val
}
jsonBytes, _ := json.Marshal(templateParam)
params := map[string]any{
// 必填,接收短信的手机号码
"PhoneNumbers": tea.String(cast.ToString(args.Phone)),
// 必填,短信签名名称
"SignName": tea.String(cast.ToString(args.SignName)),
// 必填短信模板ID
"TemplateCode": tea.String(cast.ToString(args.TemplateCode)),
// 可选,模板参数
"TemplateParam": string(jsonBytes),
}
runtime := &dara.RuntimeOptions{}
request := &AliYunClient.OpenApiRequest{
Query: AliYunUtil.Query(params),
}
clientParams := &AliYunClient.Params{
// 接口名称
Action: tea.String("SendSms"),
// 接口版本
Version: tea.String("2017-05-25"),
// 接口协议
Protocol: tea.String("HTTPS"),
// 接口 HTTP 方法
Method: tea.String("POST"),
AuthType: tea.String("AK"),
Style: tea.String("RPC"),
// 接口 PATH
Pathname: tea.String("/"),
// 接口请求体内容格式
ReqBodyType: tea.String("json"),
// 接口响应体内容格式
BodyType: tea.String("json"),
}
fmt.Println("请求参数params为", params)
fmt.Println("请求参数clientParams为", clientParams)
return impl.Provider.Aliyun.CallApi(clientParams, request, runtime)
}
func TencentSender(args *pb.SmsSendRequest) (map[string]any, error) {
return nil, nil
}
func VerifyPhone(phone string) bool {
result, _ := regexp.MatchString(`^(1[3|4|5|6|7|8|9][0-9]\d{4,8})$`, phone)
return result
}
// GenValidateCode .
func GenValidateCode(width int64) string {
if width == 0 {
width = 4
}
l := 10
numeric := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
rand.Seed(time.Now().UnixNano())
var sb strings.Builder
for i := int64(0); i < width; i++ {
fmt.Fprintf(&sb, "%d", numeric[rand.Intn(l)])
}
return sb.String()
}