Files
chat_rebot-connect-with-one…/README.md

7.3 KiB
Executable File
Raw Blame History

OneBot Chatbot Framework

该项目是一个基于OneBot标准的聊天机器人后端框架采用高度可扩展的插件架构设计支持消息的模块化处理和插件热加载。如果你有任何意见或建议可以通过 jianfeee@outlook.com 联系我。

项目特点

  • 模块化设计:每个功能作为独立插件实现,易于扩展和维护
  • 插件生命周期管理:支持插件加载、注册、依赖处理和实例管理
  • 消息处理管道:分阶段处理消息,支持各阶段拦截机制
  • 会话管理:支持群组消息和私聊消息的独立管理
  • 内嵌依赖处理自动管理插件内嵌的Python依赖包
  • 兼容性设计:支持新旧版本插件并存运行

内置插件

OpenClaw Bridge

src/process.py — QQ 消息 ↔ OpenClaw Gateway 桥接插件。 将用户消息转发给 OpenClaw Gateway 上的 AI agent 处理并自动回复。

配置: config/openclawbridge/config.toml

QQ 操作脚本

scripts/qq_*.py — 15 个独立脚本agent 可通过 subprocess 直连 NapCat API 主动操作 QQ。

Agent Skills

skills/ — AgentSkills指导 AI agent 如何使用上述脚本。

核心组件

消息处理流程 (process_message)

def process_message(uid: str, gid: str | None, message: str) -> str:
    # 1. 创建消息上下文
    ctx = MessageContext(...)
  
    # 2. 扫描并加载插件
    plugin_manager.scan_plugins()
  
    # 3. 消息处理阶段:
    #   - before_load: 加载数据前拦截点
    #   - after_load:  加载数据后处理点
    #   - after_save:  保存数据后处理点
  
    # 4. 会话数据持久化
    ctx.chat_manager.save_message(...)
  
    return ctx.response or "ok"

插件管理器 (PluginManager)

class PluginManager:
    def __init__(self):
        self._plugins = {}       # 插件类注册表
        self._active_instances = {}  # 插件实例
        self._hook_registry = {}     # 兼容旧版钩子
        self._temp_dirs = []         # 临时目录
        self._dependency_manager = DependencyManager()  # 依赖处理器

    def scan_plugins(self):
        """扫描插件目录并加载ZIP格式插件"""
  
    def load_plugin(self, zip_path: str) -> bool:
        """动态加载ZIP格式插件"""
  
    def _load_embedded_dependencies(self, plugin_dir: str) -> bool:
        """加载插件内嵌的依赖包"""
  
    def register_hook(self, hook_name: str):
        """注册兼容旧版钩子(装饰器模式)"""
  
    def cleanup(self):
        """清理临时资源"""

插件开发指南

基本插件结构

# process.py
from src.modules.plugin_modules import BasePlugin, MessageContext

class MyPlugin(BasePlugin):
    def __init__(self, ctx: MessageContext):
        super().__init__(ctx)
  
    def process(self) -> str | None:
        """核心处理方法"""
        if self.ctx.command == "help":
            return self._show_help()
  
    def before_load(self) -> str | None:
        """数据加载前拦截点"""
  
    def after_load(self) -> str | None:
        """数据加载后处理点"""
  
    def after_save(self) -> str | None:
        """数据保存后处理点"""

目录结构要求

插件应以ZIP格式打包包含以下内容

my_plugin.zip
├── process.py            # 必需 - 插件入口文件
├── requirements.txt      # 可选 - 依赖声明
└── packages/             # 可选 - 内嵌依赖包
    ├── package1/
    └── package2/

依赖声明

插件可通过两种方式声明依赖:

  1. requirements.txt 标准格式
  2. dependencies.json 自定义格式
// dependencies.json 示例
{
    "requirements": [
        "requests==2.28.2",
        "numpy>=1.25.0"
    ]
}

快速启动

  1. 为启动脚本授权Linux

    chmod +x run.sh
    
  2. 修改配置文件,list_port 为接收消息推送端口,send_url 为消息发送地址

  3. 运行启动脚本

    Linux

    ./run.sh
    

    Windows

    .\run.bat
    

AI Agent 部署OpenClaw

如需让 AI agent 主动操作 QQ发消息、管理群、查信息等需将脚本和 Skill 部署到 agent 的工作区。

1. 部署脚本

scripts/ 目录复制到 qq-agent 工作区:

cp -r scripts/ /path/to/qq-agent/workspace/

2. 部署 Skills

将 QQ 相关的 Skill 复制到 agent 的 skills 目录:

cp -r skills/qq-messenger     /path/to/agent/skills/
cp -r skills/qq-management    /path/to/agent/skills/
cp -r skills/qq-resolver      /path/to/agent/skills/
cp -r skills/qq-napcat-extras /path/to/agent/skills/

3. 替换占位符

编辑各脚本开头的配置变量,将占位符替换为实际值:

# 需替换的占位符:
ADMIN_QQ       = "YOUR_ADMIN_QQ"        # 你的 QQ 号
CQHTTP_URL     = "http://YOUR_NAPCAT_HOST:25570"  # NapCat 地址
GATEWAY_URL    = "http://127.0.0.1:18789"  # OpenClaw Gateway
GATEWAY_TOKEN  = "YOUR_GATEWAY_TOKEN"    # Gateway 鉴权 Token

4. 验证

在 agent 工作区尝试执行单个脚本确认连通性:

cd /path/to/qq-agent/workspace/scripts
python3 qq_get_groups.py

常见问题 / 踩坑指南

1. systemd 下只有 stdin/stdout没有持久化日志

本仓库设计为通过 systemd 托管,run.sh 中的 gunicorn 输出全部走 stdout/stderr。systemd 会自动捕获到 journald。

查看日志:

journalctl -u qqrebot --since "5 minutes ago" -f

如果发现日志回滚太短,在 service 中设置 StandardOutput=journal+console

2. app.py 端口硬编码

app.py__main__ 直接将端口写死在 port=25580,不走 config.toml。这意味着:

  • python3 app.py 直接运行 → 无视配置,始终占 25580
  • run.shgunicorn自动读取配置,正常

如果直接 python3 app.py 启动报 Address already in use,检查是否跟 gunicorn 实例抢端口。

3. ConfigManager 内部字典不自动刷新

当插件首次部署,config/插件名/config.toml 尚不存在时,ConfigManager.__init__ 会通过 build_config_dict() 扫描目录。此时文件不存在,内部 self.config 为空。

BasePlugin.config 属性的异常处理会触发 _ensure_config_exists() 创建文件,但 ConfigManager 的 self.config 不会被刷新,第二次 load_config("config") 仍然 KeyError。解决方法_ensure_config_exists 创建文件后调用 self._config_manager.build_config_dict() 手动刷新。

4. python3-venv 缺失

纯净 Debian/Ubuntu 没有 python3-venv

apt install python3.13-venv   # 替换 .13 为实际版本

否则 run.sh 创建虚拟环境会直接失败。

5. gunicorn / waitress 不在 requirements.txt 中

# requirements.txt 未包含,由启动脚本单独安装
# run.sh:  pip install gunicorn
# run.bat: pip install waitress

设计优势

  1. 解耦设计:插件与核心系统完全解耦
  2. 安全隔离:使用临时目录加载插件
  3. 版本兼容:内建依赖版本验证机制
  4. 灵活扩展:支持多个消息处理点
  5. 新旧兼容支持传统钩子和现代OOP插件的共存

仓库地址:chat_rebot-connect-with-onebot-standard-