From 170b036ac48b27e35f3b8780f2efe57df23c3320 Mon Sep 17 00:00:00 2001 From: ffinly Date: Sun, 9 Apr 2023 11:30:32 +0800 Subject: [PATCH 01/20] =?UTF-8?q?perf:=20=E6=96=B0=E5=A2=9EVIP=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=88=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E5=91=98=E5=92=8CVIP=E7=94=A8=E6=88=B7=E4=B8=8D?= =?UTF-8?q?=E5=8F=97=E8=AF=B7=E6=B1=82=E6=AC=A1=E6=95=B0=E9=99=90=E5=88=B6?= =?UTF-8?q?=EF=BC=89=EF=BC=8C=E5=90=8C=E6=97=B6=E4=BF=AE=E6=94=B9ALLOW=5FU?= =?UTF-8?q?SERS=E7=9A=84=E6=A0=A1=E9=AA=8C=E4=B8=BAuserid=EF=BC=88SenderSt?= =?UTF-8?q?affId=EF=BC=89=EF=BC=8C=E5=B0=86=E7=94=A8=E6=88=B7=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=A0=A1=E9=AA=8C=E7=BB=9F=E4=B8=80=E4=B8=BAuserid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++++----- config.example.yml | 8 ++++++-- config/config.go | 6 ++++++ docker-compose.yml | 10 ++++++---- main.go | 2 +- pkg/process/process_request.go | 19 ++++++++++++------- prompt.yml | 3 --- public/tools.go | 24 ++++++++++++++++++++++++ 8 files changed, 64 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 51dcae67..7a8fba5d 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \ -e HTTP_PROXY="http://host.docker.internal:15732" \ -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_USERS=a,b -e ADMIN_USERS=a,b -e APP_SECRETS="xxx,yyy" \ + -e ALLOW_GROUPS=a,b -e ALLOW_USERS=a,b -e VIP_USERS=a,b -e ADMIN_USERS=a,b -e APP_SECRETS="xxx,yyy" \ -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/) @@ -184,7 +184,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \ > 运行命令中映射的配置文件参考下边的[配置文件说明](#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E)。 - `📢 注意:`如果使用docker部署,那么PORT参数不需要进行任何调整。 -- `📢 注意:`ALLOW_GROUPS,ALLOW_USERS,ADMIN_USERS三个参数为数组,如果需要指定多个,可用英文逗号分割。 +- `📢 注意:`ALLOW_GROUPS,ALLOW_USERS,VIP_USERS,ADMIN_USERS四个参数为数组,如果需要指定多个,可用英文逗号分割。 - `📢 注意:`如果服务器节点本身就在国外或者自定义了`BASE_URL`,那么就把`HTTP_PROXY`参数留空即可。 - `📢 注意:`如果使用docker部署,那么proxy地址可以直接使用如上方式部署,`host.docker.internal`会指向容器所在宿主机的IP,只需要更改端口为你的代理端口即可。参见:[Docker容器如何优雅地访问宿主机网络](https://wiki.eryajf.net/pages/674f53/) @@ -420,10 +420,14 @@ chat_type: "0" # 对话聊天时,如下三个满足其一即可通过校验 allow_groups: - "学无止境" -# 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的名称,比如 ["张三","李四"] -allow_users: ["张三","李四"] -# 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid +# 以下 allow_users、vip_users、admin_users 配置中填写的是用户的userid # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts +# 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid +allow_users: [] +# 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人) +# 如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid +vip_users: [] +# 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid # 注意:如果下边的app_secrets为空,以及使用outgoing的方式配置机器人,这两种情况下,都表示没有人是管理员 admin_users: [] # 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret diff --git a/config.example.yml b/config.example.yml index 21b449de..93c44ef3 100644 --- a/config.example.yml +++ b/config.example.yml @@ -22,10 +22,14 @@ service_url: "http://xxxxxx" chat_type: "0" # 哪些群组可以进行对话,如果留空,则表示允许所有群组,如果要限制,则列表中写群组的名称,比如 ["aa","bb"] allow_groups: [] -# 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的名称,比如 ["张三","李四"] +# 以下 allow_users、vip_users、admin_users 配置中填写的是用户的userid +# 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts +# 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] +# 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人) +# 如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid +vip_users: [] # 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid -# 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 注意:如果下边的app_secrets为空,以及使用outgoing的方式配置机器人,这两种情况下,都表示没有人是管理员 admin_users: [] # 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret diff --git a/config/config.go b/config/config.go index 74426555..990fe441 100644 --- a/config/config.go +++ b/config/config.go @@ -42,6 +42,8 @@ type Configuration struct { AllowGroups []string `yaml:"allow_groups"` // 哪些用户可以进行对话 AllowUsers []string `yaml:"allow_users"` + // 哪些Vip用户可以进行无限对话 + VipUsers []string `yaml:"vip_users"` // 指定哪些人为此系统的管理员,必须指定,否则所有人都是 AdminUsers []string `yaml:"admin_users"` // 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret @@ -134,6 +136,10 @@ func LoadConfig() *Configuration { if allowUsers != "" { config.AllowUsers = strings.Split(allowUsers, ",") } + vipUsers := os.Getenv("VIP_USERS") + if vipUsers != "" { + config.VipUsers = strings.Split(vipUsers, ",") + } adminUsers := os.Getenv("ADMIN_USERS") if adminUsers != "" { config.AdminUsers = strings.Split(adminUsers, ",") diff --git a/docker-compose.yml b/docker-compose.yml index 65313a08..08236ca8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,11 +18,13 @@ services: SERVICE_URL: "" # 指定服务的地址,就是当前服务可供外网访问的地址(或者直接理解为你配置在钉钉回调那里的地址),用于生成图片时给钉钉做渲染 CHAT_TYPE: "0" # 限定对话类型 0:不限 1:只能单聊 2:只能群聊 ALLOW_GROUPS: "" # 哪些群组可以进行对话,如果留空,则表示允许所有群组,如果要限制,则填写群组的名字,比如 "aa,bb" - ALLOW_USERS: "" # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则填写用户的名字,比如 "张三,李四" - # 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid - # 比如 "1301691029702722,1301691029702733",这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts + # 以下 allow_users、vip_users、admin_users 配置中填写的是用户的userid + # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts + # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid + ALLOW_USERS: "" # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则填写用户的userid + VIP_USERS: "" # 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人),如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid + ADMIN_USERS: "" # 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid # 注意:如果下边的app_secrets为空,以及使用outgoing的方式配置机器人,这两种情况下,都表示没有人是管理员 - ADMIN_USERS: "" APP_SECRETS: "" # 钉钉机器人在应用信息中的AppSecret,为了校验回调的请求是否合法,如果留空,将会忽略校验,则该接口将会存在其他人也能随意调用的安全隐患,因此强烈建议配置正确的secret,如果你的服务对接给多个机器人,这里可以配置多个机器人的secret,比如 "xxxx,yyyy" AZURE_ON: "false" # 是否走Azure OpenAi API, 默认false ,如果为true,则需要配置下边的四个参数 AZURE_API_VERSION: "" # Azure OpenAi API 版本,比如 "2023-03-15-preview" diff --git a/main.go b/main.go index 3e5396c6..1e5749b4 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,7 @@ func Start() { } return nil } - if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderNick) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { + if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderStaffId) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) diff --git a/pkg/process/process_request.go b/pkg/process/process_request.go index 2b7520d4..9dadbca5 100644 --- a/pkg/process/process_request.go +++ b/pkg/process/process_request.go @@ -225,14 +225,19 @@ func CheckRequestTimes(rmsg *dingbot.ReceiveMsg) bool { return true } count := public.UserService.GetUseRequestCount(rmsg.GetSenderIdentifier()) - // 判断访问次数是否超过限制 - if count >= public.Config.MaxRequest { - logger.Info(fmt.Sprintf("亲爱的: %s,您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!", rmsg.SenderNick)) - _, err := rmsg.ReplyToDingtalk(string(dingbot.TEXT), fmt.Sprintf("一个好的问题,胜过十个好的答案!\n亲爱的: %s,您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!", rmsg.SenderNick)) - if err != nil { - logger.Warning(fmt.Errorf("send message error: %v", err)) + // 用户是管理员或VIP用户,不判断访问次数是否超过限制 + if public.JudgeAdminUsers(rmsg.SenderStaffId) || public.JudgeVipUsers(rmsg.SenderStaffId) { + return true + } else { + // 用户不是管理员和VIP用户,判断访问次数是否超过限制 + if count >= public.Config.MaxRequest { + logger.Info(fmt.Sprintf("亲爱的: %s,您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!", rmsg.SenderNick)) + _, err := rmsg.ReplyToDingtalk(string(dingbot.TEXT), fmt.Sprintf("一个好的问题,胜过十个好的答案!\n亲爱的: %s,您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!", rmsg.SenderNick)) + if err != nil { + logger.Warning(fmt.Errorf("send message error: %v", err)) + } + return false } - return false } // 访问次数未超过限制,将计数加1 public.UserService.SetUseRequestCount(rmsg.GetSenderIdentifier(), count+1) diff --git a/prompt.yml b/prompt.yml index f2f7f280..2d7ac2fa 100644 --- a/prompt.yml +++ b/prompt.yml @@ -35,9 +35,6 @@ - title: "#linux命令" prefix: "我希望你只用 linux 命令回复。不要写解释。我想:" suffix: "" -- title: "#Linux命令" - prefix: "我希望你只用 Linux 命令回复。不要写解释。我想:" - suffix: "" - title: "#英语学术润色" prefix: "Below is a paragraph from an academic paper. Polish the writing to meet the academic style, improve the spelling, grammar, clarity, concision and overall readability. When neccessary, rewrite the whole sentence. Furthermore, list all modification and explain the reasons to do so in markdown table.\n" suffix: "" diff --git a/public/tools.go b/public/tools.go index 875f6fa5..4b9ad12a 100644 --- a/public/tools.go +++ b/public/tools.go @@ -73,6 +73,30 @@ func JudgeAdminUsers(s string) bool { return false } +// JudgeVipUsers 判断用户是否为VIP用户 +func JudgeVipUsers(s string) bool { + // 如果secret或者用户的userid都为空的话,那么默认不是VIP用户 + if len(Config.AppSecrets) == 0 || s == "" { + return false + } + // 管理员默认是VIP用户 + for _, v := range Config.AdminUsers { + if v == s { + return true + } + } + // 如果没有指定,则没有人是VIP用户 + if len(Config.VipUsers) == 0 { + return false + } + for _, v := range Config.VipUsers { + if v == s { + return true + } + } + return false +} + func GetReadTime(t time.Time) string { return t.Format("2006-01-02 15:04:05") } From cc7bbd1c2da44fd7087f6b25526675ac4337e76a Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 12:03:09 +0800 Subject: [PATCH 02/20] Update process_request.go --- pkg/process/process_request.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/process/process_request.go b/pkg/process/process_request.go index 9dadbca5..baf5adb0 100644 --- a/pkg/process/process_request.go +++ b/pkg/process/process_request.go @@ -232,7 +232,7 @@ func CheckRequestTimes(rmsg *dingbot.ReceiveMsg) bool { // 用户不是管理员和VIP用户,判断访问次数是否超过限制 if count >= public.Config.MaxRequest { logger.Info(fmt.Sprintf("亲爱的: %s,您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!", rmsg.SenderNick)) - _, err := rmsg.ReplyToDingtalk(string(dingbot.TEXT), fmt.Sprintf("一个好的问题,胜过十个好的答案!\n亲爱的: %s,您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!", rmsg.SenderNick)) + _, err := rmsg.ReplyToDingtalk(string(dingbot.MARKDOWN), fmt.Sprintf("[Staple] **一个好的问题,胜过十个好的答案!** \n\n亲爱的%s:\n\n您今日请求次数已达上限,请明天再来,交互发问资源有限,请务必斟酌您的问题,给您带来不便,敬请谅解!\n\n如有需要,可联系管理员升级为VIP用户。", rmsg.SenderNick)) if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) } From ad10e3a3a34db7c455cf34da2eb42513ca96eeee Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:07:35 +0800 Subject: [PATCH 03/20] Update README.md --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7a8fba5d..f8135366 100644 --- a/README.md +++ b/README.md @@ -173,7 +173,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \ -e HTTP_PROXY="http://host.docker.internal:15732" \ -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_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_USERS=a,b -e DENY_USERS=a,b -e VIP_USERS=a,b -e ADMIN_USERS=a,b -e APP_SECRETS="xxx,yyy" \ -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/) @@ -184,7 +184,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \ > 运行命令中映射的配置文件参考下边的[配置文件说明](#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E)。 - `📢 注意:`如果使用docker部署,那么PORT参数不需要进行任何调整。 -- `📢 注意:`ALLOW_GROUPS,ALLOW_USERS,VIP_USERS,ADMIN_USERS四个参数为数组,如果需要指定多个,可用英文逗号分割。 +- `📢 注意:`ALLOW_GROUPS,ALLOW_USERS,DENY_USERS,VIP_USERS,ADMIN_USERS 参数为数组,如果需要指定多个,可用英文逗号分割。 - `📢 注意:`如果服务器节点本身就在国外或者自定义了`BASE_URL`,那么就把`HTTP_PROXY`参数留空即可。 - `📢 注意:`如果使用docker部署,那么proxy地址可以直接使用如上方式部署,`host.docker.internal`会指向容器所在宿主机的IP,只需要更改端口为你的代理端口即可。参见:[Docker容器如何优雅地访问宿主机网络](https://wiki.eryajf.net/pages/674f53/) @@ -424,6 +424,8 @@ allow_groups: # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] +# 哪些用户不可以进行对话,如果留空,则表示允许所有用户(如allow_user有配置,需满足相应条件),如果要限制,则列表中写用户的userid,黑名单优先级高于白名单 +deny_users: [] # 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人) # 如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid vip_users: [] From 37c94a96fc2e33c5f7c21069656c0283823dbdfd Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:07:57 +0800 Subject: [PATCH 04/20] Update config.example.yml --- config.example.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.example.yml b/config.example.yml index 93c44ef3..6e746f1f 100644 --- a/config.example.yml +++ b/config.example.yml @@ -26,6 +26,8 @@ allow_groups: [] # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] +# 哪些用户不可以进行对话,如果留空,则表示允许所有用户(如allow_user有配置,需满足相应条件),如果要限制,则列表中写用户的userid,黑名单优先级高于白名单 +deny_users: [] # 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人) # 如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid vip_users: [] From f3e8b741dc9d53087f623d132e5337d02ef43235 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:08:14 +0800 Subject: [PATCH 05/20] Update docker-compose.yml --- docker-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yml b/docker-compose.yml index 08236ca8..278c7ca8 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,6 +22,7 @@ services: # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid ALLOW_USERS: "" # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则填写用户的userid + DENY_USERS: "" # 哪些用户不可以进行对话,如果留空,则表示允许所有用户(如allow_user有配置,需满足相应条件),如果要限制,则列表中写用户的userid,黑名单优先级高于白名单 VIP_USERS: "" # 哪些用户可以进行无限对话,如果留空,则表示只允许管理员(如max_request配置为0,则允许所有人),如果要针对指定VIP用户放开限制(如max_request配置不为0),则列表中写用户的userid ADMIN_USERS: "" # 指定哪些人为此系统的管理员,如果留空,则表示没有人是管理员,如果要限制,则列表中写用户的userid # 注意:如果下边的app_secrets为空,以及使用outgoing的方式配置机器人,这两种情况下,都表示没有人是管理员 From b6fa52d231d488b90b7f5a789364671abb855733 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:08:38 +0800 Subject: [PATCH 06/20] Update tools.go --- public/tools.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/public/tools.go b/public/tools.go index 4b9ad12a..91ae8c33 100644 --- a/public/tools.go +++ b/public/tools.go @@ -44,6 +44,15 @@ func JudgeGroup(s string) bool { // JudgeUsers 判断用户名称是否在白名单 func JudgeUsers(s string) bool { + // 优先判断黑名单,黑名单用户返回:不在白名单 + if len(Config.DenyUsers) != 0 { + for _, v := range Config.DenyUsers { + if v == s { + return false + } + } + } + // 白名单配置逻辑处理 if len(Config.AllowUsers) == 0 { return true } From 69e01ed131aa7524aeaef3ed0bfcfd5134e61bbf Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:10:13 +0800 Subject: [PATCH 07/20] Update main.go --- main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 1e5749b4..a4d0c6bf 100644 --- a/main.go +++ b/main.go @@ -56,7 +56,8 @@ func Start() { } return nil } - if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderStaffId) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { + // 不在允许群组,不在允许用户(包括在黑名单),不是管理员,任一条件满足,将拒绝进行会话 + if !public.JudgeGroup(msgObj.GetChatTitle()) || !public.JudgeUsers(msgObj.SenderStaffId) || !public.JudgeAdminUsers(msgObj.SenderStaffId) { _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) From 485b84ab89458f3fa32fbe99e9b185277f1de551 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:12:22 +0800 Subject: [PATCH 08/20] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f8135366..5ced1b8a 100644 --- a/README.md +++ b/README.md @@ -420,7 +420,7 @@ chat_type: "0" # 对话聊天时,如下三个满足其一即可通过校验 allow_groups: - "学无止境" -# 以下 allow_users、vip_users、admin_users 配置中填写的是用户的userid +# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] From ef67c52addedea419a527e967ea39042407f89f9 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:12:42 +0800 Subject: [PATCH 09/20] Update config.example.yml --- config.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.example.yml b/config.example.yml index 6e746f1f..a8b113b2 100644 --- a/config.example.yml +++ b/config.example.yml @@ -22,7 +22,7 @@ service_url: "http://xxxxxx" chat_type: "0" # 哪些群组可以进行对话,如果留空,则表示允许所有群组,如果要限制,则列表中写群组的名称,比如 ["aa","bb"] allow_groups: [] -# 以下 allow_users、vip_users、admin_users 配置中填写的是用户的userid +# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] From 05de94959ad682308999cf6afa21cbcf1ea0d5ab Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:14:17 +0800 Subject: [PATCH 10/20] Update config.go --- config/config.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/config.go b/config/config.go index 990fe441..5d5345e3 100644 --- a/config/config.go +++ b/config/config.go @@ -42,6 +42,8 @@ type Configuration struct { AllowGroups []string `yaml:"allow_groups"` // 哪些用户可以进行对话 AllowUsers []string `yaml:"allow_users"` + // 哪些用户不可以进行对话 + DenyUsers []string `yaml:"deny_users"` // 哪些Vip用户可以进行无限对话 VipUsers []string `yaml:"vip_users"` // 指定哪些人为此系统的管理员,必须指定,否则所有人都是 @@ -136,6 +138,10 @@ func LoadConfig() *Configuration { if allowUsers != "" { config.AllowUsers = strings.Split(allowUsers, ",") } + denyUsers := os.Getenv("DENY_USERS") + if denyUsers != "" { + config.DenyUsers = strings.Split(denyUsers, ",") + } vipUsers := os.Getenv("VIP_USERS") if vipUsers != "" { config.VipUsers = strings.Split(vipUsers, ",") From 06098f84faa39a675a716fe102a49f197cc9d95f Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:15:39 +0800 Subject: [PATCH 11/20] Update docker-compose.yml --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 278c7ca8..d0eb460f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,7 @@ services: SERVICE_URL: "" # 指定服务的地址,就是当前服务可供外网访问的地址(或者直接理解为你配置在钉钉回调那里的地址),用于生成图片时给钉钉做渲染 CHAT_TYPE: "0" # 限定对话类型 0:不限 1:只能单聊 2:只能群聊 ALLOW_GROUPS: "" # 哪些群组可以进行对话,如果留空,则表示允许所有群组,如果要限制,则填写群组的名字,比如 "aa,bb" - # 以下 allow_users、vip_users、admin_users 配置中填写的是用户的userid + # 以下 ALLOW_USERS、DENY_USERS、VIP_USERS、ADMIN_USERS 配置中填写的是用户的userid # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid ALLOW_USERS: "" # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则填写用户的userid From 687a762329d6f2ce41e1f5ffd620f3109bd6eaa0 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:25:54 +0800 Subject: [PATCH 12/20] Update main.go --- main.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/main.go b/main.go index a4d0c6bf..4413e8a4 100644 --- a/main.go +++ b/main.go @@ -57,8 +57,7 @@ func Start() { return nil } // 不在允许群组,不在允许用户(包括在黑名单),不是管理员,任一条件满足,将拒绝进行会话 - if !public.JudgeGroup(msgObj.GetChatTitle()) || !public.JudgeUsers(msgObj.SenderStaffId) || !public.JudgeAdminUsers(msgObj.SenderStaffId) { - _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") + if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderNick) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) return err From 0303a4aed026ad4172c18864541385de3088a91b Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:26:27 +0800 Subject: [PATCH 13/20] Update main.go --- main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/main.go b/main.go index 4413e8a4..b101b42a 100644 --- a/main.go +++ b/main.go @@ -57,7 +57,8 @@ func Start() { return nil } // 不在允许群组,不在允许用户(包括在黑名单),不是管理员,任一条件满足,将拒绝进行会话 - if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderNick) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") + if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderNick) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { + _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) return err From c79fb612f298406d70d251df81c05a0f0059c58f Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:34:43 +0800 Subject: [PATCH 14/20] Update main.go --- main.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index b101b42a..f1abd291 100644 --- a/main.go +++ b/main.go @@ -56,8 +56,9 @@ func Start() { } return nil } - // 不在允许群组,不在允许用户(包括在黑名单),不是管理员,任一条件满足,将拒绝进行会话 - if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderNick) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { + // 不在允许群组,不在允许用户(包括在黑名单),拒绝会话 + // 移除掉多余的管理员判断( !public.JudgeAdminUsers(msgObj.SenderStaffId)) + if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderStaffId) { _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) From 0fd72ccbbde5f3e1e1ecae7d10786401ccbbc700 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:38:25 +0800 Subject: [PATCH 15/20] Update main.go --- main.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index f1abd291..b99ec128 100644 --- a/main.go +++ b/main.go @@ -56,9 +56,8 @@ func Start() { } return nil } - // 不在允许群组,不在允许用户(包括在黑名单),拒绝会话 - // 移除掉多余的管理员判断( !public.JudgeAdminUsers(msgObj.SenderStaffId)) - if !public.JudgeGroup(msgObj.GetChatTitle()) && !public.JudgeUsers(msgObj.SenderStaffId) { + // 不在允许群组,不在允许用户(包括在黑名单),满足任一条件,拒绝会话;管理员不受限制 + if (!public.JudgeGroup(msgObj.GetChatTitle()) || !public.JudgeUsers(msgObj.SenderStaffId)) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) From e85d421bc4169a1c720af13e04738e2bd159cbce Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:40:34 +0800 Subject: [PATCH 16/20] Update config.example.yml --- config.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.example.yml b/config.example.yml index a8b113b2..1142122c 100644 --- a/config.example.yml +++ b/config.example.yml @@ -22,7 +22,7 @@ service_url: "http://xxxxxx" chat_type: "0" # 哪些群组可以进行对话,如果留空,则表示允许所有群组,如果要限制,则列表中写群组的名称,比如 ["aa","bb"] allow_groups: [] -# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid +# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid,outgoing机器人模式下不适用这些配置 # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] From 664e19b4ed43f537dd87e9ef25f79b41c314e75d Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 13:42:14 +0800 Subject: [PATCH 17/20] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5ced1b8a..f42fa98e 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ $ docker run -itd --name chatgpt -p 8090:8090 \ > 运行命令中映射的配置文件参考下边的[配置文件说明](#%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%E8%AF%B4%E6%98%8E)。 - `📢 注意:`如果使用docker部署,那么PORT参数不需要进行任何调整。 -- `📢 注意:`ALLOW_GROUPS,ALLOW_USERS,DENY_USERS,VIP_USERS,ADMIN_USERS 参数为数组,如果需要指定多个,可用英文逗号分割。 +- `📢 注意:`ALLOW_GROUPS,ALLOW_USERS,DENY_USERS,VIP_USERS,ADMIN_USERS 参数为数组,如果需要指定多个,可用英文逗号分割。outgoing机器人模式下这些参数无效。 - `📢 注意:`如果服务器节点本身就在国外或者自定义了`BASE_URL`,那么就把`HTTP_PROXY`参数留空即可。 - `📢 注意:`如果使用docker部署,那么proxy地址可以直接使用如上方式部署,`host.docker.internal`会指向容器所在宿主机的IP,只需要更改端口为你的代理端口即可。参见:[Docker容器如何优雅地访问宿主机网络](https://wiki.eryajf.net/pages/674f53/) @@ -420,7 +420,7 @@ chat_type: "0" # 对话聊天时,如下三个满足其一即可通过校验 allow_groups: - "学无止境" -# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid +# 以下 allow_users、deny_users、vip_users、admin_users 配置中填写的是用户的userid,outgoing机器人模式下不适用这些配置 # 比如 ["1301691029702722","1301691029702733"],这个信息需要在钉钉管理后台的通讯录当中获取:https://oa.dingtalk.com/contacts.htm#/contacts # 哪些用户可以进行对话,如果留空,则表示允许所有用户,如果要限制,则列表中写用户的userid allow_users: [] From 51d95951224da9a0eacbbcc25332816c81ec53d4 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 16:35:41 +0800 Subject: [PATCH 18/20] Update main.go --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index b99ec128..99006237 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,7 @@ func Start() { logger.Debug(fmt.Sprintf("dingtalk callback parameters: %#v", msgObj)) if public.Config.ChatType != "0" && msgObj.ConversationType != public.Config.ChatType { - _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,管理员禁用了这种聊天方式,请选择其他聊天方式与机器人对话!") + _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "** 🤷 很抱歉,管理员禁用了这种聊天方式,请选择其他聊天方式与机器人对话!**") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) return err @@ -58,7 +58,7 @@ func Start() { } // 不在允许群组,不在允许用户(包括在黑名单),满足任一条件,拒绝会话;管理员不受限制 if (!public.JudgeGroup(msgObj.GetChatTitle()) || !public.JudgeUsers(msgObj.SenderStaffId)) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { - _, err = msgObj.ReplyToDingtalk(string(dingbot.TEXT), "抱歉,您不在该机器人对话功能的白名单当中!") + _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "** 🤷 很抱歉,您的身份信息未被认证通过,无法使用机器人对话功能。**\n>如需继续使用,请联系管理员申请访问权限。") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) return err From bfad3ff507ae48e129f3354a54b8bcf3fcc984b3 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 16:37:27 +0800 Subject: [PATCH 19/20] Update main.go --- main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.go b/main.go index 99006237..5dbf3114 100644 --- a/main.go +++ b/main.go @@ -49,7 +49,7 @@ func Start() { logger.Debug(fmt.Sprintf("dingtalk callback parameters: %#v", msgObj)) if public.Config.ChatType != "0" && msgObj.ConversationType != public.Config.ChatType { - _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "** 🤷 很抱歉,管理员禁用了这种聊天方式,请选择其他聊天方式与机器人对话!**") + _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "**🤷 抱歉,管理员禁用了这种聊天方式,请选择其他聊天方式与机器人对话!**") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) return err @@ -58,7 +58,7 @@ func Start() { } // 不在允许群组,不在允许用户(包括在黑名单),满足任一条件,拒绝会话;管理员不受限制 if (!public.JudgeGroup(msgObj.GetChatTitle()) || !public.JudgeUsers(msgObj.SenderStaffId)) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { - _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "** 🤷 很抱歉,您的身份信息未被认证通过,无法使用机器人对话功能。**\n>如需继续使用,请联系管理员申请访问权限。") + _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "**🤷 抱歉,您的身份信息未被认证通过,无法使用机器人对话功能。**\n>如需继续使用,请联系管理员申请访问权限。") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) return err From b80658e1236652f3ad5cf9a087479a29a89fc141 Mon Sep 17 00:00:00 2001 From: Finly Date: Sun, 9 Apr 2023 17:35:15 +0800 Subject: [PATCH 20/20] Update main.go --- main.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/main.go b/main.go index 5dbf3114..4031a6b8 100644 --- a/main.go +++ b/main.go @@ -49,6 +49,7 @@ func Start() { logger.Debug(fmt.Sprintf("dingtalk callback parameters: %#v", msgObj)) if public.Config.ChatType != "0" && msgObj.ConversationType != public.Config.ChatType { + logger.Info(fmt.Sprintf("🙋 %s使用了禁用的聊天方式", msgObj.SenderNick)) _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "**🤷 抱歉,管理员禁用了这种聊天方式,请选择其他聊天方式与机器人对话!**") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err)) @@ -58,6 +59,7 @@ func Start() { } // 不在允许群组,不在允许用户(包括在黑名单),满足任一条件,拒绝会话;管理员不受限制 if (!public.JudgeGroup(msgObj.GetChatTitle()) || !public.JudgeUsers(msgObj.SenderStaffId)) && !public.JudgeAdminUsers(msgObj.SenderStaffId) { + logger.Info(fmt.Sprintf("🙋 %s身份信息未被验证通过", msgObj.SenderNick)) _, err = msgObj.ReplyToDingtalk(string(dingbot.MARKDOWN), "**🤷 抱歉,您的身份信息未被认证通过,无法使用机器人对话功能。**\n>如需继续使用,请联系管理员申请访问权限。") if err != nil { logger.Warning(fmt.Errorf("send message error: %v", err))