对话笔记直发:8.16 公众号落盘改造与hermes手动发布衔接。分类:AI工程。
tags:
- 公众号
- fns
- obsidian
- publish-pipeline
- skill
- telegram
- hermes
- 自动化
- 落盘 title: 公众号落盘改造与 hermes 手动发布衔接 date: 2026-08-16
公众号落盘改造与 hermes 手动发布衔接
全程目标:让云服务器 Hermes(
你的服务器IP(已脱敏))公众号发布流水线与 Telegram 交互式 hermes 全面对齐——统一 FNS 落盘到000_Raw/10_项目/公众号/文章/子目录,并让 hermes 手动写文时复用已验证的publish_pipeline.py确定性管线,保证”确认稿 = 推送稿”。
一、环境基线(已做脱敏)
- 云服务器:
你的服务器IP(已脱敏)(Hermes,/opt/data为主工作目录),脚本用/opt/data/.venv/bin/python、Node v22 在/opt/data/.nvm/versions/node/v22.23.2/bin/。 - 公众号发布流水线:
/opt/data/scripts/publish_pipeline.py(cron job3 调用,publish_wrapper.sh入口)→ humanize → LLM 改写(stepfun)→ render_fixed 排版 → 合规门 → no-text 封面 → FNS 写盘 → publish-file 推微信草稿箱 → Telegram 回报。 - 微信草稿箱:个人订阅号无 freepublish,只能建草稿人工群发。凭证
/opt/data/.wechat-publisher/config.json(600)。 - FNS(Fast Note Sync):
https://notes.unixcs.eu.org,vaultfeng,token 缓存/opt/data/.fns-token.json,User-Agent 绑定Mozilla/5.0 (hermes-cron fns-writer)。 - skill:wechat-publish-workflow(v2.1.0 → 2.2.0)、wechat-publisher、gzh-design、byted-web-search 均已注册启用。
二、本次会话累计变更清单
1. 落盘路径统一到 文章/ 子目录
- 用户要求:FNS 落盘统一改到
000_Raw/10_项目/公众号/文章/子目录(cron 与 hermes 手动都统一),文件名文章/{标题}.md(中文标题风格,与既有 3 篇一致)。 - 子代理两轮评审:初版【否决】(M1–M8),修正后再次【否决】(R1–R3,argv 解析、确认稿漂移、DELETE 端点),第三次【通过】后实施。
2. fns_write.py 改造
- 新增
ALLOWED_SUBDIR = "文章/",write_note校验放宽支持文章/子目录;裸文章(不带尾斜杠)精确拒绝,防与目录同名笔记污染。 - 子路径校验:非空、不含
/、反斜杠、%、..、不以.开头(防.md隐藏文件)。 - 新增
delete_note(full_path)+ CLI--delete:DELETE /api/note?path=<quote(safe="/")>&vault=feng,统一 UA + token 缓存。 - 顺手修复既有 bug:DELETE 请求若带
Content-Type: application/json,服务端不解析 query(报 305 Invalid Params);_req对 DELETE 不再设该头。
3. publish_pipeline.py 改造(v2)
- 三形态参数解析(argparse 替换
len(sys.argv)!=2守卫):publish_pipeline.py <digest.md>(默认,读全局.publish-mode)publish_pipeline.py --mode auto|manual <digest.md>(显式覆盖)publish_pipeline.py --resume <manifest.json>(复用 MANIFEST 产物,只推草稿+TG,不重跑 LLM/渲染/封面)
- 新增
sanitize_title(title, date)产出独立safe_title(显示title不受污染):去/\:*?"<>|#%&+ 控制符 + 全角空格、折叠空白、去尾部.和…、空串回退AI日报_{date}。 - FNS 写盘上移到 manual 分支之前:manual 也落盘
文章/{标题}.md,仅 publish 被 hold 并产出 MANIFEST。 - MANIFEST 补字段:
safe_title、clean_md、date、publish_cmd。
4. publish_wrapper.sh(cron 入口)
- 改为
exec ... --mode auto "$DIGEST",cron 显式 auto,不再依赖全局.publish-mode文件(防 hermes 手动串扰导致 cron 静默变 manual)。
5. SKILL.md wechat-publish-workflow v2.2.0
- 新增”手动发布路径(复用自动管线)“章节:两段确认流程(产稿→
--mode manual→成品确认→--resume),明确 manual→resume 之间不得清理out_*/与 MANIFEST。
三、本次执行细节(测试验收)
测试1 fns_write 单测
- 写
文章/测试标题.md✅、根目录兼容形态 ✅ - 边界全拒:
文章/..x、文章/.md、文章/文章/x.md、文章(裸)、文章/../x.md、Compat_x/y.md全 ERR ✅ --delete往返:写→删→再删报 “Note does not exist” ✅- 修复后
文章/目录污染清理干净。
测试2 manual 冒烟
--mode manual digest_part1_models.md:humanize OK → LLM rewrite OK(1477 字)→ render rc=0 → validate+placeholder OK → cover OK → FNS_OK 落盘文章/今日 AI 大模型动态(2026-08-15 AIHOT 日报.md→ MANIFEST 产出,不推微信 ✅- sanitize 初版保留
…导致文件名….md,已改为剥尾部…(纯观感)。
测试3 resume 冒烟
--resume manifest_...json:RESUME 日志(无 humanize/LLM/render/cover 步骤)→ publish rc=0 → DRAFT_OK(media_id)→ TG_OK → 确认稿=推送稿(复用同一 html 路径)✅
测试4 cron 回归(wrapper --mode auto)
- 完整链路:humanize→LLM(1415 字)→render→cover→FNS 落盘(覆盖写幂等)→publish→TG_OK ✅
清理
- 微信草稿箱 5 篇测试草稿全删(4 篇”今日 AI 大模型动态…” + 1 篇”123”),目前 0 篇。
- FNS 测试笔记全删;
main/与文章/均只留用户原有笔记。 /opt/data/linuxdo_daily/work/测试产物清空并重建(700 权限)。- 服务器 4 文件与本地版本
diff全部 identical。
四、当前状态(全量对账)
| 组件 | 状态 |
|---|---|
| fns_write.py | 支持 文章/ 子目录 + --delete + DELETE Content-Type 修复 ✅ |
| publish_pipeline.py | 三形态解析 + sanitize + FNS 上移 manual + resume ✅ |
| publish_wrapper.sh | cron 显式 --mode auto ✅ |
| SKILL.md v2.2.0 | 手动发布路径章节 ✅ |
| 微信草稿箱 | 0 篇(干净) |
FNS 文章/ | 仅用户 3 篇 ✅ |
| cron job3 | 改后publish_wrapper.sh 显式 auto 回归通过 ✅ |
- 备份:
/opt/data/backups/wxpub_chg_20260816_011549/(改动前 4 文件)。 .publish-mode文件保留(兼容/调试),当前值为auto。
五、待办
- 上线验证:在 Telegram 对 hermes 说”写一篇公众号文章并发布到草稿箱”,验证手动路径端到端(产稿→manual→确认→resume→草稿箱)。
- 观察 cron 每日自动发布(job3 wrapper 显式 auto)前几轮是否稳定。
- (可选)draft_link(
http://mp.weixin.qq.com/s?...media_id=...#rd)有效性待验证,暂未列入本次范围。 - (可选,范围外)
fns_write.py明文硬编码 PASSWORD,建议日后移入环境变量/密钥文件。
六、回滚与风险备忘
- 回滚:
/opt/data/backups/wxpub_chg_20260816_011549/内有改动前 4 文件,直接 scp 回/opt/data/scripts/与/opt/data/skills/wechat-publish-workflow/即可。 - DELETE 若报 305 Invalid Params:确认是否又引入了
Content-Type(DELETE 不应带该头)。 - FNS 401 “Browser (UA) restricted”:所有请求必须同一 UA
Mozilla/5.0 (hermes-cron fns-writer)。 --mode manual产物必须先展示用户确认再--resume;确认期间不得清out_*/与 MANIFEST。
七、Hermes 对齐诊断与《对齐文档》落盘(同日追加)
场景:用户在 Telegram 让 Hermes”推送到公众号草稿箱”,Hermes 回复”不知道如何推送、缺少公众号 AppID 和 Key、发布半截从没搭过”。经调查:非权限问题、非未搭好,是 Hermes 认知缺失。
1. 根因诊断(实测证据)
- Hermes gateway 真实进程:
hermes用户(uid 997)、HOME=/opt/data、HERMES_HOME=/opt/data(曾误判 HOME=/root,系 pgrep 误匹配到自身 bash)。 - 以
hermes用户实测:读/opt/data/.wechat-publisher/config.json✅、auth→ token valid(7072s)✅、draft list正常 ✅。 .openclaw目录不存在,不劫持 DATA_DIR;凭证解析命中/opt/data/.wechat-publisher/config.json。- 结论:公众号后半截(凭证/发布脚本/cron)已全部搭好且 hermes 可访问。Hermes 报缺凭证是因为它查环境变量
WECHAT_APP_ID/WECHAT_APP_SECRET(.env 无),没去读config.json——纯认知问题。 - 风险提示:不能放任 Hermes”给我凭证重新写脚本”——会重复造轮子、可能破坏已跑通的 job3 管线。应让它复用 publish_pipeline.py。
2. 对齐方案落地
- 用户倾向:生成一篇 Markdown 文档存 Obsidian,让 Hermes 读取快速对齐。
- 调查发现 Hermes 无 FNS/Obsidian 读取能力(skills 无对应项),但可直接读本地文件(
/opt/data属主)。故双落点:本地技能目录 + FNS sop。
3. 产物
- 《公众号发布链路_对齐.md》(8.2KB,§1-7:现状结论/环境事实/已搭链路/pipeline 三用法/操作指引/错误速查/运营提醒,凭证只写路径不写明文 secret):
- 本地:
/opt/data/skills/wechat-publish-workflow/公众号发布链路_对齐.md(hermes 属主、644,与 enabled skill 同目录) - FNS:
000_Raw/10_项目/公众号/sop/公众号发布链路_对齐.md(id 2788)
- 本地:
4. 顺带改动:fns_write.py 白名单扩展
ALLOWED_SUBDIR(单值)→ALLOWED_SUBDIRS(元组("文章/", "sop/")),_check_rel遍历匹
注:本文涉及的服务器公网 IP / Tailnet / 局域网 IP 已脱敏,请替换为你自己的地址。