多账户,各自代理,游客独立。
1.4.0:新增多账户管理与账户独立代理;保留 GET / POST 链接解析、按需刷新游客 token 和累计使用计数。本地默认盐言 App 协议为 2.17.0 / 21806,X-Zse-93 保持 204_1_3.0。GET /api/health 分别返回服务 version、目标 app_version 和 version_code。旧本地 2.14.0 / 21504 会话在重启读入时迁移;CK 导入保留抓包原环境,使用 2.17 账号环境需导入完整同源 CK。
默认 --account-mode shared:所有前端共享账户列表及当前选择,凭据加密保存,换浏览器与重启服务均保留。--account-mode browser 则按浏览器 Cookie 隔离列表,需持续保存服务返回的 Cookie。GET /api/accounts 返回 accounts、active_account_id、account_mode 和当前 session;POST /api/accounts 创建,PATCH /api/accounts/{account_id} 编辑,POST /api/accounts/{account_id}/activate 切换,DELETE /api/accounts/{account_id} 删除。最多 50 个账户,旧账号自动纳入;删除当前项自动选择剩余项,不清除其他凭据。
创建示例:{"label":"备用账户","proxy":{"mode":"custom","protocol":"socks5h","url":"127.0.0.1:1080:user:password"},"activate":true}。连接模式为 inherit(服务默认代理)、direct(明确直连)、custom(独立代理)。支持 http、https、socks4、socks4a、socks5、socks5h;完整 URL 的协议优先,也支持 host:port 和 host:port:user:password 简写,IPv6 需方括号。简写认证自动编码;完整 URL 的 @、#、% 等特殊认证字符需百分号编码。
目标网站为 HTTPS 不代表代理应使用 https://:普通 HTTP CONNECT 代理仍填 http://,https:// 表示与代理本身建立 TLS。socks5h 在代理端解析 DNS。保存只检查格式,连接失败不会降级直连或关闭证书验证。代理凭据加密保存,只返回脱敏 display;编辑既有独立代理时 url 留空或省略表示保留原配置,不要回填掩码。代理仅作用于该账户的登录、正文和阅读上报,游客搜索与分享解析仍沿用服务默认代理。
GET /api/session 额外返回 account_id、account_label、proxy、default_proxy_configured。账户相关请求可携带 X-Yanyan-Account 绑定当前选择,不一致返回 409 / ACCOUNT_CHANGED;切换或修改代理会停止旧阅读,需要重新打开正文。POST /api/auth/sms 接收 username,POST /api/auth/sign-in 接收 username、digits;GET / PUT / POST /api/auth/captcha 用于图形验证。POST /api/session/import 支持 CK、抓包请求头和会话 JSON,只更新所选账户并保留名称与代理。受管账户的 DELETE /api/session 只删除当前项,未纳入列表的旧会话仍保留原退出行为。所有 ID 使用字符串,未登录也可搜索。
GET /api/searchtitle?search_title=关键词 和 /api/search/recommend 始终使用服务端独立游客 token、Cookie 和设备,不使用账号 CK。游客 token 到期或搜索返回 401 时自动续取,原请求最多重试一次;403、429 和网络失败不会触发 token 轮换。搜索结果不会自动预取账号正文。
前端按 App 流程以 150 ms 防抖请求 /api/search/recommend,返回 suggestions 结构化建议及顶层 query_type、url、koc_keyword 等字段,保留原 items 标题数组。提交搜索复用当前词的推荐响应,有 URL 时直达,没有 URL 才请求 /api/searchtitle;点击建议使用该条目的路由信息,分页直接沿用 cursor。KOC 假名全程用游客解析,输入和展示联想不会请求账号正文。
GET /api/resolve_share?url=完整分享链接的URL编码&refresh_guest_token=false 与 POST /api/resolve_share 同时可用。GET 的刷新参数支持 true/false 或 1/0;POST 保留 JSON 请求体 {"url":"SOIA / OIA / story 链接","refresh_guest_token":false},必须使用 JSON 布尔值。两者返回相同的 target.business_id、target.section_id、token_mode_used 和 token_usage_count。省略或 false 优先复用游客缓存,缺失、过期或 401 时自动续取;true 在联网解析前重新申请游客 token,保留游客设备和 BEC / _xsrf,不修改账号。取 token 失败直接报错。完整 story 章节路径本地提取,即使 true 也不额外取 token;解析不请求正文。“按链接阅读”完成解析后,再使用当前账号打开正文。
token_usage_count 统计当前游客 token 实际携带 Bearer 的累计上游请求尝试,搜索、联想、分享还原和目录查询共用;错误与网络异常也计数,取 token、设备注册及 Cookie 初始化不计入。纯本地解析不增加,尚无 token 为 0。GET/POST 共用同一队列,计数加密持久化并跨重启保留,旧缓存升级后从 0 开始。只有 token 值不同才重置;重新申请得到同一 token 继续累计。解析阶段的错误也返回计数,参数校验或跨站拦截不附带此字段。不返回原始 token 或指纹;计数不是上游剩余额度。
正文、取钥、权益复核、进度同步和阅读时长上报继续使用当前账号。POST /api/reader/sessions 返回 reading_id、generation 和通知地址。监听 stream 的 snapshot 事件,正文 ready 后读取 content;页面 rendered、restore_complete 后才复核权益和开始实际阅读。用 events 按 seq 顺序提交段落位置、可见性和暂停事件,最后调用 close。打开请求须携带 tab_id、client_open_id;事件须携带 generation。只有 accepted_through_seq 已确认的事件才能从客户端待发队列移除。本地保存 recording 与上游同步 upstream_sync 是两个独立状态。显式预取接口 /api/reader/preload 仍可用于已登录或导入的账号。
阅读使用 web_paragraph_v2 整数段落比例,offset_ratio 仅用于恢复,不强制末尾 100%。paywall 表示真实显示截断,rights_refresh 表示用户主动重新检查权益;两者都不声明支付成功。CK 可携带 reader_config / raw_zonfig 配置,TLS 会话恢复由 tls.session_resumption 显式选择。
/api/decrypt 只做离线解密。兼容正文和 TXT 接口不产生阅读记录。错误响应统一为 ok: false 和 error 对象。完整字段、SSE 示例与错误码见源码目录 API.md。下载 OpenAPI JSON ↗