mirror of
https://github.com/woodchen-ink/Oapi-Feishu.git
synced 2025-07-18 05:42:08 +08:00
commit
14fefa35f5
@ -1,75 +0,0 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
larkcard "github.com/larksuite/oapi-sdk-go/v3/card"
|
||||
"start-feishubot/initialization"
|
||||
"start-feishubot/services"
|
||||
"start-feishubot/services/openai"
|
||||
)
|
||||
|
||||
func NewRoleTagCardHandler(cardMsg CardMsg,
|
||||
m MessageHandler) CardHandlerFunc {
|
||||
return func(ctx context.Context, cardAction *larkcard.CardAction) (interface{}, error) {
|
||||
|
||||
if cardMsg.Kind == RoleTagsChooseKind {
|
||||
newCard, err, done := CommonProcessRoleTag(cardMsg, cardAction,
|
||||
m.sessionCache)
|
||||
if done {
|
||||
return newCard, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return nil, ErrNextHandler
|
||||
}
|
||||
}
|
||||
|
||||
func NewRoleCardHandler(cardMsg CardMsg,
|
||||
m MessageHandler) CardHandlerFunc {
|
||||
return func(ctx context.Context, cardAction *larkcard.CardAction) (interface{}, error) {
|
||||
|
||||
if cardMsg.Kind == RoleChooseKind {
|
||||
newCard, err, done := CommonProcessRole(cardMsg, cardAction,
|
||||
m.sessionCache)
|
||||
if done {
|
||||
return newCard, err
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
return nil, ErrNextHandler
|
||||
}
|
||||
}
|
||||
|
||||
func CommonProcessRoleTag(msg CardMsg, cardAction *larkcard.CardAction,
|
||||
cache services.SessionServiceCacheInterface) (interface{},
|
||||
error, bool) {
|
||||
option := cardAction.Action.Option
|
||||
//replyMsg(context.Background(), "已选择tag:"+option,
|
||||
// &msg.MsgId)
|
||||
roles := initialization.GetTitleListByTag(option)
|
||||
//fmt.Printf("roles: %s", roles)
|
||||
SendRoleListCard(context.Background(), &msg.SessionId,
|
||||
&msg.MsgId, option, *roles)
|
||||
return nil, nil, true
|
||||
}
|
||||
|
||||
func CommonProcessRole(msg CardMsg, cardAction *larkcard.CardAction,
|
||||
cache services.SessionServiceCacheInterface) (interface{},
|
||||
error, bool) {
|
||||
option := cardAction.Action.Option
|
||||
contentByTitle, error := initialization.GetFirstRoleContentByTitle(option)
|
||||
if error != nil {
|
||||
return nil, error, true
|
||||
}
|
||||
cache.Clear(msg.SessionId)
|
||||
systemMsg := append([]openai.Messages{}, openai.Messages{
|
||||
Role: "system", Content: contentByTitle,
|
||||
})
|
||||
cache.SetMsg(msg.SessionId, systemMsg)
|
||||
//pp.Println("systemMsg: ", systemMsg)
|
||||
sendSystemInstructionCard(context.Background(), &msg.SessionId,
|
||||
&msg.MsgId, contentByTitle)
|
||||
//replyMsg(context.Background(), "已选择角色:"+contentByTitle,
|
||||
// &msg.MsgId)
|
||||
return nil, nil, true
|
||||
}
|
@ -3,10 +3,9 @@ package handlers
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1"
|
||||
"start-feishubot/initialization"
|
||||
"start-feishubot/services/openai"
|
||||
"start-feishubot/utils"
|
||||
|
||||
larkim "github.com/larksuite/oapi-sdk-go/v3/service/im/v1"
|
||||
)
|
||||
|
||||
type MsgInfo struct {
|
||||
@ -86,24 +85,6 @@ func (*ClearAction) Execute(a *ActionInfo) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type RolePlayAction struct { /*角色扮演*/
|
||||
}
|
||||
|
||||
func (*RolePlayAction) Execute(a *ActionInfo) bool {
|
||||
if system, foundSystem := utils.EitherCutPrefix(a.info.qParsed,
|
||||
"/system ", "角色扮演 "); foundSystem {
|
||||
a.handler.sessionCache.Clear(*a.info.sessionId)
|
||||
systemMsg := append([]openai.Messages{}, openai.Messages{
|
||||
Role: "system", Content: system,
|
||||
})
|
||||
a.handler.sessionCache.SetMsg(*a.info.sessionId, systemMsg)
|
||||
sendSystemInstructionCard(*a.ctx, a.info.sessionId,
|
||||
a.info.msgId, system)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type HelpAction struct { /*帮助*/
|
||||
}
|
||||
|
||||
@ -132,23 +113,3 @@ func (*BalanceAction) Execute(a *ActionInfo) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type RoleListAction struct { /*角色列表*/
|
||||
}
|
||||
|
||||
func (*RoleListAction) Execute(a *ActionInfo) bool {
|
||||
if _, foundSystem := utils.EitherTrimEqual(a.info.qParsed,
|
||||
"/roles", "角色列表"); foundSystem {
|
||||
//a.handler.sessionCache.Clear(*a.info.sessionId)
|
||||
//systemMsg := append([]openai.Messages{}, openai.Messages{
|
||||
// Role: "system", Content: system,
|
||||
//})
|
||||
//a.handler.sessionCache.SetMsg(*a.info.sessionId, systemMsg)
|
||||
//sendSystemInstructionCard(*a.ctx, a.info.sessionId,
|
||||
// a.info.msgId, system)
|
||||
tags := initialization.GetAllUniqueTags()
|
||||
SendRoleTagsCard(*a.ctx, a.info.sessionId, a.info.msgId, *tags)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -95,9 +95,7 @@ func (m MessageHandler) msgReceivedHandler(ctx context.Context, event *larkim.P2
|
||||
&ProcessMentionAction{}, //判断机器人是否应该被调用
|
||||
&EmptyAction{}, //空消息处理
|
||||
&ClearAction{}, //清除消息处理
|
||||
&RoleListAction{}, //角色列表处理
|
||||
&HelpAction{}, //帮助处理
|
||||
&RolePlayAction{}, //角色扮演处理
|
||||
&MessageAction{
|
||||
chatgpt: chatgpt.NewGpt3(&m.config),
|
||||
}, //消息处理
|
||||
|
@ -19,13 +19,11 @@ 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") // 内置角色选择
|
||||
ClearCardKind = CardKind("clear") // 清空上下文
|
||||
PicModeChangeKind = CardKind("pic_mode_change") // 切换图片创作模式
|
||||
PicResolutionKind = CardKind("pic_resolution") // 图片分辨率调整
|
||||
PicTextMoreKind = CardKind("pic_text_more") // 重新根据文本生成图片
|
||||
PicVarMoreKind = CardKind("pic_var_more") // 变量图片
|
||||
)
|
||||
|
||||
var (
|
||||
@ -401,59 +399,6 @@ func withPicResolutionBtn(sessionID *string) larkcard.
|
||||
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)
|
||||
@ -645,15 +590,6 @@ func sendClearCacheCheckCard(ctx context.Context,
|
||||
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(
|
||||
@ -694,7 +630,7 @@ func sendHelpCard(ctx context.Context,
|
||||
sessionId *string, msgId *string) {
|
||||
newCard, _ := newSendCard(
|
||||
withHeader("🎒需要帮助吗?", larkcard.TemplateBlue),
|
||||
withMainMd("**我是具备打字机效果的聊天机器人!**"),
|
||||
withMainMd("**我是具备打字机效果的Oapi飞书聊天机器人**"),
|
||||
withSplitLine(),
|
||||
withMdAndExtraBtn(
|
||||
"** 🆑 清除话题上下文**\n文本回复 *清除* 或 */clear*",
|
||||
@ -704,8 +640,6 @@ func sendHelpCard(ctx context.Context,
|
||||
"chatType": UserChatType,
|
||||
"sessionId": *sessionId,
|
||||
}, larkcard.MessageCardButtonTypeDanger)),
|
||||
withMainMd("🛖 **内置角色列表** \n"+" 文本回复 *角色列表* 或 */roles*"),
|
||||
withMainMd("🥷 **角色扮演模式**\n文本回复*角色扮演* 或 */system*+空格+角色信息"),
|
||||
withSplitLine(),
|
||||
withMainMd("🎒 **需要更多帮助**\n文本回复 *帮助* 或 */help*"),
|
||||
)
|
||||
@ -744,21 +678,3 @@ func sendBalanceCard(ctx context.Context, msgId *string,
|
||||
)
|
||||
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)
|
||||
}
|
||||
|
@ -2,12 +2,13 @@ package initialization
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/pflag"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
@ -85,7 +86,7 @@ func LoadConfig(cfg string) *Config {
|
||||
UseHttps: getViperBoolValue("USE_HTTPS", false),
|
||||
CertFile: getViperStringValue("CERT_FILE", "cert.pem"),
|
||||
KeyFile: getViperStringValue("KEY_FILE", "key.pem"),
|
||||
OpenaiApiUrl: getViperStringValue("API_URL", "https://api.openai.com"),
|
||||
OpenaiApiUrl: getViperStringValue("API_URL", "https://oapi.czl.net"),
|
||||
HttpProxy: getViperStringValue("HTTP_PROXY", ""),
|
||||
AzureOn: getViperBoolValue("AZURE_ON", false),
|
||||
AzureApiVersion: getViperStringValue("AZURE_API_VERSION", "2023-03-15-preview"),
|
||||
|
@ -1,12 +1,9 @@
|
||||
version: '3.3'
|
||||
services:
|
||||
feishu-chatgpt:
|
||||
container_name: Feishu-OpenAI-Stream-Chatbot
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
image: woodchen/oapi-feishu
|
||||
oapi-feishu:
|
||||
ports:
|
||||
- "9000:9000/tcp"
|
||||
- "1008:9000"
|
||||
volumes:
|
||||
# - ./code/config.yaml:/app/config.yaml:ro
|
||||
# 要注意,这里右边的容器内的路径,不是从根目录开始的,要参考 dockerfile 中的 WORKDIR
|
||||
@ -29,14 +26,12 @@ services:
|
||||
- USE_HTTPS=false
|
||||
- CERT_FILE=cert.pem
|
||||
- KEY_FILE=key.pem
|
||||
# OpenAI 地址, 一般不需要修改, 除非你有自己的反向代理
|
||||
- API_URL=https://api.openai.com
|
||||
# 代理设置, 例如 - HTTP_PROXY=http://127.0.0.1:7890, 默认代表不使用代理
|
||||
- HTTP_PROXY
|
||||
# OpenAI 地址, 一般不需要修改
|
||||
- API_URL=https://oapi.czl.net
|
||||
## 访问控制
|
||||
# 是否启用访问控制。默认不启用。
|
||||
- ACCESS_CONTROL_ENABLE=false
|
||||
# 每个用户每天最多问多少个问题。默认为0. 配置成为小于等于0表示不限制。
|
||||
- ACCESS_CONTROL_MAX_COUNT_PER_USER_PER_DAY=0
|
||||
# 访问OpenAi的 普通 Http请求的超时时间,单位秒,不配置的话默认为 550 秒
|
||||
- OPENAI_HTTP_CLIENT_TIMEOUT
|
||||
- OPENAI_HTTP_CLIENT_TIMEOUT=600
|
||||
|
Loading…
x
Reference in New Issue
Block a user