// WxReceiveCommonMsg 接收普通消息
type WxReceiveCommonMsg struct {
ToUserName string //接收者 开发者 微信号
FromUserName string //发送者 发送方帐号(一个OpenID)
Content string //文本内容
CreateTime int64 //创建时间
MsgType string //消息类型
MsgId int64 //消息id
PicUrl string //图片url
MediaId string //媒体id
Event string //事件类型,VIEW
EventKey string //事件KEY值,设置的跳转URL
MenuId string
Format string
Recognition string
ThumbMediaId string //缩略图媒体ID
}
// WxReceiveFunc (接收到消息之后,会将消息交于这个函数处理)
var WxReceiveFunc func(msg WxReceiveCommonMsg) error
// WxMakeSign 计算签名
func WxMakeSign(token, timestamp, nonce string) string {
strs := []string{token, timestamp, nonce}
sort.Strings(strs)
sha := sha1.New()
io.WriteString(sha, strings.Join(strs, ""))
return fmt.Sprintf("%x", sha.Sum(nil))
}
// WxGetAccessToken 获取微信accesstoken
func WxGetAccessToken() string {
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%v&secret=%v", APPID, APPSECRET)
resp, err := http.Get(url)
if err != nil {
fmt.Println("获取微信token失败", err)
return ""
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("微信token读取失败", err)
return ""
}
token := token{}
err = json.Unmarshal(body, &token)
if err != nil {
fmt.Println("微信token解析json失败", err)
return ""
}
return token.AccessToken
}
// WxGetUserList 获取关注者列表
func WxGetUserList(accessToken string) []gjson.Result {
url := "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" + accessToken + "&next_openid="
resp, err := http.Get(url)
if err != nil {
fmt.Println("获取关注列表失败", err)
return nil
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取内容失败", err)
return nil
}
flist := gjson.Get(string(body), "data.openid").Array()
return flist
}
// WxPostTemplate 发送模板消息
func WxPostTemplate(accessToken string, reqdata string, fxurl string, templateid string, openid string) {
url := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken
reqbody := "{\"touser\":\"" + openid + "\", \"template_id\":\"" + templateid + "\", \"url\":\"" + fxurl + "\", \"data\": " + reqdata + "}"
fmt.Printf("WxPostTemplate:%#v\n", reqbody)
resp, err := http.Post(url,
"application/x-www-form-urlencoded",
strings.NewReader(string(reqbody)))
if err != nil {
fmt.Println(err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}
// ReceiveCommonMsg
func ReceiveCommonMsg(msgData []byte) (WxReceiveCommonMsg, error) {
fmt.Printf("received weixin msgData:\n%s\n", msgData)
msg := WxReceiveCommonMsg{}
err := xml.Unmarshal(msgData, &msg)
if WxReceiveFunc == nil {
return msg, err
}
err = WxReceiveFunc(msg)
return msg, err
}
// WxCreateMenu 创建菜单
func WxCreateMenu(accessToken, menustr string) (string, error) {
url := "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + accessToken
fmt.Printf("WxCreateMenu:%s\n", menustr)
resp, err := http.Post(url,
"application/x-www-form-urlencoded",
strings.NewReader(menustr))
if err != nil {
fmt.Println(err)
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return "", err
}
fmt.Println(string(body))
return string(body), nil
}
// WxDelMenu 删除菜单
func WxDelMenu(accessToken string) (string, error) {
url := "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=" + accessToken
resp, err := http.Get(url)
if err != nil {
fmt.Println("删除菜单失败", err)
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取内容失败", err)
return "", err
}
fmt.Println(string(body))
return string(body), nil
}
// WxGetUserInfo 根据用户openid获取基本信息
func WxGetUserInfo(accessToken, openid string) (string, error) {
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=zh_CN", accessToken, openid)
fmt.Println(url)
resp, err := http.Get(url)
if err != nil {
fmt.Println("获取信息失败", err)
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取内容失败", err)
return "", err
}
fmt.Println(string(body))
return string(body), nil
}
// WxGetOpenidByCode 微信前端页面授权之后,会给前端页面路由里带一个code
func WxGetOpenidByCode(code string) (string, error) {
url := fmt.Sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", APPID, APPSECRET, code)
resp, err := http.Get(url)
if err != nil {
fmt.Println("获取openid失败", err)
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println("读取内容失败", err)
return "", err
}
fmt.Println(string(body))
return string(body), nil
}
// web API接口
// HandleWxLogin首次接入,成为开发者
func HandleWxLogin(c *gin.Context) {
fmt.Printf("==>HandleWxLogin\n")
echostr := c.DefaultQuery("echostr", "")
if echostr != "" {
fmt.Printf("==>echostr:%s\n", echostr)
c.String(200, "%s", echostr)
return
}
}
// HandleWxPostRecv 处理微信公众号前端发起的消息事件
func HandleWxPostRecv(c *gin.Context) {
fmt.Printf("==>HandleWxPostRecv Enter\n")
data, err := c.GetRawData()
if err != nil {
log.Fatalln(err)
}
ReceiveCommonMsg(data)
}
// HandleWxGetOpenid
func HandleWxGetOpenid(c *gin.Context) {
fmt.Printf("==>HandleWxGetOpenid Enter\n")
code := c.Query("code")
result, err := WxGetOpenidByCode(code)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": -1,
"msg": "获取openid失败" + err.Error(),
})
return
}
//WxDelMenu(accessToken)
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "成功",
"data": result,
})
}
// HandleWxGetUserInfo 根据前端请求来的openid获取用户信息
func HandleWxGetUserInfo(c *gin.Context) {
fmt.Printf("==>HandleWxGetUserInfo Enter\n")
opid := c.Query("openid")
fmt.Printf("openid:%s\n", opid)
token := WxGetAccessToken()
result, err := WxGetUserInfo(token, opid)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"code": -1,
"msg": "获取用户信息失败" + err.Error(),
})
return
}
//WxDelMenu(accessToken)
c.JSON(http.StatusOK, gin.H{
"code": 0,
"msg": "成功",
"data": result,
})
}
func init() {
}