ZBLOG

golang 封装一个通用的 腾讯云 发送短信的接口

好的,以下是一个封装了腾讯云发送短信接口的示例代码,你可以参考使用:

package sms

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"

	jsoniter "github.com/json-iterator/go"
)

const (
	smsAPIHost      = "sms.tencentcloudapi.com"
	smsAPIMethod    = "POST"
	smsAPIVersion   = "2019-07-11"
	signatureMethod = "HmacSHA256"

	defaultTimeout = 10 * time.Second
)

type TencentCloudSMS struct {
	SecretID     string // API密钥ID
	SecretKey    string // API密钥KEY
	DefaultSign  string // 默认签名名称
	DefaultTplID int    // 默认模板ID
}

func (tcs *TencentCloudSMS) Send(phoneNumbers []string, tplID int, params []string, signName string) error {
	if len(phoneNumbers) == 0 || tplID == 0 {
		return errors.New("invalid phone numbers or tpl ID")
	}
	if signName == "" {
		signName = tcs.DefaultSign
	}
	if tplID == 0 {
		tplID = tcs.DefaultTplID
	}
	paramsJSON, _ := jsoniter.Marshal(params)
	queryParams := map[string]string{
        "Action":       "SendSms",
        "Version":      smsAPIVersion,
        "PhoneNumberSet.N": fmt.Sprintf("%d", len(phoneNumbers)),
    }
	for i := range phoneNumbers {
        queryParams[fmt.Sprintf("PhoneNumberSet.%d", i+1)] = phoneNumbers[i]
    }
    queryParams["TemplateID"] = fmt.Sprintf("%d", tplID)
    queryParams["SmsSdkAppid"] = tcs.SecretID
    queryParams["SignName"] = signName
    queryParams["TemplateParamSet.N"] = string(paramsJSON)
	queryParams["Nonce"] = fmt.Sprintf("%d", time.Now().Unix())
	queryParams["Timestamp"] = fmt.Sprintf("%d", time.Now().Unix())
	queryParams["SignatureMethod"] = signatureMethod
	queryParams["SecretId"] = tcs.SecretID

	signature := sign(smsAPIMethod, smsAPIHost, "/", queryParams, tcs.SecretKey)
	queryParams["Signature"] = signature

	client := http.Client{Timeout: defaultTimeout}
	req, err := http.NewRequest(smsAPIMethod, fmt.Sprintf("https://%s/", smsAPIHost), strings.NewReader(buildQuery(queryParams)))
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	bodyBytes, _ := ioutil.ReadAll(resp.Body)

	var response struct {
		Response struct {
			Result string `json:"Result"`
			Error  struct {
				Code    string `json:"Code"`
				Message string `json:"Message"`
			} `json:"Error"`
		} `json:"Response"`
	}

	err = jsoniter.Unmarshal(bodyBytes, &response)
	if err != nil {
        return errors.New(fmt.Sprintf("parse response failed:%s", bodyBytes))
    }

	if response.Response.Error.Code != "" || response.Response.Result == "failed" {
        return errors.New(response.Response.Error.Message)
    }

	return nil
}

func sign(method string, host string, path string, params map[string]string, secretKey string) string {
	var keys []string
	for key := range params {
		keys = append(keys, key)
	}
	sort.Strings(keys)

	var query string
	for _, key := range keys {
		query += fmt.Sprintf("%s=%s&", percentEncode(key), percentEncode(params[key]))
	}
	query = strings.TrimSuffix(query, "&")

	str2sign := fmt.Sprintf("%s%s?%s", method, host, query)

	mac := hmac.New(sha256.New, []byte(secretKey))
	mac.Write([]byte(str2sign))
	sum := mac.Sum(nil)

	signatureBytes := make([]byte, base64.StdEncoding.EncodedLen(len(sum)))
	base64.StdEncoding.Encode(signatureBytes, sum)
	return string(signatureBytes)
}

func buildQuery(params map[string]string) string {
	query := url.Values{}
	for k, v := range params {
		query.Add(k, v)
	}
	return query.Encode()
}

func percentEncode(s string) string {
	s = url.QueryEscape(s)
	s = strings.ReplaceAll(s, "+", "%20")
	s = strings.ReplaceAll(s, "*", "%2A")
	s = strings.ReplaceAll(s, "%7E", "~")
	return s
}

使用示例:

package main

import (
    "fmt"
    "github.com/your_username/go-sms"
)

var tencentSMS *sms.TencentCloudSMS

func init() {
    tencentSMS = &sms.TencentCloudSMS{
        SecretID:     "your_secret_id",
        SecretKey:    "your_secret_key",
        DefaultSign:  "default_sign_name",
        DefaultTplID: 12345,
    }
}

func main() {

    phoneNumbers := []string{"12345678901"}
    tplID := 0 // 如果tplID为0,则使用默认模板ID
    params := []string{"param1", "param2"}
    signName := "" // 如果signName为空,则使用默认签名名称

    err := tencentSMS.Send(phoneNumbers, tplID, params, signName)
    if err != nil {
        fmt.Printf("send sms failed: %s\n", err.Error())
    } else {
        fmt.Println("send sms success")
    }
}

请注意,此代码示例仅供参考,并不适用于生产环境。在实际项目中,还需要进行错误处理、参数校验等工作。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=2995

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?