mp.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package mp
  2. import (
  3. "errors"
  4. "fmt"
  5. "io/ioutil"
  6. "net/http"
  7. "net/url"
  8. "time"
  9. "zhiyuan/models"
  10. "zhiyuan/pkg/app"
  11. "zhiyuan/pkg/config"
  12. "zhiyuan/pkg/utils"
  13. "zhiyuan/services/form"
  14. "zhiyuan/services/weixin"
  15. )
  16. type Client struct {
  17. Account *models.Weixin
  18. }
  19. func NewClient(wxID int) (*Client, error) {
  20. weixinInfo, _ := weixin.GetOne(map[string]interface{}{"id": wxID}, nil, nil)
  21. return &Client{
  22. Account: weixinInfo,
  23. }, nil
  24. }
  25. func (c *Client) GetAccessToken() (string, error) {
  26. rc, err := utils.HttpGet(&http.Client{}, config.Cfg.App.ProductionUrl+"api/weixin/access_token/"+utils.ToStr(c.Account.ID), nil)
  27. if err != nil {
  28. return "", err
  29. }
  30. p, err := ioutil.ReadAll(rc)
  31. if err != nil {
  32. return "", err
  33. }
  34. var response app.ResponseData
  35. utils.JsonDecode(p).To(&response)
  36. if response.Code != 200 {
  37. return "", errors.New(response.Msg)
  38. }
  39. return utils.ToStr(response.Data.(map[string]interface{})["access_token"]), nil
  40. }
  41. func (c *Client) RefreshAccessToken() AccessTokenResponse {
  42. currentTime := utils.ToInt(time.Now().Unix())
  43. if c.Account.AccessToken != "" && c.Account.AccessTokenExpiresIn > 0 && currentTime < c.Account.AccessTokenExpiresIn+c.Account.AccessTokenUpdatedAt {
  44. return AccessTokenResponse{
  45. AccessToken: c.Account.AccessToken,
  46. ExpiresIn: c.Account.AccessTokenExpiresIn,
  47. }
  48. }
  49. baseUrl := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
  50. url := fmt.Sprintf(baseUrl, c.Account.AppID, c.Account.AppSecret)
  51. rc, err := utils.HttpGet(&http.Client{}, url, nil)
  52. if err != nil {
  53. return AccessTokenResponse{ErrCode: 1, ErrMsg: "http get error"}
  54. }
  55. p, err := ioutil.ReadAll(rc)
  56. if err != nil {
  57. return AccessTokenResponse{ErrCode: 1, ErrMsg: "http read error"}
  58. }
  59. var response AccessTokenResponse
  60. utils.JsonDecode(p).To(&response)
  61. if response.AccessToken != "" && response.ErrCode == 0 {
  62. weixinForm := form.WeixinEditToken{
  63. AccessToken: response.AccessToken,
  64. AccessTokenExpiresIn: response.ExpiresIn,
  65. }
  66. weixin.EditToken(weixinForm, c.Account.ID)
  67. }
  68. return response
  69. }
  70. func (c *Client) GetOauthUrl(scope string, retUrl string) (string, error) {
  71. baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=" + scope + "&state=STATE#wechat_redirect"
  72. url := fmt.Sprintf(baseUrl, c.Account.AppID, url.QueryEscape(config.Cfg.App.ProductionUrl+retUrl))
  73. return url, nil
  74. }
  75. func (c *Client) GetOauthUrls(scope string, retUrl string) (string, error) {
  76. baseUrl := "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=" + scope + "&state=STATE#wechat_redirect"
  77. url := fmt.Sprintf(baseUrl, c.Account.AppID, url.QueryEscape(retUrl))
  78. return url, nil
  79. }
  80. func (c *Client) GetOauthToken(code string) OauthTokenResponse {
  81. baseUrl := "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
  82. url := fmt.Sprintf(baseUrl, c.Account.AppID, c.Account.AppSecret, code)
  83. rc, err := utils.HttpGet(&http.Client{}, url, nil)
  84. if err != nil {
  85. return OauthTokenResponse{ErrCode: 1, ErrMsg: "http get error"}
  86. }
  87. p, err := ioutil.ReadAll(rc)
  88. if err != nil {
  89. return OauthTokenResponse{ErrCode: 1, ErrMsg: "http read error"}
  90. }
  91. var response OauthTokenResponse
  92. utils.JsonDecode(p).To(&response)
  93. return response
  94. }
  95. func (c *Client) GetUserInfo(accessToken string, openid string) UserInfo {
  96. baseUrl := "https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN"
  97. url := fmt.Sprintf(baseUrl, accessToken, openid)
  98. rc, err := utils.HttpGet(&http.Client{}, url, nil)
  99. if err != nil {
  100. return UserInfo{ErrCode: 1, ErrMsg: "http get error"}
  101. }
  102. p, err := ioutil.ReadAll(rc)
  103. if err != nil {
  104. return UserInfo{ErrCode: 1, ErrMsg: "http read error"}
  105. }
  106. var response UserInfo
  107. utils.JsonDecode(p).To(&response)
  108. return response
  109. }
  110. func (c *Client) GetJsTicket() (string, error) {
  111. rc, err := utils.HttpGet(&http.Client{}, config.Cfg.App.ProductionUrl+"api/weixin/jsapi_ticket/"+utils.ToStr(c.Account.ID), nil)
  112. fmt.Println(config.Cfg.App.ProductionUrl + "api/weixin/jsapi_ticket/" + utils.ToStr(c.Account.ID))
  113. p, err := ioutil.ReadAll(rc)
  114. if err != nil {
  115. return "", err
  116. }
  117. var response app.ResponseData
  118. utils.JsonDecode(p).To(&response)
  119. if response.Code != 200 {
  120. return "", errors.New(response.Msg)
  121. }
  122. return utils.ToStr(response.Data.(map[string]interface{})["ticket"]), nil
  123. }
  124. func (c *Client) RefreshJsapiTicket() JsapiTicketResponse {
  125. currentTime := utils.ToInt(time.Now().Unix())
  126. if c.Account.JsapiTicket != "" && c.Account.JsapiTicketExpiresIn > 0 && currentTime < c.Account.JsapiTicketExpiresIn+c.Account.JsapiTicketUpdatedAt {
  127. return JsapiTicketResponse{
  128. Ticket: c.Account.JsapiTicket,
  129. ExpiresIn: c.Account.JsapiTicketExpiresIn,
  130. }
  131. }
  132. baseUrl := "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"
  133. accessToken, err := c.GetAccessToken()
  134. if err != nil {
  135. fmt.Println(err)
  136. return JsapiTicketResponse{ErrCode: 1, ErrMsg: "http get error"}
  137. }
  138. url := fmt.Sprintf(baseUrl, accessToken)
  139. fmt.Println(url)
  140. rc, err := utils.HttpGet(&http.Client{}, url, nil)
  141. if err != nil {
  142. return JsapiTicketResponse{ErrCode: 1, ErrMsg: "http get error"}
  143. }
  144. p, err := ioutil.ReadAll(rc)
  145. if err != nil {
  146. return JsapiTicketResponse{ErrCode: 1, ErrMsg: "http read error"}
  147. }
  148. var response JsapiTicketResponse
  149. utils.JsonDecode(p).To(&response)
  150. if response.Ticket != "" && response.ErrCode == 0 {
  151. weixinForm := form.WeixinEditJsapi{
  152. JsapiTicket: response.Ticket,
  153. JsapiTicketExpiresIn: response.ExpiresIn,
  154. }
  155. weixin.EditJsapi(weixinForm, c.Account.ID)
  156. }
  157. return response
  158. }
  159. func (c *Client) GetJsapiParam(requestUrl string) (JsapiReturn, error) {
  160. requestUrl, _ = url.QueryUnescape(requestUrl)
  161. nonceStr := utils.RandomStr()
  162. timestamp := time.Now().Unix()
  163. ticket, err := c.GetJsTicket()
  164. if err != nil {
  165. return JsapiReturn{}, err
  166. }
  167. formatStr := "jsapi_ticket=%s&noncestr=%s&timestamp=%s&url=%s"
  168. formatStr = fmt.Sprintf(formatStr, ticket, nonceStr, utils.ToStr(timestamp), requestUrl)
  169. fmt.Println(formatStr)
  170. return JsapiReturn{
  171. AppID: c.Account.AppID,
  172. NonceStr: nonceStr,
  173. Timestamp: utils.ToInt(timestamp),
  174. Signature: utils.SHA1(formatStr),
  175. }, nil
  176. }
  177. func (c *Client) SendTemplateMessage(touser string, template_id string, url string, data map[string]interface{}) (interface{}, error) {
  178. baseUrl := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s&type=jsapi"
  179. accessToken, err := c.GetAccessToken()
  180. if err != nil {
  181. return nil, err
  182. }
  183. urls := fmt.Sprintf(baseUrl, accessToken)
  184. datas := map[string]interface{}{
  185. "touser": touser,
  186. "template_id": template_id,
  187. "data": data,
  188. }
  189. if url != "" {
  190. datas["url"] = url
  191. }
  192. var ret interface{}
  193. err = utils.HttpPostJSON(&http.Client{}, urls, http.Header{}, datas, &ret)
  194. if err != nil {
  195. return nil, err
  196. }
  197. return ret, err
  198. }