金山雲短信golang接入

金山雲短信golang接入

  • 一個簡單的金山雲短信golang 接入,大家有需要直接copy,不重複造輪子。
func sendVcode(phone, vcode string, smsCfg config.SmsConfig) (err error) {
	nowStr := time.Now().UTC().Format(time.RFC3339)
	urlStr := "https://ksms.api.ksyun.com"
	bodyMap := map[string]interface{}{
		"Mobile":           phone,
		"TplId":            *smsCfg.TplId,
		"TplParams":        fmt.Sprintf(*smsCfg.TplParams, vcode),
		"SignName":         *smsCfg.SignName,
		"Action":           "SendSms",
		"Version":          "2019-05-01",
		"SignatureVersion": "1.0",
		"SignatureMethod":  "HMAC-SHA256",
		"Timestamp":        nowStr,
		"Service":          "ksms",
		"Accesskey":        *smsCfg.Accesskey,
	}
	singnatuer := getSignString(bodyMap, *smsCfg.Secret)
	params := `Mobile=%s&TplId=854&TplParams=%s&SignName=xxx公司&Action=SendSms&Version=2019-05-01&Signature=%s&SignatureVersion=1.0&SignatureMethod=HMAC-SHA256&Timestamp=%s&Service=ksms&Accesskey=%s`
	params = fmt.Sprintf(params, phone, fmt.Sprintf(`{"number":"%s"}`, vcode), singnatuer, nowStr, *smsCfg.Accesskey)
	client := &http.Client{}
	req, err := http.NewRequest("POST", urlStr, strings.NewReader(params))
	if err != nil {
		svrInstance.Log.Errorf(MyName, "rpc http.NewRequest failed, err %s ", err.Error())
		return err
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("accept", "application/json")
	resp, err := client.Do(req)
	defer resp.Body.Close()

	m := map[string]interface{}{}
	err = utils.BindJson(resp.Body, &m)
	if err != nil {
		svrInstance.Log.Errorf(MyName, "rpc tools.BindJson failed, err: %s ", err)
		return
	}
	if resp.StatusCode != http.StatusOK {
		svrInstance.Log.Errorf(MyName, "rpc sendVcode failed, http code: %s, err: %s ", resp.Status, m)
		return xmerror.NewError("rpc sendVcode failed")
	}
	return nil
}

func getSignString(mapBody map[string]interface{}, secret string) (sign string) {
	sorted_keys := make([]string, 0)
	for k, _ := range mapBody {
		sorted_keys = append(sorted_keys, k)
	}
	sort.Strings(sorted_keys)

	//STEP2, 對key=value的鍵值對用&連接起來,略過空值
	index := 0
	for _, k := range sorted_keys {
		value := fmt.Sprintf("%v", mapBody[k])
		if value != "" {
			sign = sign + url.QueryEscape(k) + "=" + url.QueryEscape(value)
			//最後一項後面不要&
			if index < len(sorted_keys)-1 {
				sign = sign + "&"
			}
		}
		index++
	}
	h := hmac.New(sha256.New, []byte(secret))
	h.Write([]byte(sign))
	signCalc := strings.ToLower(hex.EncodeToString(h.Sum(nil)))
	return signCalc
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章