123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- package channel
- import (
- "context"
- "encoding/json"
- "github.com/openai/openai-go"
- "github.com/zeromicro/go-zero/core/logx"
- "math/rand"
- "time"
- "wechat-api/internal/pkg/customer_of_im/proto"
- "wechat-api/internal/pkg/wechat_ws"
- "wechat-api/internal/svc"
- )
- type IChannel interface {
- OnMessage(msg *wechat_ws.MsgJsonObject) error
- FriendTalkHandle(msgStr string) error
- TextToChatMessage(msgStr string) (*ChatMessage, error)
- GenerateRelevantContext(msg *ChatMessage) (*RelevantContext, error)
- Send(message *ReplyMessage) error
- }
- type Channel struct {
- subChannel IChannel
- }
- func (c *Channel) InitChannel(subChannel IChannel) {
- c.subChannel = subChannel
- }
- func (c *Channel) After(chatCtx *RelevantContext, message *ChatMessage, reply *ReplyMessage) bool {
- return true
- }
- func (c *Channel) Before(chatCtx *RelevantContext, message *ChatMessage, reply *ReplyMessage) bool {
- return true
- }
- func (c *Channel) randomPause() {
-
- source := rand.NewSource(time.Now().UnixNano())
-
- rng := rand.New(source)
-
- pauseDuration := 2 + rng.Intn(4)
-
- time.Sleep(time.Duration(pauseDuration) * time.Second)
- }
- func (c *Channel) beforeSendReply(reply *ReplyMessage) error {
- jsonReplay := make([]*ReplyJson, 0)
- err := json.Unmarshal([]byte(reply.Content), &jsonReplay)
- if err == nil && len(jsonReplay) > 0 {
- for i, item := range jsonReplay {
- if item.Content == "" {
- continue
- }
- switch item.Type {
- case "TEXT":
- reply.Content = item.Content
- _ = c.beforeSendReply(reply)
- default:
- logx.Error("未知类型", item.Type)
- }
-
- if i < len(jsonReplay)-1 {
- c.randomPause()
- }
- }
- return nil
- }
- err = c.subChannel.Send(reply)
- return err
- }
- func (c *Channel) handle(chatCtx *RelevantContext, message *ChatMessage, reply *ReplyMessage) error {
- chat := NewChatEngine(chatCtx.BaseURL, chatCtx.APIKey, chatCtx.IsFastGPT)
- replyText, err := chat.ChatCompletions(context.Background(), openai.ChatModelGPT4, message.Content, message.UserId)
- if err != nil {
- logx.Error(err)
- return err
- }
- reply.Content = replyText
- err = c.beforeSendReply(reply)
- return err
- }
- func (c *Channel) Produce(svcCtx *svc.ServiceContext, chatCtx *RelevantContext, message *ChatMessage) {
- reply := &ReplyMessage{
- ChatMessage: &ChatMessage{
- UserId: message.UserId,
- MsgId: svcCtx.NodeID.Generate().String(),
- CreateTime: time.Time{},
- Type: proto.EnumContentType_Text,
- Content: "",
- FromUserId: message.ToUserId,
- FromUserNickname: message.ToUserNickname,
- ToUserId: message.FromUserId,
- ToUserNickname: message.FromUserNickname,
- GroupId: message.GroupId,
- GroupName: message.GroupName,
- IsGroup: message.IsGroup,
- IsAt: message.IsAt,
- },
- }
-
- ret := c.Before(chatCtx, message, reply)
- if !ret {
- return
- }
-
- err := c.handle(chatCtx, message, reply)
- if err != nil {
- logx.Error(err)
- return
- }
- _ = c.After(chatCtx, message, reply)
- }
|