GoFrame后端推送微信公众号消息☀
1. 申请微信公众号平台的测试号🌙
点开链接,微信登录,申请测试号,新建消息模板
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2. 获取access_token ⭐
// @Description 测试-获取token,并存redis
func (c *Register) GetToken(r *ghttp.Request) {
url := "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wx1******eb0&secret=c8a******0192e"
resp, err := http.Get(url)
if err != nil {
fmt.Println("错误")
response.FailJson(true, r, "上传失败,"+err.Error())
}
robots, err := ioutil.ReadAll(resp.Body)
fmt.Println("上传的响应值robots:", string(robots)) //{"access_token":"54_ipSu******CF","expires_in":7200}
js := gjson.New(string(robots)) //json解析成对象
access_token := gconv.String(js.Get("access_token"))
//存入缓存
current, err := wechat.GetAccessTokenFromCache("current_token")
err = wechat.SetAccessTokenFromCache("history_token", current)
if access_token != "" {
err = wechat.SetAccessTokenFromCache("current_token",access_token)
}
response.SusJson(true, r, "成功", string(robots))
}
存入/取出/更新Redis数据
func GetAccessTokenFromCache(key string) (string, error) {
current, err := g.Redis().Do("HGET", REDIS_KEY_WX_ACCESS_TOKEN, key)
return gconv.String(current), err
}
func SetAccessTokenFromCache(key string, value string) error {
_, err := g.Redis().Do("HSET", REDIS_KEY_WX_ACCESS_TOKEN, key, value)
return err
}
func UpdateAccessToken() (accessToken string, err error) {
accessTokenStrJson := GetAccessToken()
accessTokenJson := gjson.New(accessTokenStrJson)
if accessTokenJson.Get("access_token") != nil {
accessToken = gconv.String(accessTokenJson.Get("access_token"))
current, err := GetAccessTokenFromCache("current_token")
err = SetAccessTokenFromCache("history_token", current)
err = SetAccessTokenFromCache("current_token", accessToken)
if err != nil {
panic(err)
}
}
return
}
3. 准备数据,调用接口 ⭐
根据对应模板准备测试数据,再调用发送消息的 templatepost 方法
我这边只是单纯测试发送公众号消息,对于大家如何融入业务看你们各自的需求
func (c *Register) MsgTest(r *ghttp.Request) {
access_token, _ := wechat.GetAccessTokenFromCache("current_token")
fmt.Printf("access_token:%v", access_token)
data := g.Map{
"touser": "opNeu******drFs7w3c",
"template_id": "WtuN2ShCTNd9q******Djky79PH70",
"page": nil,
"form_id": nil,
"topcolor": "#FF0000",
"data":g.Map{
"first": g.Map{
"value":"恭喜你购买成功!",
"color":"#173177",
},
"keyword1":g.Map{
"value":"产品名称",
"color":"#173177",
},
"keyword2":g.Map{
"value":"订单号",
"color":"#173177",
},
"keyword3":g.Map{
"value":"订单价格",
"color":"red",
},
"keyword4":g.Map{
"value":"订购时间",
"color":"#173177",
},
"remark":g.Map{
"value":"欢迎再次购买!",
"color":"#173177",
},
},
}
body, err := templatepost(access_token, data)
fmt.Println(body, err)
response.SusJson(true, r, "成功", body)
}
4. 发送模板消息 💡
//发送模板消息代码
func templatepost(access_token string, dataMap g.Map) (string, error) {
url := "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + access_token
mjson, _ := json.Marshal(dataMap)
mString := string(mjson)
resp, err := http.Post(url,
"application/x-www-form-urlencoded",
strings.NewReader(mString))
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)) //{"errcode":42001,"errmsg":"access_token expired rid: 61efbb20-222808fb-7ae0e06d"}
return string(body), nil
}
5. 通过微信小程序openid推送到微信公众号消息 💡
前提-微信小程序要和公众号关联
结合微信官方推送消息Api,进行封装
// 里面的隐私内容 用 ****** 代替
package wx_service
import (
"encoding/json"
"fmt"
"github.com/gogf/gf/encoding/gjson"
"github.com/gogf/gf/frame/g"
"io/ioutil"
"mole_org/library/wechat"
"net/http"
"strings"
)
const (
//生成二维码access_token失效
WX_ERRORCODE_40001 = 40001
WX_ERRORCODE_41001 = 41001
WX_ERRORCODE_42001 = 42001
REDIS_KEY_WX_ACCESS_TOKEN = "wx_access_token:"
)
const (
WX_MP_APPID = "wx1******93" //公众号
WX_APPID = "wx1******85" //小程序
WX_SECRET = "5f69e2454******7ff6" //小程序
WX_ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token"
WX_URL_SEND_MSG = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token="
)
const (
AUDIT_MSG = "Cx4fQnjJN7s3GO******N2RrZPaWlc" // 认证审核通知
)
// 根据小程序openid,发送到公众号消息
func TemplatePost(openid string, dataMap g.Map, msgId string, pagepath string) (string,error){
current_access_token, err := wechat.GetAccessTokenFromCache("current_token")
fmt.Println("current_access_token:",current_access_token)
if err != nil {
g.Log().Error(err)
return "", err
}
if current_access_token == "" {
wechat.UpdateAccessToken()
current_access_token,err = wechat.GetAccessTokenFromCache("current_token")
}
url := WX_URL_SEND_MSG + current_access_token
//参数: openid -> 公众号或者小程序 weapp_template_msg -> 小程序模板配置 mp_template_msg -> 公众号模板配置
msgData := g.Map{
"touser": openid,
"weapp_template_msg": nil,
"mp_template_msg": g.Map{
"appid": WX_MP_APPID,
"template_id": msgId,
"url": nil,
"miniprogram": g.Map{
"appid": WX_APPID,
"pagepath": pagepath,
},
"data": dataMap,
},
}
mjson, err := json.Marshal(msgData)
if err != nil {
g.Log().Error(err)
return "", err
}
mString := string(mjson)
resp, err := http.Post(url,"application/x-www-form-urlencoded", strings.NewReader(mString))
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)) //{"errcode":42001,"errmsg":"access_token expired rid: 61efbb20-222808fb-7ae0e06d"}
return string(body), nil
}
//业务审核发送消息
func SendMsgByOrgAudit(openid string,dataMap g.Map)(string ,error) {
msg,err := TemplatePost(openid, dataMap, AUDIT_MSG, "")
result := gjson.New(msg).Get("errcode")
if err != nil || (err == nil &&(result == float64(WX_ERRORCODE_40001) || result == float64(WX_ERRORCODE_41001) || result == float64(WX_ERRORCODE_42001))) {
wechat.UpdateAccessToken()
msg,err = TemplatePost(openid, dataMap, AUDIT_MSG, "")
}
return msg,err
}
业务调用接口
// 业务调用接口
func UpdateOrgStatus(audit string) error {
//审核通过发送公众号消息
var result string
if audit == "1" { result = "成功"} else { result = "失败"}
dataMap := g.Map{
"first": g.Map{
"value":"您好,您申请的" + "[名字]" + "机构审核" + result,
"color":"#173177",
},
"keyword2":g.Map{
"value": time.Now().Format("2006-01-02 15:04:05"),
"color":"#0000CD",
},
}
switch audit {
case "1":
dataMap["keyword1"] = g.Map{
"value":"认证成功",
"color":"#0000CD",
}
dataMap["remark"] = g.Map{
"value":"鼹鼠悠悠感谢您的支持!",
"color":"#0000CD",
}
case "3":
dataMap["keyword1"] = g.Map{
"value":"认证失败",
"color":"#DC143C",
}
dataMap["remark"] = g.Map{
"value":"失败原因:" + org.AuditRefuseReason + ",请重新提交申请",
"color":"#DC143C",
}
break
}
openid := "om******MI"
if _,err := wx_service.SendMsgByOrgAudit(openid,dataMap); err != nil {
return err
}
return nil
}