257 lines
7.1 KiB
Go
257 lines
7.1 KiB
Go
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()
|
|
}
|
|
}
|