package controllers
import (
"encoding/xml"
"fmt"
"hongze/hongze_open_api/services"
"hongze/hongze_open_api/services/wework"
"hongze/hongze_open_api/services/wework/wxbizmsgcrypt"
"hongze/hongze_open_api/utils"
"strings"
)
//用户
type WeworkController struct {
BaseCommon
}
// Notify
// @Title 企业微信通知
// @Description 企业微信通知
// @router /notify [get,post]
func (this *WeworkController) Notify() {
method := this.Ctx.Input.Method()
token := wework.NotifyToken
receiverId := wework.WeWorkCorpID
encodingAeskey := wework.NotifyEncodingAESKey
wxcpt := wxbizmsgcrypt.NewWXBizMsgCrypt(token, encodingAeskey, receiverId, wxbizmsgcrypt.XmlType)
if method == "GET" {
// 解析出url上的参数值如下:
verifyMsgSign := this.GetString("msg_signature")
//verifyMsgSign := "5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3"
verifyTimestamp := this.GetString("timestamp")
//verifyTimestamp := "1409659589"
verifyNonce := this.GetString("nonce")
//verifyNonce := "263014780"
verifyEchoStr := this.GetString("echostr")
verifyEchoStr = strings.Replace(verifyEchoStr, " ", "+", -1)
//verifyEchoStr := "vbe33my07xk&echostr=tIoxz82erKm78d5tanP8pBCQFkIPq+zsSpHPphz23rJx5VZ9Y8h9jHgqfM5oZWJ3mxRjaGLTi0dPaneQoOI6Pg=="
echoStr, cryptErr := wxcpt.VerifyURL(verifyMsgSign, verifyTimestamp, verifyNonce, verifyEchoStr)
if nil != cryptErr {
utils.ApiLog.Println("verifyUrl fail", cryptErr)
this.Ctx.WriteString(fmt.Sprintf("verifyUrl fail %s", cryptErr))
return
}
utils.ApiLog.Println("verifyUrl success echoStr", string(echoStr))
// 验证URL成功,将sEchoStr返回
this.Ctx.WriteString(string(echoStr))
return
}else {
reqData := this.Ctx.Input.RequestBody
utils.ApiLog.Println("wework notify postBody:" + string(reqData))
/*
------------使用示例二:对用户回复的消息解密---------------
用户回复消息或者点击事件响应时,企业会收到回调消息,此消息是经过企业微信加密之后的密文以post形式发送给企业,密文格式请参考官方文档
假设企业收到企业微信的回调消息如下:
POST /cgi-bin/wxpush? msg_signature=477715d11cdb4164915debcba66cb864d751f3e6×tamp=1409659813&nonce=1372623149 HTTP/1.1
Host: qy.weixin.qq.com
Content-Length: 613
企业收到post请求之后应该:
1.解析出url上的参数,包括消息体签名(msg_signature),时间戳(timestamp)以及随机数字串(nonce)
2.验证消息体签名的正确性。
3.将post请求的数据进行xml解析,并将标签的内容进行解密,解密出来的明文即是用户回复消息的明文,明文格式请参考官方文档
第2,3步可以用企业微信提供的库函数DecryptMsg来实现。
*/
reqMsgSign := this.GetString("msg_signature")
//reqMsgSign := "477715d11cdb4164915debcba66cb864d751f3e6"
reqTimestamp := this.GetString("timestamp")
//reqTimestamp := "1409659813"
reqNonce := this.GetString("nonce")
//reqNonce := "1372623149"
// post请求的密文数据
// reqData = HttpUtils.PostData()
//reqData := []byte("")
msg, cryptErr := wxcpt.DecryptMsg(reqMsgSign, reqTimestamp, reqNonce, reqData)
if nil != cryptErr {
utils.ApiLog.Println("DecryptMsg fail", cryptErr)
this.Ctx.WriteString(fmt.Sprintf("DecryptMsg fail %s", cryptErr))
return
}
fmt.Println("after decrypt msg: ", string(msg))
// TODO: 解析出明文xml标签的内容进行处理
var msgContent wxbizmsgcrypt.MsgContent
err := xml.Unmarshal(msg, &msgContent)
if err != nil {
utils.ApiLog.Println("Unmarshal fail")
return
} else {
utils.ApiLog.Println("struct", msgContent)
if msgContent.MsgType == "event" {
switch msgContent.Event {
case "msgaudit_notify": _ = services.DayNewWeworkMsgRefresh()
}
}
}
// 验证URL成功,将sEchoStr返回
this.Ctx.WriteString(string(msg))
return
}
/*
------------使用示例三:企业回复用户消息的加密---------------
企业被动回复用户的消息也需要进行加密,并且拼接成密文格式的xml串。
假设企业需要回复用户的明文如下:
1348831860
1234567890123456
128
为了将此段明文回复给用户,企业应:
1.自己生成时间时间戳(timestamp),随机数字串(nonce)以便生成消息体签名,也可以直接用从企业微信的post url上解析出的对应值。
2.将明文加密得到密文。
3.用密文,步骤1生成的timestamp,nonce和企业在企业微信设定的token生成消息体签名。
4.将密文,消息体签名,时间戳,随机数字串拼接成xml格式的字符串,发送给企业。
以上2,3,4步可以用企业微信提供的库函数EncryptMsg来实现。
*/
/*respData := "13488318601234567890123456128"
encryptMsg, cryptErr := wxcpt.EncryptMsg(respData, reqTimestamp, reqNonce)
if nil != cryptErr {
fmt.Println("DecryptMsg fail", cryptErr)
}
sEncryptMsg := string(encryptMsg)
fmt.Println("after encrypt sEncryptMsg: ", sEncryptMsg)
// 加密成功
// TODO:
// HttpUtils.SetResponse(sEncryptMsg)
*/
}