4286731348
- 添加 HTTP 代理支持(国内直连、外网走代理) - 外部 API 新增全文搜索、源健康度/错误筛选、未读筛选 - 修复 APScheduler 线程静默崩溃(_safe_fetch 异常保护) - 健康检查暴露调度器状态 - Dashboard 新增每日文章数柱状图(按 published_at) - 文章列表 API 补上 content 字段,日期筛选修复时间范围 - 修复外部 API 双重 external 前缀 - User-Agent 改为 Chrome 标识缓解 403 - 添加完整 API 接口文档 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
15 KiB
15 KiB
RSSKeeper API 接口文档
Base URL: http://<host>:7329
所有接口返回 JSON 格式数据。
目录
通用字段说明
健康度 (health_status)
| 值 | 含义 |
|---|---|
healthy |
健康:成功率 >= 90%,7天内有抓取 |
warning |
警告:成功率 50%-90%,或超过3天未更新 |
unhealthy |
异常:成功率 < 50%,或超过7天未更新 |
unknown |
未知:尚未进行过任何抓取 |
错误类型 (error_type)
| 值 | 含义 |
|---|---|
url_invalid |
URL 已失效(404) |
forbidden |
被站点拒绝(403) |
rate_limited |
频率限制(429) |
timeout |
连接超时 |
dns_failure |
DNS 解析失败 |
connection_refused |
连接被拒绝 |
connection_reset |
连接中断 |
ssl_error |
SSL/TLS 错误 |
unreachable |
服务器不可达 |
url_malformed |
URL 格式错误 |
server_error |
服务器错误(5xx) |
unknown |
其他未知错误 |
健康检查
GET /api/health
检查服务是否运行。
响应:
{
"status": "ok",
"service": "rssKeeper"
}
RSS 源管理
获取源列表
GET /api/feeds
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
skip |
int | 否 | 0 | 跳过条数(分页偏移) |
limit |
int | 否 | 100 | 每页条数 |
category |
string | 否 | - | 按分类筛选 |
search |
string | 否 | - | 按名称/URL/描述搜索 |
is_active |
bool | 否 | - | 按启用状态筛选 |
health_status |
string | 否 | - | 按健康度筛选:healthy/warning/unhealthy/unknown |
响应:
{
"total": 383,
"items": [
{
"id": 1,
"url": "https://example.com/feed.xml",
"title": "Example Feed",
"description": "Feed description",
"category": "科技",
"is_active": true,
"fetch_interval_minutes": 60,
"last_fetch_at": "2026-06-11T08:33:36.474905",
"last_fetch_status": "success",
"last_error": "",
"error_type": "",
"success_count": 5,
"fail_count": 0,
"article_count": 42,
"health_status": "healthy",
"next_fetch_time": "2026-06-11T09:33:36.000000+00:00",
"created_at": "2026-06-11T08:33:24.591074"
}
]
}
获取源详情
GET /api/feeds/{feed_id}
路径参数:
| 参数 | 类型 | 说明 |
|---|---|---|
feed_id |
int | RSS 源 ID |
响应: 同列表中的单条 items 结构。
添加源
POST /api/feeds
请求体:
{
"url": "https://example.com/feed.xml",
"title": "Example",
"description": "",
"category": "科技",
"is_active": true,
"fetch_interval_minutes": 60
}
| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
url |
string | 是 | - | RSS 源地址 |
title |
string | 否 | "" | 源名称(留空则自动抓取) |
description |
string | 否 | "" | 描述 |
category |
string | 否 | "" | 分类 |
is_active |
bool | 否 | true | 是否启用 |
fetch_interval_minutes |
int | 否 | 60 | 抓取间隔(分钟),最小 15 |
响应:
{
"id": 1,
"message": "RSS 源添加成功,正在后台抓取",
"url": "https://example.com/feed.xml"
}
添加成功后会自动在后台触发首次抓取。
错误: 409 — 该 RSS 源已存在
更新源
PUT /api/feeds/{feed_id}
请求体(只需传要修改的字段):
{
"title": "新名称",
"category": "新闻",
"is_active": false,
"fetch_interval_minutes": 120
}
响应:
{
"message": "RSS 源更新成功"
}
删除源
DELETE /api/feeds/{feed_id}
删除 RSS 源,级联删除关联的所有文章和抓取日志。
响应:
{
"message": "RSS 源已删除"
}
触发抓取
POST /api/feeds/{feed_id}/fetch
手动触发单个源的抓取。同步执行,返回抓取结果。
响应:
{
"success": true,
"articles_count": 5,
"feed_title": "Example Feed"
}
批量抓取
POST /api/feeds/batch-fetch
并发同步抓取多个源。适用于"全部抓取"等场景。
请求体:
{
"feed_ids": [1, 2, 3, 4, 5]
}
响应:
{
"message": "完成:4 个成功,1 个失败",
"total": 5,
"success": 4,
"fail": 1
}
自动发现
POST /api/feeds/discover
从任意网页自动发现 RSS/Atom feed URL。
参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
url |
string | 是 | 网页地址 |
响应:
{
"source_url": "https://example.com",
"found_feeds": [
"https://example.com/feed.xml",
"https://example.com/rss"
]
}
获取分类列表
GET /api/feeds/categories
返回所有已使用的分类。
响应:
["科技", "新闻", "设计"]
导入 OPML
POST /api/feeds/import-opml
从 OPML 内容批量导入 RSS 源。
请求体:
{
"opml_content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><opml version=\"2.0\">..."
}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
opml_content |
string | 是 | OPML 文件内容(最大 5MB) |
响应:
{
"added": 15,
"skipped": 3,
"message": "成功导入 15 个 RSS 源"
}
导出 OPML
GET /api/feeds/export-opml
导出所有 RSS 源为 OPML 格式。
响应:
{
"opml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><opml version=\"2.0\">..."
}
文章管理
获取文章列表
GET /api/articles
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
skip |
int | 否 | 0 | 分页偏移 |
limit |
int | 否 | 50 | 每页条数 |
feed_id |
int | 否 | - | 按源筛选 |
category |
string | 否 | - | 按分类筛选 |
search |
string | 否 | - | 按标题/链接搜索 |
since |
string | 否 | - | 起始时间(ISO 格式) |
until |
string | 否 | - | 截止时间(ISO 格式) |
is_read |
bool | 否 | - | 按已读状态筛选 |
响应:
{
"total": 120,
"items": [
{
"id": 1,
"feed_id": 1,
"title": "文章标题",
"link": "https://example.com/article",
"author": "作者",
"published_at": "2026-06-11T06:00:00",
"content": "文章正文内容...",
"summary": "文章摘要...",
"is_read": false,
"created_at": "2026-06-11T08:33:36.474905",
"feed_title": "Example Feed",
"category": "科技"
}
]
}
获取文章详情
GET /api/articles/{article_id}
响应: 同列表中的单条 items 结构。
全文搜索
GET /api/articles/search/fulltext
使用 SQLite FTS5 进行全文搜索。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
q |
string | 是 | - | 搜索关键词 |
skip |
int | 否 | 0 | 分页偏移 |
limit |
int | 否 | 50 | 每页条数 |
响应: 同文章列表格式。
标记已读
PUT /api/articles/{article_id}/read
响应:
{
"message": "已标记为已读"
}
仪表盘
统计概览
GET /api/dashboard/stats
响应:
{
"total_feeds": 383,
"active_feeds": 383,
"total_articles": 1024,
"healthy_feeds": 202,
"warning_feeds": 0,
"unhealthy_feeds": 167,
"today_fetches": 45,
"today_success": 40,
"today_success_rate": 88.9
}
健康度详情
GET /api/dashboard/health
获取每个 RSS 源的健康状态详情。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
skip |
int | 否 | 0 | 分页偏移 |
limit |
int | 否 | 100 | 每页条数 |
响应:
{
"total": 383,
"items": [
{
"id": 1,
"title": "Example Feed",
"url": "https://example.com/feed.xml",
"is_active": true,
"health_status": "healthy",
"health_label": "健康",
"success_rate": 100.0,
"success_count": 5,
"fail_count": 0,
"total_fetches": 5,
"last_fetch_at": "2026-06-11T08:33:36.474905",
"days_since_fetch": 0,
"article_count": 42,
"last_error": "",
"recent_logs": [
{
"status": "success",
"articles_fetched": 3,
"response_time_ms": 450,
"created_at": "2026-06-11T08:33:36.474905",
"error_message": null
}
]
}
]
}
最近活动
GET /api/dashboard/recent-activity
获取最近的抓取活动日志。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
limit |
int | 否 | 20 | 返回条数 |
响应:
{
"items": [
{
"id": 1,
"feed_id": 1,
"feed_title": "Example Feed",
"status": "success",
"articles_fetched": 3,
"error_message": "",
"response_time_ms": 450,
"created_at": "2026-06-11T08:33:36.474905"
}
]
}
外部 API
供 AI 助手、外部系统调用的接口。前缀:/api/v1/external。
获取最近文章
GET /api/v1/external/recent
获取最近 N 小时的文章,支持多条件组合筛选。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
hours |
int | 否 | 24 | 回溯小时数 |
limit |
int | 否 | 50 | 最大返回条数 |
feed_id |
int | 否 | - | 按源 ID 筛选 |
category |
string | 否 | - | 按分类筛选 |
search |
string | 否 | - | 按标题/摘要关键词筛选 |
unread_only |
bool | 否 | false | 只返回未读文章 |
响应:
{
"query": { "hours": 24, "limit": 50, "feed_id": null, "category": null, "search": null, "unread_only": false },
"count": 15,
"articles": [
{
"id": 1,
"title": "文章标题",
"link": "https://example.com/article",
"author": "作者",
"summary": "摘要文本",
"content": "正文内容(超过10000字符时返回摘要)",
"published_at": "2026-06-11T06:00:00",
"created_at": "2026-06-11T08:33:36",
"feed_title": "Example Feed",
"category": "科技"
}
]
}
全文搜索
GET /api/v1/external/search
使用 FTS5 全文搜索引擎检索文章内容。供 AI 按关键词精准查找文章。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
q |
string | 是 | - | 搜索关键词 |
limit |
int | 否 | 50 | 最大返回条数(1-200) |
offset |
int | 否 | 0 | 分页偏移 |
category |
string | 否 | - | 按分类二次筛选 |
feed_id |
int | 否 | - | 按源 ID 二次筛选 |
响应:
{
"query": "LLM",
"total": 12,
"offset": 0,
"limit": 50,
"articles": [
{
"id": 15674,
"title": "文章标题",
"summary": "匹配的摘要...",
"link": "https://example.com/article",
"published_at": "2026-06-11T06:00:00",
"created_at": "2026-06-11T08:33:36",
"feed_id": 1,
"feed_title": "Example Feed",
"category": "科技"
}
]
}
获取源列表(含筛选)
GET /api/v1/external/feeds
获取 RSS 源列表,支持按健康度、错误类型、分类等多维度筛选。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
health_status |
string | 否 | - | 按健康度筛选:healthy/warning/unhealthy/unknown |
category |
string | 否 | - | 按分类筛选 |
error_type |
string | 否 | - | 按错误类型筛选(见通用字段说明) |
is_active |
bool | 否 | true | 按启用状态筛选 |
响应:
{
"count": 167,
"feeds": [
{
"id": 1,
"title": "Example Feed",
"url": "https://example.com/feed.xml",
"category": "科技",
"is_active": true,
"health_status": "unhealthy",
"error_type": "timeout",
"article_count": 42,
"last_fetch_at": "2026-06-11T08:33:36",
"last_error": "HTTPSConnectionPool..."
}
]
}
示例:
- 查看所有异常源:
/api/v1/external/feeds?health_status=unhealthy - 查看 URL 失效的源:
/api/v1/external/feeds?error_type=url_invalid - 查看指定分类:
/api/v1/external/feeds?category=科技
获取指定源文章
GET /api/v1/external/feeds/{feed_id}/articles
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
feed_id |
int | 是 | - | RSS 源 ID(路径参数) |
limit |
int | 否 | 100 | 最大返回条数 |
since |
string | 否 | - | 起始时间过滤 |
search |
string | 否 | - | 按标题/摘要关键词筛选 |
unread_only |
bool | 否 | false | 只返回未读文章 |
响应:
{
"feed": { "id": 1, "title": "Example Feed", "url": "https://example.com/feed.xml" },
"count": 42,
"articles": [
{
"id": 1,
"title": "文章标题",
"link": "https://example.com/article",
"author": "作者",
"summary": "摘要",
"published_at": "2026-06-11T06:00:00"
}
]
}
获取每日摘要
GET /api/v1/external/summary
获取指定日期的文章摘要,按分类分组。
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
date |
string | 否 | 今天 | 日期,格式 YYYY-MM-DD |
category |
string | 否 | - | 按分类筛选 |
响应:
{
"date": "2026-06-11",
"total_articles": 35,
"by_category": {
"科技": [
{ "title": "文章标题", "link": "https://...", "feed": "Feed 名称", "summary": "文章摘要..." }
],
"新闻": [...]
}
}