diff --git a/core/config.go b/core/config.go new file mode 100644 index 000000000..1ea57c7c0 --- /dev/null +++ b/core/config.go @@ -0,0 +1,22 @@ +package core + +import ( + "github.com/imroc/req/v3" + "github.com/silenceper/wechat/v2/cache" +) + +// Config .config for 微信公众号 +type Config struct { + AppID string `json:"app_id"` // appid + AppSecret string `json:"app_secret"` // appsecret + ProxyUrl string `json:"proxy_url"` // 代理url + Cache cache.Cache +} + +func (c *Config) Req() *req.Request { + client := req.C() + if c.ProxyUrl != "" { + client.SetProxyURL(c.ProxyUrl) + } + return client.R() +} diff --git a/credential/default_access_token.go b/credential/default_access_token.go index 7c9154459..502d3e28a 100644 --- a/credential/default_access_token.go +++ b/credential/default_access_token.go @@ -1,8 +1,8 @@ package credential import ( - "encoding/json" "fmt" + "github.com/imroc/req/v3" "sync" "time" @@ -27,19 +27,21 @@ const ( type DefaultAccessToken struct { appID string appSecret string + proxyUrl string cacheKeyPrefix string cache cache.Cache accessTokenLock *sync.Mutex } // NewDefaultAccessToken new DefaultAccessToken -func NewDefaultAccessToken(appID, appSecret, cacheKeyPrefix string, cache cache.Cache) AccessTokenHandle { +func NewDefaultAccessToken(appID, appSecret, proxyUrl, cacheKeyPrefix string, cache cache.Cache) AccessTokenHandle { if cache == nil { panic("cache is ineed") } return &DefaultAccessToken{ appID: appID, appSecret: appSecret, + proxyUrl: proxyUrl, cache: cache, cacheKeyPrefix: cacheKeyPrefix, accessTokenLock: new(sync.Mutex), @@ -73,7 +75,7 @@ func (ak *DefaultAccessToken) GetAccessToken() (accessToken string, err error) { // cache失效,从微信服务器获取 var resAccessToken ResAccessToken - resAccessToken, err = GetTokenFromServer(fmt.Sprintf(accessTokenURL, ak.appID, ak.appSecret)) + resAccessToken, err = GetTokenFromServer(fmt.Sprintf(accessTokenURL, ak.appID, ak.appSecret), ak.proxyUrl) if err != nil { return } @@ -91,6 +93,7 @@ func (ak *DefaultAccessToken) GetAccessToken() (accessToken string, err error) { type WorkAccessToken struct { CorpID string CorpSecret string + ProxyUrl string `json:"proxyUrl"` // 代理url cacheKeyPrefix string cache cache.Cache accessTokenLock *sync.Mutex @@ -124,7 +127,7 @@ func (ak *WorkAccessToken) GetAccessToken() (accessToken string, err error) { // cache失效,从微信服务器获取 var resAccessToken ResAccessToken - resAccessToken, err = GetTokenFromServer(fmt.Sprintf(workAccessTokenURL, ak.CorpID, ak.CorpSecret)) + resAccessToken, err = GetTokenFromServer(fmt.Sprintf(workAccessTokenURL, ak.CorpID, ak.CorpSecret), ak.cacheKeyPrefix) if err != nil { return } @@ -139,13 +142,16 @@ func (ak *WorkAccessToken) GetAccessToken() (accessToken string, err error) { } // GetTokenFromServer 强制从微信服务器获取token -func GetTokenFromServer(url string) (resAccessToken ResAccessToken, err error) { - var body []byte - body, err = util.HTTPGet(url) +func GetTokenFromServer(url, proxyUrl string) (resAccessToken ResAccessToken, err error) { + client := req.C() + if proxyUrl != "" { + client.SetProxyURL(proxyUrl) + } + resp, err := client.R().Get(url) if err != nil { return } - err = json.Unmarshal(body, &resAccessToken) + err = resp.Unmarshal(&resAccessToken) if err != nil { return } diff --git a/go.mod b/go.mod index 24f8bf12f..e07451b1b 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d github.com/fatih/structs v1.1.0 github.com/go-redis/redis/v8 v8.11.6-0.20220405070650-99c79f7041fc + github.com/imroc/req/v3 v3.10.0 github.com/sirupsen/logrus v1.8.1 github.com/spf13/cast v1.4.1 github.com/stretchr/testify v1.7.1 diff --git a/go.sum b/go.sum index 5d577c283..bad97d059 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,14 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imroc/req/v3 v3.10.0 h1:/42KsvCdtGK/5I2t3BB2ztA/8+alLMqu3ilzpmlB7Pk= +github.com/imroc/req/v3 v3.10.0/go.mod h1:G6fkq27P+JcTcgRVxecxY+amHN1xFl8W81eLCfJ151M= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -80,6 +86,7 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -133,9 +140,4 @@ gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaD gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v2 v2.2 \ No newline at end of file diff --git a/miniprogram/config/config.go b/miniprogram/config/config.go index c2d888e0c..c3fbaef83 100644 --- a/miniprogram/config/config.go +++ b/miniprogram/config/config.go @@ -2,12 +2,10 @@ package config import ( - "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/core" ) // Config .config for 小程序 type Config struct { - AppID string `json:"app_id"` // appid - AppSecret string `json:"app_secret"` // appsecret - Cache cache.Cache + *core.Config } diff --git a/miniprogram/miniprogram.go b/miniprogram/miniprogram.go index d76d7c243..792fd059c 100644 --- a/miniprogram/miniprogram.go +++ b/miniprogram/miniprogram.go @@ -29,7 +29,7 @@ type MiniProgram struct { // NewMiniProgram 实例化小程序API func NewMiniProgram(cfg *config.Config) *MiniProgram { - defaultAkHandle := credential.NewDefaultAccessToken(cfg.AppID, cfg.AppSecret, credential.CacheKeyMiniProgramPrefix, cfg.Cache) + defaultAkHandle := credential.NewDefaultAccessToken(cfg.AppID, cfg.AppSecret, cfg.ProxyUrl, credential.CacheKeyMiniProgramPrefix, cfg.Cache) ctx := &context.Context{ Config: cfg, AccessTokenHandle: defaultAkHandle, diff --git a/officialaccount/config/config.go b/officialaccount/config/config.go index b38fccec9..e98dd5767 100644 --- a/officialaccount/config/config.go +++ b/officialaccount/config/config.go @@ -1,14 +1,12 @@ package config import ( - "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/core" ) // Config .config for 微信公众号 type Config struct { - AppID string `json:"app_id"` // appid - AppSecret string `json:"app_secret"` // appsecret + *core.Config Token string `json:"token"` // token EncodingAESKey string `json:"encoding_aes_key"` // EncodingAESKey - Cache cache.Cache } diff --git a/officialaccount/officialaccount.go b/officialaccount/officialaccount.go index 3aecce85f..9f8475c2d 100644 --- a/officialaccount/officialaccount.go +++ b/officialaccount/officialaccount.go @@ -31,7 +31,7 @@ type OfficialAccount struct { // NewOfficialAccount 实例化公众号API func NewOfficialAccount(cfg *config.Config) *OfficialAccount { - defaultAkHandle := credential.NewDefaultAccessToken(cfg.AppID, cfg.AppSecret, credential.CacheKeyOfficialAccountPrefix, cfg.Cache) + defaultAkHandle := credential.NewDefaultAccessToken(cfg.AppID, cfg.AppSecret, cfg.ProxyUrl, credential.CacheKeyOfficialAccountPrefix, cfg.Cache) ctx := &context.Context{ Config: cfg, AccessTokenHandle: defaultAkHandle, diff --git a/officialaccount/user/tag.go b/officialaccount/user/tag.go index 3a61c5dac..06b1fae8e 100644 --- a/officialaccount/user/tag.go +++ b/officialaccount/user/tag.go @@ -1,7 +1,6 @@ package user import ( - "encoding/json" "fmt" "github.com/silenceper/wechat/v2/util" @@ -42,14 +41,13 @@ func (user *User) CreateTag(tagName string) (tagInfo *TagInfo, err error) { return } uri := fmt.Sprintf(tagCreateURL, accessToken) - var response []byte var request struct { Tag struct { Name string `json:"name"` } `json:"tag"` } request.Tag.Name = tagName - response, err = util.PostJSON(uri, &request) + response, err := user.Req().SetBody(&request).Post(uri) if err != nil { return } @@ -57,7 +55,7 @@ func (user *User) CreateTag(tagName string) (tagInfo *TagInfo, err error) { util.CommonError Tag *TagInfo `json:"tag"` } - err = json.Unmarshal(response, &result) + err = response.Unmarshal(&result) if err != nil { return } @@ -81,11 +79,11 @@ func (user *User) DeleteTag(tagID int32) (err error) { } `json:"tag"` } request.Tag.ID = tagID - resp, err := util.PostJSON(url, &request) + resp, err := user.Req().SetBody(&request).Post(url) if err != nil { return } - return util.DecodeWithCommonError(resp, "DeleteTag") + return util.DecodeWithCommonError(resp.Bytes(), "DeleteTag") } // UpdateTag 编辑标签 @@ -103,11 +101,11 @@ func (user *User) UpdateTag(tagID int32, tagName string) (err error) { } request.Tag.ID = tagID request.Tag.Name = tagName - resp, err := util.PostJSON(url, &request) + resp, err := user.Req().SetBody(&request).Post(url) if err != nil { return } - return util.DecodeWithCommonError(resp, "UpdateTag") + return util.DecodeWithCommonError(resp.Bytes(), "UpdateTag") } // GetTag 获取公众号已创建的标签 @@ -117,7 +115,7 @@ func (user *User) GetTag() (tags []*TagInfo, err error) { return nil, err } url := fmt.Sprintf(tagGetURL, accessToken) - response, err := util.HTTPGet(url) + response, err := user.Req().Get(url) if err != nil { return } @@ -125,7 +123,7 @@ func (user *User) GetTag() (tags []*TagInfo, err error) { util.CommonError Tags []*TagInfo `json:"tags"` } - err = json.Unmarshal(response, &result) + err = response.Unmarshal(&result) if err != nil { return } @@ -148,12 +146,12 @@ func (user *User) OpenIDListByTag(tagID int32, nextOpenID ...string) (userList * if len(nextOpenID) > 0 { request.OpenID = nextOpenID[0] } - response, err := util.PostJSON(url, &request) + response, err := user.Req().SetBody(&request).Post(url) if err != nil { return nil, err } userList = new(TagOpenIDList) - err = json.Unmarshal(response, &userList) + err = response.Unmarshal(&userList) if err != nil { return } @@ -177,11 +175,11 @@ func (user *User) BatchTag(openIDList []string, tagID int32) (err error) { TagID: tagID, } url := fmt.Sprintf(tagBatchtaggingURL, accessToken) - resp, err := util.PostJSON(url, &request) + resp, err := user.Req().SetBody(&request).Post(url) if err != nil { return } - return util.DecodeWithCommonError(resp, "BatchTag") + return util.DecodeWithCommonError(resp.Bytes(), "BatchTag") } // BatchUntag 批量为用户取消标签 @@ -201,11 +199,11 @@ func (user *User) BatchUntag(openIDList []string, tagID int32) (err error) { OpenIDList: openIDList, TagID: tagID, } - resp, err := util.PostJSON(url, &request) + resp, err := user.Req().SetBody(&request).Post(url) if err != nil { return } - return util.DecodeWithCommonError(resp, "BatchUntag") + return util.DecodeWithCommonError(resp.Bytes(), "BatchUntag") } // UserTidList 获取用户身上的标签列表 @@ -221,7 +219,7 @@ func (user *User) UserTidList(openID string) (tagIDList []int32, err error) { }{ OpenID: openID, } - resp, err := util.PostJSON(url, &request) + resp, err := user.Req().SetBody(&request).Post(url) if err != nil { return } @@ -229,7 +227,7 @@ func (user *User) UserTidList(openID string) (tagIDList []int32, err error) { util.CommonError TagIDList []int32 `json:"tagid_list"` } - err = json.Unmarshal(resp, &result) + err = resp.UnmarshalJson(&result) if err != nil { return } diff --git a/openplatform/config/config.go b/openplatform/config/config.go index 98e7c4eba..511a88a3d 100644 --- a/openplatform/config/config.go +++ b/openplatform/config/config.go @@ -1,14 +1,12 @@ package config import ( - "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/core" ) // Config .config for 微信开放平台 type Config struct { - AppID string `json:"app_id"` // appid - AppSecret string `json:"app_secret"` // appsecret + *core.Config Token string `json:"token"` // token EncodingAESKey string `json:"encoding_aes_key"` // EncodingAESKey - Cache cache.Cache } diff --git a/openplatform/officialaccount/officialaccount.go b/openplatform/officialaccount/officialaccount.go index c5fd09bdf..03ba778f2 100644 --- a/openplatform/officialaccount/officialaccount.go +++ b/openplatform/officialaccount/officialaccount.go @@ -19,12 +19,13 @@ type OfficialAccount struct { // NewOfficialAccount 实例化 // appID :为授权方公众号 APPID,非开放平台第三方平台 APPID func NewOfficialAccount(opCtx *opContext.Context, appID string) *OfficialAccount { - officialAccount := officialaccount.NewOfficialAccount(&offConfig.Config{ - AppID: opCtx.AppID, + cfg := &offConfig.Config{ EncodingAESKey: opCtx.EncodingAESKey, Token: opCtx.Token, - Cache: opCtx.Cache, - }) + } + cfg.AppID = opCtx.AppID + cfg.Cache = opCtx.Cache + officialAccount := officialaccount.NewOfficialAccount(cfg) // 设置获取access_token的函数 officialAccount.SetAccessTokenHandle(NewDefaultAuthrAccessToken(opCtx, appID)) return &OfficialAccount{appID: appID, OfficialAccount: officialAccount} diff --git a/work/config/config.go b/work/config/config.go index 84aef7cb5..4955486ad 100644 --- a/work/config/config.go +++ b/work/config/config.go @@ -2,15 +2,15 @@ package config import ( - "github.com/silenceper/wechat/v2/cache" + "github.com/silenceper/wechat/v2/core" ) // Config for 企业微信 type Config struct { + *core.Config CorpID string `json:"corp_id"` // corp_id CorpSecret string `json:"corp_secret"` // corp_secret,如果需要获取会话存档实例,当前参数请填写聊天内容存档的Secret,可以在企业微信管理端--管理工具--聊天内容存档查看 AgentID string `json:"agent_id"` // agent_id - Cache cache.Cache RasPrivateKey string // 消息加密私钥,可以在企业微信管理端--管理工具--消息加密公钥查看对用公钥,私钥一般由自己保存 Token string `json:"token"` // 微信客服回调配置,用于生成签名校验回调请求的合法性