一、写在前头
-
该教程目标用户是想基于golang语言开发公众号后台,实现自动回复、微信支付、客服等等一些拓展功能;
-
需要会golang、gin、web服务的部署等基础知识。
-
关于微信开发的基本配置,请通过文末的链接查看。
二、整体思路
-
基于微信消息接口的逻辑,首先定义一个消息结构体;
-
然后解析微信服务器发送过来的消息;
-
根据消息的类型(MsgType字段)和消息的内容(Content字段)进行对应的处理;
-
关键字自动回复实例,通过switch-case 结构,将
MsgType=text
并且Content=关键字
的消息,回复对应的内容;
三、部分代码
package routers
import (
"blog_server_v4/config"
"crypto/sha1"
"encoding/hex"
"encoding/xml"
"fmt"
"github.com/gin-gonic/gin"
"log"
"net/http"
"sort"
"strings"
)
type ReqWxMessage struct {
ToUserName string `json:"ToUserName"`
FromUserName string `json:"FromUserName"`
CreateTime int `json:"CreateTime"`
MsgType string `json:"MsgType"` // text | image | voice | shortvideo | location
Event string `json:"Event"`
EventKey string `json:"EventKey"`
Ticket string `json:"Ticket"`
// 文本消息
Content string `json:"Content"`
MsgId int64 `json:"MsgId"`
MsgDataId int64 `json:"MsgDataId"`
Idx int `json:"Idx"`
// 图片消息
PicUrl string `json:"PicUrl"`
MediaId string `json:"MediaId"`
// 语音消息
Format string `json:"Format"` // amr | speex
// 视频消息
ThumbMediaId string `json:"ThumbMediaId"`
// 地理位置消息
LocationX string `json:"Location_X"`
LocationY string `json:"Location_Y"`
Scale string `json:"Scale"`
Label string `json:"Label"`
// 链接消息
Title string `json:"Title"`
Description string `json:"Description"`
Url string `json:"Url"`
}
type RespWxMessageText struct {
ToUserName string `json:"ToUserName"`
FromUserName string `json:"FromUserName"`
CreateTime int `json:"CreateTime"`
MsgType string `json:"MsgType"`
Content string `json:"Content"`
XMLName xml.Name `xml:"xml"`
}
func RouterPartner(router *gin.Engine) (interface{}, error) {
routerPartner := router.Group("/xxx/xxxx")
{
routerPartner.POST("/xxx/xxxx/v1", func(c *gin.Context) {
signature := c.Query("signature")
timestamp := c.Query("timestamp")
nonce := c.Query("nonce")
openid := c.Query("openid")
log.Println("signature:", signature, "timestamp:", timestamp, "nonce:", nonce, "openid:", openid)
var wxMsg ReqWxMessage
err := c.BindXML(&wxMsg)
if err != nil {
log.Println(err)
}
//log.Println("mxMsg:", wxMsg)
//byteWxMsg, err := json.Marshal(wxMsg)
//if err != nil {
// log.Println("err: ", err)
//}
//log.Println("wxMsgString: ", string(byteWxMsg))
switch wxMsg.MsgType {
case "text":
if strings.ToLower(wxMsg.Content) == "pdf2023" {
respWxMessageText := RespWxMessageText{
ToUserName: wxMsg.FromUserName,
FromUserName: wxMsg.ToUserName,
CreateTime: wxMsg.CreateTime + 1,
MsgType: "text",
Content: `链接:https://pan.baidu.com/s/1FYKllrdbZDNc5BxxLv9mcQ?pwd=pryf
提取码:pryf
--来自百度网盘超级会员V5的分享`,
}
byteResp, err := xml.Marshal(&respWxMessageText)
if err != nil {
log.Println(err)
break
}
c.String(http.StatusOK, string(byteResp))
//
//log.Println(string(byteResp))
return
}
}
c.String(http.StatusOK, "success")
return
})
}
return routerPartner, nil
}
关键点说明
-
返回的数据需要需要用
c.String()
返回,不能使用c.XML()
-
返回给微信的xml字符串,最外层应当是
<xml>
标签,不能使用默认的标签,因此,在定义结构体时,需要使用xml:"xml"
指定xml标签
四、校验
[图片上传失败...(image-107571-1699711050225)]
可以看到微信公众号对话窗口和服务端处理窗口的时间是能对上的,即校验成功。
网友评论