148 lines
3.8 KiB
Go
148 lines
3.8 KiB
Go
package controller
|
||
|
||
import (
|
||
"fmt"
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/tidwall/gjson"
|
||
"kefu/models"
|
||
"kefu/tools"
|
||
"kefu/ws"
|
||
"strings"
|
||
"time"
|
||
)
|
||
|
||
/*
|
||
{
|
||
"id": "chatcmpl-8cbx4v1ZZLQKV1YunB9DfzVJ8D40p",
|
||
"object": "chat.completion",
|
||
"created": 1704213042,
|
||
"model": "gpt-3.5-turbo-0613",
|
||
"choices": [
|
||
{
|
||
"index": 0,
|
||
"message": {
|
||
"role": "assistant",
|
||
"content": "我是一个AI助手,没有真实的身份,只是由计算机程序所驱动的虚拟个体。"
|
||
},
|
||
"logprobs": null,
|
||
"finish_reason": "stop"
|
||
}
|
||
],
|
||
"usage": {
|
||
"prompt_tokens": 11,
|
||
"completion_tokens": 34,
|
||
"total_tokens": 45
|
||
},
|
||
"system_fingerprint": null
|
||
}
|
||
*/
|
||
func PostV1ChatCompletions(c *gin.Context) {
|
||
rawData, err := c.GetRawData()
|
||
jsonData := string(rawData)
|
||
authorization := c.Request.Header.Get("Authorization")
|
||
entIdKefuName := strings.Replace(authorization, "Bearer ", "", -1)
|
||
strs := strings.Split(entIdKefuName, "-")
|
||
choices := []map[string]interface{}{
|
||
{
|
||
"message": map[string]interface{}{
|
||
"role": "assistant",
|
||
"content": "",
|
||
},
|
||
},
|
||
}
|
||
if err != nil || len(strs) < 3 {
|
||
c.JSON(200, gin.H{
|
||
"id": "chatcmpl-8cbx4v1ZZLQKV1YunB9DfzVJ8D40p",
|
||
"choices": choices,
|
||
})
|
||
return
|
||
}
|
||
entId := strs[1]
|
||
kefuName := strs[2]
|
||
messages := gjson.Get(jsonData, "messages").Array()
|
||
content := messages[len(messages)-1].Get("content").String()
|
||
visitorId := gjson.Get(jsonData, "chatId").String()
|
||
kefuInfo := models.FindUser(kefuName)
|
||
if fmt.Sprintf("%d", kefuInfo.ID) != entId {
|
||
c.JSON(200, gin.H{
|
||
"id": "chatcmpl-8cbx4v1ZZLQKV1YunB9DfzVJ8D40p",
|
||
"choices": choices,
|
||
})
|
||
return
|
||
}
|
||
visitorName := "API调用"
|
||
avator := "/static/images/api-code-avatar.jpg"
|
||
//查找访客插入访客表
|
||
visitorId = fmt.Sprintf("api|%s|%s", entId, visitorId)
|
||
vistorInfo := models.FindVisitorByVistorId(visitorId)
|
||
refer := "OpenAI客户端"
|
||
if vistorInfo.ID == 0 {
|
||
|
||
vistorInfo = models.Visitor{
|
||
Model: models.Model{
|
||
CreatedAt: time.Now(),
|
||
UpdatedAt: time.Now(),
|
||
},
|
||
Name: visitorName,
|
||
Avator: avator,
|
||
ToId: kefuName,
|
||
VisitorId: visitorId,
|
||
Status: 1,
|
||
Refer: refer,
|
||
EntId: entId,
|
||
VisitNum: 0,
|
||
City: "API调用",
|
||
ClientIp: c.ClientIP(),
|
||
}
|
||
vistorInfo.AddVisitor()
|
||
} else {
|
||
//更新状态上线
|
||
go models.UpdateVisitor(entId, visitorName, avator, visitorId, kefuName, 3, c.ClientIP(), c.ClientIP(),
|
||
refer,
|
||
refer,
|
||
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, content, c)
|
||
//判断当前访客是否机器人回复
|
||
if !models.CheckVisitorRobotReply(vistorInfo.State) {
|
||
c.JSON(200, gin.H{
|
||
"id": "chatcmpl-8cbx4v1ZZLQKV1YunB9DfzVJ8D40p",
|
||
"choices": choices,
|
||
})
|
||
return
|
||
}
|
||
result := ""
|
||
config := models.GetEntConfigsMap(entId, "QdrantAIStatus")
|
||
//调用自动回复
|
||
result = GetLearnReplyContent(entId, content)
|
||
result = tools.TrimHtml(result)
|
||
if result == "" && config["QdrantAIStatus"] == "true" {
|
||
//调用GPT3.5
|
||
result = ws.Gpt3Knowledge(entId, visitorId, kefuInfo, content)
|
||
}
|
||
|
||
go models.AddVisitorExt(visitorId, refer, c.GetHeader("User-Agent"), refer, refer, refer, c.ClientIP(), refer, entId, "")
|
||
if result != "" {
|
||
models.CreateMessage(kefuName, visitorId, result, "kefu", entId, "read")
|
||
go ws.KefuMessage(visitorId, result, kefuInfo)
|
||
}
|
||
choices = []map[string]interface{}{
|
||
{
|
||
"message": map[string]interface{}{
|
||
"role": "assistant",
|
||
"content": result,
|
||
},
|
||
},
|
||
}
|
||
c.SecureJSON(200, gin.H{
|
||
"id": "chatcmpl-8cbx4v1ZZLQKV1YunB9DfzVJ8D40p",
|
||
"choices": choices,
|
||
})
|
||
}
|