【企微开发最佳实践】自建应用服务端开发如何调试回调?
发布
社区经常有人问自建应用的回调调试应该怎么处理?受限于官方的内网穿透工具目前还不支持自建应用。这里分享下调试方法!
三方和代开发应用可以参考 内网穿透工具 使用官方的内网穿透工具进行回调调试。
目前要实现自建应用本机回调调试的前提条件:
- 一台外网可访问的机器
- 一个已经绑定过可信域名的应用
- 应用可配置可信IP(非必需,如果本地会调用企业微信接口是需要添加本地IP的)
服务端的回调可以用到的方式可以有如下几种(仅为个人观点):
- 服务器上配置ngx_http_mirror_module,把流量打回开发机器;但一般受限于办公室的网络需要做一些配置啥的,操作起来较困难
- 在外网机器上配置开发环境,使用vscode之类的工具连接远程环境开发(大多数不会有这么高的待遇)
- 把回调内容写日志,拿到日志内容在本地模拟回调
本文主要讲最后一种,先上样例代码:
package main
import (
"github.com/gin-gonic/gin"
"github.com/go-laoji/wxbizmsgcrypt"
"io/ioutil"
"log"
"net/http"
)
const (
TOKEN = "" //修改成自己配置的token
AESKEY = "" //修改成自己的aeskey
CORPID = "" //修改成自己的企业ID
)
type QueryParams struct {
MsgSignature string `form:"msg_signature"`
TimeStamp string `form:"timestamp"`
Nonce string `form:"nonce"`
EchoStr string `form:"echostr"`
}
func main() {
router := gin.Default()
wxbiz := wxbizmsgcrypt.NewWXBizMsgCrypt(TOKEN,
AESKEY,
CORPID,
wxbizmsgcrypt.XmlType)
router.GET("/callback", func(c *gin.Context) {
var q QueryParams
if ok := c.Bind(&q); ok == nil {
echoStr, err := wxbiz.VerifyURL(q.MsgSignature, q.TimeStamp, q.Nonce, q.EchoStr)
if err != nil {
c.JSON(http.StatusNotImplemented, gin.H{"error": err.ErrMsg})
} else {
c.Writer.Write(echoStr)
}
}
})
router.POST("/callback", func(c *gin.Context) {
var q QueryParams
if ok := c.Bind(&q); ok == nil {
body, e := ioutil.ReadAll(c.Request.Body)
if e != nil {
log.Fatal(e)
} else {
// 用来记录Post的过来的原始数据
log.Println(string(body))
}
msg, err := wxbiz.DecryptMsg(q.MsgSignature, q.TimeStamp, q.Nonce, body)
if err != nil {
log.Fatal(err.ErrMsg)
} else {
// 输出解密后的消息内容
log.Println(string(msg))
// TODO:实现自己的业务逻辑
}
c.Writer.WriteString("success")
} else {
c.AbortWithStatus(http.StatusNotImplemented)
}
})
router.Run(":8888")
}
代码实现一个 /callback的路由,支持get和post两个方法,分别对应应用配置回调时的get验证;post的数据回调,49行这里把body的内容做记录打印,这就是后面模拟数据的payload。54-58行这中间是要去实现自己的业务逻辑!
调试过程
1、把服务部署到外网服务器上,使回调测试能通过。下面模拟一个发送消息给应用的回调过程(主要这个用例太好实现了,像测试添加联系人啥的还得去添加操作)。
发送个消息给应用
服务器控制台输出的消息格式如下:
<xml><ToUserName><![CDATA[你的企业ID]]></ToUserName><Encrypt><![CDATA[zZRTOi3htkqSNOwzxKc0HT+WXTkmXuYBTn3Sd1t6/P++//oPNwCLW4UXaJZ052Cd0tqRa2+cte2KT4zb/+b3v75aWRpNhzaZqnnWrtlGg84MQnWC/is1+6uDmQ9LweOutj7aTnph/iwgVM6NY+DruZk3gD+QFEccktaFd+B+/C3JWHHdmPeVloXknViki7GJ9YKZGnlx1gvhNawUsVlIogp7Vfm9Kr1oOWnn6VUe4bbgXw08YselifYLlwth3BZ8Q7Mc6pHdRDX+saWMKx43bWOMu6KFIT3Qy+EJZUIDnWDzFXbYxLM8K2/I79wdgxKXx8knkAvpWbP20PiL1Zrhd3xdQ4LugHpwDj5T4wGF6GhsbS3pd8CWvKh1ejwTKXPQSWVIWvp8Y+9jz2AWarD1s4wkU34LWjOjHZ8rCsWf9fQ=]]></Encrypt><AgentID><![CDATA[你的应用id]]></AgentID></xml>
请求的url可以在web日志中看到:
/callback?msg_signature=d7ad4116996b432cd4ea60160a911249c7758011×tamp=1667876730&nonce=1668281536
2、利用apifox进行模拟,先配置请求参数
再配置 body内容
测试环境配置本地环境默认服务地址:http://127.0.0.1:8888,运行输出
3、再看服务端的单步调试
apifox的配置共享链接 https://www.apifox.cn/apidoc/shared-14fdcc37-3ff0-46cd-bd2a-3b2c201cbc0a
本文只做抛砖引玉,有更好的调试方法可以给回复进行分享!
还是个golang小伙