go语言微信公众号开发后台接口封装

简介: go语言微信公众号开发后台接口封装
+关注继续查看

个人整理的小功能,把微信公众号开发涉及的一些常用接口做了个封装。


业余时间做了个有意思的小功能,每天早上7点准时给发天气预报,每晚8点发布一条英语说说,提醒自己不能忘记学习。


封装实现的功能有:


开发者首次接入、


创建菜单、


删除菜单、


发送模板消息、


接收公众号前端推送、


获取Token,获取关注者信息,


获取用户个人信息,


根据code获取个人信息(微信前端第三方应用页面接入授权会涉及。)


这里再介绍下微信前端第三方应用如何获取微信个人openid和个人信息的功能实现思路。


如何在微信前端开发的应用界面,获取用户openid和个人信息呢?方法还是有的,思路靠谱。


就是文档里描述的那几步授权操作,先获取code,再跳转,后台获取在传给前端。


附代码封装:


// 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() {
}


每日一句,每天发布一条英语句子,接口如下:


/**
每日一句api接口
*/
package apis
 
import (
    "encoding/json"
    "fmt"
    "github.com/tidwall/gjson"
    "io/ioutil"
    "net/http"
    "weixin/wxapi"
)
 
// SentTemplateID 每日一句的模板ID
var SentTemplateID = "Xhh6e2zuKbTXlplpMezHLkHuNIF0X1_ScJT3K3hi4wg"
 
// sentence 句子结构
type sentence struct {
    Content     string `json:"content"`
    Note        string `json:"note"`
    Translation string `json:"translation"`
}
 
// GetSay 获取每日一句
func GetSay() (sentence, string) {
    resp, err := http.Get("http://open.iciba.com/dsapi/?date")
    sent := sentence{}
    if err != nil {
        fmt.Println("获取每日一句失败", err)
        return sent, ""
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("读取内容失败", err)
        return sent, ""
    }
 
    err = json.Unmarshal(body, &sent)
    if err != nil {
        fmt.Println("每日一句解析json失败")
        return sent, ""
    }
    fenxiangurl := gjson.Get(string(body), "fenxiang_img").String()
    fmt.Println(sent)
    return sent, fenxiangurl
}
 
//SendEverydaySay 发送每日一句
func SendEverydaySay() {
    req, fxurl := GetSay()
    if req.Content == "" {
        return
    }
    accessToken := wxapi.WxGetAccessToken()
    if accessToken == "" {
        return
    }
 
    flist := wxapi.WxGetUserList(accessToken)
    if flist == nil {
        return
    }
 
    reqdata := "{\"content\":{\"value\":\"" + req.Content + "\", \"color\":\"#0000CD\"}, \"note\":{\"value\":\"" + req.Note + "\"}, \"translation\":{\"value\":\"" + req.Translation + "\"}}"
    for _, v := range flist {
        wxapi.WxPostTemplate(accessToken, reqdata, fxurl, SentTemplateID, v.Str)
    }
}


image

相关文章
|
10天前
|
XML 移动开发 小程序
微信公众号开发(七)微信h5跳转小程序及小游戏示例
最近公司做活动,需要从h5页面跳转至微信小游戏。 当时接到这个需求的时候,就在想,这玩意能相互跳转么? 后来百度了一下,还真行。
23 1
|
10天前
|
XML JSON 小程序
微信公众号开发(四)获取用户信息
获取用户信息,微信公众号提供了两种方式:
17 0
|
10天前
|
小程序 PHP 开发者
微信公众号开发(八)生成带参数二维码,以及将二维码下载至本地
微信的二维码真是个神奇的东西。在我们开发中,应用也是很多~ 用户扫描带场景值(参数)二维码时,可能推送以下两种事件:
20 1
|
10天前
|
小程序 PHP
微信公众号开发(六)微信支付(发红包、企业支付到零钱)需要证书请求示例
这里最主要的就是curlpost请求的时候需要带上证书。否则请求会失败。
15 0
|
10天前
|
JSON 小程序 前端开发
微信公众号开发(三)设置底部菜单
填写access_token值,关于如何获取accesstoken值,请参见《微信公众号开发(二)微信公众号的access_token》 最后,将想要设置菜单的json写入body中。
14 0
|
2月前
|
安全 Go
Go语言封装艺术:代码安全与结构清晰
Go语言封装艺术:代码安全与结构清晰
24 0
|
2月前
|
SQL 安全 中间件
Go开发:如何封装函数来统计执行时间
Go开发:如何封装函数来统计执行时间
50 0
|
4月前
|
Go
Go 封装 mongo
Go 封装 mongo
89 0
|
4月前
|
Go
Go 定时任务方法封装
Go 定时任务方法封装
31 0
|
6月前
|
存储 消息中间件 JSON
LevelDB 存储模块 Go 语言封装及持久化队列实现
LevelDB 存储模块 Go 语言封装及持久化队列实现
相关产品
云迁移中心
推荐文章
更多