Initial commit: Project design and documentation
This commit is contained in:
commit
ab9a800785
116
AGENTS.md
Normal file
116
AGENTS.md
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
# AGENTS.md - Apprise Notify Center
|
||||||
|
|
||||||
|
This folder is home. Treat it that way.
|
||||||
|
|
||||||
|
## First Run
|
||||||
|
|
||||||
|
If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again.
|
||||||
|
|
||||||
|
## Every Session
|
||||||
|
|
||||||
|
Before doing anything else:
|
||||||
|
|
||||||
|
1. Read `SOUL.md` — this is who you are
|
||||||
|
2. Read `USER.md` — this is who you're helping
|
||||||
|
3. Read `docs/plans/*.md` for project context
|
||||||
|
4. **If in MAIN SESSION**: Also read `MEMORY.md`
|
||||||
|
|
||||||
|
Don't ask permission. Just do it.
|
||||||
|
|
||||||
|
## Project Context
|
||||||
|
|
||||||
|
### 项目目标
|
||||||
|
构建一个基于 apprise 的多通道通知中心,提供:
|
||||||
|
- HTTP API 发送通知 (POST/GET)
|
||||||
|
- Web 管理界面配置通道
|
||||||
|
- SQLite 存储配置和历史
|
||||||
|
- 支持 80+ 种通知服务
|
||||||
|
|
||||||
|
### 技术栈
|
||||||
|
- **后端**: Python + FastAPI
|
||||||
|
- **数据库**: SQLite + SQLAlchemy
|
||||||
|
- **前端**: Vue3 + TailwindCSS
|
||||||
|
- **通知引擎**: apprise
|
||||||
|
|
||||||
|
### 数据模型
|
||||||
|
|
||||||
|
**channels 表** - 通知通道配置
|
||||||
|
```sql
|
||||||
|
id: INTEGER PRIMARY KEY
|
||||||
|
name: TEXT NOT NULL -- 通道名称,如 "告警群"
|
||||||
|
type: TEXT NOT NULL -- apprise 协议,如 "discord", "telegram"
|
||||||
|
config: JSON -- 配置参数(URL、token 等)
|
||||||
|
is_active: BOOLEAN DEFAULT 1
|
||||||
|
created_at: TIMESTAMP
|
||||||
|
updated_at: TIMESTAMP
|
||||||
|
```
|
||||||
|
|
||||||
|
**notifications 表** - 发送历史
|
||||||
|
```sql
|
||||||
|
id: INTEGER PRIMARY KEY
|
||||||
|
channel_id: INTEGER FOREIGN KEY
|
||||||
|
title: TEXT
|
||||||
|
body: TEXT -- 消息内容
|
||||||
|
priority: TEXT -- low/normal/high/urgent
|
||||||
|
status: TEXT -- pending/sent/failed
|
||||||
|
error_msg: TEXT -- 失败原因
|
||||||
|
sent_at: TIMESTAMP
|
||||||
|
created_at: TIMESTAMP
|
||||||
|
```
|
||||||
|
|
||||||
|
**templates 表** (可选)
|
||||||
|
```sql
|
||||||
|
id: INTEGER PRIMARY KEY
|
||||||
|
name: TEXT
|
||||||
|
title_template: TEXT
|
||||||
|
body_template: TEXT
|
||||||
|
variables: JSON
|
||||||
|
```
|
||||||
|
|
||||||
|
### 核心功能
|
||||||
|
1. **通道管理**: 增删改查通知通道
|
||||||
|
2. **发送通知**: POST /api/notify 接收通知请求
|
||||||
|
3. **历史记录**: 查看发送历史和统计
|
||||||
|
4. **手动发送**: Web 界面手动触发通知
|
||||||
|
|
||||||
|
### 目录结构
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── AGENTS.md
|
||||||
|
├── README.md
|
||||||
|
├── docs/
|
||||||
|
│ └── plans/
|
||||||
|
│ └── 2026-02-07-design.md
|
||||||
|
├── backend/
|
||||||
|
│ ├── main.py
|
||||||
|
│ ├── models.py
|
||||||
|
│ ├── schemas.py
|
||||||
|
│ └── routers/
|
||||||
|
├── frontend/
|
||||||
|
│ └── index.html
|
||||||
|
└── tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Memory
|
||||||
|
|
||||||
|
- **Daily notes:** `memory/YYYY-MM-DD.md` — raw logs of what happened
|
||||||
|
- **Long-term:** `MEMORY.md` — curated memories
|
||||||
|
|
||||||
|
## Safety
|
||||||
|
|
||||||
|
- Don't exfiltrate private data
|
||||||
|
- Don't run destructive commands without asking
|
||||||
|
- `trash` > `rm`
|
||||||
|
- When in doubt, ask
|
||||||
|
|
||||||
|
## External vs Internal
|
||||||
|
|
||||||
|
**Safe to do freely:**
|
||||||
|
- Read files, explore, organize, learn
|
||||||
|
- Search the web, check calendars
|
||||||
|
- Work within this workspace
|
||||||
|
|
||||||
|
**Ask first:**
|
||||||
|
- Sending emails, tweets, public posts
|
||||||
|
- Anything that leaves the machine
|
||||||
|
- Anything uncertain
|
||||||
38
README.md
Normal file
38
README.md
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# Apprise Notify Center - 多通道通知中心
|
||||||
|
|
||||||
|
一个基于 apprise 的多通道通知服务,支持 Web 管理界面。
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
- **技术栈**: Python + FastAPI + SQLite + Vue3
|
||||||
|
- **核心功能**: HTTP API 发送通知、通道管理、历史记录、手动发送
|
||||||
|
- **支持服务**: 80+ 种通知渠道(Discord、Telegram、邮件、Webhook 等)
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装依赖
|
||||||
|
pip install -r requirements.txt
|
||||||
|
|
||||||
|
# 启动服务
|
||||||
|
python main.py
|
||||||
|
|
||||||
|
# 访问管理界面
|
||||||
|
open http://localhost:8000
|
||||||
|
```
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
.
|
||||||
|
├── AGENTS.md # OpenClaw 项目规范
|
||||||
|
├── docs/
|
||||||
|
│ └── plans/ # 设计文档
|
||||||
|
├── backend/ # FastAPI 后端
|
||||||
|
├── frontend/ # Vue3 前端
|
||||||
|
└── tests/ # 测试用例
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 文档
|
||||||
|
|
||||||
|
服务启动后访问 `/docs` 查看自动生成的 API 文档。
|
||||||
274
docs/plans/2026-02-07-design.md
Normal file
274
docs/plans/2026-02-07-design.md
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
# 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) # 配置参数
|
||||||
|
is_active = Column(Boolean, default=True)
|
||||||
|
created_at = Column(DateTime, default=datetime.utcnow)
|
||||||
|
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
||||||
|
```
|
||||||
|
|
||||||
|
**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
|
||||||
|
{
|
||||||
|
"channel": "告警群", // 通道名称或 ID
|
||||||
|
"title": "服务器告警", // 可选
|
||||||
|
"body": "CPU 使用率超过 90%",
|
||||||
|
"priority": "high" // 可选,默认 normal
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"success": true,
|
||||||
|
"notification_id": 123,
|
||||||
|
"channel": "告警群",
|
||||||
|
"status": "sent"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### GET /api/notify
|
||||||
|
通过 URL 参数发送通知(方便脚本调用)。
|
||||||
|
|
||||||
|
**请求**:
|
||||||
|
```
|
||||||
|
GET /api/notify?channel=告警群&body=测试消息&priority=normal
|
||||||
|
```
|
||||||
|
|
||||||
|
### 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/)
|
||||||
16
requirements.txt
Normal file
16
requirements.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# FastAPI
|
||||||
|
fastapi==0.109.0
|
||||||
|
uvicorn[standard]==0.27.0
|
||||||
|
|
||||||
|
# Database
|
||||||
|
sqlalchemy==2.0.25
|
||||||
|
aiosqlite==0.19.0
|
||||||
|
|
||||||
|
# Data validation
|
||||||
|
pydantic==2.5.3
|
||||||
|
|
||||||
|
# Notification engine
|
||||||
|
apprise==1.7.2
|
||||||
|
|
||||||
|
# Form handling
|
||||||
|
python-multipart==0.0.6
|
||||||
Loading…
x
Reference in New Issue
Block a user