# 公共反馈 API ## Endpoint ```text POST /api/v1/feedback ``` 该接口不使用用户账户。服务端按来源 IP 和 `installationId` 的 keyed digest 分别限流,并使用 `(productKey, clientRequestId)` 保证幂等。 生产环境必须使用 HTTPS。若请求包含 `Origin`,它必须与服务端 `PUBLIC_ORIGIN` 的 origin 完全一致。桌面应用的 Main 进程请求通常不发送 `Origin`。 ## JSON 提交 ```http POST /api/v1/feedback HTTP/1.1 Content-Type: application/json { "schemaVersion": 1, "productKey": "goodbuddy", "category": "bug", "title": "魔法笔记页签不可见", "description": "平台功能中的魔法笔记页签被布局压缩,无法看到或点击。", "contactEmail": "user@example.com", "environment": { "appVersion": "0.11.0", "platform": "windows", "architecture": "x64", "locale": "zh-CN" }, "installationId": "00000000-0000-4000-8000-000000000101", "clientRequestId": "00000000-0000-4000-8000-000000000102" } ``` ## Multipart 提交截图 使用 `multipart/form-data` 时: - `payload`:上述 JSON 的字符串形式 - `screenshot`:可选,最多一个 PNG、JPEG 或 WebP 文件 ```sh curl \ --fail-with-body \ --form 'payload={ "schemaVersion":1, "productKey":"goodbuddy", "category":"bug", "title":"魔法笔记页签不可见", "description":"平台功能中的魔法笔记页签被布局压缩,无法看到或点击。", "installationId":"00000000-0000-4000-8000-000000000101", "clientRequestId":"00000000-0000-4000-8000-000000000102" }' \ --form 'screenshot=@capture.png;type=image/png' \ https://feedback.example.com/api/v1/feedback ``` 服务端会验证实际解码格式,只接受单帧 PNG、JPEG 或 WebP,随后应用方向 信息、重编码为 PNG 并去除原文件元数据。 输入和重编码后的文件都必须满足 `MAX_SCREENSHOT_BYTES`。最大边长为 8192 像素,最大像素数为 3200 万。 ## 字段 | 字段 | 必填 | 约束 | | --- | --- | --- | | `schemaVersion` | 是 | 当前固定为 `1` | | `productKey` | 是 | 2–64 位小写字母、数字或连字符,产品必须启用 | | `category` | 是 | `bug`、`feature`、`experience`、`other` | | `title` | 是 | 去除首尾空白后 1–120 字符 | | `description` | 是 | 去除首尾空白后 10–5000 字符 | | `contactEmail` | 否 | 有效邮箱,最多 254 字符 | | `environment.appVersion` | 环境存在时 | 1–64 字符 | | `environment.platform` | 环境存在时 | `windows`、`macos`、`linux`、`unknown` | | `environment.architecture` | 环境存在时 | `x64`、`arm64`、`unknown` | | `environment.locale` | 否 | 2–32 字符 | | `installationId` | 是 | 应用安装级随机 UUID,不应使用硬件 ID | | `clientRequestId` | 是 | 每次新反馈生成的随机 UUID;重试时保持不变 | 请求对象采用严格 schema,未声明字段会导致请求失败。 ## 成功响应 首次创建返回 HTTP 201: ```json { "reference": "GOODBUDDY-000001", "duplicate": false } ``` 同一产品和 `clientRequestId` 的重试返回 HTTP 200,并返回原编号: ```json { "reference": "GOODBUDDY-000001", "duplicate": true } ``` ## 错误 | HTTP | 含义 | | --- | --- | | 400 | 字段、JSON、multipart 或图片无效 | | 403 | 请求 `Origin` 不允许 | | 404 | 产品不存在或已停用 | | 413 | 请求体超过限制 | | 429 | IP 或安装实例超过提交频率 | | 500 | 服务端内部错误 | 客户端应: 1. 为一次用户提交生成 `clientRequestId`,网络重试时复用。 2. 设置明确的连接与总超时。 3. 限制响应体大小,只接受 JSON。 4. 将非 2xx 响应作为失败处理,并向用户保留输入内容。 5. 仅在用户明确选择后添加截图。