Compare commits

...

48 Commits

Author SHA1 Message Date
Rock Chin
2fed6f61ba Release v2.4.4 2023-05-21 15:15:28 +08:00
Rock Chin
59b2cd26d2 Merge pull request #476 from RockChinQ/hotfix-471-at-no-response-aft-reload
[Fix] 热重载之后不响应群内at
2023-05-21 15:12:43 +08:00
Rock Chin
f7b87e99d2 fix(manager.py): 热重载之后不响应群内at 2023-05-21 15:11:34 +08:00
Rock Chin
70bc985145 perf(nakuru.py): access-token被拒时报警 2023-05-18 21:06:32 +08:00
Rock Chin
070dbe9108 chore: 排除venv/目录 2023-05-18 21:05:45 +08:00
Rock Chin
a63fa6d955 chore: yiri-mirai使用0.2.7 2023-05-18 21:05:30 +08:00
Rock Chin
c7703809b0 Merge pull request #475 from RockChinQ/actively-delay
[Feat] 支持设置消息回复强制延迟以降低风控概率
2023-05-18 20:15:52 +08:00
GitHub Actions
37eb74338f Update override-all.json 2023-05-18 12:14:19 +00:00
Rock Chin
77d5585b7c feat: 修改强制延迟默认范围 2023-05-18 20:13:53 +08:00
Rock Chin
6cab3ef029 Merge branch 'actively-delay' of https://github.com/RockChinQ/QChatGPT into actively-delay 2023-05-18 20:12:39 +08:00
Rock Chin
820a7b78fc feat: 处理过程支持强制延迟 2023-05-18 20:12:36 +08:00
GitHub Actions
c51dffef3a Update override-all.json 2023-05-18 12:10:33 +00:00
Rock Chin
983bc3da3c chore: 添加强制延迟配置项 2023-05-18 20:10:08 +08:00
Rock Chin
09be956a58 Merge pull request #474 from RockChinQ/command-notfound-err
[Perf] 修改指令不存在时的提示信息
2023-05-18 19:45:25 +08:00
Rock Chin
5eded50c53 perf: 修改指令不存在时的提示信息 2023-05-18 19:44:20 +08:00
Rock Chin
6d8eebd314 doc: 添加微信赞赏码 2023-05-16 15:36:07 +08:00
Rock Chin
19a0572b5f Release v2.4.3.1 2023-05-15 17:38:03 +08:00
Rock Chin
6272e98474 Merge pull request #467 from RockChinQ/perf-plugin-update
[Perf] 优化插件更新相关操作
2023-05-14 18:45:36 +08:00
Rock Chin
45042fe7d4 doc: 更新插件更新命令wiki 2023-05-14 18:44:14 +08:00
Rock Chin
d85e840126 perf: 优化插件更新操作,支持更新单个插件 2023-05-14 18:41:20 +08:00
Rock Chin
804889f1de perf: 加载模块的输出改为debug级别 2023-05-14 17:30:05 +08:00
Rock Chin
919c996434 doc: 添加HuggingChat 2023-05-14 17:14:46 +08:00
Rock Chin
00823b3d62 doc(README): 添加HuggingChat 2023-05-14 17:14:28 +08:00
Rock Chin
af54efd24a doc(README.md): 添加系统状态插件 2023-05-14 14:58:48 +08:00
Rock Chin
b1c9b121f6 Update go-cqhttp配置.md 2023-05-08 21:51:03 +08:00
Rock Chin
7b5649d153 Merge pull request #461 from RockChinQ/dependabot/pip/openai-approx-eq-0.27.6
chore(deps): update openai requirement from ~=0.27.5 to ~=0.27.6
2023-05-08 18:48:20 +08:00
dependabot[bot]
52bf716d84 chore(deps): update openai requirement from ~=0.27.5 to ~=0.27.6
Updates the requirements on [openai](https://github.com/openai/openai-python) to permit the latest version.
- [Release notes](https://github.com/openai/openai-python/releases)
- [Commits](https://github.com/openai/openai-python/compare/v0.27.5...v0.27.6)

---
updated-dependencies:
- dependency-name: openai
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 10:34:21 +00:00
Rock Chin
c149dd7b66 Merge pull request #462 from RockChinQ/dependabot/pip/dulwich-approx-eq-0.21.5
chore(deps): update dulwich requirement from ~=0.21.3 to ~=0.21.5
2023-05-08 18:24:59 +08:00
dependabot[bot]
65d5a1ed63 chore(deps): update dulwich requirement from ~=0.21.3 to ~=0.21.5
Updates the requirements on [dulwich](https://github.com/dulwich/dulwich) to permit the latest version.
- [Release notes](https://github.com/dulwich/dulwich/releases)
- [Changelog](https://github.com/jelmer/dulwich/blob/master/NEWS)
- [Commits](https://github.com/dulwich/dulwich/compare/dulwich-0.21.3...dulwich-0.21.5)

---
updated-dependencies:
- dependency-name: dulwich
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-08 09:01:55 +00:00
Rock Chin
5516754bbb doc(README.md): 添加docker部署提示 2023-05-02 14:30:25 +08:00
Rock Chin
08082f2ee3 Merge pull request #452 from RockChinQ/dependabot/pip/openai-approx-eq-0.27.5
chore(deps): update openai requirement from ~=0.27.4 to ~=0.27.5
2023-05-01 17:26:18 +08:00
dependabot[bot]
8489266080 chore(deps): update openai requirement from ~=0.27.4 to ~=0.27.5
Updates the requirements on [openai](https://github.com/openai/openai-python) to permit the latest version.
- [Release notes](https://github.com/openai/openai-python/releases)
- [Commits](https://github.com/openai/openai-python/compare/v0.27.4...v0.27.5)

---
updated-dependencies:
- dependency-name: openai
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-05-01 09:06:44 +00:00
Rock Chin
51c7e0b235 doc(README.md): 四群群号 2023-04-28 00:37:29 +08:00
Rock Chin
628b6b0bb4 Merge branch 'master' of https://github.com/RockChinQ/QChatGPT 2023-04-27 15:01:47 +08:00
Rock Chin
7e024d860d doc: 增加LightQChat的公告 2023-04-27 15:01:44 +08:00
Rock Chin
c2f6273f70 Merge pull request #442 from oliverkirk-sudo/master
修复异常输出时的类型问题
2023-04-26 17:31:19 +08:00
oliverkirk-sudo
96e401ec7b 修复异常输出时的类型问题 2023-04-26 17:27:33 +08:00
Rock Chin
ae8ac65447 feat: 更换使用清华源 (#438) 2023-04-26 11:52:07 +08:00
Rock Chin
2d4f59f36e doc: 强调02 2023-04-26 11:18:07 +08:00
Rock Chin
0e85467e02 Release v2.4.2 2023-04-25 10:27:57 +08:00
Rock Chin
eb41cf5481 fix(plugin.py): 兼容性问题 2023-04-25 10:27:07 +08:00
Rock Chin
b970a42d07 fix(plugin.py): send_message封装实现的兼容性问题 2023-04-25 10:26:03 +08:00
Rock Chin
8c9d123e1c Merge pull request #433 from RockChinQ/detailed-response-rules
[Feat] 细化到单个群的响应规则
2023-04-25 09:39:56 +08:00
Rock Chin
ab2a95e347 Merge branch 'detailed-response-rules' of https://github.com/RockChinQ/QChatGPT into detailed-response-rules 2023-04-25 09:31:56 +08:00
Rock Chin
2184c558a4 feat: 支持配置细化到单个群的响应规则 2023-04-25 09:31:44 +08:00
GitHub Actions
83cb8588fd Update override-all.json 2023-04-25 01:28:56 +00:00
Rock Chin
007e82c533 feat: 配置文件支持 2023-04-25 09:28:31 +08:00
Rock Chin
499f8580a7 doc: 修改wiki格式 2023-04-25 08:45:58 +08:00
17 changed files with 230 additions and 89 deletions

4
.gitignore vendored
View File

@@ -22,4 +22,6 @@ cmdpriv.json
tips.py tips.py
.venv .venv
bin/ bin/
.vscode .vscode
test_*
venv/

View File

@@ -8,6 +8,7 @@
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/RockChinQ/QChatGPT?style=flat-square)](https://github.com/RockChinQ/QChatGPT/releases/latest) [![GitHub release (latest by date)](https://img.shields.io/github/v/release/RockChinQ/QChatGPT?style=flat-square)](https://github.com/RockChinQ/QChatGPT/releases/latest)
> 2023/4/27 正在对纯Python实现的QQ登录框架、YAML配置文件、异步编程等功能进行概念验证欢迎体验[LightQChat](https://github.com/RockChinQ/LightQChat)项目
> 2023/4/24 支持使用go-cqhttp登录QQ请查看[此文档](https://github.com/RockChinQ/QChatGPT/wiki/go-cqhttp%E9%85%8D%E7%BD%AE) > 2023/4/24 支持使用go-cqhttp登录QQ请查看[此文档](https://github.com/RockChinQ/QChatGPT/wiki/go-cqhttp%E9%85%8D%E7%BD%AE)
> 2023/3/18 现已支持GPT-4 API内测请查看`config-template.py`中的`completion_api_params` > 2023/3/18 现已支持GPT-4 API内测请查看`config-template.py`中的`completion_api_params`
> 2023/3/15 逆向库已支持New Bing使用方法查看[插件文档](https://github.com/RockChinQ/revLibs) > 2023/3/15 逆向库已支持New Bing使用方法查看[插件文档](https://github.com/RockChinQ/revLibs)
@@ -32,6 +33,7 @@
- ChatGPT网页版GPT-3.5模型, 由[插件](https://github.com/RockChinQ/revLibs)接入 - ChatGPT网页版GPT-3.5模型, 由[插件](https://github.com/RockChinQ/revLibs)接入
- ChatGPT网页版GPT-4模型, 目前需要ChatGPT Plus订阅, 由[插件](https://github.com/RockChinQ/revLibs)接入 - ChatGPT网页版GPT-4模型, 目前需要ChatGPT Plus订阅, 由[插件](https://github.com/RockChinQ/revLibs)接入
- New Bing逆向库, 由[插件](https://github.com/RockChinQ/revLibs)接入 - New Bing逆向库, 由[插件](https://github.com/RockChinQ/revLibs)接入
- HuggingChat, 由[插件](https://github.com/RockChinQ/revLibs)接入, 无需账号,仅支持英文
### 故事续写 ### 故事续写
@@ -176,6 +178,8 @@
#### Docker方式 #### Docker方式
> docker方式目前仅支持使用mirai登录若您不**熟悉**docker的操作及相关知识强烈建议您使用其他方式部署我们**不会且难以**解决您主机上多个容器的连接问题。
请查看[此文档](res/docs/docker_deploy.md) 请查看[此文档](res/docs/docker_deploy.md)
由[@mikumifa](https://github.com/mikumifa)贡献 由[@mikumifa](https://github.com/mikumifa)贡献
@@ -292,6 +296,7 @@ python3 main.py
- [chordfish-k/QChartGPT_Emoticon_Plugin](https://github.com/chordfish-k/QChartGPT_Emoticon_Plugin) - 使机器人根据回复内容发送表情包 - [chordfish-k/QChartGPT_Emoticon_Plugin](https://github.com/chordfish-k/QChartGPT_Emoticon_Plugin) - 使机器人根据回复内容发送表情包
- [oliverkirk-sudo/ChatPoeBot](https://github.com/oliverkirk-sudo/ChatPoeBot) - 接入[Poe](https://poe.com/)上的机器人 - [oliverkirk-sudo/ChatPoeBot](https://github.com/oliverkirk-sudo/ChatPoeBot) - 接入[Poe](https://poe.com/)上的机器人
- [lieyanqzu/WeatherPlugin](https://github.com/lieyanqzu/WeatherPlugin) - 天气查询插件 - [lieyanqzu/WeatherPlugin](https://github.com/lieyanqzu/WeatherPlugin) - 天气查询插件
- [SysStatPlugin](https://github.com/RockChinQ/SysStatPlugin) - 查看系统状态
</details> </details>
## 😘致谢 ## 😘致谢
@@ -304,6 +309,6 @@ python3 main.py
以及所有[贡献者](https://github.com/RockChinQ/QChatGPT/graphs/contributors)和其他为本项目提供支持的朋友们。 以及所有[贡献者](https://github.com/RockChinQ/QChatGPT/graphs/contributors)和其他为本项目提供支持的朋友们。
<!-- ## 👍赞赏 ## 👍赞赏
<img alt="赞赏码" src="res/mm_reward_qrcode_1672840549070.png" width="400" height="400"/> --> <img alt="赞赏码" src="res/mm_reward_qrcode_1672840549070.png" width="400" height="400"/>

View File

@@ -27,6 +27,7 @@ English | [简体中文](README.md)
- ChatGPT website edition (GPT-3.5), see [revLibs plugin](https://github.com/RockChinQ/revLibs) - ChatGPT website edition (GPT-3.5), see [revLibs plugin](https://github.com/RockChinQ/revLibs)
- ChatGPT website edition (GPT-4), ChatGPT plus subscription required, see [revLibs plugin](https://github.com/RockChinQ/revLibs) - ChatGPT website edition (GPT-4), ChatGPT plus subscription required, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
- New Bing, see [revLibs plugin](https://github.com/RockChinQ/revLibs) - New Bing, see [revLibs plugin](https://github.com/RockChinQ/revLibs)
- HuggingChat, see [revLibs plugin](https://github.com/RockChinQ/revLibs), no accounts required, English only
### Story ### Story

View File

@@ -123,13 +123,36 @@ preset_mode = "normal"
# 注意:由消息前缀(prefix)匹配的消息中将会删除此前缀,正则表达式(regexp)匹配的消息不会删除匹配的部分 # 注意:由消息前缀(prefix)匹配的消息中将会删除此前缀,正则表达式(regexp)匹配的消息不会删除匹配的部分
# 前缀匹配优先级高于正则表达式匹配 # 前缀匹配优先级高于正则表达式匹配
# 正则表达式简明教程https://www.runoob.com/regexp/regexp-tutorial.html # 正则表达式简明教程https://www.runoob.com/regexp/regexp-tutorial.html
#
# 支持针对不同群设置不同的响应规则,例如:
# response_rules = {
# "default": {
# "at": True,
# "prefix": ["/ai", "!ai", "ai", "ai"],
# "regexp": [],
# "random_rate": 0.0,
# },
# "12345678": {
# "at": False,
# "prefix": ["/ai", "!ai", "ai", "ai"],
# "regexp": [],
# "random_rate": 0.0,
# },
# }
#
# 以上设置将会在群号为12345678的群中关闭at响应
# 未单独设置的群将使用default规则
response_rules = { response_rules = {
"at": True, # 是否响应at机器人的消息 "default": {
"prefix": ["/ai", "!ai", "ai", "ai"], "at": True, # 是否响应at机器人的消息
"regexp": [], # "为什么.*", "怎么?样.*", "怎么.*", "如何.*", "[Hh]ow to.*", "[Ww]hy not.*", "[Ww]hat is.*", ".*怎么办", ".*咋办" "prefix": ["/ai", "!ai", "ai", "ai"],
"random_rate": 0.0, # 随机响应概率0.0-1.00.0为不随机响应1.0为响应所有消息, 仅在前几项判断不通过时生效 "regexp": [], # "为什么.*", "怎么?样.*", "怎么.*", "如何.*", "[Hh]ow to.*", "[Ww]hy not.*", "[Ww]hat is.*", ".*怎么办", ".*咋办"
"random_rate": 0.0, # 随机响应概率0.0-1.00.0为不随机响应1.0为响应所有消息, 仅在前几项判断不通过时生效
},
} }
# 消息忽略规则 # 消息忽略规则
# 适用于私聊及群聊 # 适用于私聊及群聊
# 符合此规则的消息将不会被响应 # 符合此规则的消息将不会被响应
@@ -218,6 +241,14 @@ process_message_timeout = 30
# 回复消息时是否显示[GPT]前缀 # 回复消息时是否显示[GPT]前缀
show_prefix = False show_prefix = False
# 回复前的强制延迟时间,降低机器人被腾讯风控概率
# *此机制对命令和消息、私聊及群聊均生效
# 每次处理时从以下的范围取一个随机秒数,
# 当此次消息处理时间低于此秒数时,将会强制延迟至此秒数
# 例如:[1.5, 3]则每次处理时会随机取一个1.5-3秒的随机数若处理时间低于此随机数则强制延迟至此随机秒数
# 若您不需要此功能请将force_delay_range设置为[0, 0]
force_delay_range = [1.5, 3]
# 应用长消息处理策略的阈值 # 应用长消息处理策略的阈值
# 当回复消息长度超过此值时,将使用长消息处理策略 # 当回复消息长度超过此值时,将使用长消息处理策略
blob_message_threshold = 256 blob_message_threshold = 256

View File

@@ -48,8 +48,8 @@ def init_db():
def ensure_dependencies(): def ensure_dependencies():
import pkg.utils.pkgmgr as pkgmgr import pkg.utils.pkgmgr as pkgmgr
pkgmgr.run_pip(["install", "openai", "Pillow", "nakuru-project-idk", "--upgrade", pkgmgr.run_pip(["install", "openai", "Pillow", "nakuru-project-idk", "--upgrade",
"-i", "https://pypi.douban.com/simple/", "-i", "https://pypi.tuna.tsinghua.edu.cn/simple",
"--trusted-host", "pypi.douban.com"]) "--trusted-host", "pypi.tuna.tsinghua.edu.cn"])
known_exception_caught = False known_exception_caught = False
@@ -268,7 +268,7 @@ def start(first_time_init=False):
import config import config
if config.msg_source_adapter == "yirimirai": if config.msg_source_adapter == "yirimirai":
logging.info("QQ: {}, MAH: {}".format(config.mirai_http_api_config['qq'], config.mirai_http_api_config['host']+":"+str(config.mirai_http_api_config['port']))) logging.info("QQ: {}, MAH: {}".format(config.mirai_http_api_config['qq'], config.mirai_http_api_config['host']+":"+str(config.mirai_http_api_config['port'])))
logging.critical('程序启动完成,如长时间未显示 "成功登录到账号xxxxx" ,并且不回复消息,请查看 ' logging.critical('程序启动完成,如长时间未显示 "成功登录到账号xxxxx" ,并且不回复消息,解决办法(请勿到群里问): '
'https://github.com/RockChinQ/QChatGPT/issues/37') 'https://github.com/RockChinQ/QChatGPT/issues/37')
elif config.msg_source_adapter == 'nakuru': elif config.msg_source_adapter == 'nakuru':
logging.info("host: {}, port: {}, http_port: {}".format(config.nakuru_config['host'], config.nakuru_config['port'], config.nakuru_config['http_port'])) logging.info("host: {}, port: {}, http_port: {}".format(config.nakuru_config['host'], config.nakuru_config['port'], config.nakuru_config['http_port']))

View File

@@ -27,15 +27,17 @@
}, },
"preset_mode": "normal", "preset_mode": "normal",
"response_rules": { "response_rules": {
"at": true, "default": {
"prefix": [ "at": true,
"/ai", "prefix": [
"!ai", "/ai",
"ai", "!ai",
"ai" "ai",
], "ai"
"regexp": [], ],
"random_rate": 0.0 "regexp": [],
"random_rate": 0.0
}
}, },
"ignore_rules": { "ignore_rules": {
"prefix": [ "prefix": [
@@ -65,6 +67,10 @@
"include_image_description": true, "include_image_description": true,
"process_message_timeout": 30, "process_message_timeout": 30,
"show_prefix": false, "show_prefix": false,
"force_delay_range": [
1.5,
3
],
"blob_message_threshold": 256, "blob_message_threshold": 256,
"blob_message_strategy": "forward", "blob_message_strategy": "forward",
"wait_last_done": true, "wait_last_done": true,

View File

@@ -8,6 +8,7 @@ import sys
import shutil import shutil
import traceback import traceback
import pkg.utils.updater as updater
import pkg.utils.context as context import pkg.utils.context as context
import pkg.plugin.switch as switch import pkg.plugin.switch as switch
import pkg.plugin.settings as settings import pkg.plugin.settings as settings
@@ -79,7 +80,7 @@ def walk_plugin_path(module, prefix='', path_prefix=''):
__current_module_path__ = "plugins/"+path_prefix + item.name + '.py' __current_module_path__ = "plugins/"+path_prefix + item.name + '.py'
importlib.import_module(module.__name__ + '.' + item.name) importlib.import_module(module.__name__ + '.' + item.name)
logging.info('加载模块: plugins/{} 成功'.format(path_prefix + item.name + '.py')) logging.debug('加载模块: plugins/{} 成功'.format(path_prefix + item.name + '.py'))
except: except:
logging.error('加载模块: plugins/{} 失败: {}'.format(path_prefix + item.name + '.py', sys.exc_info())) logging.error('加载模块: plugins/{} 失败: {}'.format(path_prefix + item.name + '.py', sys.exc_info()))
traceback.print_exc() traceback.print_exc()
@@ -177,6 +178,43 @@ def uninstall_plugin(plugin_name: str) -> str:
return "plugins/"+plugin_path return "plugins/"+plugin_path
def update_plugin(plugin_name: str):
"""更新插件"""
# 检查是否有远程地址记录
target_plugin_dir = "plugins/" + __plugins__[plugin_name]['path'].replace("\\", "/").split("plugins/")[1].split("/")[0]
remote_url = updater.get_remote_url(target_plugin_dir)
if remote_url == "https://github.com/RockChinQ/QChatGPT" or remote_url == "https://gitee.com/RockChin/QChatGPT" \
or remote_url == "" or remote_url is None or remote_url == "http://github.com/RockChinQ/QChatGPT" or remote_url == "http://gitee.com/RockChin/QChatGPT":
raise Exception("插件没有远程地址记录,无法更新")
# 把远程clone到temp/plugins/update/插件名
logging.info("克隆插件储存库: {}".format(remote_url))
from dulwich import porcelain
clone_target_dir = "temp/plugins/update/"+target_plugin_dir.split("/")[-1]+"/"
if os.path.exists(clone_target_dir):
shutil.rmtree(clone_target_dir)
if not os.path.exists(clone_target_dir):
os.makedirs(clone_target_dir)
repo = porcelain.clone(remote_url, clone_target_dir, checkout=True)
# 检查此目录是否包含requirements.txt
if os.path.exists(clone_target_dir+"requirements.txt"):
logging.info("检测到requirements.txt正在安装依赖")
import pkg.utils.pkgmgr
pkg.utils.pkgmgr.install_requirements(clone_target_dir+"requirements.txt")
import pkg.utils.log as log
log.reset_logging()
# 将temp/plugins/update/插件名 覆盖到 plugins/插件名
shutil.rmtree(target_plugin_dir)
shutil.copytree(clone_target_dir, target_plugin_dir)
class EventContext: class EventContext:
"""事件上下文""" """事件上下文"""
eid = 0 eid = 0
@@ -283,11 +321,11 @@ class PluginHost:
def send_person_message(self, person, message): def send_person_message(self, person, message):
"""发送私聊消息""" """发送私聊消息"""
asyncio.run(self.get_bot().send_friend_message(person, message)) self.get_bot_adapter().send_message("person", person, message)
def send_group_message(self, group, message): def send_group_message(self, group, message):
"""发送群消息""" """发送群消息"""
asyncio.run(self.get_bot().send_group_message(group, message)) self.get_bot_adapter().send_message("group", group, message)
def notify_admin(self, message): def notify_admin(self, message):
"""通知管理员""" """通知管理员"""
@@ -344,3 +382,6 @@ class PluginHost:
event_context.__return_value__)) event_context.__return_value__))
return event_context return event_context
if __name__ == "__main__":
pass

View File

@@ -260,8 +260,8 @@ def execute(context: Context) -> list:
while True: while True:
try: try:
logging.debug('执行指令: {}'.format(path))
node = __command_list__[path] node = __command_list__[path]
logging.debug('执行指令: {}'.format(path))
# 检查权限 # 检查权限
if ctx.privilege < node['privilege']: if ctx.privilege < node['privilege']:

View File

@@ -97,37 +97,34 @@ class PluginUpdateCommand(AbstractCommandNode):
plugin_list = plugin_host.__plugins__ plugin_list = plugin_host.__plugins__
reply = [] reply = []
def closure():
try:
import pkg.utils.context
updated = []
for key in plugin_list:
plugin = plugin_list[key]
if updater.is_repo("/".join(plugin['path'].split('/')[:-1])):
success = updater.pull_latest("/".join(plugin['path'].split('/')[:-1]))
if success:
updated.append(plugin['name'])
# 检查是否有requirements.txt if len(ctx.crt_params) > 0:
pkg.utils.context.get_qqbot_manager().notify_admin("正在安装依赖...") def closure():
for key in plugin_list: try:
plugin = plugin_list[key] import pkg.utils.context
if os.path.exists("/".join(plugin['path'].split('/')[:-1])+"/requirements.txt"):
logging.info("{}检测到requirements.txt安装依赖".format(plugin['name'])) updated = []
import pkg.utils.pkgmgr
pkg.utils.pkgmgr.install_requirements("/".join(plugin['path'].split('/')[:-1])+"/requirements.txt")
import pkg.utils.log as log if ctx.crt_params[0] == 'all':
log.reset_logging() for key in plugin_list:
plugin_host.update_plugin(key)
updated.append(key)
else:
if ctx.crt_params[0] in plugin_list:
plugin_host.update_plugin(ctx.crt_params[0])
updated.append(ctx.crt_params[0])
else:
raise Exception("未找到插件: {}".format(ctx.crt_params[0]))
pkg.utils.context.get_qqbot_manager().notify_admin("已更新插件: {}".format(", ".join(updated))) pkg.utils.context.get_qqbot_manager().notify_admin("已更新插件: {}, 请发送 !reload 重载插件".format(", ".join(updated)))
except Exception as e: except Exception as e:
logging.error("插件更新失败:{}".format(e)) logging.error("插件更新失败:{}".format(e))
pkg.utils.context.get_qqbot_manager().notify_admin("插件更新失败:{} 请尝试手动更新插件".format(e)) pkg.utils.context.get_qqbot_manager().notify_admin("插件更新失败:{} 请尝试手动更新插件".format(e))
reply = ["[bot]正在更新插件,请勿重复发起..."]
threading.Thread(target=closure).start() threading.Thread(target=closure).start()
reply = ["[bot]正在更新所有插件,请勿重复发起..."] else:
reply = ["[bot]请指定要更新的插件, 或使用 !plugin update all 更新所有插件"]
return True, reply return True, reply

View File

@@ -25,10 +25,18 @@ import pkg.qqbot.adapter as msadapter
# 检查消息是否符合泛响应匹配机制 # 检查消息是否符合泛响应匹配机制
def check_response_rule(text: str): def check_response_rule(group_id:int, text: str):
config = pkg.utils.context.get_config() config = pkg.utils.context.get_config()
rules = config.response_rules rules = config.response_rules
# 检查是否有特定规则
if 'prefix' not in config.response_rules:
if str(group_id) in config.response_rules:
rules = config.response_rules[str(group_id)]
else:
rules = config.response_rules['default']
# 检查前缀匹配 # 检查前缀匹配
if 'prefix' in rules: if 'prefix' in rules:
for rule in rules['prefix']: for rule in rules['prefix']:
@@ -46,19 +54,39 @@ def check_response_rule(text: str):
return False, "" return False, ""
def response_at(): def response_at(group_id: int):
config = pkg.utils.context.get_config() config = pkg.utils.context.get_config()
if 'at' not in config.response_rules:
use_response_rule = config.response_rules
# 检查是否有特定规则
if 'prefix' not in config.response_rules:
if str(group_id) in config.response_rules:
use_response_rule = config.response_rules[str(group_id)]
else:
use_response_rule = config.response_rules['default']
if 'at' not in use_response_rule:
return True return True
return config.response_rules['at'] return use_response_rule['at']
def random_responding(): def random_responding(group_id):
config = pkg.utils.context.get_config() config = pkg.utils.context.get_config()
if 'random_rate' in config.response_rules:
use_response_rule = config.response_rules
# 检查是否有特定规则
if 'prefix' not in config.response_rules:
if str(group_id) in config.response_rules:
use_response_rule = config.response_rules[str(group_id)]
else:
use_response_rule = config.response_rules['default']
if 'random_rate' in use_response_rule:
import random import random
return random.random() < config.response_rules['random_rate'] return random.random() < use_response_rule['random_rate']
return False return False
@@ -100,6 +128,7 @@ class QQBotManager:
self.bot_account_id = self.adapter.bot_account_id self.bot_account_id = self.adapter.bot_account_id
else: else:
self.adapter = pkg.utils.context.get_qqbot_manager().adapter self.adapter = pkg.utils.context.get_qqbot_manager().adapter
self.bot_account_id = pkg.utils.context.get_qqbot_manager().bot_account_id
pkg.utils.context.set_qqbot_manager(self) pkg.utils.context.set_qqbot_manager(self)
@@ -317,16 +346,16 @@ class QQBotManager:
if Image in event.message_chain: if Image in event.message_chain:
pass pass
else: else:
if At(self.bot_account_id) in event.message_chain and response_at(): if At(self.bot_account_id) in event.message_chain and response_at(event.group.id):
# 直接调用 # 直接调用
reply = process() reply = process()
else: else:
check, result = check_response_rule(str(event.message_chain).strip()) check, result = check_response_rule(event.group.id, str(event.message_chain).strip())
if check: if check:
reply = process(result.strip()) reply = process(result.strip())
# 检查是否随机响应 # 检查是否随机响应
elif random_responding(): elif random_responding(event.group.id):
logging.info("随机响应group_{}消息".format(event.group.id)) logging.info("随机响应group_{}消息".format(event.group.id))
reply = process() reply = process()

View File

@@ -80,6 +80,10 @@ def process_message(launcher_type: str, launcher_id: int, text_message: str, mes
text_message = text_message.strip() text_message = text_message.strip()
# 为强制消息延迟计时
start_time = time.time()
# 处理消息 # 处理消息
try: try:
@@ -168,4 +172,23 @@ def process_message(launcher_type: str, launcher_id: int, text_message: str, mes
finally: finally:
pkg.openai.session.get_session(session_name).release_response_lock() pkg.openai.session.get_session(session_name).release_response_lock()
# 检查延迟时间
if config.force_delay_range[1] == 0:
delay_time = 0
else:
import random
# 从延迟范围中随机取一个值(浮点)
rdm = random.uniform(config.force_delay_range[0], config.force_delay_range[1])
spent = time.time() - start_time
# 如果花费时间小于延迟时间,则延迟
delay_time = rdm - spent if rdm - spent > 0 else 0
# 延迟
if delay_time > 0:
logging.info("[风控] 强制延迟{:.2f}秒(如需关闭请到config.py修改force_delay_range字段)".format(delay_time))
time.sleep(delay_time)
return MessageChain(reply) return MessageChain(reply)

View File

@@ -23,7 +23,7 @@ class NakuruProjectMessageConverter(MessageConverter):
elif type(message_chain) is list: elif type(message_chain) is list:
msg_list = message_chain msg_list = message_chain
else: else:
raise Exception("Unknown message type: " + str(message_chain) + type(message_chain)) raise Exception("Unknown message type: " + str(message_chain) + str(type(message_chain)))
nakuru_msg_list = [] nakuru_msg_list = []
@@ -157,7 +157,6 @@ class NakuruProjectEventConverter(EventConverter):
raise Exception("未支持转换的事件类型: " + str(event)) raise Exception("未支持转换的事件类型: " + str(event))
class NakuruProjectAdapter(MessageSourceAdapter): class NakuruProjectAdapter(MessageSourceAdapter):
"""nakuru-project适配器""" """nakuru-project适配器"""
bot: nakuru.CQHTTP bot: nakuru.CQHTTP
@@ -183,6 +182,9 @@ class NakuruProjectAdapter(MessageSourceAdapter):
}, },
timeout=5 timeout=5
) )
if resp.status_code == 403:
logging.error("go-cqhttp拒绝访问请检查config.py中nakuru_config的token是否与go-cqhttp设置的access-token匹配")
raise Exception("go-cqhttp拒绝访问请检查config.py中nakuru_config的token是否与go-cqhttp设置的access-token匹配")
self.bot_account_id = int(resp.json()['data']['user_id']) self.bot_account_id = int(resp.json()['data']['user_id'])
def send_message( def send_message(

File diff suppressed because one or more lines are too long

View File

@@ -1,8 +1,8 @@
requests~=2.28.1 requests~=2.28.1
openai~=0.27.4 openai~=0.27.6
dulwich~=0.21.3 dulwich~=0.21.5
colorlog~=6.6.0 colorlog~=6.6.0
yiri-mirai~=0.2.6.1 yiri-mirai~=0.2.7
websockets websockets
urllib3~=1.26.10 urllib3~=1.26.10
func_timeout~=4.3.5 func_timeout~=4.3.5

View File

@@ -5,24 +5,27 @@
## 步骤 ## 步骤
1. 从[go-cqhttp的Release](https://github.com/Mrs4s/go-cqhttp/releases/latest)下载最新的go-cqhttp可执行文件建议直接下载可执行文件压缩包而不是安装器 1. 从[go-cqhttp的Release](https://github.com/Mrs4s/go-cqhttp/releases/latest)下载最新的go-cqhttp可执行文件建议直接下载可执行文件压缩包而不是安装器
2. 解压并运行,首次运行会询问需要开放的网络协议,**请填入`02`并回车** 2. 解压并运行,首次运行会询问需要开放的网络协议,**请填入`02`并回车,必须输入`02`❗❗❗❗❗❗❗**
``` <h1> 你这里必须得输入`02`,你懂么,`0`必须得输入,看好了,看好下面输入什么了吗?别他妈的搁那就输个`2`完了启动连不上还跑群里问,问一个我踢一个。 </h1>
C:\Softwares\go-cqhttp.old> .\go-cqhttp.exe
未找到配置文件,正在为您生成配置文件中! ```
请选择你需要的通信方式: C:\Softwares\go-cqhttp.old> .\go-cqhttp.exe
> 0: HTTP通信 未找到配置文件,正在为您生成配置文件中!
> 1: 云函数服务 请选择你需要的通信方式:
> 2: 正向 Websocket 通信 > 0: HTTP通信
> 3: 反向 Websocket 通信 > 1: 云函数服务
请输入你需要的编号(0-9),可输入多个,同一编号也可输入多个(如: 233) > 2: 正向 Websocket 通信
您的选择是:02 > 3: 反向 Websocket 通信
``` 请输入你需要的编号(0-9),可输入多个,同一编号也可输入多个(如: 233)
提示已生成`config.yml`文件关闭go-cqhttp。 您的选择是:02
```
提示已生成`config.yml`文件关闭go-cqhttp。
3. 打开go-cqhttp同目录的`config.yml` 3. 打开go-cqhttp同目录的`config.yml`
1. 编辑账号登录信息(可选) 1. 编辑账号登录信息
只需要修改下方`uin``password`为你要登录的机器人账号的QQ号和密码即可。 只需要修改下方`uin``password`为你要登录的机器人账号的QQ号和密码即可。
**若您不填写,将会在启动时请求扫码登录。** **若您不填写,将会在启动时请求扫码登录。**
@@ -39,7 +42,7 @@
max-times: 0 # 最大重连次数, 0为无限制 max-times: 0 # 最大重连次数, 0为无限制
``` ```
2. 修改websocket端口(必需) 2. 修改websocket端口
在`config.yml`下方找到以下内容 在`config.yml`下方找到以下内容
@@ -64,4 +67,4 @@
4. 配置完成重新启动go-cqhttp 4. 配置完成重新启动go-cqhttp
> 若启动后登录不成功,请尝试根据[此文档](https://docs.go-cqhttp.org/guide/config.html#%E8%AE%BE%E5%A4%87%E4%BF%A1%E6%81%AF)修改`device.json`的协议编号。 > 若启动后登录不成功,请尝试根据[此文档](https://docs.go-cqhttp.org/guide/config.html#%E8%AE%BE%E5%A4%87%E4%BF%A1%E6%81%AF)修改`device.json`的协议编号。

View File

@@ -23,15 +23,16 @@ QChatGPT 插件使用Wiki
## 管理 ## 管理
### !plugin ### !plugin
``` ```
!plugin 列出所有已安装的插件 !plugin 列出所有已安装的插件
!plugin get <储存库地址> 从Git储存库安装插件(需要管理员权限) !plugin get <储存库地址> 从Git储存库安装插件(需要管理员权限)
!plugin update 更新所有插件(需要管理员权限,仅支持从储存库安装的插件) !plugin update all 更新所有插件(需要管理员权限,仅支持从储存库安装的插件)
!plugin del <插件名> 删除插件(需要管理员权限) !plugin update <插件名> 更新指定插件
!plugin on <插件名> 启用插件(需要管理员权限) !plugin del <插件名> 删除插件(需要管理员权限)
!plugin off <插件名> 用插件(需要管理员权限) !plugin on <插件名> 用插件(需要管理员权限)
!plugin off <插件名> 禁用插件(需要管理员权限)
``` ```
### 控制插件执行顺序 ### 控制插件执行顺序

View File

@@ -27,7 +27,7 @@ replys_message = "[bot]err:请求超时"
# 指令权限不足提示 # 指令权限不足提示
command_admin_message = "[bot]err:权限不足: " command_admin_message = "[bot]err:权限不足: "
# 指令无效提示 # 指令无效提示
command_err_message = "[bot]err:指令执行出错" command_err_message = "[bot]err:指令不存在"
# 会话重置提示 # 会话重置提示
command_reset_message = "[bot]:会话已重置" command_reset_message = "[bot]:会话已重置"