package utils import ( "bkb-notify/internal/conf" "crypto/hmac" "crypto/sha1" "encoding/base64" "encoding/json" "errors" "fmt" "github.com/aliyun/alibaba-cloud-sdk-go/sdk" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials" "github.com/aliyun/alibaba-cloud-sdk-go/sdk/requests" "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" const sortGlobalQueryStringFmt string = "AccessKeyId=%s" + "&Action=SendMessageToGlobe" + "&Format=JSON" + "&OutId=123" + "&To=%s" + "&Message=%s" + "&RegionId=cn-hangzhou" + "&SignName=%s" + "&SignatureMethod=HMAC-SHA1" + "&SignatureNonce=%s" + "&SignatureVersion=1.0" + "&Timestamp=%s" + "&Version=2017-05-25" + "&From=18516078412" + "&Type=OTP" 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 SendSmsGlobal(phone string, paramStr string, signName string, templateCode string, times int, c *conf.App_Dysmsapi) error { if times > 10 { return errors.New("服务器繁忙") } config := sdk.NewConfig() credential := credentials.NewAccessKeyCredential(c.AccessKeyID, c.AccessSecret) /* use STS Token credential := credentials.NewStsTokenCredential("", "", "") */ client, err := sdk.NewClientWithOptions("cn-hangzhou", config, credential) if err != nil { fmt.Println(err) return err } request := requests.NewCommonRequest() request.Method = "POST" request.Scheme = "https" // https | http request.Domain = "dysmsapi.aliyuncs.com" request.Version = "2017-05-25" //request.ApiName = "SendSms" request.ApiName = "SendMessageToGlobe" request.QueryParams["To"] = "12504603239" request.QueryParams["From"] = "18516078412" request.QueryParams["Message"] = "bkb code is 234123" request.QueryParams["Type"] = "OTP" response, err := client.ProcessCommonRequest(request) if err != nil { fmt.Println(err) return err } fmt.Print(response.GetHttpContentString()) //token := c.AccessSecret // 阿里云 accessSecret 注意这个地方要添加一个 & //// const token string = "IP2dC1XDM15A6mCt3yTRDk3ZWHri19&" // 阿里云 accessSecret 注意这个地方要添加一个 & // //AccessKeyId := c.AccessKeyID // 自己的阿里云 accessKeyID //// 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(sortGlobalQueryStringFmt, // 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) //fmt.Println(sortQueryString) //resp, err := http.Get("http://dysmsapi.aliyuncs.com/?Signature=" + signature + "&" + sortQueryString) //if err != nil { // fmt.Println(123) // fmt.Println(err) // return err //} //defer resp.Body.Close() //body, err := ioutil.ReadAll(resp.Body) //fmt.Println(string(body)) //fmt.Println(err) //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 SendSmsGlobal(phone, paramStr, signName, templateCode, times+1, c) //} else if ssr.Code != "OK" { // return errors.New(ssr.Code) //} return nil } func SendSms(phone string, paramStr string, signName string, templateCode string, times int, c *conf.App_Dysmsapi) error { if times > 10 { return errors.New("服务器繁忙") } token := c.AccessSecret // 阿里云 accessSecret 注意这个地方要添加一个 & // const token string = "IP2dC1XDM15A6mCt3yTRDk3ZWHri19&" // 阿里云 accessSecret 注意这个地方要添加一个 & AccessKeyId := c.AccessKeyID // 自己的阿里云 accessKeyID // 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, //"33757054568", 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) fmt.Println(sortQueryString) 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, times+1, c) } 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 } type HuaweiMtSms struct { Mobiles []string `json:"mobiles"` TemplateId string `json:"templateId"` TemplateParas string `json:"templateParas"` Signature string `json:"signature"` } // SendSmsReply 发送短信返回 type HuaweiSendSmsReply struct { Code string `json:"resultCode,omitempty"` Message string `json:"resultDesc,omitempty"` }