Browse Source

增加调用微信接口方法

master
guzeng 2 years ago
parent
commit
69b162d825
10 changed files with 576 additions and 0 deletions
  1. +39
    -0
      access_token.go
  2. +13
    -0
      access_token_test.go
  3. +5
    -0
      go.mod
  4. +15
    -0
      go.sum
  5. +127
    -0
      http.go
  6. +54
    -0
      message.go
  7. +63
    -0
      openid.go
  8. +77
    -0
      qrcode.go
  9. +159
    -0
      security_check.go
  10. +24
    -0
      url.go

+ 39
- 0
access_token.go View File

@ -0,0 +1,39 @@
package wechat
import (
"fmt"
"log"
)
/**
* 从微信api取access_token
*/
func GetAccessToken(appid, secret string) (wx_access_token_res, error) {
url := fmt.Sprintf(ACCESS_TOKEN_API, appid, secret)
data_byte, err := SendHttp("GET", url, nil)
type wx_access_token_res struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
var data wx_access_token_res
if err == nil {
err = json.Unmarshal(data_byte, &data)
if err != nil {
log.Println("get access token from WX api error:", err)
}
if data.Errcode != 0 {
log.Println("get access token from WX api fail:", data.Errcode, data.Errmsg)
}
}
return data, err
}

+ 13
- 0
access_token_test.go View File

@ -0,0 +1,13 @@
package wechat
import (
"testing"
)
func Test_GetAccessToken(t *testing.T) {
appid := "wxe2a6548a7ff2e558"
appsecret := "51aa4769025bd2c203b0e811b7063e1b"
ret, err := GetAccessToken(appid, appsecret)
t.Log(ret)
t.Log(err)
}

+ 5
- 0
go.mod View File

@ -0,0 +1,5 @@
module git.tetele.net/tgo/wechat
go 1.16
require github.com/json-iterator/go v1.1.12

+ 15
- 0
go.sum View File

@ -0,0 +1,15 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=

+ 127
- 0
http.go View File

