@@ -17,11 +17,16 @@ import (
1717)
1818
1919var (
20- db sqlite.DB // 数据库
21- chatCTXMap sync.Map // 群号/私聊:消息上下文
22- chatDone = make (chan struct {} ) // 用于结束会话
20+ db sqlite.DB // 数据库
21+ msgContext sync.Map // 群号/私聊:消息上下文
22+ chatRoom = make (map [ string ] ChatRoom ) // 连续会话聊天室
2323)
2424
25+ type ChatRoom struct {
26+ wxId string
27+ done chan struct {}
28+ }
29+
2530// ApiKey apikey表,存放openai key
2631type ApiKey struct {
2732 Key string `gorm:"column:key;index"`
@@ -58,7 +63,11 @@ func init() {
5863 DataFolder : "chatgpt" ,
5964 OnDisable : func (ctx * robot.Ctx ) {
6065 ctx .ReplyText ("禁用成功" )
61- chatDone <- struct {}{}
66+ wxId := ctx .Event .FromUniqueID
67+ if room , ok := chatRoom [wxId ]; ok {
68+ close (room .done )
69+ delete (chatRoom , wxId )
70+ }
6271 },
6372 })
6473
@@ -76,39 +85,51 @@ func init() {
7685
7786 // 连续会话
7887 engine .OnFullMatch ("开始会话" ).SetBlock (true ).Handle (func (ctx * robot.Ctx ) {
88+ wxId := ctx .Event .FromUniqueID
7989 // 检查是否已经在进行会话
80- if _ , ok := chatCTXMap . Load ( ctx . Event . FromUniqueID ) ; ok {
90+ if _ , ok := chatRoom [ wxId ] ; ok {
8191 ctx .ReplyTextAndAt ("当前已经在会话中了" )
8292 return
8393 }
8494
85- var nullMessage []gogpt.ChatCompletionMessage
95+ var (
96+ nullMessage []gogpt.ChatCompletionMessage
97+ room = ChatRoom {
98+ wxId : wxId ,
99+ done : make (chan struct {}),
100+ }
101+ )
102+
103+ chatRoom [wxId ] = room
86104
87105 // 开始会话
88106 recv , cancel := ctx .EventChannel (ctx .CheckGroupSession ()).Repeat ()
89107 defer cancel ()
90- chatCTXMap .LoadOrStore (ctx . Event . FromUniqueID , nullMessage )
108+ msgContext .LoadOrStore (wxId , nullMessage )
91109 ctx .ReplyTextAndAt ("收到!已开始ChatGPT连续会话中,输入\" 结束会话\" 结束会话,或5分钟后自动结束,请开始吧!" )
92110 for {
93111 select {
94112 case <- time .After (time .Minute * 5 ):
95- chatCTXMap .LoadAndDelete (ctx . Event . FromUniqueID )
113+ msgContext .LoadAndDelete (wxId )
96114 ctx .ReplyTextAndAt ("😊检测到您已有5分钟不再提问,那我先主动结束会话咯" )
97115 return
98- case <- chatDone :
99- chatCTXMap .LoadAndDelete (ctx .Event .FromUniqueID )
100- ctx .ReplyTextAndAt ("已退出ChatGPT" )
101- return
116+ case <- room .done :
117+ if room .wxId == wxId {
118+ msgContext .LoadAndDelete (wxId )
119+ ctx .ReplyTextAndAt ("已退出ChatGPT" )
120+ return
121+ }
102122 case ctx := <- recv :
123+ wxId := ctx .Event .FromUniqueID
103124 msg := ctx .MessageString ()
104125 if msg == "" {
105126 continue
106127 } else if msg == "结束会话" {
107- chatCTXMap .LoadAndDelete (ctx . Event . FromUniqueID )
128+ msgContext .LoadAndDelete (wxId )
108129 ctx .ReplyTextAndAt ("已结束聊天的上下文语境,您可以重新发起提问" )
109130 return
110131 } else if msg == "清空会话" {
111- chatCTXMap .Store (ctx . Event . FromUniqueID , nullMessage )
132+ msgContext .Store (wxId , nullMessage )
112133 ctx .ReplyTextAndAt ("已清空会话,您可以继续提问新的问题" )
113134 continue
114135 } else if strings .HasPrefix (msg , "作画" ) {
@@ -129,7 +150,7 @@ func init() {
129150 }
130151
131152 var messages []gogpt.ChatCompletionMessage
132- if c , ok := chatCTXMap .Load (ctx . Event . FromUniqueID ); ok {
153+ if c , ok := msgContext .Load (wxId ); ok {
133154 messages = append (c .([]gogpt.ChatCompletionMessage ), gogpt.ChatCompletionMessage {
134155 Role : "user" ,
135156 Content : msg ,
@@ -152,7 +173,7 @@ func init() {
152173 Role : "assistant" ,
153174 Content : answer ,
154175 })
155- chatCTXMap .Store (ctx . Event . FromUniqueID , messages )
176+ msgContext .Store (wxId , messages )
156177 ctx .ReplyTextAndAt (answer )
157178 }
158179 }
0 commit comments