Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit e50dd39

Browse files
authored
Merge pull request #12 from chyroc/support-reply-card
feat: support reply card message
2 parents 7a324b3 + d3f6d2e commit e50dd39

File tree

6 files changed

+100
-11
lines changed

6 files changed

+100
-11
lines changed

.env.example

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ LARK_OPEN_BASE_URL=
44
LARK_WWW_BASE_URL=
55
CHATGPT_API_KEY=
66
CHATGPT_API_URL=
7-
ENABLE_SESSION_FOR_LARK_GROUP=true
7+
ENABLE_SESSION_FOR_LARK_GROUP=true
8+
ENABLE_CARD_RESP=true

larkgpt/client.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type Client struct {
1414
serverPort string
1515
maintained bool
1616
enableSessionForLarkGroup bool
17+
enableCardResp bool
1718
}
1819

1920
type ClientConfig struct {
@@ -32,6 +33,7 @@ type ClientConfig struct {
3233
ServerPort string
3334
Metrics IMetrics
3435
EnableSessionForLarkGroup bool // 给群聊的消息启动 session,session id 是消息的 root id
36+
EnableCardResp bool // 以飞书卡片消息的形式回复消息
3537
}
3638

3739
func New(config *ClientConfig) *Client {
@@ -56,9 +58,9 @@ func New(config *ClientConfig) *Client {
5658
res.chatGPTIns = newChatGPTClient(config.ChatGPTAPIURL, config.ChatGPTAPIKey, res.metricsIns)
5759

5860
res.serverPort = config.ServerPort
59-
6061
res.maintained = config.Maintained
6162
res.enableSessionForLarkGroup = config.EnableSessionForLarkGroup
63+
res.enableCardResp = config.EnableCardResp
6264

6365
return res
6466
}

larkgpt/lark.go

+11
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,14 @@ func (r *larkClient) replyText(ctx context.Context, msgID, text string) error {
2929
}
3030
return err
3131
}
32+
33+
func (r *larkClient) replyCard(ctx context.Context, msgID string, card *lark.MessageContentCard) error {
34+
_, _, err := r.cli.Message.Reply(msgID).SendCard(ctx, card.String())
35+
if err != nil {
36+
r.metricsIns.EmitLarkApiFailed()
37+
log.Println("LarkAPI 调用失败 请稍后重试. ", err)
38+
} else {
39+
r.metricsIns.EmitLarkApiSuccess()
40+
}
41+
return err
42+
}

larkgpt/larkbot.go

+11-9
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func (r *Client) ReceiveChatGPTMessage(ctx context.Context, msg string, event *l
4949

5050
log.Print("Receive message: ", msg)
5151
if r.maintained {
52-
return r.larkIns.replyText(context.Background(), event.Message.MessageID, "ChatGPT Bot 正在维护中 请稍后重试.请飞书搜索 ChatGPT 讨论群, 选择同款头像进群看进度.")
52+
return r.replyMaintained(event.Message.MessageID)
5353
}
5454

5555
var result string
@@ -62,10 +62,10 @@ func (r *Client) ReceiveChatGPTMessage(ctx context.Context, msg string, event *l
6262
log.Println("msg: ", msg, "session", sessionID, "result: ", result)
6363
if err != nil {
6464
log.Println("ChatGPT 请求失败 请稍后重试. ", err)
65-
return r.larkIns.replyText(context.Background(), event.Message.MessageID, "ChatGPT 请求失败 请稍后重试.")
65+
return r.replyChatGPTError(event.Message.MessageID, "ChatGPT 请求失败 请稍后重试.")
6666
}
6767

68-
return r.larkIns.replyText(context.Background(), event.Message.MessageID, result)
68+
return r.larkIns.replyChatGPTMessage(event.Message.MessageID, msg, result, r.enableCardResp)
6969
}
7070

7171
func (r *Client) ReceiveCommandMessage(ctx context.Context, command string, event *lark.EventV2IMMessageReceiveV1) {
@@ -77,19 +77,21 @@ func (r *Client) ReceiveCommandMessage(ctx context.Context, command string, even
7777
err = r.chatGPTIns.DeleteSession(sessionID)
7878
}
7979
if err != nil {
80-
r.larkIns.replyText(context.Background(), event.Message.MessageID, "Reset Failed.")
80+
_ = r.replyChatGPTError(event.Message.MessageID, "Reset Failed.")
8181
return
8282
}
83-
r.larkIns.replyText(context.Background(), event.Message.MessageID, "Reset Success.")
83+
_ = r.replyChatGPTSuccess(event.Message.MessageID, "Reset Success.")
8484
default:
85-
r.larkIns.replyText(context.Background(), event.Message.MessageID, "Unknown Command.")
85+
_ = r.replyChatGPTError(event.Message.MessageID, "Unknown Command.")
8686
}
8787
}
8888

8989
func (r *Client) larkMessageReceiverHandler(ctx context.Context, cli *lark.Lark, schema string, header *lark.EventHeaderV2, event *lark.EventV2IMMessageReceiveV1) (string, error) {
9090
content, err := lark.UnwrapMessageContent(event.Message.MessageType, event.Message.Content)
9191
if err != nil {
92-
return "", err
92+
log.Println("解析消息内容失败. ", err)
93+
_ = r.replyChatGPTError(event.Message.MessageID, "解析消息内容失败.")
94+
return "", nil // 无法重试
9395
}
9496
msg := ""
9597
switch event.Message.MessageType {
@@ -99,8 +101,8 @@ func (r *Client) larkMessageReceiverHandler(ctx context.Context, cli *lark.Lark,
99101
msg = wrapLarkPostMessageText(content)
100102
default:
101103
log.Println("暂不支持的消息类型.")
102-
_ = r.larkIns.replyText(context.Background(), event.Message.MessageID, "暂不支持的消息类型.")
103-
return "", nil
104+
_ = r.replyChatGPTError(event.Message.MessageID, "暂不支持的消息类型.")
105+
return "", nil // 无法重试
104106
}
105107
msg = filterMsg(msg)
106108
if isNonsense(content, msg) {

larkgpt/reply.go

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package larkgpt
2+
3+
import (
4+
"context"
5+
6+
"github.com/chyroc/lark"
7+
"github.com/chyroc/lark/card"
8+
)
9+
10+
func (r *Client) replyMaintained(msgID string) error {
11+
if !r.enableCardResp {
12+
text := "ChatGPT Bot 正在维护中 请稍后重试.请飞书搜索 ChatGPT 讨论群, 选择同款头像进群看进度."
13+
return r.larkIns.replyText(context.Background(), msgID, text)
14+
}
15+
cardIns := card.Card(
16+
card.Div().SetFields(
17+
card.FieldMarkdown("ChatGPT Bot 正在维护中 请稍后重试."),
18+
),
19+
card.HR(),
20+
card.Note(card.Text("请飞书搜索 ChatGPT 讨论群, 选择同款头像进群看进度.")),
21+
).SetHeader(
22+
card.Header("ChatGPT Bot Error").SetRed(),
23+
)
24+
return r.larkIns.replyCard(context.Background(), msgID, cardIns)
25+
}
26+
27+
func (r *Client) replyChatGPTError(msgID string, text string) error {
28+
if !r.enableCardResp {
29+
return r.larkIns.replyText(context.Background(), msgID, text)
30+
}
31+
cardIns := card.Card(
32+
card.Div().SetFields(
33+
card.FieldMarkdown(text),
34+
),
35+
).SetHeader(
36+
card.Header("ChatGPT Bot Error").SetRed(),
37+
)
38+
return r.larkIns.replyCard(context.Background(), msgID, cardIns)
39+
}
40+
41+
func (r *Client) replyChatGPTSuccess(msgID string, text string) error {
42+
if !r.enableCardResp {
43+
return r.larkIns.replyText(context.Background(), msgID, text)
44+
}
45+
cardIns := card.Card(
46+
card.Div().SetFields(
47+
card.FieldMarkdown(text),
48+
),
49+
).SetHeader(
50+
card.Header("ChatGPT Bot Error").SetGreen(),
51+
)
52+
return r.larkIns.replyCard(context.Background(), msgID, cardIns)
53+
}
54+
55+
func (r *larkClient) replyChatGPTMessage(msgID, title, text string, enableCardResp bool) error {
56+
if !enableCardResp {
57+
return r.replyText(context.Background(), msgID, text)
58+
}
59+
cardIns := card.Card(
60+
card.Div().SetFields(
61+
card.FieldMarkdown(text),
62+
),
63+
card.HR(),
64+
card.Note(
65+
card.I18nText(&lark.I18NText{
66+
ZhCn: "HELP: 回复消息支持上下文对话; /reset 重置对话",
67+
EnUs: "HELP: Reply messages with context; send /reset resets dialogue",
68+
}),
69+
),
70+
).SetHeader(card.Header(title))
71+
return r.replyCard(context.Background(), msgID, cardIns)
72+
}

main.go

+1
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@ func loadConfig() (*larkgpt.ClientConfig, error) {
3838
ServerPort: port,
3939
Maintained: os.Getenv("MAINTAINED") == "true",
4040
EnableSessionForLarkGroup: os.Getenv("ENABLE_SESSION_FOR_LARK_GROUP") == "true",
41+
EnableCardResp: os.Getenv("ENABLE_CARD_RESP") == "true",
4142
}, nil
4243
}

0 commit comments

Comments
 (0)