go语言微信公众号开发后台接口封装
时间:2022-07-22
本文章向大家介绍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:%#vn", 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%sn", 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:%sn", 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("==>HandleWxLoginn")
echostr := c.DefaultQuery("echostr", "")
if echostr != "" {
fmt.Printf("==>echostr:%sn", echostr)
c.String(200, "%s", echostr)
return
}
}
// HandleWxPostRecv 处理微信公众号前端发起的消息事件
func HandleWxPostRecv(c *gin.Context) {
fmt.Printf("==>HandleWxPostRecv Entern")
data, err := c.GetRawData()
if err != nil {
log.Fatalln(err)
}
ReceiveCommonMsg(data)
}
// HandleWxGetOpenid
func HandleWxGetOpenid(c *gin.Context) {
fmt.Printf("==>HandleWxGetOpenid Entern")
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 Entern")
opid := c.Query("openid")
fmt.Printf("openid:%sn", 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)
}
}
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Android使用多线程进行网络聊天室通信
- android实现banner轮播图无限轮播效果
- Android CheckBox中设置padding无效解决办法
- Android开发中使用颜色矩阵改变图片颜色,透明度及亮度的方法
- Android手势左右滑动效果
- Android开发实现根据包名判断App运行状态的方法
- Android实现朋友圈多图显示功能
- Android实现朋友圈评论回复列表
- android调用webservice接口获取信息
- RecyclerView嵌套RecyclerView完美实现京东tab吸顶效果
- Android使用SmsManager实现短信发送功能
- Kotlin结合Rxjava+Retrofit实现极简网络请求的方法
- 用Android Studio3.0新功能加快构建速度
- Android实现图片添加阴影效果的2种方法
- Android Webview与ScrollView的滚动兼容及留白处理的方法