feat: 增加敏感词功能 (#204)

This commit is contained in:
二丫讲梵
2023-04-13 22:03:30 +08:00
committed by GitHub
parent 1b9edc5e63
commit add42dd774
7 changed files with 59 additions and 0 deletions

View File

@@ -229,6 +229,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \
-e DEFAULT_MODE="单聊" -e MAX_REQUEST=0 -e PORT=8090 \ -e DEFAULT_MODE="单聊" -e MAX_REQUEST=0 -e PORT=8090 \
-e SERVICE_URL="你当前服务外网可访问的URL" -e CHAT_TYPE="0" \ -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 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_ON="false" -e AZURE_API_VERSION="" -e AZURE_RESOURCE_NAME="" \
-e AZURE_DEPLOYMENT_NAME="" -e AZURE_OPENAI_TOKEN="" \ -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/) -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: [] admin_users: []
# 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果留空将会忽略校验则该接口将会存在其他人也能随意调用的安全隐患因此强烈建议配置正确的secret如果你的服务对接给多个机器人这里可以配置多个机器人的secret # 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果留空将会忽略校验则该接口将会存在其他人也能随意调用的安全隐患因此强烈建议配置正确的secret如果你的服务对接给多个机器人这里可以配置多个机器人的secret
app_secrets: [] 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/),觉得不错你可以来波素质三连." help: "欢迎使用本工具\n\n你可以查看[用户指南](https://github.com/eryajf/chatgpt-dingtalk/blob/main/docs/userGuide.md)\n\n这是一个[开源项目](https://github.com/eryajf/chatgpt-dingtalk/),觉得不错你可以来波素质三连."

View File

@@ -42,6 +42,8 @@ vip_users: []
admin_users: [] admin_users: []
# 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果留空将会忽略校验则该接口将会存在其他人也能随意调用的安全隐患因此强烈建议配置正确的secret如果你的服务对接给多个机器人这里可以配置多个机器人的secret # 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果留空将会忽略校验则该接口将会存在其他人也能随意调用的安全隐患因此强烈建议配置正确的secret如果你的服务对接给多个机器人这里可以配置多个机器人的secret
app_secrets: [] 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/),觉得不错你可以来波素质三连." help: "欢迎使用本工具\n\n你可以查看[用户指南](https://github.com/eryajf/chatgpt-dingtalk/blob/main/docs/userGuide.md)\n\n这是一个[开源项目](https://github.com/eryajf/chatgpt-dingtalk/),觉得不错你可以来波素质三连."

View File

@@ -52,6 +52,8 @@ type Configuration struct {
AdminUsers []string `yaml:"admin_users"` AdminUsers []string `yaml:"admin_users"`
// 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果你的服务对接给多个机器人这里可以配置多个机器人的secret // 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果你的服务对接给多个机器人这里可以配置多个机器人的secret
AppSecrets []string `yaml:"app_secrets"` AppSecrets []string `yaml:"app_secrets"`
// 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 *** 代替
SensitiveWords []string `yaml:"sensitive_words"`
// 自定义帮助信息 // 自定义帮助信息
Help string `yaml:"help"` Help string `yaml:"help"`
// AzureOpenAI 配置 // AzureOpenAI 配置
@@ -160,6 +162,10 @@ func LoadConfig() *Configuration {
if appSecrets != "" { if appSecrets != "" {
config.AppSecrets = strings.Split(appSecrets, ",") config.AppSecrets = strings.Split(appSecrets, ",")
} }
sensitiveWords := os.Getenv("SENSITIVE_WORDS")
if sensitiveWords != "" {
config.SensitiveWords = strings.Split(sensitiveWords, ",")
}
help := os.Getenv("HELP") help := os.Getenv("HELP")
if help != "" { if help != "" {
config.Help = help config.Help = help

View File

@@ -31,6 +31,7 @@ services:
ADMIN_USERS: "" # 指定哪些人为此系统的管理员如果留空则表示没有人是管理员如果要限制则列表中写用户的userid ADMIN_USERS: "" # 指定哪些人为此系统的管理员如果留空则表示没有人是管理员如果要限制则列表中写用户的userid
# 注意如果下边的app_secrets为空以及使用outgoing的方式配置机器人这两种情况下都表示没有人是管理员 # 注意如果下边的app_secrets为空以及使用outgoing的方式配置机器人这两种情况下都表示没有人是管理员
APP_SECRETS: "" # 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果留空将会忽略校验则该接口将会存在其他人也能随意调用的安全隐患因此强烈建议配置正确的secret如果你的服务对接给多个机器人这里可以配置多个机器人的secret比如 "xxxx,yyyy" APP_SECRETS: "" # 钉钉机器人在应用信息中的AppSecret为了校验回调的请求是否合法如果留空将会忽略校验则该接口将会存在其他人也能随意调用的安全隐患因此强烈建议配置正确的secret如果你的服务对接给多个机器人这里可以配置多个机器人的secret比如 "xxxx,yyyy"
SENSITIVE_WORDS: "" # 敏感词,提问时触发,则不允许提问,回答的内容中触发,则以 *** 代替
AZURE_ON: "false" # 是否走Azure OpenAi API, 默认false ,如果为true则需要配置下边的四个参数 AZURE_ON: "false" # 是否走Azure OpenAi API, 默认false ,如果为true则需要配置下边的四个参数
AZURE_API_VERSION: "" # Azure OpenAi API 版本,比如 "2023-03-15-preview" AZURE_API_VERSION: "" # Azure OpenAi API 版本,比如 "2023-03-15-preview"
AZURE_RESOURCE_NAME: "" # Azure OpenAi API 资源名称,比如 "openai" AZURE_RESOURCE_NAME: "" # Azure OpenAi API 资源名称,比如 "openai"

View File

@@ -48,6 +48,14 @@ func Start() {
} }
// 去除问题的前后空格 // 去除问题的前后空格
msgObj.Text.Content = strings.TrimSpace(msgObj.Text.Content) 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)) logger.Debug(fmt.Sprintf("dingtalk callback parameters: %#v", msgObj))

View File

@@ -146,6 +146,9 @@ func Do(mode string, rmsg *dingbot.ReceiveMsg) error {
logger.Error("往MySQL新增数据失败,错误信息:", err) logger.Error("往MySQL新增数据失败,错误信息:", err)
} }
logger.Info(fmt.Sprintf("🤖 %s得到的答案: %#v", rmsg.SenderNick, reply)) logger.Info(fmt.Sprintf("🤖 %s得到的答案: %#v", rmsg.SenderNick, reply))
if public.JudgeSensitiveWord(reply) {
reply = public.SolveSensitiveWord(reply)
}
// 回复@我的用户 // 回复@我的用户
_, err = rmsg.ReplyToDingtalk(string(dingbot.TEXT), reply) _, err = rmsg.ReplyToDingtalk(string(dingbot.TEXT), reply)
if err != nil { if err != nil {
@@ -204,6 +207,9 @@ func Do(mode string, rmsg *dingbot.ReceiveMsg) error {
// 将当前回答的ID放入缓存 // 将当前回答的ID放入缓存
public.UserService.SetAnswerID(rmsg.SenderNick, rmsg.GetChatTitle(), aid) public.UserService.SetAnswerID(rmsg.SenderNick, rmsg.GetChatTitle(), aid)
logger.Info(fmt.Sprintf("🤖 %s得到的答案: %#v", rmsg.SenderNick, reply)) logger.Info(fmt.Sprintf("🤖 %s得到的答案: %#v", rmsg.SenderNick, reply))
if public.JudgeSensitiveWord(reply) {
reply = public.SolveSensitiveWord(reply)
}
// 回复@我的用户 // 回复@我的用户
_, err = rmsg.ReplyToDingtalk(string(dingbot.TEXT), reply) _, err = rmsg.ReplyToDingtalk(string(dingbot.TEXT), reply)
if err != nil { if err != nil {

View File

@@ -9,6 +9,7 @@ import (
"os" "os"
"strings" "strings"
"time" "time"
"unicode/utf8"
) )
// 将内容写入到文件,如果文件名带路径,则会判断路径是否存在,不存在则创建 // 将内容写入到文件,如果文件名带路径,则会判断路径是否存在,不存在则创建
@@ -140,3 +141,35 @@ func CheckRequest(ts, sg string) bool {
} }
return false 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
}