From 975469e1907ce555e048946a2b9d4fd594fd02e2 Mon Sep 17 00:00:00 2001 From: laodaming <11058467+laudamine@user.noreply.gitee.com> Date: Tue, 7 Nov 2023 10:16:20 +0800 Subject: [PATCH] fix --- .../internal/handler/webhookhandler.go | 24 +------- .../internal/logic/webhooklogic.go | 61 +++++++++++++------ server/feishu-sync/internal/types/types.go | 8 --- server_api/feishu-sync.api | 10 +-- 4 files changed, 45 insertions(+), 58 deletions(-) diff --git a/server/feishu-sync/internal/handler/webhookhandler.go b/server/feishu-sync/internal/handler/webhookhandler.go index befbe7fa..190267a1 100644 --- a/server/feishu-sync/internal/handler/webhookhandler.go +++ b/server/feishu-sync/internal/handler/webhookhandler.go @@ -14,30 +14,8 @@ import ( func WebhookHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req types.WebhookReq - userinfo, err := basic.RequestParse(w, r, svcCtx, &req) - if err != nil { - return - } - //验证连接(直接返回) - if req.Type == "url_verification" { - challengeRsp := map[string]string{ - "challenge": req.Challenge, - } - b, _ := json.Marshal(challengeRsp) - w.Write(b) - return - } // 创建一个业务逻辑层实例 l := logic.NewWebhookLogic(r.Context(), svcCtx) - - rl := reflect.ValueOf(l) - basic.BeforeLogic(w, r, rl) - - resp := l.Webhook(&req, userinfo) - - if !basic.AfterLogic(w, r, rl, resp) { - basic.NormalAfterLogic(w, r, resp) - } + l.Webhook(w, r) } } diff --git a/server/feishu-sync/internal/logic/webhooklogic.go b/server/feishu-sync/internal/logic/webhooklogic.go index 9c6a5a02..8863f2fa 100644 --- a/server/feishu-sync/internal/logic/webhooklogic.go +++ b/server/feishu-sync/internal/logic/webhooklogic.go @@ -2,14 +2,12 @@ package logic import ( "encoding/json" - "fusenapi/utils/auth" - "fusenapi/utils/basic" + "io" + "net/http" "context" "fusenapi/server/feishu-sync/internal/svc" - "fusenapi/server/feishu-sync/internal/types" - "github.com/zeromicro/go-zero/core/logx" ) @@ -27,10 +25,14 @@ func NewWebhookLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebhookLo } } -// 处理进入前逻辑w,r -// func (l *WebhookLogic) BeforeLogic(w http.ResponseWriter, r *http.Request) { -// } -// webhook消息事件基础信息 +type WebhookMsg struct { + Type string `json:"type"` + Challenge string `json:"challenge"` + Header map[string]interface{} `json:"header"` + Event map[string]interface{} `json:"event"` +} + +// webhook消息事件header(body参数)基础信息 type BaseWebhookMsgHeaderType struct { EventId string `json:"event_id"` //事件id(可作为消息唯一性确认) EventType string `json:"event_type"` //事件类型 @@ -40,16 +42,39 @@ type BaseWebhookMsgHeaderType struct { TenantKey string `json:"tenant_key"` //租户key } -func (l *WebhookLogic) Webhook(req *types.WebhookReq, userinfo *auth.UserInfo) (resp *basic.Response) { - logx.Info("收到事件:", req) - var msgHeader BaseWebhookMsgHeaderType - if req.Event["header"] == nil { - logx.Error("invalid request") - return resp.SetStatusWithMessage(basic.CodeRequestParamsErr, "invalid request") +func (l *WebhookLogic) Webhook(w http.ResponseWriter, r *http.Request) { + bodyBytes, err := io.ReadAll(r.Body) + if err != nil { + logx.Error("读取请求body失败", err) + return } - if err := json.Unmarshal([]byte(req.Event["header"].(string)), &msgHeader); err != nil { - logx.Error(err) - return resp.SetStatusAddMessage(basic.CodeJsonErr, "failed to parse params") + defer r.Body.Close() + //如果只是验证http连接的消息 + var webhookMsg WebhookMsg + if err = json.Unmarshal(bodyBytes, &webhookMsg); err != nil { + logx.Error("反序列化请求body失败", err) + return + } + logx.Info("收到消息:", webhookMsg) + //验证连接(直接返回) + if webhookMsg.Type == "url_verification" { + challengeRsp := map[string]string{ + "challenge": webhookMsg.Challenge, + } + b, _ := json.Marshal(challengeRsp) + w.Write(b) + return + } + + headerByte, err := json.Marshal(webhookMsg.Header) + if err != nil { + logx.Error("序列化请求体header失败:", err) + return + } + var msgHeader BaseWebhookMsgHeaderType + if err = json.Unmarshal(headerByte, &msgHeader); err != nil { + logx.Error("反序列化请求体中的header失败", err) + return } switch msgHeader.EventType { case "contact.custom_attr_event.updated_v3": //成员字段管理属性变更事件 @@ -67,7 +92,7 @@ func (l *WebhookLogic) Webhook(req *types.WebhookReq, userinfo *auth.UserInfo) ( case "contact.user.updated_v3": //员工信息变化 } - return resp.SetStatus(basic.CodeOK) + return } // 处理逻辑后 w,r 如:重定向, resp 必须重新处理 diff --git a/server/feishu-sync/internal/types/types.go b/server/feishu-sync/internal/types/types.go index 18135772..b5fd43e5 100644 --- a/server/feishu-sync/internal/types/types.go +++ b/server/feishu-sync/internal/types/types.go @@ -5,14 +5,6 @@ import ( "fusenapi/utils/basic" ) -type WebhookReq struct { - Schema string `json:"schema,optional"` - Header map[string]interface{} `json:"header,optional"` - Event map[string]interface{} `json:"event,optional"` - Challenge string `json:"challenge,optional"` //设置飞书通知接口验证用 - Type string `json:"type,optional"` //设置飞书通知接口验证用 -} - type Request struct { } diff --git a/server_api/feishu-sync.api b/server_api/feishu-sync.api index 4fa8dd8d..31db4bea 100644 --- a/server_api/feishu-sync.api +++ b/server_api/feishu-sync.api @@ -12,13 +12,5 @@ import "basic.api" service feishu-sync { //飞书ticket webhook事件接口 @handler WebhookHandler - post /api/feishu/webhook(WebhookReq) returns (response); -} - -type WebhookReq { - Schema string `json:"schema,optional"` - Header map[string]interface{} `json:"header,optional"` - Event map[string]interface{} `json:"event,optional"` - Challenge string `json:"challenge,optional"` //设置飞书通知接口验证用 - Type string `json:"type,optional"` //设置飞书通知接口验证用 + post /api/feishu/webhook(request) returns (response); } \ No newline at end of file