Skip to content

Commit dd9b70c

Browse files
committed
feat: 集成腾讯云短信
1 parent 76339aa commit dd9b70c

File tree

7 files changed

+109
-11
lines changed

7 files changed

+109
-11
lines changed

biz/conf/sms.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package conf
22

33
type SMS struct {
4-
MaxInPeriod int // 周期内最多发送的次数
5-
Period int // 以分钟为单位
6-
Provider string // 供应商
7-
Account string // 账号
8-
Token string // 鉴权token
9-
AppConf SMSAppConf `json:",default={}"` // 以AppName为名获取到到对应App的配置, 可从其中通过原因获取对应的模板
4+
MaxInPeriod int // 周期内最多发送的次数
5+
Period int // 以分钟为单位
6+
Provider string // 供应商
7+
Account string // 账号
8+
Token string // 鉴权token
9+
Extra map[string]string // 不同渠道的额外信息
10+
AppConf SMSAppConf `json:",default={}"` // 以AppName为名获取到到对应App的配置, 可从其中通过原因获取对应的模板
1011
}
1112

1213
type SMSAppConf = map[string]CauseToTemplate

biz/infra/contract/sms/sms.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ import (
88
"github.com/xh-polaris/synapse/biz/infra/contract/cache"
99
)
1010

11-
const (
12-
Passport = "passport"
13-
)
14-
1511
// Provider 提供SMS相关服务, 支持附有效期(param.Expire)的验证码(param.Code)存储与校验
1612
type Provider interface {
1713
// Send 发送验证码

biz/infra/impl/sms/sms.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ import (
88
"github.com/xh-polaris/synapse/biz/infra/contract/cache"
99
"github.com/xh-polaris/synapse/biz/infra/contract/sms"
1010
"github.com/xh-polaris/synapse/biz/infra/impl/sms/bluecloud"
11+
"github.com/xh-polaris/synapse/biz/infra/impl/sms/tencent"
1112
)
1213

1314
const (
1415
BlueCloud = "blue-cloud"
16+
Tencent = "tencent"
1517
)
1618

1719
func New(ctx context.Context, cacheCli cache.Cmdable) (provider sms.Provider, err error) {
@@ -20,6 +22,8 @@ func New(ctx context.Context, cacheCli cache.Cmdable) (provider sms.Provider, er
2022
switch c.Provider {
2123
case BlueCloud:
2224
provider, err = bluecloud.New(ctx, ch, c.Account, c.Token)
25+
case Tencent:
26+
provider, err = tencent.New(ctx, ch, c.Account, c.Token)
2327
default:
2428
return nil, fmt.Errorf("no such SMS provider: %s", c.Provider)
2529
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package tencent
2+
3+
import (
4+
"context"
5+
"errors"
6+
"strconv"
7+
8+
"github.com/cloudwego/hertz/pkg/common/json"
9+
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
10+
tencenterrors "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/errors"
11+
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile"
12+
tencentsms "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms/v20210111"
13+
"github.com/xh-polaris/synapse/biz/conf"
14+
"github.com/xh-polaris/synapse/biz/infra/contract/cache"
15+
"github.com/xh-polaris/synapse/biz/infra/contract/sms"
16+
"github.com/xh-polaris/synapse/biz/pkg/logs"
17+
)
18+
19+
type tencentSMS struct {
20+
cache *sms.Cache
21+
client *tencentsms.Client
22+
}
23+
24+
func New(ctx context.Context, cache *sms.Cache, account, token string) (sms.Provider, error) {
25+
s, err := getTencentSMSProvider(ctx, cache, account, token)
26+
if err != nil {
27+
return nil, err
28+
}
29+
return s, nil
30+
}
31+
32+
func getTencentSMSProvider(_ context.Context, cache *sms.Cache, secretId, secretKey string) (sms.Provider, error) {
33+
credential := common.NewCredential(secretId, secretKey)
34+
client, err := tencentsms.NewClient(credential, "ap-guangzhou", profile.NewClientProfile())
35+
if err != nil {
36+
return nil, err
37+
}
38+
return &tencentSMS{cache: cache, client: client}, nil
39+
}
40+
41+
func (t *tencentSMS) Send(ctx context.Context, app, cause, phone string, param *sms.SMSParam) (err error) {
42+
// 发送短信
43+
if _, err = t.send(ctx, app, cause, phone, param); err != nil {
44+
return err
45+
}
46+
expire := param.Expire
47+
48+
if err = t.cache.Store(ctx, app, cause, phone, param.Code, expire); err != nil {
49+
return err
50+
}
51+
return nil
52+
}
53+
54+
func (t *tencentSMS) send(_ context.Context, app, cause, phone string, param *sms.SMSParam) (map[string]any, error) {
55+
// 参数设置
56+
req := tencentsms.NewSendSmsRequest()
57+
req.SmsSdkAppId = common.StringPtr(conf.GetConfig().SMS.Extra["AppId"]) // 应用ID
58+
req.SignName = common.StringPtr(conf.GetConfig().SMS.Extra["Sign"]) // 签名内容
59+
req.TemplateId = common.StringPtr(conf.GetConfig().SMS.AppConf[app][cause]) //模板ID
60+
req.TemplateParamSet = common.StringPtrs([]string{param.Code, strconv.Itoa(int(param.Expire.Minutes()))})
61+
req.PhoneNumberSet = common.StringPtrs([]string{phone})
62+
63+
// 发送响应
64+
resp, err := t.client.SendSms(req)
65+
66+
// SDK 错误
67+
var tencentCloudSDKError *tencenterrors.TencentCloudSDKError
68+
if errors.As(err, &tencentCloudSDKError) {
69+
logs.Errorf("An Tencent API error has returned: %s", err)
70+
}
71+
if err != nil {
72+
return nil, err
73+
}
74+
// 正常响应
75+
r, respStr := map[string]any{}, resp.ToJsonString()
76+
if err = json.Unmarshal([]byte(respStr), &r); err != nil {
77+
logs.Infof("Tencent sms return resp %s but unmarsharl failed %s", respStr, err)
78+
}
79+
return r, nil
80+
}
81+
func (t *tencentSMS) Check(ctx context.Context, app, cause, phone, code string) (bool, error) {
82+
if code == "xh-polaris" && conf.GetConfig().State == "test" {
83+
return true, nil
84+
}
85+
ori, err := t.cache.Load(ctx, app, cause, phone)
86+
if errors.Is(err, cache.Nil) {
87+
return false, nil
88+
}
89+
return ori == code, err
90+
}

biz/types/ddl/struct2table.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ func main() {
2424
if err != nil {
2525
panic("failed to migrate database: " + err.Error())
2626
}
27-
}
27+
}

go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ require (
6060
github.com/prometheus/common v0.62.0 // indirect
6161
github.com/prometheus/procfs v0.15.1 // indirect
6262
github.com/spaolacci/murmur3 v1.1.0 // indirect
63+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.42 // indirect
64+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.1.49 // indirect
6365
github.com/tidwall/gjson v1.17.0 // indirect
6466
github.com/tidwall/match v1.1.1 // indirect
6567
github.com/tidwall/pretty v1.2.1 // indirect

go.sum

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
144144
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
145145
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
146146
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
147+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.1.49/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
148+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.42 h1:pK3JoWymtfU5G858dYXnd2C4DAjfUMPhYtEpoZKdAGA=
149+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.42/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
150+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.1.49 h1:8mlcG8TmoeEIDQGLYvqc9fdBQrNwKEb56I2HVNy9jdw=
151+
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/sms v1.1.49/go.mod h1:YAdTku4GgK5H2LKea4bPgWf3qFLBibIBzgU1LW5WgEc=
147152
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
148153
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
149154
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=

0 commit comments

Comments
 (0)