package weixinapi import ( "net/http" "net/url" "git.rosy.net.cn/baseapi" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/baseapi/utils" ) const ( prodURL = "https://api.weixin.qq.com" ) const ( ResponseCodeBusy = -1 ResponseCodeSuccess = 0 ) type TokenInfo struct { AccessToken string `json:"access_token"` ExpiresIn int `json:"expires_in"` } type ErrorInfo struct { ErrCode int `json:"errcode"` ErrMsg string `json:"errmsg"` } type API struct { token string appID string secret string client *http.Client config *platformapi.APIConfig } func New(appID, secret string, config ...*platformapi.APIConfig) *API { curConfig := platformapi.DefAPIConfig if len(config) > 0 { curConfig = *config[0] } return &API{ appID: appID, secret: secret, client: &http.Client{Timeout: curConfig.ClientTimeout}, config: &curConfig, } } func (a *API) AccessAPI(action string, params map[string]interface{}) (retVal interface{}, err error) { if params == nil { panic("params is nil!") } params2 := make(map[string]interface{}) for k, v := range params { params2[k] = v } params2["appid"] = a.appID params2["secret"] = a.secret url, _ := url.Parse(utils.GenerateGetURL(prodURL, action, params2)) // baseapi.SugarLogger.Debug(url.String()) request := &http.Request{ Method: "GET", URL: url, } err = platformapi.AccessPlatformAPIWithRetry(a.client, request, a.config, func(response *http.Response) (result string, err error) { jsonResult1, err := utils.HTTPResponse2Json(response) if err != nil { return platformapi.ErrLevelGeneralFail, platformapi.ErrResponseDataFormatWrong } var errInfo *ErrorInfo // 微信的返回值,在错误与正常情况下,结构是完全不一样的 if errCode, ok := jsonResult1["errcode"]; ok { errInfo = &ErrorInfo{ ErrCode: int(utils.MustInterface2Int64(errCode)), ErrMsg: jsonResult1["errmsg"].(string), } } else { retVal = &TokenInfo{ AccessToken: jsonResult1["access_token"].(string), ExpiresIn: int(utils.MustInterface2Int64(jsonResult1["expires_in"])), } } if retVal != nil { return platformapi.ErrLevelSuccess, nil } baseapi.SugarLogger.Warnf("response business code is not ok, data:%v, code:%v", jsonResult1, errInfo.ErrCode) newErr := utils.NewErrorIntCode(errInfo.ErrMsg, errInfo.ErrCode) if errInfo.ErrCode == ResponseCodeBusy { return platformapi.ErrLevelRecoverableErr, newErr } return platformapi.ErrLevelCodeIsNotOK, newErr }) return retVal, err } func (a *API) RefreshToken() (tokenInfo *TokenInfo, err error) { result, err := a.AccessAPI("cgi-bin/token", utils.Params2Map("grant_type", "client_credential")) if err != nil { return nil, err } tokenInfo = result.(*TokenInfo) // update my token too. a.token = tokenInfo.AccessToken return tokenInfo, nil }