@ -0,0 +1,127 @@
package wechat
import (
"bytes"
"encoding/xml"
"io/ioutil"
"net/http"
"strings"
)
/**
* 自定义HTTP请求
*/
func SendHttp(method, url string, param map[string]string, header ...map[string]string) ([]byte, error) {
httpClient := &http.Client{}
paramStr := ""
if len(param) > 0 {
for key, value := range param {
paramStr += key + "=" + value + "&"
}
paramStr = paramStr[0 : len(paramStr)-1]
}
req, err := http.NewRequest(method, url, strings.NewReader(paramStr))
if err != nil {
return []byte(""), err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if len(header) > 0 {
for _, item := range header {
for k, v := range item {
req.Header.Set(k, v)
}
}
}
resp, err := httpClient.Do(req)
if err != nil {
return []byte(""), err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte(""), err
}
return body, nil
}
/**
* send xml
*/
func SendXml(method, url string, requestxml interface{}, header ...map[string]string) ([]byte, error) {
bytexml, err := xml.Marshal(&requestxml)
if err != nil {
return []byte(""), err
}
httpClient := &http.Client{}
req, err := http.NewRequest(method, url, bytes.NewBuffer(bytexml))
if err != nil {
return []byte(""), err
}
req.Header.Add("Content-Type", "application/xml; charset=utf-8")
if len(header) > 0 {
for _, item := range header {
for k, v := range item {
req.Header.Add(k, v)
}
}
}
resp, err := httpClient.Do(req)
if err != nil {
return []byte(""), err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte(""), err
}
return body, nil
}
/**
* post 请求
*/
func PostJson(url string, param []byte, header ...map[string]string) ([]byte, error) {
httpClient := &http.Client{}
req, err := http.NewRequest("POST", url, bytes.NewBuffer(param))
if err != nil {
return []byte(""), err
}
req.Header.Set("Content-Type", "application/json")
if len(header) > 0 {
for _, item := range header {
for k, v := range item {
req.Header[k] = []string{v}
}
}
}
resp, err := httpClient.Do(req)
if err != nil {
return []byte(""), err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return []byte(""), err
}
return body, nil
}

+ 54
- 0
message.go View File

@ -0,0 +1,54 @@
package wechat
import (
"fmt"
"log"
)
//发送订阅消息返回结果
type SendSubscribeMessageData struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
//发送统一消息返回结果
type SendUniformMessageData struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
func SendSubscribeMessage(access_token string, message []byte) (SendSubscribeMessageData, error) {
url := fmt.Sprintf(MINIAPP_SUBSCRIBE_MESSAGE_SEND_API, access_token)
ret, err := PostJson(url, message)
var data SendSubscribeMessageData
if err != nil {
return data, err
}
err = json.Unmarshal(ret, &data)
return data, err
}
func SendUniformMessage(access_token string, message []byte) (SendUniformMessageData, error) {
url := fmt.Sprintf(MINIAPP_UNIFORM_MESSAGE_API, access_token)
ret, err := PostJson(url, message)
var data SendUniformMessageData
if err != nil {
return data, err
}
err = json.Unmarshal(ret, &data)
return data, err
}

+ 63
- 0
openid.go View File

@ -0,0 +1,63 @@
package wechat
import (
"fmt"
)
type AppOpenIdData struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Openid string `json:"openid"`
Scope string `json:"scope"`
Unionid interface{} `json:"unionid"`
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
type MiniAppOpenidData struct {
Openid string `json:"openid"`
SessionKey interface{} `json:"session_key"`
Unionid interface{} `json:"unionid"`
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
/**
* 从微信api取openid
*/
func GetAppOpenid(appid, secret, code string) (AppOpenIdData, error) {
var data AppOpenIdData
url := fmt.Sprintf(GET_APP_OPENID, appid, secret, code)
data_byte, err := SendHttp("GET", url, nil)
if err != nil {
return data, err
}
err = json.Unmarshal(data_byte, &data)
return data, err
}
/**
* 从微信api取openid
*/
func GetMiniAppOpenid(appid, secret, code string) (MiniAppOpenidData, error) {
url := fmt.Sprintf(GET_MINIAPP_OPENID_API, appid, secret, code)
data_byte, err := SendHttp("GET", url, nil)
var data MiniAppOpenidData
if err != nil {
return data, err
}
err = json.Unmarshal(data_byte, &data)
return data, err
}

+ 77
- 0
qrcode.go View File

@ -0,0 +1,77 @@
package wechat
import (
"encoding/base64"
"errors"
"fmt"
"log"
"git.tetele.net/tgo/helper"
"git.tetele.net/tgo/network"
)
// 获取小程序码
func GetMiniappQrcode(access_token string, qrcodeParamsMap map[string]interface{}) (string, error) {
getCodeUrl := fmt.Sprintf(GET_MINIAPP_QRCODE, access_token)
checkPath := true
envVersion := "release"
width := 430
autoColor := false
isHyaline := false
if _, exist := qrcodeParamsMap["check_path"]; exist {
checkPath = qrcodeParamsMap["check_path"].(bool)
}
if _, exist := qrcodeParamsMap["env_version"]; exist {
envVersion = helper.ToStr(qrcodeParamsMap["env_version"])
}
if _, exist := qrcodeParamsMap["width"]; exist {
width = helper.ToInt(qrcodeParamsMap["width"])
}
if _, exist := qrcodeParamsMap["auto_color"]; exist {
autoColor = qrcodeParamsMap["auto_color"].(bool)
}
if _, exist := qrcodeParamsMap["is_hyaline"]; exist {
isHyaline = qrcodeParamsMap["is_hyaline"].(bool)
}
requestData := map[string]interface{}{
"scene": qrcodeParamsMap["scene"],
"page": qrcodeParamsMap["page"],
"check_path": checkPath,
"env_version": envVersion,
"width": width,
"auto_color": autoColor,
"is_hyaline": isHyaline,
}
requestDataJson, err := json.Marshal(requestData)
if err != nil {
return "", err
}
response, err := PostJson(getCodeUrl, requestDataJson)
if err != nil {
return "", err
}
responseData := map[string]interface{}{}
err = json.Unmarshal(response, &responseData)
if err != nil {
// 有错,但能解析
log.Println(err)
}
if _, exist := responseData["errcode"]; exist && helper.ToInt(responseData["errcode"]) != 0 {
return "", errors.New(helper.ToStr(responseData["errmsg"]))
}
return "data:image/png;base64," + base64.StdEncoding.EncodeToString(response), nil
}

+ 159
- 0
security_check.go View File

@ -0,0 +1,159 @@
package wechat
import (
"bytes"
"errors"
"fmt"
"io/ioutil"
"log"
"mime/multipart"
"net/http"
"git.tetele.net/tgo/helper"
)
//检测图片内容是否合规
func ImgSecCheck(access_token, imgUrl string) error {
var err error
checkUrl := "https://api.weixin.qq.com/wxa/img_sec_check?access_token=%s"
checkUrl = fmt.Sprintf(checkUrl, access_token)
imgResponse, err := http.Get(imgUrl) //获取图片
if err != nil {
return err
}
defer imgResponse.Body.Close()
if imgResponse.StatusCode != 200 {
return errors.New("resp status:" + fmt.Sprint(imgResponse.StatusCode))
}
buf := new(bytes.Buffer)
w := multipart.NewWriter(buf)
bin, err := ioutil.ReadAll(imgResponse.Body)
if err != nil {
fmt.Println(err)
return err
}
fw, err := w.CreateFormFile("media", "fijgrpgpegjrepoikr")
if err != nil {
fmt.Println(err)
return err
}
_, err = fw.Write(bin)
if err != nil {
fmt.Println(err)
return err
}
w.Close()
req, err := http.NewRequest("POST", checkUrl, buf)
if err != nil {
fmt.Println("req err: ", err)
return err
}
req.Header.Set("Content-Type", w.FormDataContentType())
checkResponse, err := http.DefaultClient.Do(req)
if err != nil {
fmt.Println("resp err: ", err)
return err
}
defer checkResponse.Body.Close()
if checkResponse.StatusCode != 200 {
return errors.New("resp status:" + fmt.Sprint(checkResponse.StatusCode))
}
response, err := ioutil.ReadAll(checkResponse.Body)
if err != nil {
return err
}
responseData := map[string]interface{}{}
err = json.Unmarshal(response, &responseData)
if err != nil {
// 有错,但能解析
log.Println(err)
}
if _, exist := responseData["errcode"]; exist && helper.ToInt(responseData["errcode"]) != 0 {
return errors.New(helper.ToStr(responseData["errmsg"]))
}
return nil
}
//检测文本内容是否合规
func MsgSecCheck(access_token string, data map[string]interface{}, retry ...int) error {
var err error
data["version"] = 2
checkUrl := "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=%s"
checkUrl = fmt.Sprintf(checkUrl, access_token)
requestDataJson, err := json.Marshal(data)
if err != nil {
return err
}
response, err := PostJson(checkUrl, requestDataJson)
if err != nil {
return err
}
responseData := map[string]interface{}{}
err = json.Unmarshal(response, &responseData)
if err != nil {
// 有错,但能解析
log.Println(err)
}
if _, exist := responseData["errcode"]; exist && helper.ToInt(responseData["errcode"]) != 0 {
return errors.New(helper.ToStr(responseData["errmsg"]))
}
resultData, err := helper.InterfaceToMapInterface(responseData["result"])
if err != nil {
return err
}
if resultData["suggest"] != "pass" {
return errors.New("内容不能包含" + GetCheckContentByCode(helper.ToStr(resultData["label"])))
}
return nil
}
func GetCheckContentByCode(code string) string {
codeList := map[string]string{
"10001": "广告",
"20001": "时政",
"20002": "色情",
"20003": "辱骂",
"20006": "违法犯罪",
"20008": "欺诈",
"20012": "低俗",
"20013": "版权",
"21000": "其他",
}
return codeList[code]
}

+ 24
- 0
url.go View File

@ -0,0 +1,24 @@
package wechat
import (
"github.com/json-iterator/go"
)
var json = jsoniter.ConfigCompatibleWithStandardLibrary
//获取access token
const ACCESS_TOKEN_API string = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
//小程序发送统一服务消息
const MINIAPP_UNIFORM_MESSAGE_API string = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=%s"
//小程序获取openid
const GET_MINIAPP_OPENID_API string = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
//小程序发送订阅消息
const MINIAPP_SUBSCRIBE_MESSAGE_SEND_API string = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s"
//app获取openid
const GET_APP_OPENID string = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
const GET_MINIAPP_QRCODE string = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"

Loading…
Cancel
Save