fix: 代码优化 1.需要环境区分的配置,从常量移动到yaml 2. 新增获取机器人应用配置的公共方法 3.以上修改相应的业务调整 4.修复一些单元测试文件的报错
This commit is contained in:
parent
32cd8691b7
commit
fa08cad74a
|
|
@ -147,6 +147,26 @@ dingtalk:
|
|||
# 机器人群组
|
||||
bot_group_id:
|
||||
bbxt: 23
|
||||
# 互动卡片
|
||||
card:
|
||||
# 卡片回调路由key
|
||||
callback_route_key: "gateway.dev.cdlsxd.cn-dingtalk-card"
|
||||
# 卡片调试工具 [show:展示 hide:隐藏]
|
||||
debug_tool_entry_show: "hide"
|
||||
# 卡片模板
|
||||
template:
|
||||
# 基础消息卡片(title + content)
|
||||
base_msg: "291468f8-a048-4132-a37e-a14365e855e9.schema"
|
||||
# 内容收集卡片(title + textarea + button)
|
||||
content_collect: "3a447814-6a3e-4a02-b48a-92c57b349d77.schema"
|
||||
# 创建群聊申请(title + content + button)
|
||||
create_group_approve: "faad6d5d-726d-467f-a6ba-28c1930aa5f3.schema"
|
||||
# 场景群
|
||||
scene_group:
|
||||
# 问题处理群模板ID
|
||||
group_template_id_issue_handling: "420089e3-b0fb-40f5-89d2-ec47223bff3b"
|
||||
# 问题处理群模板机器人ID
|
||||
group_template_robot_id_issue_handling: "VqgJYpB91j3RnB217690607273471011"
|
||||
|
||||
qywx:
|
||||
corp_id: "ww48151f694fb8ec67"
|
||||
|
|
|
|||
|
|
@ -591,8 +591,8 @@ func (g *GroupConfigBiz) shouldCreateIssueHandlingGroup(ctx context.Context, rec
|
|||
}
|
||||
issueOwnerStr := strings.Join(userNames, "、")
|
||||
|
||||
// 获取机器人应用配置
|
||||
botConfig, err := g.botConfigImpl.GetRobotConfig(callback.RobotCode)
|
||||
// 获取应用配置
|
||||
appKey, err := g.botConfigImpl.GetRobotAppKey(callback.RobotCode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("获取机器人配置失败,err: %v", err)
|
||||
}
|
||||
|
|
@ -601,35 +601,34 @@ func (g *GroupConfigBiz) shouldCreateIssueHandlingGroup(ctx context.Context, rec
|
|||
outTrackId := constants.BuildCardOutTrackId(callback.ConversationId, callback.RobotCode)
|
||||
|
||||
// 发送钉钉卡片
|
||||
_, err = g.dingtalkCardClient.CreateAndDeliver(dingtalk.AppKey{
|
||||
AppKey: botConfig.ClientId,
|
||||
AppSecret: botConfig.ClientSecret,
|
||||
}, &card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String(constants.DingtalkCardTplCreateGroupApprove),
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CallbackType: tea.String("STREAM"),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
CardParamMap: map[string]*string{
|
||||
"title": tea.String("创建群聊提醒"),
|
||||
"content": tea.String(fmt.Sprintf("**确认创建群聊?**\n\n将邀请以下成员加入群聊:\n\n%s", issueOwnerStr)),
|
||||
"remark": tea.String("注:如若无需,忽略即可"),
|
||||
"button_left": tea.String("创建群聊"),
|
||||
"button_right": tea.String("忽略"),
|
||||
"action_id": tea.String("create_group"),
|
||||
"button_display": tea.String("true"),
|
||||
"group_scope": tea.String(strings.TrimSpace(rec.UserContent.Text)),
|
||||
"_CARD_DEBUG_TOOL_ENTRY": tea.String(constants.CardDebugToolEntryShow), // 调试字段
|
||||
_, err = g.dingtalkCardClient.CreateAndDeliver(
|
||||
appKey,
|
||||
&card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String(g.conf.Dingtalk.Card.Template.CreateGroupApprove),
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CallbackType: tea.String("STREAM"),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
CardParamMap: map[string]*string{
|
||||
"title": tea.String("创建群聊提醒"),
|
||||
"content": tea.String(fmt.Sprintf("**确认创建群聊?**\n\n将邀请以下成员加入群聊:\n\n%s", issueOwnerStr)),
|
||||
"remark": tea.String("注:如若无需,忽略即可"),
|
||||
"button_left": tea.String("创建群聊"),
|
||||
"button_right": tea.String("忽略"),
|
||||
"action_id": tea.String("create_group"),
|
||||
"button_display": tea.String("true"),
|
||||
"group_scope": tea.String(strings.TrimSpace(rec.UserContent.Text)),
|
||||
"_CARD_DEBUG_TOOL_ENTRY": tea.String(g.conf.Dingtalk.Card.DebugToolEntryShow), // 调试字段
|
||||
},
|
||||
},
|
||||
},
|
||||
ImGroupOpenSpaceModel: &card_1_0.CreateAndDeliverRequestImGroupOpenSpaceModel{
|
||||
SupportForward: tea.Bool(false),
|
||||
},
|
||||
OpenSpaceId: tea.String("dtv1.card//im_group." + callback.ConversationId),
|
||||
ImGroupOpenDeliverModel: &card_1_0.CreateAndDeliverRequestImGroupOpenDeliverModel{
|
||||
RobotCode: tea.String(callback.RobotCode),
|
||||
Recipients: userIds,
|
||||
},
|
||||
})
|
||||
ImGroupOpenSpaceModel: &card_1_0.CreateAndDeliverRequestImGroupOpenSpaceModel{
|
||||
SupportForward: tea.Bool(false),
|
||||
},
|
||||
OpenSpaceId: tea.String("dtv1.card//im_group." + callback.ConversationId),
|
||||
ImGroupOpenDeliverModel: &card_1_0.CreateAndDeliverRequestImGroupOpenDeliverModel{
|
||||
RobotCode: tea.String(callback.RobotCode),
|
||||
Recipients: userIds,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("发送钉钉卡片失败,err: %v", err)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,11 @@ import (
|
|||
"ai_scheduler/internal/domain/repo"
|
||||
"ai_scheduler/internal/domain/workflow"
|
||||
"ai_scheduler/internal/pkg"
|
||||
"ai_scheduler/internal/pkg/dingtalk"
|
||||
"ai_scheduler/internal/pkg/lsxd"
|
||||
"ai_scheduler/internal/pkg/utils_ollama"
|
||||
"ai_scheduler/internal/pkg/utils_oss"
|
||||
"ai_scheduler/internal/tools"
|
||||
"ai_scheduler/utils"
|
||||
"context"
|
||||
"testing"
|
||||
|
|
@ -53,6 +55,14 @@ func run() {
|
|||
|
||||
registry := workflow.NewRegistry(configConfig, client, repos, components)
|
||||
botGroupConfigImpl := impl.NewBotGroupConfigImpl(db)
|
||||
botConfigImpl := impl.NewBotConfigImpl(db)
|
||||
qywxAppBiz = NewQywxAppBiz(configConfig, botGroupQywxImpl, group, other)
|
||||
groupConfigBiz = NewGroupConfigBiz(toolRegis, utils_ossClient, botGroupConfigImpl, registry, configConfig)
|
||||
reportDailyCacheImpl := impl.NewReportDailyCacheImpl(db)
|
||||
toolManager := tools.NewManager(configConfig, client)
|
||||
oauth2Client, _ := dingtalk.NewOauth2Client(rdb)
|
||||
dingtalkCardClient, _ := dingtalk.NewCardClient(oauth2Client)
|
||||
|
||||
// reportDailyCacheImpl *impl.ReportDailyCacheImpl, rdb *utils.Rdb, toolManager *tools.Manager, dingtalkCardClient *dingtalk.CardClient
|
||||
|
||||
groupConfigBiz = NewGroupConfigBiz(toolRegis, utils_ossClient, botGroupConfigImpl, botConfigImpl, registry, configConfig, reportDailyCacheImpl, rdb, toolManager, dingtalkCardClient)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -72,10 +72,12 @@ type LLMCapabilityConfig struct {
|
|||
|
||||
// DingtalkConfig 钉钉配置
|
||||
type DingtalkConfig struct {
|
||||
ApiKey string `mapstructure:"api_key"`
|
||||
ApiSecret string `mapstructure:"api_secret"`
|
||||
TableDemand AITableConfig `mapstructure:"table_demand"`
|
||||
BotGroupID map[string]int `mapstructure:"bot_group_id"` // 机器人群组
|
||||
ApiKey string `mapstructure:"api_key"`
|
||||
ApiSecret string `mapstructure:"api_secret"`
|
||||
TableDemand AITableConfig `mapstructure:"table_demand"`
|
||||
BotGroupID map[string]int `mapstructure:"bot_group_id"` // 机器人群组
|
||||
Card CardConfig `mapstructure:"card"` // 互动卡片
|
||||
SceneGroup SceneGroupConfig `mapstructure:"scene_group"` // 场景群
|
||||
}
|
||||
|
||||
// QywxConfig 企业微信配置
|
||||
|
|
@ -97,6 +99,34 @@ type AITableConfig struct {
|
|||
SheetIdOrName string `mapstructure:"sheet_id_or_name"`
|
||||
}
|
||||
|
||||
// CardConfig 互动卡片配置
|
||||
type CardConfig struct {
|
||||
// 卡片回调路由key
|
||||
CallbackRouteKey string `mapstructure:"callback_route_key"`
|
||||
// 卡片调试工具 [show:展示 hide:隐藏]
|
||||
DebugToolEntryShow string `mapstructure:"debug_tool_entry_show"`
|
||||
// 卡片模板
|
||||
Template CardTemplateConfig `mapstructure:"template"`
|
||||
}
|
||||
|
||||
// CardTemplateConfig 卡片模板配置
|
||||
type CardTemplateConfig struct {
|
||||
// 基础消息卡片(title + content)
|
||||
BaseMsg string `mapstructure:"base_msg"`
|
||||
// 内容收集卡片(title + textarea + button)
|
||||
ContentCollect string `mapstructure:"content_collect"`
|
||||
// 创建群聊申请(title + content + button)
|
||||
CreateGroupApprove string `mapstructure:"create_group_approve"`
|
||||
}
|
||||
|
||||
// SceneGroupConfig 场景群配置
|
||||
type SceneGroupConfig struct {
|
||||
// 问题处理群模板ID
|
||||
GroupTemplateIDIssueHandling string `mapstructure:"group_template_id_issue_handling"`
|
||||
// 问题处理群模板机器人ID
|
||||
GroupTemplateRobotIDIssueHandling string `mapstructure:"group_template_robot_id_issue_handling"`
|
||||
}
|
||||
|
||||
// SysConfig 系统配置
|
||||
type SysConfig struct {
|
||||
SessionLen int `mapstructure:"session_len"`
|
||||
|
|
|
|||
|
|
@ -84,13 +84,12 @@ const (
|
|||
}`
|
||||
)
|
||||
|
||||
// 交互卡片回调类型
|
||||
// 交互卡片回调
|
||||
const (
|
||||
// 回调类型
|
||||
CardActionCallbackTypeAction string = "actionCallback" // 交互卡片回调事件类型
|
||||
)
|
||||
|
||||
// 交互卡片回调事件类型
|
||||
const (
|
||||
// 回调事件类型
|
||||
CardActionTypeCreateGroup string = "create_group" // 创建群聊
|
||||
)
|
||||
|
||||
|
|
@ -117,24 +116,50 @@ func ParseCardOutTrackId(outTrackId string) (spaceId string, botId string) {
|
|||
return
|
||||
}
|
||||
|
||||
// dingtalk 卡片模板
|
||||
const (
|
||||
DingtalkCardTplBaseMsg string = "291468f8-a048-4132-a37e-a14365e855e9.schema" // 基础消息卡片(title + content)
|
||||
DingtalkCardTplCreateGroupApprove string = "faad6d5d-726d-467f-a6ba-28c1930aa5f3.schema" // 创建群聊申请
|
||||
)
|
||||
// 问题处理群机器人 - LLM 提示词
|
||||
const IssueHandlingExtractContentPrompt string = `你是一个【问题与答案生成助手】。
|
||||
|
||||
// dingtalk 模板群相关
|
||||
const (
|
||||
// 群模板id
|
||||
GroupTemplateIdIssueHandling string = "420089e3-b0fb-40f5-89d2-ec47223bff3b" // 问题处理群模板id
|
||||
你的职责是:
|
||||
- 分析用户输入的内容
|
||||
- 识别其中隐含或明确的问题
|
||||
- 基于输入内容本身,生成对应的问题与答案
|
||||
|
||||
// 模板群机器人ID
|
||||
GroupTemplateRobotIdIssueHandling string = "VqgJYpB91j3RnB217690607273471011" // 问题处理群模板机器人ID
|
||||
)
|
||||
当用户输入为【多条群聊聊天记录】时:
|
||||
- 结合问题主题,判断聊天记录中正在讨论或试图解决的问题
|
||||
- 一个群聊中可能包含多个相互独立的问题,但它们都围绕着一个主题,一般为用户提出的第一个问题,尽可能总结为一个问题
|
||||
- 若确实问题很独立,需要分别识别,对每个问题,整理出清晰、可复用的“问题描述”和“对应答案”
|
||||
|
||||
// 群模板机器人 - 主应用机器人映射
|
||||
var GroupTemplateRobotIdMap = map[string]string{
|
||||
GroupTemplateRobotIdIssueHandling: "ding5wwvnf9hxeyjau7t",
|
||||
}
|
||||
生成答案时的原则:
|
||||
- 答案必须来源于聊天内容中已经给出的信息或共识
|
||||
- 不要引入外部知识,不要使用聊天记录中真实人名或敏感信息,适当总结
|
||||
- 若聊天中未形成明确答案,应明确标记为“暂无明确结论”
|
||||
- 若存在多种不同观点,应分别列出,不要擅自合并或裁决
|
||||
|
||||
const CardDebugToolEntryShow string = "hide" // 卡片调试工具 [show:展示 hide:隐藏]
|
||||
【JSON 输出原则】:
|
||||
- 你的最终输出必须是**合法的 JSON**
|
||||
- 不得输出任何额外解释性文字
|
||||
- JSON 结构必须严格符合以下约定
|
||||
|
||||
JSON 结构约定:
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"question": "清晰、独立、可复用的问题描述",
|
||||
"answer": "基于聊天内容整理出的答案;如无结论则为“暂无明确结论”",
|
||||
"confidence": "high | medium | low"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
字段说明:
|
||||
- items:问题与答案列表;若未识别到有效问题,则返回空数组 []
|
||||
- question:抽象后的标准问题表述,不包含具体聊天语句
|
||||
- answer:整理后的答案,不得引入聊天之外的信息
|
||||
- confidence:根据聊天中信息的一致性和明确程度给出判断
|
||||
|
||||
如果无法从输入中识别出任何有效问题,返回:
|
||||
{ "items": [] }
|
||||
|
||||
用户输入:
|
||||
%s
|
||||
`
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package impl
|
|||
import (
|
||||
"ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/internal/entitys"
|
||||
"ai_scheduler/internal/pkg/dingtalk"
|
||||
"ai_scheduler/tmpl/dataTemp"
|
||||
"ai_scheduler/utils"
|
||||
"encoding/json"
|
||||
|
|
@ -21,20 +22,31 @@ func NewBotConfigImpl(db *utils.Db) *BotConfigImpl {
|
|||
}
|
||||
|
||||
// GetRobotConfig 获取机器人配置
|
||||
func (b *BotConfigImpl) GetRobotConfig(robotCode string) (entitys.DingTalkBot, error) {
|
||||
func (b *BotConfigImpl) GetRobotConfig(robotCode string) (*entitys.DingTalkBot, error) {
|
||||
// 获取机器人配置
|
||||
var botConfig model.AiBotConfig
|
||||
cond := builder.NewCond().And(builder.Eq{"robot_code": robotCode})
|
||||
cond := builder.NewCond().And(builder.Eq{"robot_code": robotCode}).And(builder.Eq{"status": 1})
|
||||
err := b.GetOneBySearchToStrut(&cond, &botConfig)
|
||||
if err != nil {
|
||||
return entitys.DingTalkBot{}, err
|
||||
return nil, err
|
||||
}
|
||||
// 解出 config
|
||||
var config entitys.DingTalkBot
|
||||
err = json.Unmarshal([]byte(botConfig.BotConfig), &config)
|
||||
if err != nil {
|
||||
return entitys.DingTalkBot{}, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config, nil
|
||||
return &config, nil
|
||||
}
|
||||
|
||||
// GetRobotAppKey 获取机器人应用ID
|
||||
func (b *BotConfigImpl) GetRobotAppKey(robotCode string) (dingtalk.AppKey, error) {
|
||||
// 获取机器人配置
|
||||
dingTalkBotConfig, err := b.GetRobotConfig(robotCode)
|
||||
if err != nil {
|
||||
return dingtalk.AppKey{}, err
|
||||
}
|
||||
|
||||
return dingTalkBotConfig.GetAppKey(), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package entitys
|
|||
|
||||
import (
|
||||
"ai_scheduler/internal/data/model"
|
||||
"ai_scheduler/internal/pkg/dingtalk"
|
||||
|
||||
"gitea.cdlsxd.cn/self-tools/l-dingtalk-stream-sdk-go/chatbot"
|
||||
)
|
||||
|
|
@ -21,3 +22,10 @@ type DingTalkBot struct {
|
|||
ClientId string `json:"client_id"`
|
||||
ClientSecret string `json:"client_secret"`
|
||||
}
|
||||
|
||||
func (d *DingTalkBot) GetAppKey() dingtalk.AppKey {
|
||||
return dingtalk.AppKey{
|
||||
AppKey: d.ClientId,
|
||||
AppSecret: d.ClientSecret,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,14 +35,9 @@ func NewDingTalkBotServer(
|
|||
for _, service := range services {
|
||||
serviceConfigs, err := service.GetServiceCfg()
|
||||
for _, serviceConf := range serviceConfigs {
|
||||
// 配置不全
|
||||
if serviceConf.ClientId == "" || serviceConf.ClientSecret == "" {
|
||||
continue
|
||||
}
|
||||
// 非应用主机器人 pass ,防止重复
|
||||
if serviceConf.ClientId != serviceConf.BotIndex {
|
||||
continue
|
||||
}
|
||||
cli := DingBotServerInit(serviceConf.ClientId, serviceConf.ClientSecret, service)
|
||||
if cli == nil {
|
||||
log.Infof("%s客户端初始失败:%s", serviceConf.BotIndex, err.Error())
|
||||
|
|
|
|||
|
|
@ -409,7 +409,7 @@ func (s *CallbackService) CallbackDingtalkRobot(c *fiber.Ctx) (err error) {
|
|||
|
||||
// 通过机器人ID路由到不同能力
|
||||
switch data.RobotCode {
|
||||
case constants.GroupTemplateRobotIdIssueHandling:
|
||||
case s.cfg.Dingtalk.SceneGroup.GroupTemplateRobotIDIssueHandling:
|
||||
// 问题处理群机器人
|
||||
err := s.issueHandling(c, data)
|
||||
if err != nil {
|
||||
|
|
@ -420,20 +420,6 @@ func (s *CallbackService) CallbackDingtalkRobot(c *fiber.Ctx) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
|
||||
// defer cancel()
|
||||
|
||||
// 统一初始化请求参数
|
||||
// requireData, err := s.dingTalkBotBiz.InitRequire(ctx, &data)
|
||||
// if err != nil {
|
||||
// return fmt.Errorf("初始化请求参数失败: %v", err)
|
||||
// }
|
||||
|
||||
// 这里需要再实现一套HTTP形式的回调,用于处理钉钉群模板机器人的回调
|
||||
// 主程等待处理结果
|
||||
// resChan := make(chan string, 10)
|
||||
// defer close(resChan)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -456,60 +442,10 @@ func (s *CallbackService) issueHandling(c *fiber.Ctx, data chatbot.BotCallbackDa
|
|||
|
||||
// 问题处理群机器人内容提取
|
||||
func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDataModel) {
|
||||
systemPrompt := `你是一个【问题与答案生成助手】。
|
||||
|
||||
你的职责是:
|
||||
- 分析用户输入的内容
|
||||
- 识别其中隐含或明确的问题
|
||||
- 基于输入内容本身,生成对应的问题与答案
|
||||
|
||||
当用户输入为【多条群聊聊天记录】时:
|
||||
- 结合问题主题,判断聊天记录中正在讨论或试图解决的问题
|
||||
- 一个群聊中可能包含多个相互独立的问题,但它们都围绕着一个主题,尽可能总结为一个问题
|
||||
- 若确实问题很独立,需要分别识别,对每个问题,整理出清晰、可复用的“问题描述”和“对应答案”
|
||||
|
||||
生成答案时的原则:
|
||||
- 答案必须来源于聊天内容中已经给出的信息或共识
|
||||
- 不要引入外部知识,不要使用聊天记录中真实人名或敏感信息,适当总结
|
||||
- 若聊天中未形成明确答案,应明确标记为“暂无明确结论”
|
||||
- 若存在多种不同观点,应分别列出,不要擅自合并或裁决
|
||||
|
||||
【JSON 输出原则】:
|
||||
- 你的最终输出必须是**合法的 JSON**
|
||||
- 不得输出任何额外解释性文字
|
||||
- JSON 结构必须严格符合以下约定
|
||||
|
||||
JSON 结构约定:
|
||||
{
|
||||
"items": [
|
||||
{
|
||||
"question": "清晰、独立、可复用的问题描述",
|
||||
"answer": "基于聊天内容整理出的答案;如无结论则为“暂无明确结论”",
|
||||
"confidence": "high | medium | low"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
字段说明:
|
||||
- items:问题与答案列表;若未识别到有效问题,则返回空数组 []
|
||||
- question:抽象后的标准问题表述,不包含具体聊天语句
|
||||
- answer:整理后的答案,不得引入聊天之外的信息
|
||||
- confidence:根据聊天中信息的一致性和明确程度给出判断
|
||||
|
||||
如果无法从输入中识别出任何有效问题,返回:
|
||||
{ "items": [] }
|
||||
|
||||
问题主题:
|
||||
%s
|
||||
|
||||
用户输入:
|
||||
%s
|
||||
`
|
||||
|
||||
prompt := fmt.Sprintf(systemPrompt, "紧急加款,提示当前账户为离线账户,请输入银行流水号", data.Text.Content)
|
||||
|
||||
fmt.Println("prompt:", prompt)
|
||||
|
||||
// 1.提取用户输入
|
||||
prompt := fmt.Sprintf(constants.IssueHandlingExtractContentPrompt, data.Text.Content)
|
||||
log.Infof("问题提取提示词: %s", prompt)
|
||||
// LLM 提取
|
||||
generateResp, err := s.ollamaClient.Generation(context.Background(), &api.GenerateRequest{
|
||||
Model: s.cfg.Ollama.GenerateModel,
|
||||
Prompt: prompt,
|
||||
|
|
@ -519,7 +455,6 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa
|
|||
log.Errorf("问题提取失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 解析 JSON 响应
|
||||
var resp struct {
|
||||
Items []struct {
|
||||
|
|
@ -533,6 +468,7 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa
|
|||
return
|
||||
}
|
||||
|
||||
// 2.构建文本域内容
|
||||
cardContentTpl := "问题:%s \n答案:%s"
|
||||
var cardContentList []string
|
||||
for _, item := range resp.Items {
|
||||
|
|
@ -540,20 +476,22 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa
|
|||
}
|
||||
cardContent := strings.Join(cardContentList, "\n\n")
|
||||
|
||||
// 调用卡片
|
||||
// 构建卡片 OutTrackId
|
||||
outTrackId := constants.BuildCardOutTrackId(data.ConversationId, data.RobotCode)
|
||||
// 3.获取应用AppKey
|
||||
appKey, err := s.botConfigImpl.GetRobotAppKey(data.RobotCode)
|
||||
if err != nil {
|
||||
log.Errorf("获取应用配置失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 4.创建并投放卡片
|
||||
outTrackId := constants.BuildCardOutTrackId(data.ConversationId, data.RobotCode) // 构建卡片 OutTrackId
|
||||
_, err = s.dingtalkCardClient.CreateAndDeliver(
|
||||
dingtalk.AppKey{
|
||||
AppKey: "ding5wwvnf9hxeyjau7t",
|
||||
AppSecret: "FxXVlTzxrKXvJ8h-9uK0s5TjaBfOJSXumpmrHal-NmQAtku9wOPxcss0Af6WHoAK",
|
||||
},
|
||||
appKey,
|
||||
&card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String("3a447814-6a3e-4a02-b48a-92c57b349d77.schema"),
|
||||
CardTemplateId: tea.String(s.cfg.Dingtalk.Card.Template.ContentCollect),
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CallbackType: tea.String("HTTP"),
|
||||
CallbackRouteKey: tea.String("gateway.dev.cdlsxd.cn-dingtalk-card"),
|
||||
CallbackRouteKey: tea.String(s.cfg.Dingtalk.Card.CallbackRouteKey),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
CardParamMap: map[string]*string{
|
||||
"title": tea.String("QA知识收集"),
|
||||
|
|
@ -562,7 +500,7 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa
|
|||
"textarea_display": tea.String("normal"),
|
||||
"action_id": tea.String("collect_qa"),
|
||||
"tenant_id": tea.String(constants.KnowledgeTenantIdDefault),
|
||||
"_CARD_DEBUG_TOOL_ENTRY": tea.String(constants.CardDebugToolEntryShow), // 调试字段
|
||||
"_CARD_DEBUG_TOOL_ENTRY": tea.String(s.cfg.Dingtalk.Card.DebugToolEntryShow), // 调试字段
|
||||
},
|
||||
},
|
||||
ImGroupOpenSpaceModel: &card_1_0.CreateAndDeliverRequestImGroupOpenSpaceModel{
|
||||
|
|
@ -570,7 +508,7 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa
|
|||
},
|
||||
OpenSpaceId: tea.String("dtv1.card//im_group." + data.ConversationId),
|
||||
ImGroupOpenDeliverModel: &card_1_0.CreateAndDeliverRequestImGroupOpenDeliverModel{
|
||||
RobotCode: tea.String(constants.GroupTemplateRobotIdIssueHandling),
|
||||
RobotCode: tea.String(s.cfg.Dingtalk.SceneGroup.GroupTemplateRobotIDIssueHandling),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
|
@ -579,26 +517,24 @@ func (s *CallbackService) issueHandlingExtractContent(data chatbot.BotCallbackDa
|
|||
|
||||
// 问题处理群机器人查询知识库
|
||||
func (s *CallbackService) issueHandlingQueryKnowledgeBase(data chatbot.BotCallbackDataModel) {
|
||||
// 获取应用主机器人
|
||||
mainRobotCode := data.RobotCode
|
||||
if robotCode, ok := constants.GroupTemplateRobotIdMap[data.RobotCode]; ok {
|
||||
mainRobotCode = robotCode
|
||||
}
|
||||
// 获取应用机器人配置
|
||||
robotConfig, err := s.botConfigImpl.GetRobotConfig(mainRobotCode)
|
||||
// // 获取应用主机器人
|
||||
// mainRobotCode := data.RobotCode
|
||||
// if robotCode, ok := constants.GroupTemplateRobotIdMap[data.RobotCode]; ok {
|
||||
// mainRobotCode = robotCode
|
||||
// }
|
||||
|
||||
// 获取应用配置
|
||||
appKey, err := s.botConfigImpl.GetRobotAppKey(data.RobotCode)
|
||||
if err != nil {
|
||||
log.Errorf("应用机器人配置不存在: %s, err: %v", mainRobotCode, err)
|
||||
log.Errorf("应用机器人配置不存在: %s, err: %v", data.RobotCode, err)
|
||||
return
|
||||
}
|
||||
// 创建卡片
|
||||
outTrackId := constants.BuildCardOutTrackId(data.ConversationId, mainRobotCode)
|
||||
outTrackId := constants.BuildCardOutTrackId(data.ConversationId, data.RobotCode)
|
||||
_, err = s.dingtalkCardClient.CreateAndDeliver(
|
||||
dingtalk.AppKey{
|
||||
AppKey: robotConfig.ClientId,
|
||||
AppSecret: robotConfig.ClientSecret,
|
||||
},
|
||||
appKey,
|
||||
&card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String(constants.DingtalkCardTplBaseMsg),
|
||||
CardTemplateId: tea.String(s.cfg.Dingtalk.Card.Template.BaseMsg),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
CardParamMap: map[string]*string{
|
||||
"title": tea.String(data.Text.Content),
|
||||
|
|
@ -650,10 +586,7 @@ func (s *CallbackService) issueHandlingQueryKnowledgeBase(data chatbot.BotCallba
|
|||
|
||||
// 卡片更新
|
||||
_, err = s.dingtalkCardClient.UpdateCard(
|
||||
dingtalk.AppKey{
|
||||
AppKey: robotConfig.ClientId,
|
||||
AppSecret: robotConfig.ClientSecret,
|
||||
},
|
||||
appKey,
|
||||
&card_1_0.UpdateCardRequest{
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CardData: &card_1_0.UpdateCardRequestCardData{
|
||||
|
|
@ -740,27 +673,24 @@ func (s *CallbackService) issueHandlingCollectQA(data card.CardRequest) *card.Ca
|
|||
conversationId, robotCode := constants.ParseCardOutTrackId(data.OutTrackId)
|
||||
|
||||
// 获取主应用机器人(这里可能是群模板机器人)
|
||||
mainRobotId := robotCode
|
||||
if robotCode, ok := constants.GroupTemplateRobotIdMap[robotCode]; ok {
|
||||
mainRobotId = robotCode
|
||||
}
|
||||
// mainRobotId := robotCode
|
||||
// if robotCode, ok := constants.GroupTemplateRobotIdMap[robotCode]; ok {
|
||||
// mainRobotId = robotCode
|
||||
// }
|
||||
|
||||
// 获取 robot 配置
|
||||
robotConfig, err := s.botConfigImpl.GetRobotConfig(mainRobotId)
|
||||
// 获取应用配置
|
||||
appKey, err := s.botConfigImpl.GetRobotAppKey(robotCode)
|
||||
if err != nil {
|
||||
log.Errorf("获取 robot 配置失败: %v", err)
|
||||
log.Errorf("获取应用机器人配置失败: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 发送卡片通知用户注入成功
|
||||
outTrackId := constants.BuildCardOutTrackId(conversationId, robotCode)
|
||||
s.dingtalkCardClient.CreateAndDeliver(
|
||||
dingtalk.AppKey{
|
||||
AppKey: robotConfig.ClientId,
|
||||
AppSecret: robotConfig.ClientSecret,
|
||||
},
|
||||
appKey,
|
||||
&card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String(constants.DingtalkCardTplBaseMsg),
|
||||
CardTemplateId: tea.String(s.cfg.Dingtalk.Card.Template.BaseMsg),
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
CardParamMap: map[string]*string{
|
||||
|
|
|
|||
|
|
@ -296,16 +296,14 @@ func (d *DingBotService) createIssueHandlingGroupAndInit(ctx context.Context, ca
|
|||
// 初始化群聊
|
||||
// 1.开场白
|
||||
|
||||
// 构建卡片 OutTrackId
|
||||
outTrackId := constants.BuildCardOutTrackId(openConversationId, constants.GroupTemplateRobotIdIssueHandling)
|
||||
|
||||
// 群主题
|
||||
groupScope := callbackParams["group_scope"].(string)
|
||||
|
||||
// 构建卡片 OutTrackId
|
||||
outTrackId := constants.BuildCardOutTrackId(openConversationId, d.config.Dingtalk.SceneGroup.GroupTemplateRobotIDIssueHandling)
|
||||
_, err = d.dingtalkCardClient.CreateAndDeliver(
|
||||
appKey,
|
||||
&card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String(constants.DingtalkCardTplBaseMsg),
|
||||
CardTemplateId: tea.String(d.config.Dingtalk.Card.Template.BaseMsg),
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CallbackType: tea.String("HTTP"),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
|
|
@ -319,7 +317,7 @@ func (d *DingBotService) createIssueHandlingGroupAndInit(ctx context.Context, ca
|
|||
},
|
||||
OpenSpaceId: tea.String("dtv1.card//im_group." + openConversationId),
|
||||
ImGroupOpenDeliverModel: &card_1_0.CreateAndDeliverRequestImGroupOpenDeliverModel{
|
||||
RobotCode: tea.String(constants.GroupTemplateRobotIdIssueHandling),
|
||||
RobotCode: tea.String(d.config.Dingtalk.SceneGroup.GroupTemplateRobotIDIssueHandling),
|
||||
AtUserIds: map[string]*string{
|
||||
"@ALL": tea.String("@ALL"),
|
||||
},
|
||||
|
|
@ -329,11 +327,11 @@ func (d *DingBotService) createIssueHandlingGroupAndInit(ctx context.Context, ca
|
|||
|
||||
// 2. 机器人能力
|
||||
// 构建卡片 OutTrackId
|
||||
outTrackId = constants.BuildCardOutTrackId(openConversationId, constants.GroupTemplateRobotIdIssueHandling)
|
||||
outTrackId = constants.BuildCardOutTrackId(openConversationId, d.config.Dingtalk.SceneGroup.GroupTemplateRobotIDIssueHandling)
|
||||
_, err = d.dingtalkCardClient.CreateAndDeliver(
|
||||
appKey,
|
||||
&card_1_0.CreateAndDeliverRequest{
|
||||
CardTemplateId: tea.String(constants.DingtalkCardTplBaseMsg),
|
||||
CardTemplateId: tea.String(d.config.Dingtalk.Card.Template.BaseMsg),
|
||||
OutTrackId: tea.String(outTrackId),
|
||||
CallbackType: tea.String("HTTP"),
|
||||
CardData: &card_1_0.CreateAndDeliverRequestCardData{
|
||||
|
|
@ -347,7 +345,7 @@ func (d *DingBotService) createIssueHandlingGroupAndInit(ctx context.Context, ca
|
|||
},
|
||||
OpenSpaceId: tea.String("dtv1.card//im_group." + openConversationId),
|
||||
ImGroupOpenDeliverModel: &card_1_0.CreateAndDeliverRequestImGroupOpenDeliverModel{
|
||||
RobotCode: tea.String(constants.GroupTemplateRobotIdIssueHandling),
|
||||
RobotCode: tea.String(d.config.Dingtalk.SceneGroup.GroupTemplateRobotIDIssueHandling),
|
||||
AtUserIds: map[string]*string{
|
||||
"@ALL": tea.String("@ALL"),
|
||||
},
|
||||
|
|
@ -371,7 +369,7 @@ func (d *DingBotService) createIssueHandlingGroup(ctx context.Context, accessTok
|
|||
|
||||
// 根据群模板ID创建群
|
||||
if useTemplateGroup {
|
||||
return d.dingTalkOld.CreateSceneGroupConversation(ctx, accessToken, "问题处理群", userIds, constants.GroupTemplateIdIssueHandling)
|
||||
return d.dingTalkOld.CreateSceneGroupConversation(ctx, accessToken, "问题处理群", userIds, d.config.Dingtalk.SceneGroup.GroupTemplateIDIssueHandling)
|
||||
}
|
||||
|
||||
return
|
||||
|
|
|
|||
|
|
@ -93,10 +93,14 @@ func run() {
|
|||
ollamaService := llm_service.NewOllamaGenerate(client, utils_vllmClient, configConfig, chatHisImpl)
|
||||
// 初始化工具管理器
|
||||
manager := tools.NewManager(configConfig, client)
|
||||
// 初始化钉钉认证客户端
|
||||
oauth2Client, _ := dingtalk.NewOauth2Client(rdb)
|
||||
// 初始化钉钉联系人客户端
|
||||
contactClient, _ := dingtalk.NewContactClient(configConfig)
|
||||
contactClient, _ := dingtalk.NewContactClient(oauth2Client)
|
||||
// 初始化钉钉记事本客户端
|
||||
notableClient, _ := dingtalk.NewNotableClient(configConfig)
|
||||
notableClient, _ := dingtalk.NewNotableClient(oauth2Client)
|
||||
// 初始化钉钉卡片客户端
|
||||
cardClient, _ := dingtalk.NewCardClient(oauth2Client)
|
||||
// 初始化工具注册
|
||||
toolRegis := tools_regis.NewToolsRegis(botToolsImpl)
|
||||
// 初始化机器人聊天历史实现层
|
||||
|
|
@ -120,8 +124,9 @@ func run() {
|
|||
group := qywx.NewGroup(botGroupQywxImpl, qywxAuth)
|
||||
other := qywx.NewOther(qywxAuth)
|
||||
qywxAppBiz := biz.NewQywxAppBiz(configConfig, botGroupQywxImpl, group, other)
|
||||
groupConfigBiz := biz.NewGroupConfigBiz(toolRegis, utils_ossClient, botGroupConfigImpl, registry, configConfig, impl.NewReportDailyCacheImpl(db), rdb)
|
||||
dingTalkBotBiz := biz.NewDingTalkBotBiz(doDo, handle, botConfigImpl, botGroupImpl, user, botChatHisImpl, impl.NewReportDailyCacheImpl(db), manager, configConfig, sendCardClient, groupConfigBiz)
|
||||
groupConfigBiz := biz.NewGroupConfigBiz(toolRegis, utils_ossClient, botGroupConfigImpl, botConfigImpl, registry, configConfig, impl.NewReportDailyCacheImpl(db), rdb, manager, cardClient)
|
||||
macro := do.NewMacro(botGroupImpl, impl.NewReportDailyCacheImpl(db))
|
||||
dingTalkBotBiz := biz.NewDingTalkBotBiz(doDo, handle, botConfigImpl, botGroupImpl, user, botChatHisImpl, impl.NewReportDailyCacheImpl(db), manager, configConfig, sendCardClient, groupConfigBiz, macro)
|
||||
// 初始化钉钉机器人服务
|
||||
cronService = NewCronService(configConfig, dingTalkBotBiz, qywxAppBiz, groupConfigBiz)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue