mirror of
https://github.com/eryajf/chatgpt-dingtalk.git
synced 2025-10-07 00:52:52 +08:00
feat: 增加敏感词功能 (#204)
This commit is contained in:
@@ -229,6 +229,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \
|
||||
-e DEFAULT_MODE="单聊" -e MAX_REQUEST=0 -e PORT=8090 \
|
||||
-e SERVICE_URL="你当前服务外网可访问的URL" -e CHAT_TYPE="0" \
|
||||
-e ALLOW_GROUPS=a,b -e ALLOW_OUTGOING_GROUPS=a,b -e ALLOW_USERS=a,b -e DENY_USERS=a,b -e VIP_USERS=a,b -e ADMIN_USERS=a,b -e APP_SECRETS="xxx,yyy" \
|
||||
-e SENSITIVE_WORDS="aa,bb" \
|
||||
-e AZURE_ON="false" -e AZURE_API_VERSION="" -e AZURE_RESOURCE_NAME="" \
|
||||
-e AZURE_DEPLOYMENT_NAME="" -e AZURE_OPENAI_TOKEN="" \
|
||||
-e HELP="欢迎使用本工具\n\n你可以查看:[用户指南](https://github.com/eryajf/chatgpt-dingtalk/blob/main/docs/userGuide.md)\n\n这是一个[开源项目](https://github.com/eryajf/chatgpt-dingtalk/)
|
||||
@@ -493,6 +494,8 @@ vip_users: []
|
||||
admin_users: []
|
||||
# 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret
|
||||
app_secrets: []
|
||||
# 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 *** 代替
|
||||
sensitive_words: []
|
||||
# 帮助信息,放在配置文件,可供自定义
|
||||
help: "欢迎使用本工具\n\n你可以查看:[用户指南](https://github.com/eryajf/chatgpt-dingtalk/blob/main/docs/userGuide.md)\n\n这是一个[开源项目](https://github.com/eryajf/chatgpt-dingtalk/),觉得不错你可以来波素质三连."
|
||||
|
||||
|
@@ -42,6 +42,8 @@ vip_users: []
|
||||
admin_users: []
|
||||
# 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret
|
||||
app_secrets: []
|
||||
# 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 *** 代替
|
||||
sensitive_words: []
|
||||
# 帮助信息,放在配置文件,可供自定义
|
||||
help: "欢迎使用本工具\n\n你可以查看:[用户指南](https://github.com/eryajf/chatgpt-dingtalk/blob/main/docs/userGuide.md)\n\n这是一个[开源项目](https://github.com/eryajf/chatgpt-dingtalk/),觉得不错你可以来波素质三连."
|
||||
|
||||
|
@@ -52,6 +52,8 @@ type Configuration struct {
|
||||
AdminUsers []string `yaml:"admin_users"`
|
||||
// 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret
|
||||
AppSecrets []string `yaml:"app_secrets"`
|
||||
// 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 *** 代替
|
||||
SensitiveWords []string `yaml:"sensitive_words"`
|
||||
// 自定义帮助信息
|
||||
Help string `yaml:"help"`
|
||||
// AzureOpenAI 配置
|
||||
@@ -160,6 +162,10 @@ func LoadConfig() *Configuration {
|
||||
if appSecrets != "" {
|
||||
config.AppSecrets = strings.Split(appSecrets, ",")
|
||||
}
|
||||
sensitiveWords := os.Getenv("SENSITIVE_WORDS")
|
||||
if sensitiveWords != "" {
|
||||
config.SensitiveWords = strings.Split(sensitiveWords, ",")
|
||||
}
|
||||
help := os.Getenv("HELP")
|
||||
if help != "" {
|
||||
config.Help = help
|
||||
|
@@ -31,6 +31,7 @@ services:
|
||||
ADMIN_USERS: "" # 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid
|
||||
# 注意:如果下边的app_secrets为空,以及使用outgoing的方式配置机器人,这两种情况下,都表示没有人是管理员
|
||||
APP_SECRETS: "" # 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret,比如 "xxxx,yyyy"
|
||||
SENSITIVE_WORDS: "" # 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 *** 代替
|
||||
AZURE_ON: "false" # 是否走Azure OpenAi API, 默认false ,如果为true,则需要配置下边的四个参数
|
||||
AZURE_API_VERSION: "" # Azure OpenAi API 版本,比如 "2023-03-15-preview"
|
||||
AZURE_RESOURCE_NAME: "" # Azure OpenAi API 资源名称,比如 "openai"
|
||||
|
8
main.go
8
main.go
@@ -48,6 +48,14 @@ func Start() {
|
||||
}
|
||||
// 去除问题的前后空格
|
||||
msgObj.Text.Content = strings.TrimSpace(msgObj.Text.Content)
|
||||
if public.JudgeSensitiveWord(msgObj.Text.Content) {
|
||||
_, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "**🤷 抱歉,您提问的问题中包含敏感词汇,请审核自己的对话内容之后再进行!**")
|
||||
if err != nil {
|
||||
logger.Warning(fmt.Errorf("send message error: %v", err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
// 打印钉钉回调过来的请求明细,调试时打开
|
||||
logger.Debug(fmt.Sprintf("dingtalk callback parameters: %#v", msgObj))
|
||||
|
||||
|
@@ -146,6 +146,9 @@ func Do(mode string, rmsg *dingbot.ReceiveMsg) error {
|
||||
logger.Error("往MySQL新增数据失败,错误信息:", err)
|
||||
}
|
||||
logger.Info(fmt.Sprintf("🤖 %s得到的答案: %#v", rmsg.SenderNick, reply))
|
||||
if public.JudgeSensitiveWord(reply) {
|
||||
reply = public.SolveSensitiveWord(reply)
|
||||
}
|
||||
// 回复@我的用户
|
||||
_, err = rmsg.ReplyToDingtalk(string(dingbot.TEXT), reply)
|
||||
if err != nil {
|
||||
@@ -204,6 +207,9 @@ func Do(mode string, rmsg *dingbot.ReceiveMsg) error {
|
||||
// 将当前回答的ID放入缓存
|
||||
public.UserService.SetAnswerID(rmsg.SenderNick, rmsg.GetChatTitle(), aid)
|
||||
logger.Info(fmt.Sprintf("🤖 %s得到的答案: %#v", rmsg.SenderNick, reply))
|
||||
if public.JudgeSensitiveWord(reply) {
|
||||
reply = public.SolveSensitiveWord(reply)
|
||||
}
|
||||
// 回复@我的用户
|
||||
_, err = rmsg.ReplyToDingtalk(string(dingbot.TEXT), reply)
|
||||
if err != nil {
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
// 将内容写入到文件,如果文件名带路径,则会判断路径是否存在,不存在则创建
|
||||
@@ -140,3 +141,35 @@ func CheckRequest(ts, sg string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// JudgeSensitiveWord 判断内容是否包含敏感词
|
||||
func JudgeSensitiveWord(s string) bool {
|
||||
if len(Config.SensitiveWords) == 0 {
|
||||
return false
|
||||
}
|
||||
for _, v := range Config.SensitiveWords {
|
||||
if strings.Contains(s, v) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SolveSensitiveWord 将敏感词用*号占位
|
||||
func SolveSensitiveWord(s string) string {
|
||||
for _, v := range Config.SensitiveWords {
|
||||
if strings.Contains(s, v) {
|
||||
return strings.Replace(s, v, printStars(utf8.RuneCountInString(v)), -1)
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// 将对应敏感词替换为*
|
||||
func printStars(num int) string {
|
||||
s := ""
|
||||
for i := 0; i < num; i++ {
|
||||
s += "*"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
Reference in New Issue
Block a user