首页/踩坑排查
踩坑排查2026年8月6日6 分钟阅读

我给公众号发布加了一道不会偷跑的安全闸

“保存到草稿”和“正式群发”必须是两次不同授权;接口返回成功之后,还要从平台读取一次真实状态。

我给公众号发布加了一道不会偷跑的安全闸

请求超时之后,到底算成功还是失败

发布器里最难处理的情况,往往没有红色报错。请求已经发出,连接却在返回完整结果前断了。

平台可能已经创建草稿,也可能什么都没发生。本地唯一确定的事实,是自己没有拿到完整响应。此时如果脚本按普通网络请求的习惯自动重试,账号里很可能多出第二份草稿;换成群发,代价会更大。

所以我的发布器遇到这种情况不会显示 failed,而是停在 unknown:

unknown 不等于 failed,也绝对不等于可以再提交一次。

后面的所有安全设计,都从这条不确定性开始。

先把四个动作拆开

内容自动化里经常混用“提交”这个词,但下面四个动作风险完全不同:

  1. 生成本地正文:只改变本地文件。
  2. 上传素材:向平台传图片或封面。
  3. 保存平台草稿:目标账号出现可编辑内容。
  4. 正式发布或群发:内容对外可见,可能无法无痕撤回。

按钮、命令和日志都应该使用准确动作名。一个叫“提交”的按钮如果背后可能群发,操作者无法做出知情判断。

我的默认能力只到保存草稿。正式发布是另一个入口,需要新的授权。

安全闸不是一个确认框,而是四层证据

身份闸:确认目标账号

系统不能只显示内部 appid 或配置文件名。执行前要让人看到可识别的账号名称和环境,例如“测试号”还是“正式号”。

目标账号无法确认时,流程失败关闭,不选择第一个默认账号。

内容闸:冻结当前版本

授权对象不是一个标题,而是一组确定内容:

  • 标题。
  • 摘要。
  • 正文版本或哈希。
  • 封面文件。
  • 目标账号。
  • 动作类型。

授权后如果正文或封面变化,旧授权自动失效。否则人确认的是 A 版本,系统可能发布 B 版本。

动作闸:草稿与群发分权

保存草稿的凭证和入口不应自然获得群发权限。即使平台技术上使用相近接口,业务上也要视为两个权限等级。

“上一次允许群发”不能成为长期默认设置。每次群发都要绑定当前内容和当前账号。

证据闸:提交后从平台回读

本地文件只能证明内容准备好了。

接口响应只能证明平台返回了某个结果。

平台回读才能证明目标账号里存在对应草稿或公开文章。

证据闸要求保存平台标识、标题、创建时间、状态和必要的内容摘要。只有这些信息与本地版本对应,状态才升级。

我使用的状态机

状态名必须让人看出系统知道多少:

prepared
authorized_for_draft
draft_submitted
draft_confirmed
authorized_for_publish
publish_submitted
published_confirmed
failed
unknown

状态不能随意跳跃。例如 prepared 不能直接变成 published_confirmed;draft_submitted 也不能因为本地提示“成功”就跳过回读。

failed 和 unknown 的处理方式不同:

  • failed:有明确错误证据。修复后仍要先确认前一次未被平台接收,才能重试。
  • unknown:证据不足。先对账,不自动重试。

这种区分会让代码多几行,却能避免最难恢复的重复动作。

一次超时后,我会怎样处理

假设保存草稿请求在 30 秒后超时。

第一步:冻结本次运行

不修改正文,不重新生成封面,不换账号。任何变化都会增加对账难度。

第二步:保存本地收据

收据至少记录:

  • 运行 ID。
  • 内容版本。
  • 目标账号。
  • 动作类型。
  • 请求开始时间。
  • 已拿到的平台标识。
  • 当前状态 unknown。
  • 敏感字段已隐藏的错误摘要。

第三步:只读查询平台

优先使用草稿读取接口;没有接口时打开当前账号后台,按时间、标题和素材核对。

只按标题查不够,因为同标题可能存在多个版本。平台标识和创建时间更可靠。

第四步:根据新证据升级

查到对应草稿,状态升级为 draft_confirmed。

收到明确的未创建证据,才可以进入可重试状态。

仍无法确认,就继续保持 unknown。等待不是系统无能,而是在阻止损失扩大。

为什么不能“重试三次就算了”

网络程序常用自动重试,但发布动作不是普通读取。读取同一页面三次通常不会改变外部世界,创建草稿或群发三次会。

是否能自动重试,要看动作是否具有可靠的幂等设计:同一个运行 ID 重复提交,平台或本地适配层能否保证只产生一个结果。

如果平台不提供这类保证,最安全的策略就是提交一次、记录一次、回读一次。不能因为工程框架默认重试三次,就把这个默认带进发布系统。

一份发布收据应该能回答什么

我希望任何一次运行都能在事后回答:

  • 谁授权了什么动作。
  • 内容当时是哪一个版本。
  • 目标账号是什么。
  • 请求何时发出。
  • 平台返回了什么标识。
  • 回读时看到了什么。
  • 最终状态由哪一条证据支持。

收据不应该保存完整 Token、Cookie 或私钥。它记录的是可审计事实,不是把敏感凭证复制一份。

重复草稿出现后,不要立刻批量删除

看到两个相似草稿时,第一反应通常是清掉一个。但如果没有先比对,很容易删除更新版本。

更稳的顺序是:

  1. 比较平台标识。
  2. 比较创建与更新时间。
  3. 比较正文版本或关键摘要。
  4. 确认哪一个被后续流程引用。
  5. 备份必要内容。
  6. 再执行单个、可追踪的删除。

清理动作也属于外部动作,需要明确目标和结果回读。

小团队也值得做这道闸

有人会觉得只有大公司才需要状态机和审计。个人创作者反而更需要,因为一个人同时扮演作者、编辑、运营和开发者,最容易把“我知道自己在做什么”当成系统控制。

安全闸不要求复杂后台。最小版本可以只是:

  • 草稿和群发两个独立命令。
  • 一份冻结后的内容摘要。
  • 一个确认目标账号的步骤。
  • 一次平台回读。
  • 一条 unknown 不重试规则。

我衡量发布自动化,不看它是否从不报错,而看一次超时会不会制造第二个结果。先检查现有入口:如果“保存”和“发出”仍藏在同一个动作里,先把它们拆开,再谈提速。

SOURCE AND VERIFICATION

来源与核验边界

本文记录 Kenton 自建草稿发布器的控制边界,不声称平台接口在所有账号上都具备相同权限。

没有把外部文章当作正文来源;内容来自 Kenton 的本地构建记录。

核验状态:基于本地草稿发布器的失败关闭与回读流程,核验日期 2026-08-11。

ONE PRACTICAL NEXT STEP

把你的真实流程带过来

如果你已经知道目标,却不知道应该先改工具、流程还是内容,把当前步骤和失败证据发来。我会先帮你判断最短路径。

一起检查你的发布安全闸

SEARCH THE FIELD NOTES

你卡在哪一步?

输入关键词后,会从标题、摘要、分类和标签中查找。