diff --git a/internal/services/callback.go b/internal/services/callback.go index 3a69526..f1a9447 100644 --- a/internal/services/callback.go +++ b/internal/services/callback.go @@ -34,9 +34,19 @@ func NewCallbackService(cfg *config.Config, gateway *gateway.Gateway, dingtalkCl // Envelope 回调统一请求体 type Envelope struct { - Action string `json:"action"` - TaskID string `json:"task_id"` - Data map[string]string `json:"data"` + Action string `json:"action"` + TaskID string `json:"task_id"` + Data json.RawMessage `json:"data"` +} + +// bug_optimization_submit_done 工单完成回调 +const ActionBugOptimizationSubmitDone = "bug_optimization_submit_done" + +// BugOptimizationSubmitDoneData 工单完成回调数据 +type BugOptimizationSubmitDoneData struct { + Receivers []string `json:"receivers"` + DetailPage string `json:"detail_page"` + Msg string `json:"msg"` } // Callback 统一回调处理 @@ -47,7 +57,7 @@ func (s *CallbackService) Callback(c *fiber.Ctx) error { ts := strings.TrimSpace(c.Get("X-Timestamp")) // 时间窗口(如果提供了 ts 则校验,否则跳过),窗口 5 分钟 - if ts != "" && !validateTimestamp(ts, 300*time.Minute) { + if ts != "" && !validateTimestamp(ts, 5*time.Minute) { return errorcode.AuthNotFound } @@ -59,7 +69,7 @@ func (s *CallbackService) Callback(c *fiber.Ctx) error { if env.Action == "" || env.TaskID == "" { return errorcode.ParamErr("missing action/task_id") } - if len(env.Data) == 0 { + if env.Data == nil { return errorcode.ParamErr("missing data") } @@ -109,35 +119,31 @@ func parseInt64(s string) (int64, bool) { func (s *CallbackService) handleDingTalkCallback(c *fiber.Ctx, env Envelope) error { switch env.Action { // bug/优化完成回调 - case "bug_optimization_submit_done": + case ActionBugOptimizationSubmitDone: // 获取 session_id sessionID, ok := s.botTool.GetSessionByTaskID(env.TaskID) if !ok { return errorcode.ParamErr("missing session_id for task_id: %s", env.TaskID) } - // 获取接收者 - receiverJson := env.Data["receivers"] - if receiverJson == "" { - return errorcode.ParamErr("missing receivers") + var data BugOptimizationSubmitDoneData + if err := json.Unmarshal(env.Data, &data); err != nil { + return errorcode.ParamErr("invalid data type: %v", err) } - var receiverIds []string - if err := json.Unmarshal([]byte(receiverJson), &receiverIds); err != nil { - return errorcode.ParamErr("invalid receivers: %v", err) - } - if len(receiverIds) == 0 { + + if len(data.Receivers) == 0 { return errorcode.ParamErr("empty receivers") } // 构建接收者 - receivers := s.getDingtalkReceivers(c.Context(), receiverIds) + receivers := s.getDingtalkReceivers(c.Context(), data.Receivers) // 构建跳转链接 - detailPage := env.Data["detail_page"] - if detailPage != "" { - detailPage = util.BuildJumpLink(detailPage, "去查看") + var detailPage string + if data.DetailPage != "" { + detailPage = util.BuildJumpLink(data.DetailPage, "去查看") } - msg := env.Data["msg"] + msg := data.Msg msg = util.ReplacePlaceholder(msg, "receivers", receivers) msg = util.ReplacePlaceholder(msg, "detail_page", detailPage)