From 2f6b2470a4d6f3eb91425be670e4d200cd9ab40c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 04:44:20 +0000 Subject: [PATCH] Add API documentation in English and Chinese Co-authored-by: krau <71133316+krau@users.noreply.github.com> --- api/README.md | 26 ++++ docs/content/en/usage/api.md | 262 +++++++++++++++++++++++++++++++++++ docs/content/zh/usage/api.md | 262 +++++++++++++++++++++++++++++++++++ 3 files changed, 550 insertions(+) create mode 100644 api/README.md create mode 100644 docs/content/en/usage/api.md create mode 100644 docs/content/zh/usage/api.md diff --git a/api/README.md b/api/README.md new file mode 100644 index 0000000..38d4ccb --- /dev/null +++ b/api/README.md @@ -0,0 +1,26 @@ +# API Module + +This module provides a RESTful HTTP API for programmatic file downloads from Telegram. + +## Features + +- **RESTful API endpoints** for creating, querying, and canceling download tasks +- **Bearer token authentication** for API access control +- **IP whitelist** support for additional security +- **Webhook callbacks** for task completion notifications +- **Task status tracking** (queued, running, completed, failed, canceled) +- **Graceful shutdown** with proper cleanup + +## Usage + +See the full documentation at: +- English: `/docs/content/en/usage/api.md` +- Chinese: `/docs/content/zh/usage/api.md` + +## Architecture + +- `server.go` - HTTP server initialization and route registration +- `handlers.go` - API endpoint handlers and business logic +- `middleware.go` - Authentication and logging middleware + +The API integrates with the existing task queue system and uses the bot's Telegram client to fetch messages. diff --git a/docs/content/en/usage/api.md b/docs/content/en/usage/api.md new file mode 100644 index 0000000..f29390a --- /dev/null +++ b/docs/content/en/usage/api.md @@ -0,0 +1,262 @@ +--- +title: "HTTP API" +weight: 4 +--- + +# HTTP API + +SaveAny-Bot provides a RESTful HTTP API for programmatic file downloads from Telegram. + +## Configuration + +Enable the API in your `config.toml`: + +```toml +[api] +# Enable HTTP API service +enable = true +# API server listen port +port = 8080 +# API access token (leave empty to disable authentication) +token = "your-secret-token-here" +# Task completion callback webhook URL (leave empty to disable) +webhook_url = "https://your-server.com/webhook" +# Trusted IP addresses (leave empty to allow all), supports single IP or CIDR notation +trusted_ips = ["127.0.0.1", "192.168.1.0/24"] +``` + +## Authentication + +If `token` is configured, all API requests (except `/health`) must include an `Authorization` header: + +``` +Authorization: Bearer your-secret-token-here +``` + +If `trusted_ips` is configured, requests will only be accepted from specified IP addresses. + +## Endpoints + +### Health Check + +Check if the API server is running. + +**Request:** +``` +GET /health +``` + +**Response:** +```json +{ + "status": "ok" +} +``` + +### Create Download Task + +Create a new file download task from a Telegram message link. + +**Request:** +``` +POST /api/v1/tasks +Content-Type: application/json +Authorization: Bearer your-secret-token-here + +{ + "telegram_url": "https://t.me/channel/123", + "user_id": 123456789, + "storage_name": "local1", + "dir_path": "/downloads" +} +``` + +**Request Parameters:** +- `telegram_url` (required): Telegram message link (e.g., `https://t.me/channel/123`) +- `user_id` (required): Telegram user ID (must be configured in `config.toml`) +- `storage_name` (optional): Storage name to use. If not specified, uses the first available storage for the user +- `dir_path` (optional): Directory path in storage. Default is `/` + +**Response (201 Created):** +```json +{ + "task_id": "c9h8t1234abcd", + "message": "task created successfully" +} +``` + +**Error Response (4xx/5xx):** +```json +{ + "error": "error description" +} +``` + +### Get Task Status + +Get the status of a specific task. + +**Request:** +``` +GET /api/v1/tasks/{task_id} +Authorization: Bearer your-secret-token-here +``` + +**Response (200 OK):** +```json +{ + "task_id": "c9h8t1234abcd", + "status": "completed", + "title": "[tgfiles](file.pdf->local1:/downloads/file.pdf)", + "created_at": "2024-01-19T04:30:00Z", + "error": "" +} +``` + +**Status Values:** +- `queued`: Task is waiting in queue +- `running`: Task is currently downloading +- `completed`: Task completed successfully +- `failed`: Task failed with error (see `error` field) +- `canceled`: Task was canceled + +### List All Tasks + +List all queued and running tasks. + +**Request:** +``` +GET /api/v1/tasks +Authorization: Bearer your-secret-token-here +``` + +**Response (200 OK):** +```json +{ + "queued": [ + { + "id": "c9h8t1234abcd", + "title": "[tgfiles](file1.pdf->local1:/downloads/file1.pdf)" + } + ], + "running": [ + { + "id": "d2k9u5678efgh", + "title": "[tgfiles](file2.pdf->local1:/downloads/file2.pdf)" + } + ] +} +``` + +### Cancel Task + +Cancel a running or queued task. + +**Request:** +``` +DELETE /api/v1/tasks/{task_id} +Authorization: Bearer your-secret-token-here +``` + +**Response (200 OK):** +```json +{ + "message": "task canceled" +} +``` + +## Webhook Callback + +If `webhook_url` is configured, the API will send a POST request to the webhook URL when a task completes or fails. + +**Webhook Request:** +``` +POST {webhook_url} +Content-Type: application/json +Authorization: Bearer your-secret-token-here + +{ + "task_id": "c9h8t1234abcd", + "status": "completed", + "title": "[tgfiles](file.pdf->local1:/downloads/file.pdf)", + "created_at": "2024-01-19T04:30:00Z", + "error": "" +} +``` + +## Example Usage + +### Using cURL + +**Create a download task:** +```bash +curl -X POST http://localhost:8080/api/v1/tasks \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer your-secret-token-here" \ + -d '{ + "telegram_url": "https://t.me/channel/123", + "user_id": 123456789, + "storage_name": "local1", + "dir_path": "/downloads" + }' +``` + +**Get task status:** +```bash +curl http://localhost:8080/api/v1/tasks/c9h8t1234abcd \ + -H "Authorization: Bearer your-secret-token-here" +``` + +**List all tasks:** +```bash +curl http://localhost:8080/api/v1/tasks \ + -H "Authorization: Bearer your-secret-token-here" +``` + +**Cancel a task:** +```bash +curl -X DELETE http://localhost:8080/api/v1/tasks/c9h8t1234abcd \ + -H "Authorization: Bearer your-secret-token-here" +``` + +### Using Python + +```python +import requests + +API_URL = "http://localhost:8080" +TOKEN = "your-secret-token-here" +HEADERS = { + "Authorization": f"Bearer {TOKEN}", + "Content-Type": "application/json" +} + +# Create a download task +response = requests.post( + f"{API_URL}/api/v1/tasks", + headers=HEADERS, + json={ + "telegram_url": "https://t.me/channel/123", + "user_id": 123456789, + "storage_name": "local1", + "dir_path": "/downloads" + } +) +task_id = response.json()["task_id"] + +# Get task status +response = requests.get( + f"{API_URL}/api/v1/tasks/{task_id}", + headers=HEADERS +) +status = response.json() +print(f"Task status: {status['status']}") +``` + +## Security Recommendations + +1. **Always use a strong token** for production environments +2. **Enable IP whitelist** (`trusted_ips`) to restrict access +3. **Use HTTPS** in production by placing the API behind a reverse proxy (e.g., Nginx, Caddy) +4. **Keep logs secure** as they may contain sensitive information +5. **Validate user permissions** - ensure `user_id` in requests corresponds to authorized users in your config diff --git a/docs/content/zh/usage/api.md b/docs/content/zh/usage/api.md new file mode 100644 index 0000000..f8ebab7 --- /dev/null +++ b/docs/content/zh/usage/api.md @@ -0,0 +1,262 @@ +--- +title: "HTTP API" +weight: 4 +--- + +# HTTP API + +SaveAny-Bot 提供 RESTful HTTP API,支持通过编程方式从 Telegram 下载文件。 + +## 配置 + +在 `config.toml` 中启用 API: + +```toml +[api] +# 启用 HTTP API 服务 +enable = true +# API 服务监听端口 +port = 8080 +# API 访问令牌 (留空则不验证) +token = "your-secret-token-here" +# 任务完成回调 Webhook URL (留空则不回调) +webhook_url = "https://your-server.com/webhook" +# 可信任的 IP 地址列表 (留空则不限制), 支持单个 IP 或 CIDR 格式 +trusted_ips = ["127.0.0.1", "192.168.1.0/24"] +``` + +## 认证 + +如果配置了 `token`,所有 API 请求(除了 `/health`)都必须包含 `Authorization` 头: + +``` +Authorization: Bearer your-secret-token-here +``` + +如果配置了 `trusted_ips`,请求只会从指定的 IP 地址被接受。 + +## 端点 + +### 健康检查 + +检查 API 服务器是否正在运行。 + +**请求:** +``` +GET /health +``` + +**响应:** +```json +{ + "status": "ok" +} +``` + +### 创建下载任务 + +从 Telegram 消息链接创建新的文件下载任务。 + +**请求:** +``` +POST /api/v1/tasks +Content-Type: application/json +Authorization: Bearer your-secret-token-here + +{ + "telegram_url": "https://t.me/channel/123", + "user_id": 123456789, + "storage_name": "local1", + "dir_path": "/downloads" +} +``` + +**请求参数:** +- `telegram_url` (必填): Telegram 消息链接 (例如: `https://t.me/channel/123`) +- `user_id` (必填): Telegram 用户 ID (必须在 `config.toml` 中配置) +- `storage_name` (可选): 要使用的存储名称。如果未指定,使用用户的第一个可用存储 +- `dir_path` (可选): 存储中的目录路径。默认为 `/` + +**响应 (201 Created):** +```json +{ + "task_id": "c9h8t1234abcd", + "message": "task created successfully" +} +``` + +**错误响应 (4xx/5xx):** +```json +{ + "error": "错误描述" +} +``` + +### 获取任务状态 + +获取特定任务的状态。 + +**请求:** +``` +GET /api/v1/tasks/{task_id} +Authorization: Bearer your-secret-token-here +``` + +**响应 (200 OK):** +```json +{ + "task_id": "c9h8t1234abcd", + "status": "completed", + "title": "[tgfiles](file.pdf->local1:/downloads/file.pdf)", + "created_at": "2024-01-19T04:30:00Z", + "error": "" +} +``` + +**状态值:** +- `queued`: 任务正在队列中等待 +- `running`: 任务正在下载 +- `completed`: 任务成功完成 +- `failed`: 任务失败(查看 `error` 字段) +- `canceled`: 任务已取消 + +### 列出所有任务 + +列出所有排队和正在运行的任务。 + +**请求:** +``` +GET /api/v1/tasks +Authorization: Bearer your-secret-token-here +``` + +**响应 (200 OK):** +```json +{ + "queued": [ + { + "id": "c9h8t1234abcd", + "title": "[tgfiles](file1.pdf->local1:/downloads/file1.pdf)" + } + ], + "running": [ + { + "id": "d2k9u5678efgh", + "title": "[tgfiles](file2.pdf->local1:/downloads/file2.pdf)" + } + ] +} +``` + +### 取消任务 + +取消正在运行或排队的任务。 + +**请求:** +``` +DELETE /api/v1/tasks/{task_id} +Authorization: Bearer your-secret-token-here +``` + +**响应 (200 OK):** +```json +{ + "message": "task canceled" +} +``` + +## Webhook 回调 + +如果配置了 `webhook_url`,API 会在任务完成或失败时向 webhook URL 发送 POST 请求。 + +**Webhook 请求:** +``` +POST {webhook_url} +Content-Type: application/json +Authorization: Bearer your-secret-token-here + +{ + "task_id": "c9h8t1234abcd", + "status": "completed", + "title": "[tgfiles](file.pdf->local1:/downloads/file.pdf)", + "created_at": "2024-01-19T04:30:00Z", + "error": "" +} +``` + +## 使用示例 + +### 使用 cURL + +**创建下载任务:** +```bash +curl -X POST http://localhost:8080/api/v1/tasks \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer your-secret-token-here" \ + -d '{ + "telegram_url": "https://t.me/channel/123", + "user_id": 123456789, + "storage_name": "local1", + "dir_path": "/downloads" + }' +``` + +**获取任务状态:** +```bash +curl http://localhost:8080/api/v1/tasks/c9h8t1234abcd \ + -H "Authorization: Bearer your-secret-token-here" +``` + +**列出所有任务:** +```bash +curl http://localhost:8080/api/v1/tasks \ + -H "Authorization: Bearer your-secret-token-here" +``` + +**取消任务:** +```bash +curl -X DELETE http://localhost:8080/api/v1/tasks/c9h8t1234abcd \ + -H "Authorization: Bearer your-secret-token-here" +``` + +### 使用 Python + +```python +import requests + +API_URL = "http://localhost:8080" +TOKEN = "your-secret-token-here" +HEADERS = { + "Authorization": f"Bearer {TOKEN}", + "Content-Type": "application/json" +} + +# 创建下载任务 +response = requests.post( + f"{API_URL}/api/v1/tasks", + headers=HEADERS, + json={ + "telegram_url": "https://t.me/channel/123", + "user_id": 123456789, + "storage_name": "local1", + "dir_path": "/downloads" + } +) +task_id = response.json()["task_id"] + +# 获取任务状态 +response = requests.get( + f"{API_URL}/api/v1/tasks/{task_id}", + headers=HEADERS +) +status = response.json() +print(f"任务状态: {status['status']}") +``` + +## 安全建议 + +1. **生产环境始终使用强令牌** +2. **启用 IP 白名单** (`trusted_ips`) 限制访问 +3. **生产环境使用 HTTPS**,通过反向代理(如 Nginx、Caddy)放置 API +4. **保护日志安全**,因为它们可能包含敏感信息 +5. **验证用户权限** - 确保请求中的 `user_id` 对应于配置中的授权用户