forked from ConnectAI-E/feishu-openai
-
Notifications
You must be signed in to change notification settings - Fork 0
/
handler.go
233 lines (209 loc) · 6.45 KB
/
handler.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
package handlers
import (
"context"
"encoding/json"
"fmt"
"start-feishubot/initialization"
"start-feishubot/services"
"start-feishubot/services/openai"
"strings"
larkcard "github.com/larksuite/oapi-sdk-go/v3/card"
larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1"
)
// 责任链
func chain(data *ActionInfo, actions ...Action) bool {
for _, v := range actions {
if !v.Execute(data) {
return false
}
}
return true
}
type MessageHandler struct {
sessionCache services.SessionServiceCacheInterface
msgCache services.MsgCacheInterface
gpt *openai.ChatGPT
config initialization.Config
}
func (m MessageHandler) cardHandler(_ context.Context,
cardAction *larkcard.CardAction) (interface{}, error) {
var cardMsg CardMsg
actionValue := cardAction.Action.Value
actionValueJson, _ := json.Marshal(actionValue)
json.Unmarshal(actionValueJson, &cardMsg)
//fmt.Println("cardMsg: ", cardMsg)
if cardMsg.Kind == ClearCardKind {
newCard, err, done := CommonProcessClearCache(cardMsg, m.sessionCache)
if done {
return newCard, err
}
return nil, nil
}
if cardMsg.Kind == PicResolutionKind {
CommonProcessPicResolution(cardMsg, cardAction, m.sessionCache)
return nil, nil
}
if cardMsg.Kind == PicTextMoreKind {
go func() {
m.CommonProcessPicMore(cardMsg)
}()
}
//if cardMsg.Kind == PicVarMoreKind {
// //todo: 暂时不允许 以图搜图 模式下的 再来一张
// go func() {
// m.CommonProcessPicMore(cardMsg)
// }()
//}
if cardMsg.Kind == PicModeChangeKind {
newCard, err, done := CommonProcessPicModeChange(cardMsg, m.sessionCache)
if done {
return newCard, err
}
return nil, nil
}
return nil, nil
}
func (m MessageHandler) CommonProcessPicMore(msg CardMsg) {
resolution := m.sessionCache.GetPicResolution(msg.SessionId)
//fmt.Println("resolution: ", resolution)
//fmt.Println("msg: ", msg)
question := msg.Value.(string)
bs64, _ := m.gpt.GenerateOneImage(question, resolution)
replayImageCardByBase64(context.Background(), bs64, &msg.MsgId,
&msg.SessionId, question)
}
func CommonProcessPicResolution(msg CardMsg,
cardAction *larkcard.CardAction,
cache services.SessionServiceCacheInterface) {
option := cardAction.Action.Option
//fmt.Println(larkcore.Prettify(msg))
cache.SetPicResolution(msg.SessionId, services.Resolution(option))
//send text
replyMsg(context.Background(), "已更新图片分辨率为"+option,
&msg.MsgId)
}
func CommonProcessClearCache(cardMsg CardMsg, session services.SessionServiceCacheInterface) (
interface{}, error, bool) {
if cardMsg.Value == "1" {
newCard, _ := newSendCard(
withHeader("️🆑 机器人提醒", larkcard.TemplateRed),
withMainMd("已删除此话题的上下文信息"),
withNote("我们可以开始一个全新的话题,继续找我聊天吧"),
)
session.Clear(cardMsg.SessionId)
return newCard, nil, true
}
if cardMsg.Value == "0" {
newCard, _ := newSendCard(
withHeader("️🆑 机器人提醒", larkcard.TemplateGreen),
withMainMd("依旧保留此话题的上下文信息"),
withNote("我们可以继续探讨这个话题,期待和您聊天。如果您有其他问题或者想要讨论的话题,请告诉我哦"),
)
return newCard, nil, true
}
return nil, nil, false
}
func CommonProcessPicModeChange(cardMsg CardMsg,
session services.SessionServiceCacheInterface) (
interface{}, error, bool) {
if cardMsg.Value == "1" {
sessionId := cardMsg.SessionId
session.Clear(sessionId)
session.SetMode(sessionId,
services.ModePicCreate)
session.SetPicResolution(sessionId,
services.Resolution256)
newCard, _ :=
newSendCard(
withHeader("🖼️ 已进入图片创作模式", larkcard.TemplateBlue),
withPicResolutionBtn(&sessionId),
withNote("提醒:回复文本或图片,让AI生成相关的图片。"))
return newCard, nil, true
}
if cardMsg.Value == "0" {
newCard, _ := newSendCard(
withHeader("️🎒 机器人提醒", larkcard.TemplateGreen),
withMainMd("依旧保留此话题的上下文信息"),
withNote("我们可以继续探讨这个话题,期待和您聊天。如果您有其他问题或者想要讨论的话题,请告诉我哦"),
)
return newCard, nil, true
}
return nil, nil, false
}
func judgeMsgType(event *larkim.P2MessageReceiveV1) (string, error) {
msgType := event.Event.Message.MessageType
switch *msgType {
case "text", "image", "audio":
return *msgType, nil
default:
return "", fmt.Errorf("unknown message type: %v", *msgType)
}
}
func (m MessageHandler) msgReceivedHandler(ctx context.Context, event *larkim.P2MessageReceiveV1) error {
handlerType := judgeChatType(event)
if handlerType == "otherChat" {
fmt.Println("unknown chat type")
return nil
}
//fmt.Println(larkcore.Prettify(event.Event.Message))
msgType, err := judgeMsgType(event)
if err != nil {
fmt.Printf("error getting message type: %v\n", err)
return nil
}
content := event.Event.Message.Content
msgId := event.Event.Message.MessageId
rootId := event.Event.Message.RootId
chatId := event.Event.Message.ChatId
mention := event.Event.Message.Mentions
sessionId := rootId
if sessionId == nil || *sessionId == "" {
sessionId = msgId
}
msgInfo := MsgInfo{
handlerType: handlerType,
msgType: msgType,
msgId: msgId,
chatId: chatId,
qParsed: strings.Trim(parseContent(*content), " "),
fileKey: parseFileKey(*content),
imageKey: parseImageKey(*content),
sessionId: sessionId,
mention: mention,
}
data := &ActionInfo{
ctx: &ctx,
handler: &m,
info: &msgInfo,
}
actions := []Action{
&ProcessedUniqueAction{}, //避免重复处理
&ProcessMentionAction{}, //判断机器人是否应该被调用
&AudioAction{}, //语音处理
&PicAction{}, //图片处理
&EmptyAction{}, //空消息处理
&ClearAction{}, //清除消息处理
&HelpAction{}, //帮助处理
&RolePlayAction{}, //角色扮演处理
&MessageAction{}, //消息处理
}
chain(data, actions...)
return nil
}
var _ MessageHandlerInterface = (*MessageHandler)(nil)
func NewMessageHandler(gpt *openai.ChatGPT,
config initialization.Config) MessageHandlerInterface {
return &MessageHandler{
sessionCache: services.GetSessionCache(),
msgCache: services.GetMsgCache(),
gpt: gpt,
config: config,
}
}
func (m MessageHandler) judgeIfMentionMe(mention []*larkim.
MentionEvent) bool {
if len(mention) != 1 {
return false
}
return *mention[0].Name == m.config.FeishuBotName
}