From 498d1659150533e025da038cd5d00a1b480eae76 Mon Sep 17 00:00:00 2001 From: fuzhongyun <15339891972@163.com> Date: Sat, 24 Jan 2026 11:58:29 +0800 Subject: [PATCH] =?UTF-8?q?fix:=201.=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89json=E8=A7=A3=E6=9E=90=E7=9A=84type?= =?UTF-8?q?=202.=E5=A4=84=E7=90=86=E5=8F=96=E6=B6=88=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E5=9B=9E=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/pkg/util/json.go | 33 ++++++++++++++++ internal/services/callback.go | 73 ++++++++++++++++++++++++++++------- 2 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 internal/pkg/util/json.go diff --git a/internal/pkg/util/json.go b/internal/pkg/util/json.go new file mode 100644 index 0000000..2d68184 --- /dev/null +++ b/internal/pkg/util/json.go @@ -0,0 +1,33 @@ +package util + +import ( + "encoding/json" + "fmt" + "strconv" +) + +type FlexibleType string + +func (ft *FlexibleType) UnmarshalJSON(data []byte) error { + var v interface{} + if err := json.Unmarshal(data, &v); err != nil { + return err + } + + switch val := v.(type) { + case string: + *ft = FlexibleType(val) + case float64: + *ft = FlexibleType(strconv.FormatFloat(val, 'f', -1, 64)) + case bool: + *ft = FlexibleType(strconv.FormatBool(val)) + default: + *ft = FlexibleType(fmt.Sprintf("%v", val)) + } + return nil +} + +func (ft FlexibleType) Int() int { + i, _ := strconv.Atoi(string(ft)) + return i +} diff --git a/internal/services/callback.go b/internal/services/callback.go index 37be38e..1626beb 100644 --- a/internal/services/callback.go +++ b/internal/services/callback.go @@ -21,6 +21,7 @@ import ( "strings" "time" + "gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go/card" "gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go/chatbot" "github.com/alibabacloud-go/dingtalk/card_1_0" "github.com/alibabacloud-go/tea/tea" @@ -398,8 +399,6 @@ func (s *CallbackService) CallbackDingtalkRobot(c *fiber.Ctx) (err error) { return fmt.Errorf("invalid body: %v", err) } - fmt.Println(string(body)) - // token 校验 ? token 好像没带? // 通过机器人ID路由到不同能力 @@ -437,12 +436,9 @@ func (s *CallbackService) CallbackDingtalkRobot(c *fiber.Ctx) (err error) { // 能力2: 通过[QA收集] 宏,收集用户反馈,写入知识库 func (s *CallbackService) issueHandling(c *fiber.Ctx, data chatbot.BotCallbackDataModel) error { // 宏解析 - if strings.Contains(data.Text.Content, "[内容提取]") { + if strings.Contains(data.Text.Content, "[内容提取]") || strings.Contains(data.Text.Content, "[QA收集]") { s.issueHandlingExtractContent(data) } - if strings.Contains(data.Text.Content, "[QA收集]") { - s.issueHandlingCollectQA() - } return nil } @@ -546,7 +542,7 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa CardTemplateId: tea.String("3a447814-6a3e-4a02-b48a-92c57b349d77.schema"), OutTrackId: tea.String(outTrackId), CallbackType: tea.String("HTTP"), - CallbackRouteKey: tea.String("gateway.dev.cdlsxd.cn-dingtalk-robot"), + CallbackRouteKey: tea.String("gateway.dev.cdlsxd.cn-dingtalk-card"), CardData: &card_1_0.CreateAndDeliverRequestCardData{ CardParamMap: map[string]*string{ "title": tea.String("QA知识收集"), @@ -573,14 +569,63 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa } -// 问题处理群机器人 QA 收集 -func (s *CallbackService) issueHandlingCollectQA() { - -} - // CallbackDingtalkCard 处理钉钉卡片回调 // 钉钉 callbackRouteKey: gateway.dev.cdlsxd.cn-dingtalk-card // 钉钉 apiSecret: aB3dE7fG9hI2jK4L5M6N7O8P9Q0R1S2T -func (s *CallbackService) CallbackDingtalkCard(ctx *fiber.Ctx) error { - return ctx.SendString("dingtalk card callback") +func (s *CallbackService) CallbackDingtalkCard(c *fiber.Ctx) error { + // 获取body中的参数 + body := c.Request().Body() + + // HTTP 回调结构与SDK结构体不符,包装结构体 + tmp := struct { + card.CardRequest // 嵌入原结构体 + UserIdType util.FlexibleType `json:"userIdType"` // 重写type字段 + }{} + if err := json.Unmarshal(body, &tmp); err != nil { + return fmt.Errorf("invalid body: %v", err) + } + // 异常字段覆盖 + data := tmp.CardRequest + data.UserIdType = tmp.UserIdType.Int() + if err := json.Unmarshal([]byte(data.Content), &data.CardActionData); err != nil { + return fmt.Errorf("invalid content: %v", err) + } + + // 非回调类型不处理 + if data.Type != constants.CardActionCallbackTypeAction { + return nil + } + + // 处理卡片回调 + var resp *card.CardResponse + for _, actionId := range data.CardActionData.CardPrivateData.ActionIdList { + switch actionId { + case "collect_qa": + // 问题处理群机器人 QA 收集 + resp = s.issueHandlingCollectQA(data) + } + } + + return c.JSON(resp) +} + +// 问题处理群机器人 QA 收集 +func (s *CallbackService) issueHandlingCollectQA(data card.CardRequest) *card.CardResponse { + if data.CardActionData.CardPrivateData.Params["submit"] != "submit" { + // 取消提交,禁用输入框 + resp := &card.CardResponse{ + CardUpdateOptions: &card.CardUpdateOptions{ + UpdateCardDataByKey: true, + }, + CardData: &card.CardDataDto{ + CardParamMap: map[string]string{ + "textarea_display": "disabled", + }, + }, + } + + return resp + } + + return nil }