逻辑层代码如下:
package controllers
// WechatTextMsgRule 微信文本消息
type WechatTextMsgRule struct {
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Content string
MsgId int64
}
// OfficialAccountAction 控制器类型
type OfficialAccountAction struct {
global.BaseControllerAbstract
}
// Valid 秘钥验证
func (a *OfficialAccountAction) Valid(c *gin.Context) {
waId := c.DefaultQuery("waId", "")
echoStr := c.DefaultQuery("echostr", "")
signature := c.DefaultQuery("signature", "")
timestamp := c.DefaultQuery("timestamp", "")
nonce := c.DefaultQuery("nonce", "")
if len(echoStr) > 0 {
if !utils.Valid(waId, timestamp, nonce, signature) {
log.WithFields(log.Fields{"error": waId}).Warn("公众号秘钥组装失败")
c.String(http.StatusOK, "error:公众号秘钥组装失败")
return
}
}
c.String(http.StatusOK, echoStr)
}
// HandleMessage 处理返回信息
func (a *OfficialAccountAction) HandleMessage(c *gin.Context) {
var form WechatTextMsgRule
if err := c.ShouldBind(&form); err != nil {
log.WithFields(log.Fields{"error": err.Error()}).Warn("无效参数:" + err.Error())
c.String(http.StatusOK, e.GetMsg(e.PARAMS_INVALID))
return
}
c.String(http.StatusOK, "ceshi")
}
核心代码如下:
/*
* .::::.
* .::::::::.
* :::::::::::
* ..:::::::::::'
* '::::::::::::'
* .::::::::::
* '::::::::::::::..
* ..::::::::::::. Utils:wechat 微信公众号操作
* ``::::::::::::::::
* ::::``:::::::::' .:::.
* ::::' ':::::' .::::::::.
* .::::' :::: .:::::::'::::.
* .:::' ::::: .:::::::::' ':::::.
* .::' :::::.:::::::::' ':::::.
* .::' ::::::::::::::' ``::::.
* ...::: ::::::::::::' ``::.
* ```` ':. ':::::::::' ::::..
* '.:::::' ':'````..
*/
package utils
import (
"crypto/sha1"
"encoding/hex"
"encoding/xml"
"sort"
"time"
log "github.com/sirupsen/logrus"
)
// WechatReplyTextMsgRule 微信回复文本消息
type WechatReplyTextMsgRule struct {
ToUserName string
FromUserName string
CreateTime int64
MsgType string
Content string
XMLName xml.Name `xml:"xml"`
}
// Valid 验证微信权限
func Valid(waId, timestamp, nonce, signature string) bool {
if len(waId) == 0 || len(timestamp) == 0 || len(nonce) == 0 {
return false
}
if _, ok := global.OfficialAccountTokenData[waId]; !ok {
log.WithFields(log.Fields{"error": waId}).Warn("公众号标识获取失败")
return false
}
wechatToken := global.OfficialAccountTokenData[waId].(string)
tempArray := []string{wechatToken, timestamp, nonce}
sort.Strings(tempArray)
var sha1Str string
for _, v := range tempArray {
sha1Str += v
}
h := sha1.New()
h.Write([]byte(sha1Str))
return hex.EncodeToString(h.Sum([]byte(""))) == signature
}
// MessageReply 微信消息回复
func TextMessageReply(fromUser, toUser, content string) []byte {
if len(fromUser) == 0 || len(toUser) == 0 || len(content) == 0 {
log.WithFields(log.Fields{
"error": "参数为空",
"fromUser": fromUser,
"toUser": toUser,
"msgType": "text",
"content": content,
}).Warn("WechatMessageReply")
return []byte{}
}
xmlMsg, xmlMsgErr := xml.Marshal(&WechatReplyTextMsgRule{
ToUserName: toUser,
FromUserName: fromUser,
CreateTime: time.Now().Unix(),
MsgType: "text",
Content: content,
})
if xmlMsgErr != nil {
log.WithFields(log.Fields{"error": xmlMsgErr.Error()}).Warn("XML加密错误-WechatMessageReply")
return []byte{}
}
return xmlMsg
}