package controller import ( "encoding/json" "fmt" "github.com/gin-gonic/gin" "io" "kefu/lib" "kefu/models" "kefu/tools" "kefu/types" "kefu/ws" "log" "net/http" "net/url" "time" ) type PostApiRobotMessageForm struct { Id uint `form:"id" json:"id" uri:"id" xml:"id"` VisitorId string `form:"visitor_id" json:"visitor_id" uri:"visitor_id" xml:"visitor_id" binding:"required"` Content string `form:"content" json:"content" uri:"content" xml:"content" binding:"required"` VisitorName string `form:"visitor_name" json:"visitor_name" uri:"visitor_name" xml:"visitor_name"` Refer string `form:"refer" json:"refer" uri:"refer" xml:"refer"` Avatar string `form:"avatar" json:"avatar" uri:"avatar" xml:"avatar"` } // api调用方式插入访客 func PostApiRobotMessage(c *gin.Context) { var form PostApiRobotMessageForm err := c.Bind(&form) if err != nil { c.JSON(200, gin.H{ "code": types.ApiCode.FAILED, "msg": types.ApiCode.GetMessage(types.ApiCode.INVALID), "result": err.Error(), }) return } visitor_id := form.VisitorId visitor_name := form.VisitorName avatar := form.Avatar content := form.Content entId := c.Param("entId") kefuName := c.Param("kefuName") kefuInfo, _ := c.Get("kefuInfo") avator := avatar if visitor_name == "" { visitor_name = "API访客" } if avator == "" { avator = "/static/images/api-code-avatar.jpg" } if form.Refer == "" { form.Refer = "来自API调用方" } //查找访客插入访客表 visitorId := fmt.Sprintf("api|%s|%s", entId, visitor_id) vistorInfo := models.FindVisitorByVistorId(visitorId) if vistorInfo.ID == 0 { vistorInfo = models.Visitor{ Model: models.Model{ CreatedAt: time.Now(), UpdatedAt: time.Now(), }, Name: visitor_name, Avator: avator, ToId: kefuName, VisitorId: visitorId, Status: 1, Refer: form.Refer, EntId: entId, VisitNum: 0, City: "API调用", ClientIp: c.ClientIP(), } vistorInfo.AddVisitor() } else { //更新状态上线 go models.UpdateVisitor(entId, form.VisitorName, avatar, visitorId, kefuName, 3, c.ClientIP(), c.ClientIP(), form.Refer, form.Refer, form.Refer, vistorInfo.VisitNum+1, ) } go ws.VisitorOnline(kefuName, vistorInfo) go ws.VisitorSendToKefu(kefuName, vistorInfo, content) //发送消息通知 go SendWechatVisitorMessageTemplate(kefuName, vistorInfo.Name, vistorInfo.VisitorId, content, vistorInfo.EntId) go SendWorkWechatWebHook(vistorInfo.EntId, vistorInfo, kefuInfo.(models.User), content, c) //判断当前访客是否机器人回复 if !models.CheckVisitorRobotReply(vistorInfo.State) { c.JSON(200, gin.H{ "code": types.ApiCode.SUCCESS, "msg": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), "result": gin.H{ "content": "", }, }) return } result := "" config := models.GetEntConfigsMap(entId, "QdrantAIStatus") //调用自动回复 result = GetLearnReplyContent(entId, content) if result == "" && config["QdrantAIStatus"] == "true" { //调用GPT3.5 result = ws.Gpt3Knowledge(entId, visitorId, kefuInfo.(models.User), content) } go models.AddVisitorExt(visitorId, form.Refer, c.GetHeader("User-Agent"), form.Refer, form.Refer, form.Refer, c.ClientIP(), form.Refer, entId, "") if result != "" { models.CreateMessage(kefuName, visitorId, result, "kefu", entId, "read") go ws.KefuMessage(visitorId, result, kefuInfo.(models.User)) } c.JSON(200, gin.H{ "code": types.ApiCode.SUCCESS, "msg": types.ApiCode.GetMessage(types.ApiCode.SUCCESS), "result": gin.H{ "content": result, }, }) } // 微信自动回复 func PostWechatRobotMessage(c *gin.Context) { visitor_id := c.PostForm("visitor_id") nickName := c.PostForm("nickname") avatar := "/static/images/we-chat-wx.png" entId := c.PostForm("ent_id") content := c.PostForm("content") kefuName := c.PostForm("kefu_name") kefuInfo := models.FindUserByUid(entId) if kefuInfo.ID == 0 || kefuInfo.Name != kefuName { c.JSON(200, gin.H{ "code": types.ApiCode.ACCOUNT_NO_EXIST, "msg": types.ApiCode.GetMessage(types.ApiCode.ACCOUNT_NO_EXIST), }) return } //查找访客插入访客表 visitorId := fmt.Sprintf("wxperson|%s|%s", entId, visitor_id) vistorInfo := models.FindVisitorByVistorId(visitorId) if vistorInfo.ID == 0 { visitorName := nickName avator := avatar if visitorName == "" { visitorName = "微信客服用户" } if avator == "" { avator = "/static/images/we-chat-wx.png" } vistorInfo = models.Visitor{ Model: models.Model{ CreatedAt: time.Now(), UpdatedAt: time.Now(), }, Name: visitorName, Avator: avator, ToId: kefuInfo.Name, VisitorId: visitorId, Status: 1, Refer: "来自个人微信", EntId: entId, VisitNum: 0, City: "个人微信", ClientIp: c.ClientIP(), } vistorInfo.AddVisitor() } else { go models.UpdateVisitorStatus(visitorId, 3) } go ws.VisitorOnline(kefuInfo.Name, vistorInfo) go ws.VisitorSendToKefu(kefuInfo.Name, vistorInfo, content) //调用GPT3.5 result := ws.Gpt3Knowledge(entId, visitorId, kefuInfo, content) models.CreateMessage(kefuInfo.Name, visitorId, result, "kefu", entId, "read") go ws.KefuMessage(visitorId, result, kefuInfo) c.JSON(200, gin.H{ "code": 200, "msg": "ok", "result": gin.H{ "content": result, }, }) } func GetKefuAiKnowledge(c *gin.Context) { c.Header("Content-Type", "text/html;charset=utf-8;") f, _ := c.Writer.(http.Flusher) entId, _ := c.Get("ent_id") visitorId := c.Query("visitor_id") config := models.GetEntConfigsMap(entId.(string), "chatGPTUrl", "chatGPTSecret", "QdrantAIStatus", "QdrantAICollect", "chatGPTSystem", "chatGPTPrompt", "RobotName", "RobotAvator", "chatGPTHistory") api := models.FindConfig("BaseGPTKnowledge") if config["chatGPTUrl"] == "" || config["chatGPTSecret"] == "" || config["QdrantAICollect"] == "" || api == "" { c.Writer.Write([]byte("未配置AI服务")) f.Flush() return } path := fmt.Sprintf("%s/%s/searchStream", api, config["QdrantAICollect"]) data := url.Values{} system := "" if config["chatGPTSystem"] != "" { system = config["chatGPTSystem"] } data.Set("system", system) data.Set("prompt", config["chatGPTPrompt"]) data.Set("gptUrl", config["chatGPTUrl"]) data.Set("gptSecret", config["chatGPTSecret"]) messages := models.FindMessageByQueryPage(1, 6, "visitor_id = ?", visitorId) gptMessages := make([]lib.Gpt3Dot5Message, 0) for i := len(messages) - 1; i >= 1; i-- { reqContent := messages[i].Content if messages[i].MesType == "visitor" { gptMessages = append(gptMessages, lib.Gpt3Dot5Message{ Role: "user", Content: reqContent, }) } else { gptMessages = append(gptMessages, lib.Gpt3Dot5Message{ Role: "assistant", Content: reqContent, }) } } historyJson, _ := json.Marshal(gptMessages) data.Set("history", string(historyJson)) data.Set("keywords", messages[0].Content) log.Printf("请求GPT:%v", data) reader, body, err := tools.PostFormStream(path, data) if err == nil { for { r, _, err := reader.ReadRune() if err != nil { if err == io.EOF { break } break } c.Writer.Write([]byte(string(r))) f.Flush() } body.Close() } }