This commit is contained in:
parent
4409bea9fc
commit
44aa1fbc9f
|
|
@ -2,12 +2,15 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
"crypto/sha1"
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
"github.com/flipped-aurora/gin-vue-admin/server/global"
|
||||||
|
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model"
|
||||||
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/service"
|
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/service"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
@ -30,21 +33,59 @@ var webhookMessageService = service.ServiceGroupApp.MpMessageService
|
||||||
// @Success 200 {string} string "success"
|
// @Success 200 {string} string "success"
|
||||||
// @Router /wechat/official/webhook [get,post]
|
// @Router /wechat/official/webhook [get,post]
|
||||||
func (w *WechatWebhookApi) OfficialAccountWebhook(c *gin.Context) {
|
func (w *WechatWebhookApi) OfficialAccountWebhook(c *gin.Context) {
|
||||||
|
startTime := time.Now()
|
||||||
|
|
||||||
// 获取参数
|
// 获取参数
|
||||||
signature := c.Query("signature")
|
signature := c.Query("signature")
|
||||||
timestamp := c.Query("timestamp")
|
timestamp := c.Query("timestamp")
|
||||||
nonce := c.Query("nonce")
|
nonce := c.Query("nonce")
|
||||||
echostr := c.Query("echostr")
|
echostr := c.Query("echostr")
|
||||||
|
|
||||||
|
// 准备webhook日志记录
|
||||||
|
webhookLog := &model.MpWebhookLog{
|
||||||
|
ConfigID: 1, // 默认配置ID,实际应该根据具体配置获取
|
||||||
|
RequestURL: c.Request.URL.String(),
|
||||||
|
RequestMethod: c.Request.Method,
|
||||||
|
Signature: &signature,
|
||||||
|
Timestamp: ×tamp,
|
||||||
|
Nonce: &nonce,
|
||||||
|
Echostr: &echostr,
|
||||||
|
}
|
||||||
|
|
||||||
|
// 记录请求头
|
||||||
|
if headers, err := json.Marshal(c.Request.Header); err == nil {
|
||||||
|
headersStr := string(headers)
|
||||||
|
webhookLog.RequestHeaders = &headersStr
|
||||||
|
}
|
||||||
|
|
||||||
// 验证签名
|
// 验证签名
|
||||||
if !w.verifySignature(signature, timestamp, nonce) {
|
if !w.verifySignature(signature, timestamp, nonce) {
|
||||||
global.GVA_LOG.Error("微信签名验证失败")
|
global.GVA_LOG.Error("微信签名验证失败")
|
||||||
|
|
||||||
|
// 记录失败信息
|
||||||
|
webhookLog.ResponseStatus = 403
|
||||||
|
responseBody := "签名验证失败"
|
||||||
|
webhookLog.ResponseBody = &responseBody
|
||||||
|
errorMsg := "签名验证失败"
|
||||||
|
webhookLog.ErrorMessage = &errorMsg
|
||||||
|
webhookLog.ProcessTime = int(time.Since(startTime).Milliseconds())
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
w.saveWebhookLog(webhookLog)
|
||||||
|
|
||||||
c.String(403, "签名验证失败")
|
c.String(403, "签名验证失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET请求用于验证服务器配置
|
// GET请求用于验证服务器配置
|
||||||
if c.Request.Method == "GET" {
|
if c.Request.Method == "GET" {
|
||||||
|
webhookLog.ResponseStatus = 200
|
||||||
|
webhookLog.ResponseBody = &echostr
|
||||||
|
webhookLog.ProcessTime = int(time.Since(startTime).Milliseconds())
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
w.saveWebhookLog(webhookLog)
|
||||||
|
|
||||||
c.String(200, echostr)
|
c.String(200, echostr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -53,16 +94,41 @@ func (w *WechatWebhookApi) OfficialAccountWebhook(c *gin.Context) {
|
||||||
body, err := io.ReadAll(c.Request.Body)
|
body, err := io.ReadAll(c.Request.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
global.GVA_LOG.Error("读取请求体失败", zap.Error(err))
|
global.GVA_LOG.Error("读取请求体失败", zap.Error(err))
|
||||||
|
|
||||||
|
// 记录失败信息
|
||||||
|
webhookLog.ResponseStatus = 400
|
||||||
|
responseBody := "读取请求体失败"
|
||||||
|
webhookLog.ResponseBody = &responseBody
|
||||||
|
errorMsg := err.Error()
|
||||||
|
webhookLog.ErrorMessage = &errorMsg
|
||||||
|
webhookLog.ProcessTime = int(time.Since(startTime).Milliseconds())
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
w.saveWebhookLog(webhookLog)
|
||||||
|
|
||||||
c.String(400, "读取请求体失败")
|
c.String(400, "读取请求体失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 记录请求体
|
||||||
|
bodyStr := string(body)
|
||||||
|
webhookLog.RequestBody = &bodyStr
|
||||||
|
|
||||||
// 简化消息处理 - 暂时只记录日志
|
// 简化消息处理 - 暂时只记录日志
|
||||||
global.GVA_LOG.Info("收到微信消息", zap.String("body", string(body)))
|
global.GVA_LOG.Info("收到微信消息", zap.String("body", bodyStr))
|
||||||
|
|
||||||
// TODO: 实现完整的消息解析和处理
|
// TODO: 实现完整的消息解析和处理
|
||||||
// 由于微信SDK API变化,暂时简化处理
|
// 由于微信SDK API变化,暂时简化处理
|
||||||
|
|
||||||
|
// 记录成功响应
|
||||||
|
webhookLog.ResponseStatus = 200
|
||||||
|
responseBody := "success"
|
||||||
|
webhookLog.ResponseBody = &responseBody
|
||||||
|
webhookLog.ProcessTime = int(time.Since(startTime).Milliseconds())
|
||||||
|
|
||||||
|
// 保存到数据库
|
||||||
|
w.saveWebhookLog(webhookLog)
|
||||||
|
|
||||||
c.String(200, "success")
|
c.String(200, "success")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,3 +153,13 @@ func (w *WechatWebhookApi) verifySignature(signature, timestamp, nonce string) b
|
||||||
// 将加密后的字符串与signature对比
|
// 将加密后的字符串与signature对比
|
||||||
return encrypted == signature
|
return encrypted == signature
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// saveWebhookLog 保存Webhook日志到数据库
|
||||||
|
func (w *WechatWebhookApi) saveWebhookLog(log *model.MpWebhookLog) {
|
||||||
|
if err := global.GVA_DB.Create(log).Error; err != nil {
|
||||||
|
global.GVA_LOG.Error("保存Webhook日志失败", zap.Error(err))
|
||||||
|
// 数据库记录失败不影响webhook正常响应
|
||||||
|
} else {
|
||||||
|
global.GVA_LOG.Debug("Webhook日志保存成功", zap.Uint("id", log.ID))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue