mirror of
https://github.com/woodchen-ink/Oapi-Feishu.git
synced 2025-07-18 05:42:08 +08:00
764 lines
19 KiB
Go
764 lines
19 KiB
Go
package handlers
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/google/uuid"
|
|
larkcard "github.com/larksuite/oapi-sdk-go/v3/card"
|
|
larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1"
|
|
"start-feishubot/initialization"
|
|
"start-feishubot/services"
|
|
"start-feishubot/services/openai"
|
|
)
|
|
|
|
type CardKind string
|
|
type CardChatType string
|
|
|
|
var (
|
|
ClearCardKind = CardKind("clear") // 清空上下文
|
|
PicModeChangeKind = CardKind("pic_mode_change") // 切换图片创作模式
|
|
PicResolutionKind = CardKind("pic_resolution") // 图片分辨率调整
|
|
PicTextMoreKind = CardKind("pic_text_more") // 重新根据文本生成图片
|
|
PicVarMoreKind = CardKind("pic_var_more") // 变量图片
|
|
RoleTagsChooseKind = CardKind("role_tags_choose") // 内置角色所属标签选择
|
|
RoleChooseKind = CardKind("role_choose") // 内置角色选择
|
|
)
|
|
|
|
var (
|
|
GroupChatType = CardChatType("group")
|
|
UserChatType = CardChatType("personal")
|
|
)
|
|
|
|
type CardMsg struct {
|
|
Kind CardKind
|
|
ChatType CardChatType
|
|
Value interface{}
|
|
SessionId string
|
|
MsgId string
|
|
}
|
|
|
|
type MenuOption struct {
|
|
value string
|
|
label string
|
|
}
|
|
|
|
func replyCard(ctx context.Context,
|
|
msgId *string,
|
|
cardContent string,
|
|
) error {
|
|
client := initialization.GetLarkClient()
|
|
resp, err := client.Im.Message.Reply(ctx, larkim.NewReplyMessageReqBuilder().
|
|
MessageId(*msgId).
|
|
Body(larkim.NewReplyMessageReqBodyBuilder().
|
|
MsgType(larkim.MsgTypeInteractive).
|
|
Uuid(uuid.New().String()).
|
|
Content(cardContent).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return errors.New(resp.Msg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func replyCardWithBackId(ctx context.Context,
|
|
msgId *string,
|
|
cardContent string,
|
|
) (*string, error) {
|
|
client := initialization.GetLarkClient()
|
|
resp, err := client.Im.Message.Reply(ctx, larkim.NewReplyMessageReqBuilder().
|
|
MessageId(*msgId).
|
|
Body(larkim.NewReplyMessageReqBodyBuilder().
|
|
MsgType(larkim.MsgTypeInteractive).
|
|
Uuid(uuid.New().String()).
|
|
Content(cardContent).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return nil, errors.New(resp.Msg)
|
|
}
|
|
|
|
//ctx = context.WithValue(ctx, "SendMsgId", *resp.Data.MessageId)
|
|
//SendMsgId := ctx.Value("SendMsgId")
|
|
//pp.Println(SendMsgId)
|
|
return resp.Data.MessageId, nil
|
|
}
|
|
|
|
func newSendCard(header *larkcard.MessageCardHeader, elements ...larkcard.MessageCardElement) (string, error) {
|
|
config := larkcard.NewMessageCardConfig().
|
|
WideScreenMode(false).
|
|
EnableForward(true).
|
|
UpdateMulti(true).
|
|
Build()
|
|
var aElementPool []larkcard.MessageCardElement
|
|
for _, element := range elements {
|
|
aElementPool = append(aElementPool, element)
|
|
}
|
|
// 卡片消息体
|
|
cardContent, err := larkcard.NewMessageCard().
|
|
Config(config).
|
|
Header(header).
|
|
Elements(
|
|
aElementPool,
|
|
).
|
|
String()
|
|
return cardContent, err
|
|
}
|
|
func newSendCardWithOutHeader(
|
|
elements ...larkcard.MessageCardElement) (string, error) {
|
|
config := larkcard.NewMessageCardConfig().
|
|
WideScreenMode(false).
|
|
EnableForward(true).
|
|
UpdateMulti(true).
|
|
Build()
|
|
var aElementPool []larkcard.MessageCardElement
|
|
for _, element := range elements {
|
|
aElementPool = append(aElementPool, element)
|
|
}
|
|
// 卡片消息体
|
|
cardContent, err := larkcard.NewMessageCard().
|
|
Config(config).
|
|
Elements(
|
|
aElementPool,
|
|
).
|
|
String()
|
|
return cardContent, err
|
|
}
|
|
|
|
func newSimpleSendCard(
|
|
elements ...larkcard.MessageCardElement) (string,
|
|
error) {
|
|
config := larkcard.NewMessageCardConfig().
|
|
WideScreenMode(false).
|
|
EnableForward(true).
|
|
UpdateMulti(false).
|
|
Build()
|
|
var aElementPool []larkcard.MessageCardElement
|
|
for _, element := range elements {
|
|
aElementPool = append(aElementPool, element)
|
|
}
|
|
// 卡片消息体
|
|
cardContent, err := larkcard.NewMessageCard().
|
|
Config(config).
|
|
Elements(
|
|
aElementPool,
|
|
).
|
|
String()
|
|
return cardContent, err
|
|
}
|
|
|
|
// withSplitLine 用于生成分割线
|
|
func withSplitLine() larkcard.MessageCardElement {
|
|
splitLine := larkcard.NewMessageCardHr().
|
|
Build()
|
|
return splitLine
|
|
}
|
|
|
|
// withHeader 用于生成消息头
|
|
func withHeader(title string, color string) *larkcard.
|
|
MessageCardHeader {
|
|
if title == "" {
|
|
title = "🤖️机器人提醒"
|
|
}
|
|
header := larkcard.NewMessageCardHeader().
|
|
Template(color).
|
|
Title(larkcard.NewMessageCardPlainText().
|
|
Content(title).
|
|
Build()).
|
|
Build()
|
|
return header
|
|
}
|
|
|
|
// withNote 用于生成纯文本脚注
|
|
func withNote(note string) larkcard.MessageCardElement {
|
|
noteElement := larkcard.NewMessageCardNote().
|
|
Elements([]larkcard.MessageCardNoteElement{larkcard.NewMessageCardPlainText().
|
|
Content(note).
|
|
Build()}).
|
|
Build()
|
|
return noteElement
|
|
}
|
|
|
|
// withMainMd 用于生成markdown消息体
|
|
func withMainMd(msg string) larkcard.MessageCardElement {
|
|
msg, i := processMessage(msg)
|
|
msg = processNewLine(msg)
|
|
if i != nil {
|
|
return nil
|
|
}
|
|
mainElement := larkcard.NewMessageCardDiv().
|
|
Fields([]*larkcard.MessageCardField{larkcard.NewMessageCardField().
|
|
Text(larkcard.NewMessageCardLarkMd().
|
|
Content(msg).
|
|
Build()).
|
|
IsShort(true).
|
|
Build()}).
|
|
Build()
|
|
return mainElement
|
|
}
|
|
|
|
// withMainText 用于生成纯文本消息体
|
|
func withMainText(msg string) larkcard.MessageCardElement {
|
|
msg, i := processMessage(msg)
|
|
msg = cleanTextBlock(msg)
|
|
if i != nil {
|
|
return nil
|
|
}
|
|
mainElement := larkcard.NewMessageCardDiv().
|
|
Fields([]*larkcard.MessageCardField{larkcard.NewMessageCardField().
|
|
Text(larkcard.NewMessageCardPlainText().
|
|
Content(msg).
|
|
Build()).
|
|
IsShort(false).
|
|
Build()}).
|
|
Build()
|
|
return mainElement
|
|
}
|
|
|
|
func withImageDiv(imageKey string) larkcard.MessageCardElement {
|
|
imageElement := larkcard.NewMessageCardImage().
|
|
ImgKey(imageKey).
|
|
Alt(larkcard.NewMessageCardPlainText().Content("").
|
|
Build()).
|
|
Preview(true).
|
|
Mode(larkcard.MessageCardImageModelCropCenter).
|
|
CompactWidth(true).
|
|
Build()
|
|
return imageElement
|
|
}
|
|
|
|
// withMdAndExtraBtn 用于生成带有额外按钮的消息体
|
|
func withMdAndExtraBtn(msg string, btn *larkcard.
|
|
MessageCardEmbedButton) larkcard.MessageCardElement {
|
|
msg, i := processMessage(msg)
|
|
msg = processNewLine(msg)
|
|
if i != nil {
|
|
return nil
|
|
}
|
|
mainElement := larkcard.NewMessageCardDiv().
|
|
Fields(
|
|
[]*larkcard.MessageCardField{
|
|
larkcard.NewMessageCardField().
|
|
Text(larkcard.NewMessageCardLarkMd().
|
|
Content(msg).
|
|
Build()).
|
|
IsShort(true).
|
|
Build()}).
|
|
Extra(btn).
|
|
Build()
|
|
return mainElement
|
|
}
|
|
|
|
func newBtn(content string, value map[string]interface{},
|
|
typename larkcard.MessageCardButtonType) *larkcard.
|
|
MessageCardEmbedButton {
|
|
btn := larkcard.NewMessageCardEmbedButton().
|
|
Type(typename).
|
|
Value(value).
|
|
Text(larkcard.NewMessageCardPlainText().
|
|
Content(content).
|
|
Build())
|
|
return btn
|
|
}
|
|
|
|
func newMenu(
|
|
placeHolder string,
|
|
value map[string]interface{},
|
|
options ...MenuOption,
|
|
) *larkcard.
|
|
MessageCardEmbedSelectMenuStatic {
|
|
var aOptionPool []*larkcard.MessageCardEmbedSelectOption
|
|
for _, option := range options {
|
|
aOption := larkcard.NewMessageCardEmbedSelectOption().
|
|
Value(option.value).
|
|
Text(larkcard.NewMessageCardPlainText().
|
|
Content(option.label).
|
|
Build())
|
|
aOptionPool = append(aOptionPool, aOption)
|
|
|
|
}
|
|
btn := larkcard.NewMessageCardEmbedSelectMenuStatic().
|
|
MessageCardEmbedSelectMenuStatic(larkcard.NewMessageCardEmbedSelectMenuBase().
|
|
Options(aOptionPool).
|
|
Placeholder(larkcard.NewMessageCardPlainText().
|
|
Content(placeHolder).
|
|
Build()).
|
|
Value(value).
|
|
Build()).
|
|
Build()
|
|
return btn
|
|
}
|
|
|
|
// 清除卡片按钮
|
|
func withClearDoubleCheckBtn(sessionID *string) larkcard.MessageCardElement {
|
|
confirmBtn := newBtn("确认清除", map[string]interface{}{
|
|
"value": "1",
|
|
"kind": ClearCardKind,
|
|
"chatType": UserChatType,
|
|
"sessionId": *sessionID,
|
|
}, larkcard.MessageCardButtonTypeDanger,
|
|
)
|
|
cancelBtn := newBtn("我再想想", map[string]interface{}{
|
|
"value": "0",
|
|
"kind": ClearCardKind,
|
|
"sessionId": *sessionID,
|
|
"chatType": UserChatType,
|
|
},
|
|
larkcard.MessageCardButtonTypeDefault)
|
|
|
|
actions := larkcard.NewMessageCardAction().
|
|
Actions([]larkcard.MessageCardActionElement{confirmBtn, cancelBtn}).
|
|
Layout(larkcard.MessageCardActionLayoutBisected.Ptr()).
|
|
Build()
|
|
|
|
return actions
|
|
}
|
|
|
|
func withPicModeDoubleCheckBtn(sessionID *string) larkcard.
|
|
MessageCardElement {
|
|
confirmBtn := newBtn("切换模式", map[string]interface{}{
|
|
"value": "1",
|
|
"kind": PicModeChangeKind,
|
|
"chatType": UserChatType,
|
|
"sessionId": *sessionID,
|
|
}, larkcard.MessageCardButtonTypeDanger,
|
|
)
|
|
cancelBtn := newBtn("我再想想", map[string]interface{}{
|
|
"value": "0",
|
|
"kind": PicModeChangeKind,
|
|
"sessionId": *sessionID,
|
|
"chatType": UserChatType,
|
|
},
|
|
larkcard.MessageCardButtonTypeDefault)
|
|
|
|
actions := larkcard.NewMessageCardAction().
|
|
Actions([]larkcard.MessageCardActionElement{confirmBtn, cancelBtn}).
|
|
Layout(larkcard.MessageCardActionLayoutBisected.Ptr()).
|
|
Build()
|
|
|
|
return actions
|
|
}
|
|
|
|
func withOneBtn(btn *larkcard.MessageCardEmbedButton) larkcard.
|
|
MessageCardElement {
|
|
actions := larkcard.NewMessageCardAction().
|
|
Actions([]larkcard.MessageCardActionElement{btn}).
|
|
Layout(larkcard.MessageCardActionLayoutFlow.Ptr()).
|
|
Build()
|
|
return actions
|
|
}
|
|
|
|
//新建对话按钮
|
|
|
|
func withPicResolutionBtn(sessionID *string) larkcard.
|
|
MessageCardElement {
|
|
cancelMenu := newMenu("默认分辨率",
|
|
map[string]interface{}{
|
|
"value": "0",
|
|
"kind": PicResolutionKind,
|
|
"sessionId": *sessionID,
|
|
"msgId": *sessionID,
|
|
},
|
|
MenuOption{
|
|
label: "256x256",
|
|
value: string(services.Resolution256),
|
|
},
|
|
MenuOption{
|
|
label: "512x512",
|
|
value: string(services.Resolution512),
|
|
},
|
|
MenuOption{
|
|
label: "1024x1024",
|
|
value: string(services.Resolution1024),
|
|
},
|
|
)
|
|
|
|
actions := larkcard.NewMessageCardAction().
|
|
Actions([]larkcard.MessageCardActionElement{cancelMenu}).
|
|
Layout(larkcard.MessageCardActionLayoutFlow.Ptr()).
|
|
Build()
|
|
return actions
|
|
}
|
|
func withRoleTagsBtn(sessionID *string, tags ...string) larkcard.
|
|
MessageCardElement {
|
|
var menuOptions []MenuOption
|
|
|
|
for _, tag := range tags {
|
|
menuOptions = append(menuOptions, MenuOption{
|
|
label: tag,
|
|
value: tag,
|
|
})
|
|
}
|
|
cancelMenu := newMenu("选择角色分类",
|
|
map[string]interface{}{
|
|
"value": "0",
|
|
"kind": RoleTagsChooseKind,
|
|
"sessionId": *sessionID,
|
|
"msgId": *sessionID,
|
|
},
|
|
menuOptions...,
|
|
)
|
|
|
|
actions := larkcard.NewMessageCardAction().
|
|
Actions([]larkcard.MessageCardActionElement{cancelMenu}).
|
|
Layout(larkcard.MessageCardActionLayoutFlow.Ptr()).
|
|
Build()
|
|
return actions
|
|
}
|
|
|
|
func withRoleBtn(sessionID *string, titles ...string) larkcard.
|
|
MessageCardElement {
|
|
var menuOptions []MenuOption
|
|
|
|
for _, tag := range titles {
|
|
menuOptions = append(menuOptions, MenuOption{
|
|
label: tag,
|
|
value: tag,
|
|
})
|
|
}
|
|
cancelMenu := newMenu("查看内置角色",
|
|
map[string]interface{}{
|
|
"value": "0",
|
|
"kind": RoleChooseKind,
|
|
"sessionId": *sessionID,
|
|
"msgId": *sessionID,
|
|
},
|
|
menuOptions...,
|
|
)
|
|
|
|
actions := larkcard.NewMessageCardAction().
|
|
Actions([]larkcard.MessageCardActionElement{cancelMenu}).
|
|
Layout(larkcard.MessageCardActionLayoutFlow.Ptr()).
|
|
Build()
|
|
return actions
|
|
}
|
|
|
|
func replyMsg(ctx context.Context, msg string, msgId *string) error {
|
|
msg, i := processMessage(msg)
|
|
if i != nil {
|
|
return i
|
|
}
|
|
client := initialization.GetLarkClient()
|
|
content := larkim.NewTextMsgBuilder().
|
|
Text(msg).
|
|
Build()
|
|
|
|
resp, err := client.Im.Message.Reply(ctx, larkim.NewReplyMessageReqBuilder().
|
|
MessageId(*msgId).
|
|
Body(larkim.NewReplyMessageReqBodyBuilder().
|
|
MsgType(larkim.MsgTypeText).
|
|
Uuid(uuid.New().String()).
|
|
Content(content).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return errors.New(resp.Msg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func uploadImage(base64Str string) (*string, error) {
|
|
imageBytes, err := base64.StdEncoding.DecodeString(base64Str)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
client := initialization.GetLarkClient()
|
|
resp, err := client.Im.Image.Create(context.Background(),
|
|
larkim.NewCreateImageReqBuilder().
|
|
Body(larkim.NewCreateImageReqBodyBuilder().
|
|
ImageType(larkim.ImageTypeMessage).
|
|
Image(bytes.NewReader(imageBytes)).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return nil, err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return nil, errors.New(resp.Msg)
|
|
}
|
|
return resp.Data.ImageKey, nil
|
|
}
|
|
func replyImage(ctx context.Context, ImageKey *string,
|
|
msgId *string) error {
|
|
//fmt.Println("sendMsg", ImageKey, msgId)
|
|
|
|
msgImage := larkim.MessageImage{ImageKey: *ImageKey}
|
|
content, err := msgImage.String()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
client := initialization.GetLarkClient()
|
|
|
|
resp, err := client.Im.Message.Reply(ctx, larkim.NewReplyMessageReqBuilder().
|
|
MessageId(*msgId).
|
|
Body(larkim.NewReplyMessageReqBodyBuilder().
|
|
MsgType(larkim.MsgTypeImage).
|
|
Uuid(uuid.New().String()).
|
|
Content(content).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return errors.New(resp.Msg)
|
|
}
|
|
return nil
|
|
|
|
}
|
|
|
|
func replayImageCardByBase64(ctx context.Context, base64Str string,
|
|
msgId *string, sessionId *string, question string) error {
|
|
imageKey, err := uploadImage(base64Str)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
//example := "img_v2_041b28e3-5680-48c2-9af2-497ace79333g"
|
|
//imageKey := &example
|
|
//fmt.Println("imageKey", *imageKey)
|
|
err = sendImageCard(ctx, *imageKey, msgId, sessionId, question)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sendMsg(ctx context.Context, msg string, chatId *string) error {
|
|
//fmt.Println("sendMsg", msg, chatId)
|
|
msg, i := processMessage(msg)
|
|
if i != nil {
|
|
return i
|
|
}
|
|
client := initialization.GetLarkClient()
|
|
content := larkim.NewTextMsgBuilder().
|
|
Text(msg).
|
|
Build()
|
|
|
|
//fmt.Println("content", content)
|
|
|
|
resp, err := client.Im.Message.Create(ctx, larkim.NewCreateMessageReqBuilder().
|
|
ReceiveIdType(larkim.ReceiveIdTypeChatId).
|
|
Body(larkim.NewCreateMessageReqBodyBuilder().
|
|
MsgType(larkim.MsgTypeText).
|
|
ReceiveId(*chatId).
|
|
Content(content).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return errors.New(resp.Msg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func PatchCard(ctx context.Context, msgId *string,
|
|
cardContent string) error {
|
|
//fmt.Println("sendMsg", msg, chatId)
|
|
client := initialization.GetLarkClient()
|
|
//content := larkim.NewTextMsgBuilder().
|
|
// Text(msg).
|
|
// Build()
|
|
|
|
//fmt.Println("content", content)
|
|
|
|
resp, err := client.Im.Message.Patch(ctx, larkim.NewPatchMessageReqBuilder().
|
|
MessageId(*msgId).
|
|
Body(larkim.NewPatchMessageReqBodyBuilder().
|
|
Content(cardContent).
|
|
Build()).
|
|
Build())
|
|
|
|
// 处理错误
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err
|
|
}
|
|
|
|
// 服务端错误处理
|
|
if !resp.Success() {
|
|
fmt.Println(resp.Code, resp.Msg, resp.RequestId())
|
|
return errors.New(resp.Msg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sendClearCacheCheckCard(ctx context.Context,
|
|
sessionId *string, msgId *string) {
|
|
newCard, _ := newSendCard(
|
|
withHeader("🆑 机器人提醒", larkcard.TemplateBlue),
|
|
withMainMd("您确定要清除对话上下文吗?"),
|
|
withNote("请注意,这将开始一个全新的对话,您将无法利用之前话题的历史信息"),
|
|
withClearDoubleCheckBtn(sessionId))
|
|
replyCard(ctx, msgId, newCard)
|
|
}
|
|
|
|
func sendSystemInstructionCard(ctx context.Context,
|
|
sessionId *string, msgId *string, content string) {
|
|
newCard, _ := newSendCard(
|
|
withHeader("🥷 已进入角色扮演模式", larkcard.TemplateIndigo),
|
|
withMainText(content),
|
|
withNote("请注意,这将开始一个全新的对话,您将无法利用之前话题的历史信息"))
|
|
replyCard(ctx, msgId, newCard)
|
|
}
|
|
|
|
func sendOnProcessCard(ctx context.Context,
|
|
sessionId *string, msgId *string) (*string, error) {
|
|
newCard, _ := newSendCardWithOutHeader(
|
|
withNote("正在思考,请稍等..."))
|
|
id, err := replyCardWithBackId(ctx, msgId, newCard)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return id, nil
|
|
}
|
|
|
|
func updateTextCard(ctx context.Context, msg string,
|
|
msgId *string) error {
|
|
newCard, _ := newSendCardWithOutHeader(
|
|
withMainText(msg),
|
|
withNote("正在生成,请稍等..."))
|
|
err := PatchCard(ctx, msgId, newCard)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
func updateFinalCard(
|
|
ctx context.Context,
|
|
msg string,
|
|
msgId *string,
|
|
) error {
|
|
newCard, _ := newSendCardWithOutHeader(
|
|
withMainText(msg))
|
|
err := PatchCard(ctx, msgId, newCard)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func sendHelpCard(ctx context.Context,
|
|
sessionId *string, msgId *string) {
|
|
newCard, _ := newSendCard(
|
|
withHeader("🎒需要帮助吗?", larkcard.TemplateBlue),
|
|
withMainMd("**我是具备打字机效果的聊天机器人!**"),
|
|
withSplitLine(),
|
|
withMdAndExtraBtn(
|
|
"** 🆑 清除话题上下文**\n文本回复 *清除* 或 */clear*",
|
|
newBtn("立刻清除", map[string]interface{}{
|
|
"value": "1",
|
|
"kind": ClearCardKind,
|
|
"chatType": UserChatType,
|
|
"sessionId": *sessionId,
|
|
}, larkcard.MessageCardButtonTypeDanger)),
|
|
withMainMd("🛖 **内置角色列表** \n"+" 文本回复 *角色列表* 或 */roles*"),
|
|
withMainMd("🥷 **角色扮演模式**\n文本回复*角色扮演* 或 */system*+空格+角色信息"),
|
|
withSplitLine(),
|
|
withMainMd("🎒 **需要更多帮助**\n文本回复 *帮助* 或 */help*"),
|
|
)
|
|
replyCard(ctx, msgId, newCard)
|
|
}
|
|
|
|
func sendImageCard(ctx context.Context, imageKey string,
|
|
msgId *string, sessionId *string, question string) error {
|
|
newCard, _ := newSimpleSendCard(
|
|
withImageDiv(imageKey),
|
|
withSplitLine(),
|
|
//再来一张
|
|
withOneBtn(newBtn("再来一张", map[string]interface{}{
|
|
"value": question,
|
|
"kind": PicTextMoreKind,
|
|
"chatType": UserChatType,
|
|
"msgId": *msgId,
|
|
"sessionId": *sessionId,
|
|
}, larkcard.MessageCardButtonTypePrimary)),
|
|
)
|
|
replyCard(ctx, msgId, newCard)
|
|
return nil
|
|
}
|
|
|
|
func sendBalanceCard(ctx context.Context, msgId *string,
|
|
balance openai.BalanceResponse) {
|
|
newCard, _ := newSendCard(
|
|
withHeader("🎰️ 余额查询", larkcard.TemplateBlue),
|
|
withMainMd(fmt.Sprintf("总额度: %.2f$", balance.TotalGranted)),
|
|
withMainMd(fmt.Sprintf("已用额度: %.2f$", balance.TotalUsed)),
|
|
withMainMd(fmt.Sprintf("可用额度: %.2f$",
|
|
balance.TotalAvailable)),
|
|
withNote(fmt.Sprintf("有效期: %s - %s",
|
|
balance.EffectiveAt.Format("2006-01-02 15:04:05"),
|
|
balance.ExpiresAt.Format("2006-01-02 15:04:05"))),
|
|
)
|
|
replyCard(ctx, msgId, newCard)
|
|
}
|
|
|
|
func SendRoleTagsCard(ctx context.Context,
|
|
sessionId *string, msgId *string, roleTags []string) {
|
|
newCard, _ := newSendCard(
|
|
withHeader("🛖 请选择角色类别", larkcard.TemplateIndigo),
|
|
withRoleTagsBtn(sessionId, roleTags...),
|
|
withNote("提醒:选择角色所属分类,以便我们为您推荐更多相关角色。"))
|
|
replyCard(ctx, msgId, newCard)
|
|
}
|
|
|
|
func SendRoleListCard(ctx context.Context,
|
|
sessionId *string, msgId *string, roleTag string, roleList []string) {
|
|
newCard, _ := newSendCard(
|
|
withHeader("🛖 角色列表"+" - "+roleTag, larkcard.TemplateIndigo),
|
|
withRoleBtn(sessionId, roleList...),
|
|
withNote("提醒:选择内置场景,快速进入角色扮演模式。"))
|
|
replyCard(ctx, msgId, newCard)
|
|
}
|