阿里雲簡訊傳送 sdk

JeffreyBool發表於2020-01-16

程式碼封裝

sms.proto

syntax = "proto3";
package sms;

// 傳送簡訊引數
message SmsRequest {
    string mobile = 1; // 手機號
    string template = 2; // 模板編號
    string payload = 3; // 附加引數
}
  • sdk 初始化引數 options.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 編寫
/**
* 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
/**
* 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)
}

編寫測試用例

/**
* 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 啦,開箱即用

本作品採用《CC 協議》,轉載必須註明作者和本文連結
by JeffreyBool blog :point_right: link

相關文章