You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.2 KiB
173 lines
4.2 KiB
5 months ago
|
package utils
|
||
|
|
||
|
import (
|
||
|
"crypto/hmac"
|
||
|
"crypto/sha1"
|
||
|
"encoding/base64"
|
||
|
"encoding/json"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"io/ioutil"
|
||
|
"math/rand"
|
||
|
"net/http"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
const sortQueryStringFmt string = "AccessKeyId=%s" +
|
||
|
"&Action=SendSms" +
|
||
|
"&Format=JSON" +
|
||
|
"&OutId=123" +
|
||
|
"&PhoneNumbers=%s" +
|
||
|
"&RegionId=cn-hangzhou" +
|
||
|
"&SignName=%s" +
|
||
|
"&SignatureMethod=HMAC-SHA1" +
|
||
|
"&SignatureNonce=%s" +
|
||
|
"&SignatureVersion=1.0" +
|
||
|
"&TemplateCode=%s" +
|
||
|
"&TemplateParam=%s" +
|
||
|
"&Timestamp=%s" +
|
||
|
"&Version=2017-05-25"
|
||
|
|
||
|
func encodeLocal(encodeStr string) string {
|
||
|
urlEncode := url.QueryEscape(encodeStr)
|
||
|
urlEncode = strings.Replace(urlEncode, "+", "%%20", -1)
|
||
|
urlEncode = strings.Replace(urlEncode, "*", "%2A", -1)
|
||
|
urlEncode = strings.Replace(urlEncode, "%%7E", "~", -1)
|
||
|
urlEncode = strings.Replace(urlEncode, "/", "%%2F", -1)
|
||
|
return urlEncode
|
||
|
}
|
||
|
|
||
|
// SendSmsReply 发送短信返回
|
||
|
type SendSmsReply struct {
|
||
|
Code string `json:"Code,omitempty"`
|
||
|
Message string `json:"Message,omitempty"`
|
||
|
}
|
||
|
|
||
|
func SendSms(phone string, paramStr string, signName string, templateCode string) error {
|
||
|
const token string = "IP2dC1XDM15A6mCt3yTRDk3ZWHri19&" // 阿里云 accessSecret 注意这个地方要添加一个 &
|
||
|
|
||
|
AccessKeyId := "LTAI5t6oHZUFW5bqNTbDwd5n" // 自己的阿里云 accessKeyID
|
||
|
|
||
|
SignatureNonce := strconv.Itoa(GenerateRandNumByCount(9))
|
||
|
TemplateParam := url.QueryEscape(paramStr)
|
||
|
Timestamp := url.QueryEscape(time.Now().UTC().Format("2006-01-02T15:04:05Z"))
|
||
|
|
||
|
sortQueryString := fmt.Sprintf(sortQueryStringFmt,
|
||
|
AccessKeyId,
|
||
|
phone,
|
||
|
url.QueryEscape(signName),
|
||
|
SignatureNonce,
|
||
|
templateCode,
|
||
|
TemplateParam,
|
||
|
Timestamp,
|
||
|
)
|
||
|
|
||
|
urlencode := encodeLocal(sortQueryString)
|
||
|
sign_str := fmt.Sprintf("GET&%%2F&%s", urlencode)
|
||
|
|
||
|
key := []byte(token)
|
||
|
mac := hmac.New(sha1.New, key)
|
||
|
mac.Write([]byte(sign_str))
|
||
|
signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
||
|
signature = encodeLocal(signature)
|
||
|
resp, err := http.Get("http://dysmsapi.aliyuncs.com/?Signature=" + signature + "&" + sortQueryString)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
return err
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
body, err := ioutil.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
ssr := &SendSmsReply{}
|
||
|
|
||
|
if err := json.Unmarshal(body, ssr); err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if ssr.Code == "SignatureNonceUsed" {
|
||
|
return SendSms(phone, paramStr, signName, templateCode)
|
||
|
} else if ssr.Code != "OK" {
|
||
|
return errors.New(ssr.Code)
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func GenerateRandNumByCount(count int) int {
|
||
|
rand.Seed(time.Now().Unix())
|
||
|
rnd := rand.Intn(9*int(exponent(10, uint64(count-1)))-1) + int(exponent(10, uint64(count-1)))
|
||
|
return rnd
|
||
|
}
|
||
|
|
||
|
func exponent(a, n uint64) uint64 {
|
||
|
result := uint64(1)
|
||
|
for i := n; i > 0; i >>= 1 {
|
||
|
if i&1 != 0 {
|
||
|
result *= a
|
||
|
}
|
||
|
a *= a
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func SendMessageNotice(phone string, content string, signName string, templateCode string) {
|
||
|
const token string = "IXvbHeyNLAWJHC08mg4quGYQtmf84h&" // 阿里云 accessSecret 注意这个地方要添加一个 &
|
||
|
|
||
|
AccessKeyId := "LTAIZSh7LB8zkmtO" // 自己的阿里云 accessKeyID
|
||
|
|
||
|
SignatureNonce := strconv.Itoa(GenerateRandNumByCount(9))
|
||
|
//TemplateCode := "SMS_140625198"
|
||
|
TemplateParam := url.QueryEscape("{\"content\":\"" + content + "\"}")
|
||
|
Timestamp := url.QueryEscape(time.Now().UTC().Format("2006-01-02T15:04:05Z"))
|
||
|
|
||
|
sortQueryString := fmt.Sprintf(sortQueryStringFmt,
|
||
|
AccessKeyId,
|
||
|
phone,
|
||
|
url.QueryEscape(signName),
|
||
|
SignatureNonce,
|
||
|
templateCode,
|
||
|
TemplateParam,
|
||
|
Timestamp,
|
||
|
)
|
||
|
|
||
|
urlEncode := encodeLocal(sortQueryString)
|
||
|
signStr := fmt.Sprintf("GET&%%2F&%s", urlEncode)
|
||
|
|
||
|
key := []byte(token)
|
||
|
mac := hmac.New(sha1.New, key)
|
||
|
mac.Write([]byte(signStr))
|
||
|
signature := base64.StdEncoding.EncodeToString(mac.Sum(nil))
|
||
|
signature = encodeLocal(signature)
|
||
|
resp, err := http.Get("http://dysmsapi.aliyuncs.com/?Signature=" + signature + "&" + sortQueryString)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
body, err := ioutil.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
ssr := &SendSmsReply{}
|
||
|
|
||
|
if err := json.Unmarshal(body, ssr); err != nil {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if ssr.Code == "SignatureNonceUsed" {
|
||
|
SendMessageNotice(phone, content, signName, templateCode)
|
||
|
return
|
||
|
} else if ssr.Code != "OK" {
|
||
|
return
|
||
|
}
|
||
|
return
|
||
|
}
|