apprise-notify-center/docs/plans/2026-02-07-design.md
2026-02-07 17:07:54 +00:00

299 lines
9.6 KiB
Markdown

# Apprise Notify Center 设计文档
**日期**: 2026-02-07
**作者**: OpenClaw Agent
**版本**: v1.0
---
## 1. 项目目标
构建一个基于 apprise 的多通道通知中心,提供统一的 HTTP API 接口和 Web 管理界面,支持 80+ 种通知服务。
### 核心需求
- 通过 HTTP POST/GET 请求发送通知
- SQLite 存储配置和历史记录
- Web 管理界面:增删改查通道、查看历史、手动发送
---
## 2. 技术架构
### 2.1 技术栈
| 组件 | 技术选型 | 理由 |
|------|----------|------|
| 后端框架 | FastAPI | 异步高性能、自动生成 API 文档、类型提示 |
| 数据库 | SQLite | 轻量、无需额外服务、适合单机部署 |
| ORM | SQLAlchemy | 成熟、支持异步 |
| 通知引擎 | apprise | 支持 80+ 种通知服务 |
| 前端 | Vue3 + TailwindCSS | CDN 引入,无需构建步骤 |
### 2.2 系统架构图
```
┌─────────────────────────────────────────────┐
│ Web 管理界面 (Vue3 SPA) │
└──────────────┬──────────────────────────────┘
│ HTTP/REST
┌──────────────▼──────────────────────────────┐
│ FastAPI 后端服务 │
│ ┌─────────────┐ ┌──────────────────────┐ │
│ │ 通道管理 API │ │ 通知发送 API (POST) │ │
│ └─────────────┘ └──────────────────────┘ │
│ ┌─────────────┐ ┌──────────────────────┐ │
│ │ 配置管理 API │ │ 历史记录 / 统计 API │ │
│ └─────────────┘ └──────────────────────┘ │
└──────────────┬──────────────────────────────┘
┌──────────┴──────────┐
▼ ▼
┌─────────┐ ┌──────────┐
│ SQLite │ │ apprise │
│ (配置+历史)│ │(发送通知) │
└─────────┘ └──────────┘
```
---
## 3. 数据模型
### 3.1 channels 表 - 通知通道配置
```python
class Channel(Base):
__tablename__ = "channels"
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, unique=True) # 通道名称,如 "告警群"
type = Column(String, nullable=False) # apprise 协议,如 "discord"
config = Column(JSON, nullable=False) # 配置参数
tags = Column(JSON, default=list) # 标签,如 ["alerts", "urgent"]
is_active = Column(Boolean, default=True)
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
```
**tags 字段示例**: `["production", "alerts", "discord"]` - 用于批量选择通道
**config 字段示例**:
```json
{
"discord": {
"webhook_url": "https://discord.com/api/webhooks/xxx"
},
"telegram": {
"bot_token": "123456:ABC-DEF...",
"chat_id": "-1001234567890"
},
"email": {
"smtp_host": "smtp.gmail.com",
"smtp_port": 587,
"username": "user@gmail.com",
"password": "app_password",
"to_email": "admin@example.com"
}
}
```
### 3.2 notifications 表 - 发送历史
```python
class Notification(Base):
__tablename__ = "notifications"
id = Column(Integer, primary_key=True)
channel_id = Column(Integer, ForeignKey("channels.id"))
title = Column(String, nullable=True)
body = Column(Text, nullable=False)
priority = Column(String, default="normal") # low/normal/high/urgent
status = Column(String, default="pending") # pending/sent/failed
error_msg = Column(Text, nullable=True)
sent_at = Column(DateTime, nullable=True)
created_at = Column(DateTime, default=datetime.utcnow)
```
### 3.3 templates 表 - 消息模板 (可选)
```python
class Template(Base):
__tablename__ = "templates"
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False, unique=True)
title_template = Column(String, nullable=True)
body_template = Column(Text, nullable=False)
variables = Column(JSON, default=list) # ["server_name", "alert_level"]
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
```
---
## 4. API 设计
### 4.1 通知发送 API
#### POST /api/notify
发送通知到指定通道(支持批量发送)。
**请求体**:
```json
{
"channels": ["告警群", "运维群"], // 通道名称列表(与 tags 二选一)
"tags": ["alerts", "production"], // 标签列表,发送到所有匹配的通道
"title": "服务器告警", // 可选
"body": "CPU 使用率超过 90%",
"priority": "high" // 可选,默认 normal
}
```
**说明**:
- `channels``tags` 二选一,不能同时为空
- 使用 `channels`: 精确指定通道名称列表
- 使用 `tags`: 发送到包含任一标签的所有通道
**响应**:
```json
{
"success": true,
"results": [
{
"channel": "告警群",
"channel_id": 1,
"status": "sent",
"notification_id": 123
},
{
"channel": "运维群",
"channel_id": 2,
"status": "sent",
"notification_id": 124
}
],
"total": 2,
"sent": 2,
"failed": 0
}
```
#### GET /api/notify
通过 URL 参数发送通知(方便脚本调用)。
**请求**:
```
GET /api/notify?channels=告警群,运维群&body=测试消息&priority=normal
GET /api/notify?tags=alerts,urgent&body=测试消息&priority=high
```
### 4.2 通道管理 API
| 方法 | 路径 | 描述 |
|------|------|------|
| GET | /api/channels | 获取所有通道 |
| GET | /api/channels/{id} | 获取单个通道 |
| POST | /api/channels | 创建通道 |
| PUT | /api/channels/{id} | 更新通道 |
| DELETE | /api/channels/{id} | 删除通道 |
| POST | /api/channels/{id}/test | 测试通道 |
### 4.3 历史记录 API
| 方法 | 路径 | 描述 |
|------|------|------|
| GET | /api/notifications | 获取历史记录(支持分页、筛选) |
| GET | /api/notifications/{id} | 获取单条记录 |
| GET | /api/stats | 获取统计信息 |
---
## 5. Web 管理界面
### 5.1 页面结构
- **仪表盘**: 概览统计(今日发送量、通道数量、成功率)
- **通道管理**: 列表视图、添加/编辑通道表单
- **发送历史**: 筛选、搜索、分页
- **手动发送**: 选择通道、填写内容、预览发送
### 5.2 UI 布局
```
┌─────────────────────────────────────────────┐
│ Logo 仪表盘 通道管理 历史记录 手动发送 │
├──────────┬──────────────────────────────────┤
│ │ │
│ 侧边栏 │ 主内容区 │
│ (可选) │ │
│ │ │
└──────────┴──────────────────────────────────┘
```
---
## 6. 项目结构
```
apprise-notify-center/
├── AGENTS.md # OpenClaw 项目规范
├── README.md # 项目介绍
├── requirements.txt # Python 依赖
├── docs/
│ └── plans/
│ └── 2026-02-07-design.md # 本设计文档
├── backend/
│ ├── main.py # FastAPI 入口
│ ├── config.py # 配置管理
│ ├── database.py # 数据库连接
│ ├── models.py # SQLAlchemy 模型
│ ├── schemas.py # Pydantic 模型
│ └── routers/
│ ├── __init__.py
│ ├── channels.py # 通道管理路由
│ ├── notify.py # 通知发送路由
│ ├── history.py # 历史记录路由
│ └── stats.py # 统计路由
├── frontend/
│ ├── index.html # 主页面
│ ├── css/
│ │ └── style.css # 自定义样式
│ └── js/
│ └── app.js # Vue3 应用
└── tests/
└── test_api.py # API 测试
```
---
## 7. 依赖列表
```
# requirements.txt
fastapi==0.109.0
uvicorn[standard]==0.27.0
sqlalchemy==2.0.25
apprise==1.7.2
pydantic==2.5.3
python-multipart==0.0.6
aiosqlite==0.19.0
```
---
## 8. 后续优化方向
1. **模板系统**: 支持变量替换的模板功能
2. **批量发送**: 支持一次发送到多个通道
3. **重试机制**: 失败自动重试
4. **通知队列**: 使用 Celery/RQ 处理大量通知
5. **用户认证**: 添加登录和权限管理
6. **Webhook 回调**: 支持外部系统接收通知状态
---
## 9. 参考资源
- [apprise 文档](https://github.com/caronc/apprise)
- [FastAPI 文档](https://fastapi.tiangolo.com/)
- [SQLAlchemy 文档](https://docs.sqlalchemy.org/)