- change all request to NewRequest, don't use bare Request{}.
- MessageTemplateSend added. - refactor weixin api.
This commit is contained in:
@@ -4,7 +4,6 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -101,11 +100,7 @@ func (a *API) AccessAPI(apiStr string, params map[string]interface{}) (retVal Re
|
|||||||
params2 := utils.MergeMaps(utils.Params2Map("key", a.key, "output", "json"), params)
|
params2 := utils.MergeMaps(utils.Params2Map("key", a.key, "output", "json"), params)
|
||||||
params2[signKey] = a.signParams(params2)
|
params2[signKey] = a.signParams(params2)
|
||||||
|
|
||||||
finalURL, _ := url.Parse(utils.GenerateGetURL(prodURL, apiStr, params2))
|
request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params2), nil)
|
||||||
request := &http.Request{
|
|
||||||
Method: "GET",
|
|
||||||
URL: finalURL,
|
|
||||||
}
|
|
||||||
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (errLevel string, err error) {
|
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (errLevel string, err error) {
|
||||||
jsonResult1, err := utils.HTTPResponse2Json(response)
|
jsonResult1, err := utils.HTTPResponse2Json(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -41,14 +40,14 @@ type TokenInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type API struct {
|
type API struct {
|
||||||
token string
|
token string
|
||||||
appKey string
|
appKey string
|
||||||
secret string
|
secret string
|
||||||
isProd bool
|
isProd bool
|
||||||
url *url.URL
|
fullURL string
|
||||||
client *http.Client
|
client *http.Client
|
||||||
config *platformapi.APIConfig
|
config *platformapi.APIConfig
|
||||||
locker sync.RWMutex
|
locker sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
type payload struct {
|
type payload struct {
|
||||||
@@ -77,9 +76,9 @@ func New(token, appKey, secret string, isProd bool, config ...*platformapi.APICo
|
|||||||
}
|
}
|
||||||
|
|
||||||
if isProd {
|
if isProd {
|
||||||
api.url, _ = url.Parse(prodURL + "/")
|
api.fullURL = prodURL + "/"
|
||||||
} else {
|
} else {
|
||||||
api.url, _ = url.Parse(sandboxURL + "/")
|
api.fullURL = sandboxURL + "/"
|
||||||
}
|
}
|
||||||
return api
|
return api
|
||||||
}
|
}
|
||||||
@@ -149,18 +148,10 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal *R
|
|||||||
pl.Signature = a.signParams(action, pl)
|
pl.Signature = a.signParams(action, pl)
|
||||||
|
|
||||||
bodyStr := string(utils.MustMarshal(pl))
|
bodyStr := string(utils.MustMarshal(pl))
|
||||||
request := &http.Request{
|
request, _ := http.NewRequest(http.MethodPost, a.fullURL, strings.NewReader(bodyStr))
|
||||||
Method: "POST",
|
request.Header.Set("Content-Type", "application/json; charset=utf-8")
|
||||||
URL: a.url,
|
request.Header.Set("Content-Encoding", "gzip, deflate")
|
||||||
Header: http.Header{
|
request.Header.Set("User-Agent", "eleme-golang-api")
|
||||||
"Content-Type": []string{"application/json; charset=utf-8"},
|
|
||||||
"Content-Encoding": []string{"gzip, deflate"},
|
|
||||||
"User-Agent": []string{"eleme-golang-api"},
|
|
||||||
// "x-eleme-requestid": []string{payload.Id},
|
|
||||||
},
|
|
||||||
|
|
||||||
Body: ioutil.NopCloser(strings.NewReader(bodyStr)),
|
|
||||||
}
|
|
||||||
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
|
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
|
||||||
jsonResult1, err := utils.HTTPResponse2Json(response)
|
jsonResult1, err := utils.HTTPResponse2Json(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ func init() {
|
|||||||
baseapi.Init(sugarLogger)
|
baseapi.Init(sugarLogger)
|
||||||
|
|
||||||
// sandbox
|
// sandbox
|
||||||
elmapi = New("7b642f1767b6ad5c074238f1bf4720f8", "RwT214gAsS", "56afff4b9ebd8a7eb532d18fa33f17be57f9b9db", false)
|
elmapi = New("623c0904c0d2499e83df15b62902eb65", "RwT214gAsS", "56afff4b9ebd8a7eb532d18fa33f17be57f9b9db", false)
|
||||||
|
|
||||||
// prod
|
// prod
|
||||||
// elmapi = New("a530ade4a8e0b99542df0592b06575b5", "KLRDcOZGrk", "1fc221f8265506531da36fb613d5f5ad673f2e9a", true)
|
// elmapi = New("a530ade4a8e0b99542df0592b06575b5", "KLRDcOZGrk", "1fc221f8265506531da36fb613d5f5ad673f2e9a", true)
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi"
|
"git.rosy.net.cn/baseapi"
|
||||||
@@ -147,12 +146,7 @@ func (a *API) AccessAPI(apiStr string, jdParams map[string]interface{}) (retVal
|
|||||||
params["timestamp"] = utils.GetCurTimeStr()
|
params["timestamp"] = utils.GetCurTimeStr()
|
||||||
sign := a.signParams(params)
|
sign := a.signParams(params)
|
||||||
params[signKey] = sign
|
params[signKey] = sign
|
||||||
|
request, _ := http.NewRequest(http.MethodGet, utils.GenerateGetURL(prodURL, apiStr, params), nil)
|
||||||
finalURL, _ := url.Parse(utils.GenerateGetURL(prodURL, apiStr, params))
|
|
||||||
request := &http.Request{
|
|
||||||
Method: "GET",
|
|
||||||
URL: finalURL,
|
|
||||||
}
|
|
||||||
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (errLevel string, err error) {
|
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (errLevel string, err error) {
|
||||||
jsonResult1, err := utils.HTTPResponse2Json(response)
|
jsonResult1, err := utils.HTTPResponse2Json(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package weixinapi
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"git.rosy.net.cn/baseapi"
|
"git.rosy.net.cn/baseapi"
|
||||||
@@ -11,7 +11,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
prodURL = "https://api.weixin.qq.com"
|
prodURL = "https://api.weixin.qq.com/cgi-bin"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
actionGetToken = "token"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -59,7 +63,6 @@ func (a *API) SetToken(newToken string) bool {
|
|||||||
a.token = newToken
|
a.token = newToken
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,29 +72,37 @@ func (a *API) GetToken() string {
|
|||||||
return a.token
|
return a.token
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal interface{}, err error) {
|
func (a *API) AccessAPI(action string, params map[string]interface{}, body string) (retVal map[string]interface{}, err error) {
|
||||||
if params == nil {
|
if params != nil && body != "" {
|
||||||
panic("params is nil!")
|
panic("params and body can not all non-empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
params2 := make(map[string]interface{})
|
params2 := make(map[string]interface{})
|
||||||
for k, v := range params {
|
for k, v := range params {
|
||||||
params2[k] = v
|
params2[k] = v
|
||||||
}
|
}
|
||||||
params2["appid"] = a.appID
|
if action == actionGetToken {
|
||||||
params2["secret"] = a.secret
|
params2["appid"] = a.appID
|
||||||
fullURL, _ := url.Parse(utils.GenerateGetURL(prodURL, action, params2))
|
params2["secret"] = a.secret
|
||||||
// baseapi.SugarLogger.Debug(url.String())
|
} else {
|
||||||
request := &http.Request{
|
accessToken := a.GetToken()
|
||||||
Method: "GET",
|
if accessToken == "" {
|
||||||
URL: fullURL,
|
panic("token is empty!")
|
||||||
|
}
|
||||||
|
params2["access_token"] = accessToken
|
||||||
|
}
|
||||||
|
fullURL := utils.GenerateGetURL(prodURL, action, params2)
|
||||||
|
// baseapi.SugarLogger.Debug(fullURL)
|
||||||
|
var request *http.Request
|
||||||
|
if body == "" {
|
||||||
|
request, _ = http.NewRequest(http.MethodGet, fullURL, nil)
|
||||||
|
} else {
|
||||||
|
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(body))
|
||||||
}
|
}
|
||||||
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
|
err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) {
|
||||||
jsonResult1, err := utils.HTTPResponse2Json(response)
|
jsonResult1, err := utils.HTTPResponse2Json(response)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong
|
return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong
|
||||||
}
|
}
|
||||||
|
|
||||||
var errInfo *ErrorInfo
|
var errInfo *ErrorInfo
|
||||||
// 微信的返回值,在错误与正常情况下,结构是完全不一样的
|
// 微信的返回值,在错误与正常情况下,结构是完全不一样的
|
||||||
if errCode, ok := jsonResult1["errcode"]; ok {
|
if errCode, ok := jsonResult1["errcode"]; ok {
|
||||||
@@ -99,13 +110,12 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal in
|
|||||||
ErrCode: int(utils.MustInterface2Int64(errCode)),
|
ErrCode: int(utils.MustInterface2Int64(errCode)),
|
||||||
ErrMsg: jsonResult1["errmsg"].(string),
|
ErrMsg: jsonResult1["errmsg"].(string),
|
||||||
}
|
}
|
||||||
} else {
|
if errInfo.ErrCode == 0 {
|
||||||
retVal = &TokenInfo{
|
retVal = jsonResult1
|
||||||
AccessToken: jsonResult1["access_token"].(string),
|
|
||||||
ExpiresIn: int(utils.MustInterface2Int64(jsonResult1["expires_in"])),
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
retVal = jsonResult1
|
||||||
}
|
}
|
||||||
|
|
||||||
if retVal != nil {
|
if retVal != nil {
|
||||||
return platformapi.ErrLevelSuccess, nil
|
return platformapi.ErrLevelSuccess, nil
|
||||||
}
|
}
|
||||||
@@ -116,18 +126,33 @@ func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal in
|
|||||||
}
|
}
|
||||||
return platformapi.ErrLevelCodeIsNotOK, newErr
|
return platformapi.ErrLevelCodeIsNotOK, newErr
|
||||||
})
|
})
|
||||||
|
|
||||||
return retVal, err
|
return retVal, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *API) RefreshToken() (tokenInfo *TokenInfo, err error) {
|
func (a *API) RefreshToken() (tokenInfo *TokenInfo, err error) {
|
||||||
result, err := a.AccessAPI("cgi-bin/token", utils.Params2Map("grant_type", "client_credential"))
|
result, err := a.AccessAPI(actionGetToken, utils.Params2Map("grant_type", "client_credential"), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
tokenInfo = result.(*TokenInfo)
|
tokenInfo = &TokenInfo{
|
||||||
|
AccessToken: utils.Interface2String(result["access_token"]),
|
||||||
|
ExpiresIn: int(utils.MustInterface2Int64(result["expires_in"])),
|
||||||
|
}
|
||||||
// update my token too.
|
// update my token too.
|
||||||
a.SetToken(tokenInfo.AccessToken)
|
a.SetToken(tokenInfo.AccessToken)
|
||||||
return tokenInfo, nil
|
return tokenInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *API) MessageTemplateSend(userOpneID, templateID, downloadURL string, miniProgram, data interface{}) (err error) {
|
||||||
|
bodyJson := map[string]interface{}{
|
||||||
|
"touser": userOpneID,
|
||||||
|
"template_id": templateID,
|
||||||
|
"url": downloadURL,
|
||||||
|
"data": data,
|
||||||
|
}
|
||||||
|
if miniProgram != nil {
|
||||||
|
bodyJson["miniprogram"] = miniProgram
|
||||||
|
}
|
||||||
|
_, err = a.AccessAPI("message/template/send", nil, string(utils.MustMarshal(bodyJson)))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,8 +33,23 @@ func TestTest(t *testing.T) {
|
|||||||
|
|
||||||
func TestRefreshToken(t *testing.T) {
|
func TestRefreshToken(t *testing.T) {
|
||||||
result, err := weixinapi.RefreshToken()
|
result, err := weixinapi.RefreshToken()
|
||||||
if err != nil {
|
if err != nil || result.ExpiresIn != 7200 {
|
||||||
t.Fatal(err.Error())
|
t.Fatal(err.Error())
|
||||||
}
|
}
|
||||||
sugarLogger.Debug(result)
|
sugarLogger.Debug(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMessageTemplateSend(t *testing.T) {
|
||||||
|
weixinapi.SetToken("11_Gio44UhE5jgP_TNuAwrV9IjSX2QuVwKDyAsVYSWl94RXOJCjcxHcLjzJ81tr-e8cxithGxSlh3accjrdxoo8viWMG9MppZV6IftFPS8WNkFI8ToEbnhMz79UU-d84hLYbVLfecGavVN3HkIvZJYiAFAMWL")
|
||||||
|
err := weixinapi.MessageTemplateSend("oYN_usvnObzrPweIgHTad9-uMf78", "_DtNGwmOeR6TkkTVUblxLIlkV2MAPOX57TkvfdqG6nY", "http://www.163.com", nil, map[string]interface{}{
|
||||||
|
"first": "first",
|
||||||
|
"Day": "Day",
|
||||||
|
"orderId": "orderId",
|
||||||
|
"orderType": "orderType",
|
||||||
|
"customerName": "customerName",
|
||||||
|
"customerPhone": "customerPhone",
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user