官方文档在这里

我们的公众号服务器可以接收来自微信服务器的普通消息,包括:

  • 文本消息
  • 图片消息
  • 语音消息
  • 小视频消息
  • 地理位置消息
  • 链接消息

这里以文本消息为例,介绍如何处理微信服务器转发给我们的用户消息。

当普通微信用户向公众账号发消息时,微信服务器将向我们填写写的URL上发送一条包含XML数据包的POST请求,其格式如下:

<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>1348831860</CreateTime>
  <MsgType><![CDATA[text]]></MsgType>
  <Content><![CDATA[this is a test]]></Content>
  <MsgId>1234567890123456</MsgId>
  <MsgDataId>xxxx</MsgDataId>
  <Idx>xxxx</Idx>
</xml>

以下代码只是一个简单的示例,只是将微信服务器转发给我们的消息回发的用户:

type WeChatVerify struct {
	Signature string `json:"signature" form:"signature"`
	Timestamp string `json:"timestamp" form:"timestamp"`
	Nonce     string `json:"nonce" form:"nonce"`
	Echostr   string `json:"echostr" form:"echostr"`
}

type WeChatMsg struct {
	XMLName      xml.Name `xml:"xml"`
	ToUserName   string
	FromUserName string
	CreateTime   int64
	MsgType      string
	Content      string
}

func wxPost(ctx *gin.Context) {
	log.Info("Get Msg from wechat")
	verify := &WeChatVerify{
		Signature: ctx.Query("signature"),
		Timestamp: ctx.Query("timestamp"),
		Nonce:     ctx.Query("nonce"),
		Echostr:   ctx.Query("echostr"),
	}
	if !verify.Verify() {
		log.Error("WeChat Verify failed")
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "WeChat Verify failed"})
		return
	}
	log.Info("verify pass")

	reqBody := &WeChatMsg{}
	body, err := io.ReadAll(ctx.Request.Body)
	if err != nil {
		log.Errorf("read request body error: %s", err.Error())
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "read request body error"})
		return
	}
	xml.Unmarshal(body, reqBody)
	reqBytes, _ := sonic.Marshal(reqBody)
	log.Infof("Get requset from wechat: %s", string(reqBytes))

	switch reqBody.MsgType {
	case "text":
		resp := &WeChatMsg{}
		resp.FromUserName = reqBody.ToUserName
		resp.ToUserName = reqBody.FromUserName
		resp.CreateTime = time.Now().Unix()
		resp.MsgType = "text"
		resp.Content = reqBody.Content
		respBytes, _ := xml.Marshal(resp)
		log.Infof("return msg to wechat: %s", string(respBytes))
		ctx.Writer.Header().Set("Content-Type", "text/xml")
		ctx.Writer.WriteString(string(respBytes))
	default:
		log.Errorf("unknow MsgType: %s", reqBody.MsgType)
		ctx.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("unknow MsgType: %s", reqBody.MsgType)})
		return
	}
}

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin92
Github: mengbin92
cnblogs: 恋水无意