## 代码封装
`sms.proto`
```protobuf
syntax = "proto3";
package sms;
// 发送短信参数
message SmsRequest {
string mobile = 1; // 手机号
string template = 2; // 模板编号
string payload = 3; // 附加参数
}
```
- sdk 初始化参数 `options.go`
```go
/**
* Author: zhanggaoyuancn@163.com
* Date: 2020/1/16
* Time: 15:42
* Software: GoLand
*/
package sms
var defaultOptions = options{
signName: "xx科技",
}
type options struct {
regionId string // 区域
accessKeyId string // key
accessKeySecret string // 秘钥
signName string // 签名
}
// Option 配置项
type Option func(o *options)
// 设置区域
func SetRegionId(regionId string) Option {
return func(o *options) {
o.regionId = regionId
}
}
// 设置 KEY
func SetAccessKeyId(accessKeyId string) Option {
return func(o *options) {
o.accessKeyId = accessKeyId
}
}
// 设置秘钥
func SetAccessKeySecret(accessKeySecret string) Option {
return func(o *options) {
o.accessKeySecret = accessKeySecret
}
}
// 设置签名
func SetSignName(signName string) Option {
return func(o *options) {
o.signName = signName
}
}
```
- 客户端 实例 `client.go` 编写
```go
/**
* Author: zhanggaoyuancn@163.com
* Date: 2020/1/16
* Time: 15:51
* Software: GoLand
*/
package sms
import (
"encoding/json"
"errors"
"sync"
sms "sdk-sms/proto"
"github.com/aliyun/alibaba-cloud-sdk-go/services/dysmsapi"
"github.com/tidwall/gjson"
)
var (
initClient *Client
onceClient sync.Once
)
type Client struct {
opts *options
}
func NewClient(opts ...Option) *Client {
o := defaultOptions
for _, opt := range opts {
opt(&o)
}
onceClient.Do(func() {
initClient = &Client{
opts: &o,
}
})
return initClient
}
func client() *Client {
if initClient == nil {
panic("sms client is not initialized")
}
return initClient
}
// 发送短信
func (c *Client) Send(request *sms.SmsRequest) (result *Result, err error) {
smsRequest := dysmsapi.CreateSendSmsRequest()
smsRequest.SignName = c.opts.signName
smsRequest.PhoneNumbers = request.GetMobile()
smsRequest.TemplateCode = request.GetTemplate()
smsRequest.TemplateParam = request.GetPayload()
client, err := dysmsapi.NewClientWithAccessKey(c.opts.regionId, c.opts.accessKeyId, c.opts.accessKeySecret)
if err != nil {
return nil, err
}
response, err := client.SendSms(smsRequest)
if err != nil {
return nil, err
}
result = &Result{
RequestId: response.RequestId,
BizId: response.BizId,
Code: response.Code,
Message: response.Message,
}
bytes := response.GetHttpContentBytes()
responseCode := gjson.GetBytes(bytes, "Code").String()
if response.IsSuccess() && responseCode == "OK" {
return result, nil
}
return result, errors.New(gjson.GetBytes(bytes, "Message").String())
}
// result 响应结果
type Result struct {
RequestId string `json:"request_id"`
BizId string `json:"biz_id"`
Code string `json:"code"`
Message string `json:"message"`
}
func (r *Result) String() string {
buf, _ := json.Marshal(r)
return string(buf)
}
// 获取RequestId
func (r *Result) GetRequestId() string {
return r.RequestId
}
// 获取BizId
func (r *Result) GetBizId() string {
return r.BizId
}
// 获取Code
func (r *Result) GetCode() string {
return r.Code
}
// 获取Message
func (r *Result) GetMessage() string {
return r.Message
}
```
- 发送短信 `sms.go`
```go
/**
* Author: zhanggaoyuancn@163.com
* Date: 2020/1/16
* Time: 16:43
* Software: GoLand
*/
package sms
import (
sms "sdk-sms/proto"
)
// 发送短信
func Send(request *sms.SmsRequest) (result *Result, err error) {
return client().Send(request)
}
```
## 编写测试用例
```go
/**
* Author: zhanggaoyuancn@163.com
* Date: 2020/1/16
* Time: 16:44
* Software: GoLand
*/
package sms_test
import (
"encoding/json"
"fmt"
"testing"
sms "sdk-sms"
request "sdk-sms/proto"
)
func TestMain(t *testing.M) {
fmt.Println("test main run..")
sms.NewClient(sms.SetRegionId("xxx"), sms.SetAccessKeyId("xxx"), sms.SetAccessKeySecret("xxx"), sms.SetSignName("xx"))
t.Run()
fmt.Println("test main stop..")
}
func TestClient_Send(t *testing.T) {
data := map[string]interface{}{
"month": "202001",
"money": 1200 / 100,
}
bytes, _ := json.Marshal(data)
r := &request.SmsRequest{
Mobile: "12345678901",
Template: "SMS_123456789",
Payload: string(bytes),
}
result, err := sms.Send(r)
if err != nil {
t.Error(err)
return
}
t.Log(result.String())
}
```
好啦,这是一个方便使用的 sdk 啦,开箱即用
有疑问加站长微信联系(非本文作者)