Fanqie Author API
适用前提
- 先用
rg --files确认当前工作区存在以下文件,再开始执行:fanqie/api-doc.mdscripts/fanqie-api.tsscripts/fanqie-autosave.ts
- 当前仓库的默认位置是
/Users/moka/Documents/da-code/readnote。如果不在这个仓库,先定位等价文件,再继续。
执行优先级
- 用户本轮硬约束。
- 本地
fanqie/api-doc.md。 scripts/fanqie-api.ts与scripts/fanqie-autosave.ts的真实实现。- 本 skill 的默认流程。
若文档与脚本冲突:
- 已封装命令,以脚本真实行为为准。
- 尚未封装的接口,以
fanqie/api-doc.md为准,并明确说明“当前走原始请求,不走脚本封装”。
配置分层
默认按四层解析,不要把“项目上下文”和“敏感认证”混在一起:
- CLI flags:本次命令临时覆盖,优先级最高。
- 项目级
.env.local:可选缓存当前仓库的书籍与写作上下文,用来避免重复查询,不是必填事实源。 ~/.ssh/fanqie/*.env:保存认证、签名、浏览器抓包字段等敏感值。- 脚本默认值。
项目级 .env.local 允许保存:
FQ_BOOK_IDFQ_BOOK_NAMEFQ_VOLUME_NAMEFQ_SOURCE_FILEFQ_TITLE_FROMFQ_TITLE_OVERRIDEFQ_STRIP_FIRST_HEADINGFQ_LOOKUP_DRAFTFQ_CREATE_NEWFQ_DRAFT_LIST_PAGE_INDEXFQ_DRAFT_LIST_PAGE_COUNTFQ_INTERVAL_MINUTESFQ_RUN_IMMEDIATELY
说明:
- 这些项目级变量默认都视为“缓存命中项”,不是强制配置项。
- 若
.env.local缺少FQ_BOOK_ID、FQ_VOLUME_NAME、FQ_SOURCE_FILE等业务变量,skill 应先尝试从当前仓库文件、发布记录、卷纲、最近请求上下文或番茄查询接口中补齐,不要把“项目级 env 缺失”直接视为阻塞。 FQ_BOOK_ID、FQ_VOLUME_NAME、FQ_SOURCE_FILE适合放在.env.local,主要是为了减少重复调用或重复确认。FQ_BOOK_NAME作为供 skill 阅读的人类可读元数据使用,便于确认“当前项目对应哪本书”;当前 TypeScript 脚本不直接消费它。- 若
.env.local里出现FQ_COOKIE、FQ_CSRF_TOKEN、FQ_MS_TOKEN、FQ_A_BOGUS_*,视为旧布局,优先建议迁回~/.ssh/fanqie/*.env。
隐私与路径索引
- 所有 Cookie、CSRF、
msToken、a_bogus一律放在~/.ssh/fanqie,不要写回仓库。 - 先读 references/privacy-path-index.md。
- 默认只展示“路径 + 变量名”,不要在聊天、提交、文档、日志里回显真实值。
- 只有在排查失败请求时,才读取敏感文件;对外输出必须打码。
- 允许并推荐 repo 内
.env.local保存非敏感项目上下文,但不要把认证信息写进去。
默认 env 布局
- 当前项目根目录
.env.local:可选缓存当前仓库绑定的业务上下文,如FQ_BOOK_ID、FQ_BOOK_NAME、FQ_VOLUME_NAME、FQ_SOURCE_FILE;没有这些值时,skill 应继续通过仓库上下文或番茄接口自行补齐。 ~/.ssh/fanqie/default.env:通用认证与签名字段,不放项目私有书籍说明。~/.ssh/fanqie/*.env:可按书或场景拆分认证,但仍只做“路径索引”,不在 skill 中硬编码真实值。- 若需要模板,使用
~/.ssh/fanqie/default.env.example复制为default.env。
若当前仓库已有旧版 .env.local 且里面带认证字段,处理顺序:
- 保留
FQ_BOOK_ID、FQ_VOLUME_NAME、FQ_SOURCE_FILE等项目缓存变量在.env.local;若这些变量不存在,也不视为错误。 - 把
FQ_COOKIE、FQ_CSRF_TOKEN、FQ_MS_TOKEN、FQ_A_BOGUS_*迁到~/.ssh/fanqie/default.env。 - 后续命令改为先 source 私密 env,再 source 项目
.env.local。
快速路由
- 书籍、分卷、草稿、已发布章节查询:
scripts/fanqie-api.ts - 分卷改名:
scripts/fanqie-api.ts volume-modify - 一次性草稿保存、自动保存、cron 示例:
scripts/fanqie-autosave.ts - 文档已知但当前脚本未封装:
publish_article/v0、add_volume/v0、stats/chapter_list_v1/v0
常用命令
推荐统一用“先 source 私密 env,再 source 项目 .env.local”的方式执行。这样既兼容当前仓库脚本默认读 .env.local,又不会把认证写回仓库。
基础模板:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-api.ts book-list
说明:
- 不默认使用
npm run autosave:*,因为它只传--env-file=.env.local,适合“所有变量都已放在 repo env” 的旧布局。 - 若用户明确采用旧布局,才继续沿用
node --env-file=.env.local ...或 npm scripts。
查询作品列表:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-api.ts book-list
查询卷列表:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-api.ts volume-list --book-id "<BOOK_ID>"
修改分卷名:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-api.ts volume-modify \
--book-id "<BOOK_ID>" \
--volume-id "<VOLUME_ID>" \
--volume-name "第一卷:血囚入阙" \
--ms-token "<MS_TOKEN>" \
--a-bogus "<A_BOGUS>"
查询草稿列表:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-api.ts draft-list --book-id "<BOOK_ID>" --page-count 50
新建草稿并上传正文:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-autosave.ts run \
--source "正文/第014章_董事会里的临时动议.md" \
--book-id "<BOOK_ID>" \
--volume-name "<卷名>" \
--create-new
按标题查已有草稿并覆盖:
set -a
source "$HOME/.ssh/fanqie/default.env"
[ -f ./.env.local ] && source ./.env.local
set +a
node --experimental-strip-types scripts/fanqie-autosave.ts run \
--source "正文/第014章_董事会里的临时动议.md" \
--book-id "<BOOK_ID>" \
--lookup-draft
工作流
- 先读 references/current-api-map.md,确认本次目标接口是否已被脚本封装。
- 先确认配置来源:优先看 CLI flags;项目根
.env.local里的FQ_BOOK_ID、FQ_BOOK_NAME、FQ_VOLUME_NAME、FQ_SOURCE_FILE只当作快捷缓存;若缺失,则继续用私密 env 提供认证,并从仓库上下文、最近请求或番茄查询接口补齐业务参数。 - 变更远端内容前,先确认
source、标题、book_id、volume_id/volume_name。 - Markdown 上传优先走脚本,让脚本负责转成
<p>+<br>HTML。 - 若是草稿写入,优先走:
new_article/v0->cover_article/v0->save_doc_history/v0- 或
draft_list/v1->cover_article/v0->save_doc_history/v0
- 若是修改已发布章节:
- 先用
chapter_list/v1找到正式文章item_id - 再按文档调用
publish_article/v0 - 不要把草稿
item_id和正式文章item_id混用
- 先用
- 若是发布或改写正式章节:
- 在每次
publish_article/v0返回成功后,必须再次调用chapter_list/v1回查目标volume_id的正式文章列表 - 至少核对受影响章节窗口中的
item_id、title、章号顺序是否与预期一致,不能只看单次接口成功日志 - 若本次是连续多章发布或顺延修正,必须确认正式列表里没有跳号、重号、倒序,再向用户汇报“已完成”
- 若正式列表短暂仍显示旧标题、
display_status=5或cant_modify_reason为“审核中暂不支持修改”,先等待数秒后重查,直到列表刷新或明确告知用户仍未收敛
- 在每次
- 若是查询章节统计:
- 当前优先按文档调用原始
stats/chapter_list_v1/v0 stats_type=3重点看read_completion_rate(章节读完率)与loss_rate(章节流失率)stats_type=4重点看follow_read_rate(章节跟读率)- 这些统计字段当前都按字符串返回,落库优先保留原始字符串
- 当前优先按文档调用原始
- 若是修改分卷名:
- 先用
volume_list/v1确认目标volume_id - 再优先用
scripts/fanqie-api.ts volume-modify volume_data必须按 JSON 字符串传,不能拆成多个表单字段
- 先用
- 若是新建分卷:
- 按文档调用
add_volume/v0 - 若返回
code = -4054,先给现有空分卷创建至少 1 个章节,再重试
失败排查
- HTTP 非 2xx 或
code != 0,优先怀疑:FQ_COOKIEFQ_CSRF_TOKENFQ_MS_TOKENFQ_A_BOGUS_*
- 需要刷新时,从浏览器开发者工具重新抓:
cover_article/v0save_doc_history/v0new_article/v0draft_list/v1volume/modify/v0
- 若只是查询失败,先验证同一份 env 能否跑通
book-list,再缩小到具体接口。
注意事项
content提交的是 HTML,不是 Markdown。- 若脚本可用,不要手写 HTML 转换逻辑。
- 标题要保持文件名、文内标题、平台标题一致。
publish_article/v0返回code = 0只代表请求被后台接受,不代表正式文章列表已经刷新;结束前必须回查chapter_list/v1。- 涉及正式章节发布时,要以正式文章列表中的最终顺序为准做结论,不能只依据单条成功日志。
- 不要把缺少项目级
FQ_BOOK_ID/FQ_VOLUME_NAME视为硬阻塞;这些值优先当作缓存,不在时应继续推导或查询。 - 书籍 ID 与书名优先从项目根
.env.local快速命中当前上下文;未命中时,再由 skill 主动查询,不要把仓库绑死在 env 上。 - 若用户要做重复任务,优先在现有 TypeScript 脚本里补封装,而不是每次手写
curl。