Files
2025-08-17 11:39:53 +08:00

243 lines
9.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 插件SDK工具文档
## 1. 工具概览
### 文件结构
```
sdk/
├── dist/ # 打包输出目录
├── src/ # 插件源码目录
│ ├── packages/ # 依赖库目录(自动生成)
│ ├── process.py # 插件主逻辑文件
│ └── config.toml # 插件配置文件
├── packup.bat # Windows打包脚本
├── packup.sh # Linux/macOS打包脚本
├── dependence.py # 依赖安装工具
├── package.py # 打包工具
└── requirements.txt # 依赖声明文件
```
## 2. 快速开始
### 2.1 开发流程
1.`src/process.py`中开发插件逻辑
2. 添加依赖到 `requirements.txt`
3. 运行打包脚本:
```bash
# Windows
./packup.bat
# Linux/macOS
chmod +x packup.sh
./packup.sh
```
### 2.2 示例插件结构
`process.py` 最小示例:
```python
from src.modules.plugin_modules import BasePlugin
class MyPlugin(BasePlugin):
def after_save(self):
self.ctx.user.send_message("Hello World")
return "ok"
```
## 3. SDK工具详解
### 3.1 dependence.py
**功能**:安装依赖到 `src/packages/`
### 3.2 package.py
**打包规则**
1. 自动检测继承 `BasePlugin`的类
2. 打包生成 `dist/{插件类名小写}.zip`
3. 包含文件:
- `process.py`
- `config.toml`
- `packages/`(依赖目录)
**错误处理**
| 错误码 | 说明 | 解决方案 |
| ------ | -------------------- | --------------- |
| 1 | process.py未找到 | 检查src目录结构 |
| 2 | 未找到BasePlugin子类 | 检查类继承关系 |
### 3.3 打包脚本
**packup.bat/packup.sh** 执行顺序:
1. 安装依赖dependence.py
2. 打包插件package.py
3. 输出到dist目录
## 4. 测试与调试
### 4.1 测试流程
使用 `test.py`进行本地测试:
```python
from sdk.src.process import MyPlugin
from src.modules.plugin_modules import MessageContext
# 模拟上下文
ctx = MessageContext(uid="test", gid=None, raw_message="hello", id="bot")
# 测试插件
plugin = MyPlugin(ctx)
print(plugin.after_save()) # 应该输出"ok"
```
### 4.2 调试技巧
```python
# 在process.py中添加调试代码
import pdb; pdb.set_trace() # 添加断点
# 查看可用属性
print(dir(self.ctx.user))
```
## 5. 最佳实践
### 5.1 依赖管理
✅ **推荐做法**
```text
# requirements.txt 示例
requests==2.31.0 # 固定版本
numpy>=1.21.0 # 最低版本限制
```
❌ **应避免**
```text
pytorch # 无版本声明
```
### 5.2 配置建议
`config.toml`标准结构:
```toml
[plugin]
name = "my_plugin"
version = "1.0.0"
[settings]
timeout = 30
```
## 6. 常见问题
### Q1: 打包后插件不生效
- ✅ 检查类名是否继承 `BasePlugin`
- ✅ 确认ZIP内文件在根目录不在src子目录
## **7. `self.ctx` 核心对象方法/属性总表**
#### **1. 基础信息**
| 属性/方法 | 类型 | 说明 | 示例 |
| --------------- | ----------------- | -------------------------------------- | ------------------------------ |
| `raw_message` | `str` | 用户原始消息文本 | `ctx.raw_message` → "hello" |
| `response` | `Optional[str]` | 可设置的响应内容(设置后拦截后续处理) | `ctx.response = "ok"` |
| `rebot_id` | `str` | 当前机器人ID | `print(ctx.rebot_id)` |
| `_processed` | `bool` | 标记消息是否已被处理(自动管理) | `if ctx._processed: ...` |
#### **2. 用户相关 (`ctx.user`)**
| 属性/方法 | 类型 | 说明 | 示例 |
| --------------------------- | ----------------- | --------------------------------------------- | ------------------------------------------------- |
| `user.user_id` | `str` | 用户唯一ID | `uid = ctx.user.user_id` |
| `user.nickname` | `Optional[str]` | 用户昵称自动从API获取 | `greet = f"Hi {ctx.user.nickname}"` |
| `user.messages` | `List[dict]` | 用户历史消息记录(需 `after_load`后才有值) | `last_msg = ctx.user.messages[-1]` |
| `user.send_message()` | `method` | **发送私聊消息** | `ctx.user.send_message("Hello")` |
| `user.set_input_status()` | `method` | 设置用户输入状态(如"typing" | `ctx.user.set_input_status(1)(为用户正在输入)` |
| `user.send_file()` | `method` | 上传文件 | `ctx.user.set.send_file("/path",filename)` |
#### **3. 群组相关 (`ctx.group`)**
> *仅当消息来自群聊时可用*
>
> | 属性/方法 | 类型 | 说明 | 示例 |
> | ------------------------ | ----------------- | ------------------------------------- | ------------------------------------------------------ |
> | `group.group_id` | `str` | 群组唯一ID | `gid = ctx.group.group_id` |
> | `group.nickname` | `Optional[str]` | 群名称自动从API获取 | `print(ctx.group.nickname)` |
> | `group.users` | `List[dict]` | 群成员列表 | `members = ctx.group.users` |
> | `group.current_user` | `User` | 当前发言用户(即 `ctx.user`的引用) | `sender = ctx.group.current_user` |
> | `group.send_message()` | `method` | **发送群消息** | `ctx.group.send_message("@all 通知")` |
> | `group.messages` | `List[dict]` | 群聊历史消息 | `last_msg = ctx.group.messages[-1]` |
> | `group.upload_file` | `method` | 上传群文件 | `ctx.group.upload_file("/path",filename,group_path)` |
在群聊消息中current_user中的message存储了用户在群里的近十条消息。
#### **4. 数据存储 (`ctx.chat_manager`)**
| 方法 | 参数 | 说明 | 示例 |
| --------------------------- | --------------------------------------------------------- | -------------------- | ---------------------------------------------------------------------------------- |
| `save_private_message()` | `user: User, role: str, content: str` | 保存私聊消息到数据库 | `ctx.chat_manager.save_private_message(ctx.user, "user", "hi")` |
| `save_group_message()` | `group: Group, role: str, content: str, sender_id: str` | 保存群消息 | `ctx.chat_manager.save_group_message(ctx.group, "user", "hi", ctx.user.user_id)` |
| `load_private_messages()` | `user: User` → `List[dict]` | 加载用户私聊历史 | `ctx.user.messages = ctx.chat_manager.load_private_messages(ctx.user)` |
| `load_group_messages()` | `group: Group` → `List[dict]` | 加载群聊历史 | `ctx.group.messages = ctx.chat_manager.load_group_messages(ctx.group)` |
#### **5. 插件配置 (`self.config`)**
| 方法/属性 | 说明 | 示例 |
| ------------------------------- | ---------------------------------------------------- | ------------------------------------------------- |
| `self.config` | **自动加载**的配置字典(来自 `config.toml` | `timeout = self.config.get("timeout", 30)` |
| `self.save_config()` | 保存修改后的配置 | `self.save_config({"key": "value"})` |
| `self._get_plugin_resource()` | 从插件ZIP包内读取文件 | `data = self._get_plugin_resource("data.json")` |
---
#### **6. 调试工具**
| 属性 | 类型 | 说明 |
| ------------------- | -------- | ------------------------------------------------------------- |
| `ctx.phase` | `str` | 当前处理阶段(`before_load`/`after_load`/`after_save` |
| `ctx.intercepted` | `bool` | 是否已被其他插件拦截 |
### **典型使用场景**
#### 场景1消息预处理
```python
def before_load(self):
if "admin" in ctx.raw_message:
if not self.check_admin(ctx.user.user_id):
ctx.response = "权限不足" # 拦截请求
return
```
#### 场景2响应生成
```python
def after_save(self):
if "天气" in ctx.raw_message:
city = extract_city(ctx.raw_message) # 自定义解析逻辑
ctx.response = get_weather(city) # 返回天气信息
```
### **注意事项**
1. **`ctx.group` 可能为 `None`**:私聊消息时需判空
```python
if ctx.group: # 群聊专属逻辑
```
2. **配置热更新**:修改 `self.config` 后需手动调用 `save_config()`
3. **大文件处理**:通过 `_get_plugin_resource()` 读取ZIP内资源避免解压
示例插件 转发消息到mc服务器[chatrebot_mcrcon_plug](https://jianfgit.xyz/jianf/chatrebot_mcrcon_plug) 自动ai回复[chatrebot_aireply_plug](https://jianfgit.xyz/jianf/chatrebot_aireply_plug)