公众号封面生成与草稿推送

SKILL内容创作

原名 易海推送skill · 标识 易海推送技能包

内容创作 未标注权限 许可证不明确
安装这个技能

接手上一步排版好的成品 HTML,生成多种风格的公众号封面,推送到草稿箱并逐项验证,还能替换草稿、排查接口报错、检查线上草稿与封面是否一致,只推草稿不发布。

一句话选型结论

按资料字段整理

公众号封面生成与草稿推送是内容创作类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类内容创作 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_a40be762/yhpush
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

内容创作
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_a40be762仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验2026-11-06上游最后核验时间 · 数据更新 2026-11-06
正文体量38.5 KBSKILL.md 原文大小,越大说明说明书写得越细

能做什么

0 项能力
上游给出的能力概览与适用场景
生成公众号封面推送文章到草稿箱排查推送接口报错

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
写文章与脚本

按主题产出初稿与分镜脚本。

改稿与润色

把草稿改顺、统一语气。

多平台文案改写

同一内容按平台改成长短不同的版本。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在内容创作场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
公众号封面生成与草稿推送当前 未标注权限 未标注 未标注 未标注 有
AI 视频生成 调用外部服务 GitHub 仓库 431.3 万 Codex、Claude、Cursor 有
视频帧 联网访问 ClawHub 市场 262.1 万 OpenClaw 有
Markdown 转换器 写入文件 ClawHub 市场 135.3 万 OpenClaw 有
哔哩哔哩全合一 接触敏感数据 ClawHub 市场 64.1 万 OpenClaw 有
Remotion video toolkit 命令行 浏览器控制 ClawHub 市场 63.9 万 OpenClaw 有

SKILL.md 全文

38.5 KB
模型实际读到的说明书原文,来自技能仓库

易海推送技能包(封面 + 推草稿箱)

> 读者是模型,不是人。 按 §0 → §9 顺序执行,不要跳步。
> 适用账号:易海工程AI(订阅号,AppID 见环境变量 WECHAT_APPID)。不要用于其他矩阵号。
> 本包只管交付链路最后一段:接收成品 HTML → 生成封面 → 推草稿箱 → 验证。
> 不写稿、不做正文排版、不套品牌头尾。 上游是「易海排版技能包」,它交出来的就是成品。


§0 你的第一个动作:先问封面风格(禁止跳过)

封面风格与正文风格是两回事,必须单独问一次。 用户没选就问,不要拿上次的封面接着用。

封面风格 长什么样 素材从哪来 适用题材 用哪个脚本
① 真人风 人物为主视觉(半身/特写),压暗或加渐变蒙版后压白色大字标题 你自己生成人物图;用户主动给了照片则优先用用户的 名人稿、人物故事、创始人叙事、访谈 make_cover_huangrenxun.py
② 大字报风 强色底 + 超大加粗文字占满画面,几乎无图 纯代码绘制,无需素材 观点文、金句、政策解读、悬念标题 make_covers_tiangong.py(换 --main)
③ 实景风 工地/产品/设备/办公场景为底,叠半透明色块压字 你自己生成场景图;用户主动给了实拍图则优先用 项目纪实、产品落地、案例复盘 make_cover_jihaoxing.py
④ 品牌渐变风 蓝色对角渐变 + 品牌名/主标题居中 纯代码绘制,无需素材 产品介绍、能力平台、系列文章 make_covers_tiangong.py
⑤ 真实照片满铺 真实照片满铺 + 底部黑渐变承白字,一次出方形/微信首图/横版三张 你自己生成照片;用户主动给了照片则优先用 用户明确说「用实际的方形照片」「照片更有吸引力」时 make_cover_photo.py

★ 核心原则(用户明确纠正过):
①②③⑤ 四种需要图像的封面,全部由你自己生成(用图像生成工具),不要一上来就向用户要图、更不要因为没有素材就拒绝或降级。
只有当用户主动说"用我这张照片/这张实拍图"时,才用用户提供的图(此时用图生图方式处理)。
禁止:向用户索要素材当作必填前置条件;也禁止用与内容无关的网图/图库图凑数。

0.1 提问话术(可直接复制发给用户)

封面用哪种?(和正文排版风格分开选)

  ① 真人风   —— 人物为主视觉 + 大字标题(我会生成人物图)★人物/名人稿推荐
  ② 大字报   —— 纯色底 + 超大文字(最快,不需要素材)
  ③ 实景风   —— 场景/产品为主视觉 + 文字(我会生成场景图)
  ④ 品牌渐变 —— 蓝色渐变 + 品牌名(天工词元系列默认款)
  ⑤ 真实照片满铺 —— 真照片铺满,一次出方形/微信首图/横版(我会生成照片)

▸ 也可以直接发一张你想要的封面参考图,我照着做;
  或者直接给我一张照片/实拍图,我用你的图来做。
▸ 你不需要提前准备素材——①②③⑤ 的底图我来生成(单张约 5–10 credits,会先告知)。

0.2 明确禁止

  • ❌ 未问封面风格就套用模板 / 上次封面 / 自己挑一个
  • ❌ 把「要用户提供照片」当成前置条件(缺图就自己生成,这是默认动作)
  • ❌ 用与文章内容无关的网图、图库图凑数
  • ❌ 在公众号后台点「发布」——这一步永远留给人工
  • ❌ 批量删草稿、按标题模糊删草稿

§1 全程固定参数与本包资产

1.1 固定参数(照抄,不要改)

参数 值
公众号名称 易海工程AI(订阅号)
AppID 环境变量 WECHAT_APPID(不在本包内写出)
AppSecret 环境变量 WECHAT_SECRET(不在本包内写出)
author 字段 必须显式传 易海工程AI(wechat_publisher 默认值是别人的号)
need_open_comment 1(开启留言,账号要求,不要覆盖为 0)
only_fans_can_comment 0(所有人可评论)
标题长度 ≤ 64 字(超了报 45003)
digest 摘要 50–60 字
封面尺寸 900 × 500(微信首图展示位实为 2.35:1 = 900×383,见 §5)

> 🔐 凭据从环境变量取,本包不含任何明文 AppID / AppSecret。
> bash > export WECHAT_APPID=wx**************** # Windows: set WECHAT_APPID=wx**************** > export WECHAT_SECRET=**************** >
> 真实值请向账号管理员索取,不要写进本包任何文件。脚本缺环境变量时会直接退出并提示。

1.2 本包自带的东西

易海推送技能包/
├── SKILL.md                          ← 本文件(唯一入口)
├── assets/
│   ├── 品牌头尾/                       ⚠️ 兜底副本(权威在「易海排版技能包」,正常流程不用)
│   │   ├── _ref_head_only.html        品牌头部块(顶部 banner GIF + 装饰卡)
│   │   ├── _ref_tail_only.html        品牌尾部块(蓝线+署名+三篇历史文章链接+加星标 GIF)
│   │   ├── 开头.gif                   头图 GIF(正文里用的是线上 URL,此份为备份)
│   │   └── 尾标.gif                   尾图 GIF(同上)
│   └── 封面参考图/
│       ├── ref_cover_guide.jpg        品牌渐变的采样参考(900×383,取自线上草稿封面)
│       ├── ref_cover_guide1.png       备选参考
│       ├── ref_cover_guide3.png       备选参考
│       ├── ref_cover_guide4.png       备选参考
│       └── ref_photo_default.png      ⑤ 真实照片满铺的默认底图(示例,可 --src 覆盖)
└── scripts/
    ├── wechat_publisher.py           微信 API 封装(token/建草稿/删草稿/传图/封面)
    ├── test_draft_flow.py            链路自检(建→查→删一条测试草稿)
    ├── fix_rewrap.py                 套品牌头尾(⚠️ 兜底用;正常由排版包负责)
    ├── validate_gzh_html.py          合规校验(ERROR/WARNING 计数)
    ├── _chk.py                       版式核查(左右边界/大块底色/字号分布)
    ├── wrap_preview.py               生成浏览器预览页
    ├── make_covers_tiangong.py       ② 大字报 / ④ 品牌渐变(蓝渐变+居中大字)
    ├── make_cover_huangrenxun.py     ① 真人风(--photo 传人物图;不传则渐变底)
    ├── make_cover_jihaoxing.py       ③ 实景/样机风(--ref 传场景图)
    ├── make_cover_photo.py           ⑤ 真实照片满铺(一次出方形/微信首图/横版三张)
    ├── upload_images_batch.py        正文配图批量换微信图床
    ├── verify_draft_images.py        核对线上草稿与本地正文是否一致
    ├── build_img_body.py             配图按章节嵌进正文(含图裸正文)
    ├── make_img_preview.py           本地自包含预览页
    └── .wechat_cache/                 token / 封面缓存(见 §8)

> 另有 assets/preview-template.html(预览页外壳)与本节同级的 5 个脚本,
> 是 wrap_preview.py / _chk.py / validate_gzh_html.py 的运行时依赖,不要删。
> 排版包内另有一份独立副本,两包各自自足、互不依赖。

1.3 执行前准备

# SK = 本 SKILL.md 所在目录。两个安装位置,用你实际加载的那个:
#   工作区镜像(唯一可信源):D:/中建三局/公众号易海工程/易海推送技能包
#   安装目录(供 agent 调用):C:/Users/mi/.workbuddy/skills/易海推送技能包
SK="<本 SKILL.md 所在目录>"
PY="C:/Users/mi/.workbuddy/binaries/python/envs/default/Scripts/python.exe"

> 下文所有命令都用这两个变量。用绝对路径,不要依赖当前目录。


§2 通道打通(首次 / 换机器 / 报 40164 时做)

2.1 ★ IP 白名单(最容易卡住,必须带用户做完)

为什么必须做:微信 API 只接受来自白名单 IP 的调用。

你要做的四步:

  1. 帮用户查出 IP——让用户在运行脚本的那台机器执行:

bash curl ifconfig.me

⚠️ 填的是运行脚本那台机器的公网出口 IP,不是 192.168.x.x 内网地址(填内网无效)。

  1. 告诉用户去哪里配(原样念给用户):

1. 用「管理员微信」扫码登录 mp.weixin.qq.com 2. 左侧菜单「设置与开发」→「基本配置」 3. 找到「公众号开发信息」→「IP 白名单」→ 点「修改」 4. 一行填一个 IP,保存(需要管理员扫码确认)

  1. 配完立刻跑 §2.3 自检,用结果判定,不要只听用户说"配好了"。

  2. 失败时读报错:报 40164 时错误信息里直接带着当前 IP,把它填进白名单即可。

四个坑(要主动提醒用户):

坑 说明
出口 IP 会变 家庭宽带/公司网络多为动态 IP,重启路由后可能变;报 40164 先怀疑它。本机最近一次为 113.56.181.173
换机器要重加 换一台电脑跑就要加那台的 IP;云服务器填服务器公网 IP
不要填内网地址 192.168.x.x 之类无效
白名单有数量上限 不要一次堆一堆无关 IP

2.2 凭据注意事项

凭据走环境变量 WECHAT_APPID / WECHAT_SECRET(见 §1.1),本包不存明文。
一旦被重置,旧值立即失效;若突然报 40125,第一件事就是确认它有没有被重置。
复制粘贴时带上换行或不可见字符也会导致 40125,粘完核对长度。

2.3 链路自检(每次推送前必须跑通)

export WECHAT_APPID=wx****************
export WECHAT_SECRET=****************
$PY "$SK/scripts/test_draft_flow.py"

也可显式传参:--appid <APPID> --secret <SECRET>(同样不要把真实值写进任何文件)。

它依次执行:清缓存 → 取 token → 建测试草稿 → 查询确认 → 删除 → 复查。
判定标准:5 步全部显示 [通过] 才算通。 任一失败 → 查 §8 错误码表,修好再重跑。

> 自检会建一条测试草稿再删掉,属正常动作,不要跳过。


§3 接收上游成品(只验收,不重做)

品牌头尾、署名、三篇历史链接是「固定格式」,由「易海排版技能包」负责套好。
本包接收的是成品 HTML,正常情况下不要再套一次、不要改任何一个字。

3.1 成品验收清单(吃到文件先跑这三条)

# ① <section> 开合平衡
grep -o "<section" <文件>.html | wc -l ; grep -o "</section>" <文件>.html | wc -l   # 两者差值应为 0

# ② 作者签名在(重写正文最容易弄丢)
grep -c "我是工程AI团队,AI建筑领域的创业者。" <文件>.html                        # 应为 1

# ③ 头尾齐全:头部 banner GIF + 尾部蓝线/署名/三链接/星标 GIF
grep -c "data-imgfileid" <文件>.html            # 头部 1 张 + 尾部星标 1 张,≥ 2
grep -c "mid=2247488216" <文件>.html            # 更多AI场景
grep -c "mid=2247488428" <文件>.html            # 全民营销
grep -c "mid=2247490062" <文件>.html            # 工程AI事业团队产品与服务手册
grep -o "编辑 |.\{0,6\} \?.\{0,6\}校对 |.\{0,6\} \?.\{0,6\}审核丨.\{0,6\}" <文件>.html   # 三行署名

署名格式铁律:编辑、校对与竖线「|」之间有一个半角空格;审核用全角「丨」,两侧无空格。
线上渲染即如此——竖线前的空隙是真实空格,竖线后没有空格;审核行两侧的大空隙只是「丨」字自带边距,
不要"修正"它。

3.2 头尾三条历史链接(验收时核对,不要改动、不要增删)

链接文字 href
更多AI场景 …mid=2247488216…
全民营销 …mid=2247488428…
工程AI事业团队产品与服务手册 …mid=2247490062&sn=c660b0938467ec14145fe3093f857c06…

三链接以线上草稿逐字核对过。将来要换,统一在排版包的尾块文件里改,本包不碰。

3.3 验收不过怎么办

情况 处置
头尾缺失 / 被套了两层 / 署名错 退回排版包重套。请用户重新跑一次排版包(fix_rewrap.py --credits "三人名"),本包不代做
<section> 不平衡,差值 -6 本地文件还套着旧版头尾,新尾块剥不掉。以线上最新草稿为准,不要强改本地快照;需重推就从草稿箱拉最新正文再套
是完整 HTML 文档 带 <!DOCTYPE>/<html> 外壳,是预览页不是推文产物,不要推它
全部合格 进入 §4 交付前校验 → §5 封面 → §6 推送

> 兜底(仅当用户明确要求"就在这推,别来回切包"时):本包 scripts/fix_rewrap.py 与
> assets/品牌头尾/ 保留了一份可用副本,可临时执行:
> bash > $PY "$SK/scripts/fix_rewrap.py" --dir <文章目录> \ > --head "$SK/assets/品牌头尾/_ref_head_only.html" \ > --tail "$SK/assets/品牌头尾/_ref_tail_only.html" \ > --credits "雨函,Jerry,阿良" >
> 输出 [OK] … diff=0 才算通过(--credits 与 --keep-credits 都不传 → exit 2,人名必须每次确认)。
>
> ⚠️ 头尾资产的唯一权威副本在「易海排版技能包」。本包这份只是兜底,改动一律以排版包为准;
> 若两边不一致,以排版包 assets/品牌头尾/ 覆盖本包。


§4 交付前校验

# ① 合规校验(硬门禁:ERROR=0 且 半角标点 WARNING=0)
$PY "$SK/scripts/validate_gzh_html.py" <套好头尾的文件.html>

# ② 边界/底色/字号实测(Playwright 390 视口 + 左右 20px 模拟微信容器)
$PY "$SK/scripts/_chk.py" <套好头尾的文件.html>
#    期望:左边界集合=[20]  右边界集合=[370]

# ③ 生成人工预览页(浏览器可「复制到公众号」)
$PY "$SK/scripts/wrap_preview.py" <套好头尾的文件.html>

判定标准:ERROR = 0 且 半角标点 WARNING = 0。 未清零不得推送。

校验器内置两条排版底线门禁:
- ❌ ERROR:全局容器两种版式都没声明(既无 margin:0 -16px,也无 padding:0 0 Npx)→ 页面会两侧留白
(2026-10-16 由"必须负 margin"放宽为"二选一":套头尾稿件用后者才对齐)
- ⚠️ WARNING:左右 padding > 12px(疑似留白);字号 < 15px 或 > 24px;正文缺 16px 主字号

4.1 _chk.py 期望输出

左边界集合=[20]  右边界集合=[370]      ← 对齐通过
--- 大块有底色元素(&gt;60x16)---
  rgb(255, 255, 255)  ×N               ← 只有纯白
H2 ... fs=17px / P ... fs=16px / P ... fs=15px

> L:20 R:370 之外若出现 L:28 R:29(1×36px)或 L:20 R:28(8×8px)属品牌头装饰资产,正常。
> 出现任何 &gt;60px 宽 的彩色底 → 说明头部装饰卡又被拆开未闭合,退回排版包排查
> (见「易海排版技能包」§4.6 头尾资产的已知病理)。

4.2 ★ 头尾资产的已知病理(2026-10-16 修复,勿回退|权威在排版包)

> 本包只保留此条目供验收时判断异常;实际修复动作在「易海排版技能包」。
> assets/品牌头尾/_ref_head_only.html 曾有三处缺陷,同时造成"整篇蓝底 + 两边不齐":

# 病理 修复
1 淡蓝装饰卡 background-color:rgba(95,156,239,0.06);padding:7px;width:100% 的 &lt;section&gt; 未闭合,把整篇正文包了进去 → 实测浅蓝区 430×3680(整篇高) 改为 background-color:rgb(255,255,255);padding:0px
2 同层另一块 flex:0 0 auto;padding:0 10px; → 头图比正文缩进 17px 改为 flex:0 0 auto;padding:0px
3 正文根容器 margin:0 -16px → 比头尾各宽 16px 正文改 padding:0 0 56px(零负 margin)

> .orig1016 备份存于 D:/中建三局/公众号易海工程/_技能拆分备份_20261019/
> —— 那份 .orig 只是留档对照,已被修复的版本才是正确版本,不要拿它覆盖在用的头尾。
> 头尾资产任何改动都要同步两包 + 两处安装位置:先在「易海排版技能包」改,
> 再 cp 覆盖本包兜底副本,并同步工作区镜像 + 安装目录。

4.3 预览页的两个坑(实测)

现象 原因 解法
预览页里品牌头/尾的 GIF 是空白 品牌头尾的 &lt;img&gt; 是微信懒加载写法,只有 data-src 没有 src,file:// 下不会触发加载 生成预览时把 data-src 同步补一份 src
内联后 GIF 仍 broken base64 内联时 MIME 写死成 image/png,GIF 解码失败 MIME 按扩展名判(.gif→image/gif、.jpg→image/jpeg)
远程图全部空白 外链在 file:// / 预览面板下不加载 预览用的图先下载到本地再 base64 内联,做成自包含单文件

> 自包含预览页 ≈ wrap_preview.py + 「本地图 base64 内联」+ 「data-src 补 src」。
> 生成后用 Playwright 断言 loaded == total &amp;&amp; broken == 0 才算过。
>
> ⚠️ 资产自检:预览页外壳依赖本包 assets/preview-template.html。
> 该文件曾在同步中丢失导致 FileNotFoundError。跑之前先确认存在;
> 缺失时从任意 xxx_预览.html 反推重建:取第一个 &lt;section 之前为前缀、
> 最后一个 &lt;/section&gt; 之后为后缀,&lt;title&gt; 换成 {{TITLE}} · 公众号排版预览,
> 正文位置换成 &lt;!--GZH_CONTENT--&gt;。
>
> 另:wrap_preview.py 只在纯正文片段上工作,产出页含 &lt;script&gt;,
> 不要拿预览页去跑 validate_gzh_html.py(会误报)。校验一律对 _预览.html 之外的原文件跑。
> 排版包内也有一份同样职责的 wrap_preview.py,两处模板各存一份,互不依赖。


§5 封面生成

5.0 ★ 规格与铁律

项 要求
规格 900 × 500 px,命名 01_cover_xxx.png、02_cover_xxx.png …
主标题字号 建议 84–112px(真人/实景风可适当小,文字别压住人脸)
副标题字号 30–38px
文字对比度 白字必须压在暗部或加蒙版,禁止浅底浅字
文字安全区 四边留 ≥ 40px,不贴边
主体避让 人脸/关键信息不要被文字压住
通用实现 Pillow 中若闭包绑定了外层 draw,img.copy() 后文字会画到副本外面(丢失且不报错)→ 每张图内部必须重新 ImageDraw.Draw(canvas)
字体 中文用系统黑体(Windows C:/Windows/Fonts/msyhbd.ttc 微软雅黑粗体)
量宽 文字必须先量宽再居中(draw.textlength),不要凭字数估算
导出 统一 resize((900, 500)),避免不同底图尺寸不一致
⛔ 文字 绝对不要把文字交给图像生成模型写(会写错字/乱码),标题文字一律由 Pillow 后压
底图 默认自己生成(①②③⑤);只有用户主动给图时才用用户的。不要向用户索要素材,也不要用无关网图凑数

5.1 生成底图的注意事项

项 要求
生成尺寸 用横版比例生成(如 1536x1024),再裁切缩放
画面预留 prompt 里明确要求"画面左侧/下部留出大面积纯色或暗部空间用于压字",避免文字压主体
真人肖像 生成公众人物肖像时,优先用"剪影/背影/侧脸/虚化"等不依赖面部还原的构图,或明确按"形象示意图"处理,避免肖像权与还原度争议;用户提供真实照片时不受此限
成本告知 图像生成会消耗额外额度(单张约 5–10 credits),调用前先告知用户
文字 不要让模型在图里写字,标题一律 Pillow 后压

5.2 模板 A · ② 大字报 / ④ 品牌渐变(make_covers_tiangong.py)

# 批量(生成脚本内 SUBTITLES 列表里的三张)
$PY &quot;$SK/scripts/make_covers_tiangong.py&quot; --out &lt;输出目录&gt;

# 只生成单张(非天工词元题材必须换 --main 与 --prefix)
$PY &quot;$SK/scripts/make_covers_tiangong.py&quot; \
    --tag 01 --main &quot;文章主标题&quot; --prefix &lt;题材标识&gt; --subtitle &quot;本篇主旨&quot; --out &lt;输出目录&gt;
参数 说明
--ref 采样渐变的参考图,默认 assets/封面参考图/ref_cover_guide.jpg
--out 输出目录
--tag + --subtitle 只出单张时用(--tag 是文件名前缀,如 05)
--main 主标题,默认「天工词元」;非天工词元题材必须换
--prefix 输出文件名前缀,默认 tiangong → 01_cover_tiangong.png
  • 背景:从参考图采样对角渐变(左上深蓝 → 右下亮蓝),右下角加柔光
  • 主标题 112px 白色加粗居中;副标题 34px 白色居中
  • 只支持两行结构(主标题 + 副标题),没有第三行标签;需要三行请用模板 D

5.3 模板 B · ③ 实景/样机风(make_cover_jihaoxing.py)

# 底图来源二选一:
#   a) 自己生成场景图 → 先用图像生成工具出图,再用 --ref 传入
#   b) 用户主动给了实拍图 → 直接用用户的图
$PY &quot;$SK/scripts/make_cover_jihaoxing.py&quot; --ref &lt;场景图或手机样机图&gt; --out &lt;输出目录&gt;
  • 深蓝横向渐变打底 + 对角光带 + 星点;右侧样机/实拍主体高铺满、左缘 alpha 渐变融合
  • 主体图叠一层半透明色块压字,保证白字对比度
  • 底图默认自己生成:用图像生成工具按文章题材出场景图(如"建筑工地塔吊黄昏""手机办公场景"),
    存入本地后 --ref 传入;用户主动提供了实拍图则优先用用户的图
  • 必须显式传 --ref:脚本不内置样机图,找不到会直接退出(有意设计,避免误用旧图)
  • 适用:单品推介、项目纪实、案例复盘

5.4 模板 C · ① 真人风(make_cover_huangrenxun.py)

# 底图来源二选一:
#   a) 自己生成人物图 → 先用图像生成工具出图,再用 --photo 传入
#   b) 用户主动给了人物照片 → 直接用用户的照片
$PY &quot;$SK/scripts/make_cover_huangrenxun.py&quot; \
    --photo &lt;人物图&gt; --main &quot;主标题&quot; --sub &quot;副标题&quot; --tag &quot;标签行&quot; --out &lt;输出目录/文件名.png&gt;
参数 说明
--photo 人物照片路径;不传则用蓝渐变底(无人物,退化成渐变款)
--main / --sub / --tag 主标题 / 副标题 / 标签行
--out 输出路径(可含文件名,如 &lt;目录&gt;/真人.png)
  • 底图默认自己生成(人物半身/特写、构图留白、压暗处理),脚本再做裁切 → 渐变蒙版 → 左下角压白色大字标题
  • 用户主动提供照片时,用图生图保特征处理(不重画成另一个人)
  • 裁切规则:人物居中/偏右,文字区留在画面下部或左侧留白处,禁止文字压脸
  • 如底图背景杂乱:先整体加一层 rgba(0,0,0,0.35) 蒙版再压字,不要直接白字压亮背景
  • 适用:名人稿、人物故事、创始人叙事、访谈

5.5 模板 D · ⑤ 真实照片满铺(make_cover_photo.py)

用户明确说「封面改成实际的方形/照片,更有吸引力」时,用这一套——不要再做
「左侧补纸面 + 右侧羽化贴图」那种拼贴,那会出来合成海报感,不是"实际照片"。

$PY &quot;$SK/scripts/make_cover_photo.py&quot; \
    --src &lt;底图&gt; \
    --main1 &quot;主标题第1行&quot; --main2 &quot;主标题第2行&quot; \
    --sub &quot;副标题&quot; --tag1 &quot;标签行①&quot; --tag2 &quot;标签行②&quot; \
    --out-dir &lt;输出目录&gt;
参数 说明
--src 底图路径,默认 assets/封面参考图/ref_photo_default.png(内置示例)
--main1 / --main2 主标题两行(单行标题把 --main2 传空串)
--sub 副标题
--tag1 标签行①(方形版与微信首图共用)
--tag2 标签行②(仅横版用)
--out-dir 输出目录(不传会写进脚本目录,务必传)
--cy-wx / --cy-sq / --cy-wd 各尺寸裁切中心 y(0~1),决定取哪一带

一次出三张:

输出 规格 用途
01_cover_square_900.png 900×900 方形 分享卡/Feed,字必须落居中安全区 y 258~641
01_cover_wechat_900x383.png 2.35:1 微信首图 ★ 上传这张最稳,微信不裁
01_cover_wide_900x500.png 900×500 横版 备用,字落 2.35:1 可见区 y 58~441
_preview_square_wechat_cut.png 方形按 2.35:1 居中裁切模拟 自检用,看方形被裁后文字是否还在

★★ 血泪教训:微信封面实际展示比例是 2.35:1,方形会被居中裁切

症状:上传 900×900 方形封面,线上预览/首图里副标与标签整个消失、主标被切一半。
根因:微信订阅号封面展示位是 2.35:1(900×383),上传非该比例的图会居中裁切。
结论与做法:
1. 优先上传 900×383(01_cover_wechat_900x383.png)——比例原生,微信不动刀
2. 若必须给方形(分享卡),方形内所有文字压在中段 y 258~641,这样被裁也完整
3. 原图比例不足 2.35:1 时只能裁上下,--cy-wx 决定取哪一带:先扫行剖面
(std 越大细节越足、亮% 越低越不透白)再定,别默认居中

★ 遮罩必调参数:bottom_scrim(canvas, top_y, alpha_max, gamma, floor)
- 遮罩偏浅会导致白字对比度不足。自检标准:压字区亮度 mean < 120、亮像素(>170) 占比 < 15%
- 首次用 top=28%, alpha=0.90 出图,压字区亮度 138.7 → 白字发灰
- 改 top=16%, alpha=0.95, floor=0.58, gamma=0.70 → 亮度降到 61.0,白字才立住

自检(脚本自带输出):每条文字量宽 vs 可用宽度(可用 = 图宽 - 104)、压字区亮度/亮像素占比、
以及方形版按 2.35:1 裁切模拟后的"文字占用 y 范围是否落在安全区"。三项都过才导出。


§6 推送草稿箱

6.1 推送代码模板(复制即用)

import sys, os
sys.path.insert(0, &quot;&lt;SK&gt;/scripts&quot;)
import wechat_publisher
from wechat_publisher import WeChatPublisher

APPID = os.environ[&quot;WECHAT_APPID&quot;]        # 凭据走环境变量,不写明文
APPSECRET = os.environ[&quot;WECHAT_SECRET&quot;]

wp = WeChatPublisher(APPID, APPSECRET)
wp.get_token()

# ⚠️ 关键:每次 create_draft 前必须清封面缓存,否则多篇全用第一张封面
if wechat_publisher.THUMB_FILE.exists():
    wechat_publisher.THUMB_FILE.unlink()

html = open(&quot;&lt;套好头尾的正文.html&gt;&quot;, encoding=&quot;utf-8&quot;).read()   # 从文件读,不要拼字符串

media_id = wp.create_draft(
    title=&quot;文章标题(≤64 字)&quot;,
    content=html,                      # 纯 &lt;section&gt; 片段
    digest=&quot;摘要,50-60 字&quot;,
    author=&quot;易海工程AI&quot;,                # 必须显式传
    thumb_path=&quot;&lt;封面.png&gt;&quot;,            # 900×500 或 900×383
)
print(media_id)

6.2 create_draft 参数说明

参数 类型 默认值 说明
title str 必填 ≤ 64 字,超出报 45003
content str 必填 纯 &lt;section&gt; 片段
author str 老李读书笔记 必须覆盖为 易海工程AI
digest str &quot;&quot; 建议 50–60 字
thumb_path str None 封面路径;不传则自动生成纯色图
source_url str &quot;&quot; 原文链接,一般留空
show_cover int 1 封面是否显示在正文前
need_open_comment int 1 开启留言(账号要求,不要覆盖为 0)
only_fans_can_comment int 0 0=所有人可评论

6.3 推送前 checklist(逐项确认)

□ 封面风格已询问并选定(①真人/②大字报/③实景/④品牌渐变/⑤真实照片满铺)
□ 链路自检 5 步全 [通过]
□ **上游成品已验收**(§3.1):&lt;section&gt; diff=0 | 头尾齐全 | 署名三人名正确 | 三链接在
□ 签名「我是工程AI团队,AI建筑领域的创业者。」grep -c == 1
□ validate_gzh_html.py:ERROR=0 且半角标点 WARNING=0
□ _chk.py:边界 L=20 / R=370
□ 封面已生成,且风格与用户选定一致
□ 已删除 scripts/.wechat_cache/thumb_media_id.txt
□ author=&quot;易海工程AI&quot;、need_open_comment=1
□ 文章用词已核对:正文无官网明文链接(用户要求双路径时除外)、无假按钮、无「点击进入天工先问」图

6.4 推送后必须验证

items = wp.list_drafts(0, 20) + wp.list_drafts(20, 20)   # 分页!

> 返回结构:每个元素是 {media_id, content:{news_item:[{title, author, digest, thumb_media_id}]}}。
> 标题/作者/封面要从 news_item[0] 里取,不要在 content 层找(取不到会误报"未找到")。

> ⚠️ 编码坑(核对线上正文时必踩):draft/get 返回的 content / title 中文是
> latin-1 包装的 UTF-8,直接拿中文字符串做 in 判断会全部假阴性,
> 误判成"线上内容没改"。核对前先还原:
>
> python &gt; def fix(s): &gt; try: &gt; return s.encode(&quot;latin-1&quot;).decode(&quot;utf-8&quot;) &gt; except Exception: &gt; return s &gt;
>
> draft/batchget(list_drafts)返回的标题不受影响,只有 draft/get 需要还原。

> ⚠️ list_drafts 单页上限 20 条。只调 list_drafts(0,20) 会误判总数,统计必须分页累加。

核对三件事:标题正确 / 作者是易海工程AI / 封面是本篇封面。

★ draft/get 报 40007 不等于推送失败(2026-10-17 踩到)

事后回查草稿箱时,若拿旧 media_id 调 draft/get 返回
40007 invalid media_id,不要直接判定"草稿没推上去/推丢了"。先做两步取证:

# 1) 全量分页列草稿,看总数与最新条目
items, off = [], 0
while True:
    b = wp.list_drafts(off, 20)
    if not b: break
    items += b; off += 20
print(len(items))
rows = sorted(((it.get(&quot;update_time&quot;) or 0,
                ((it.get(&quot;content&quot;) or {}).get(&quot;news_item&quot;) or [{}])[0].get(&quot;title&quot;, &quot;&quot;),
                it.get(&quot;media_id&quot;)) for it in items), reverse=True)
for r in rows[:8]: print(r)

# 2) 按标题判断该篇是否还在草稿箱
#    不在 → 大概率已被用户手动发布(订阅号 freepublish 接口未授权,48001,查不到已发布列表)

判定规则:草稿箱里找不到该标题 → 该篇已不在草稿箱(通常为用户已发布),
不是推送失败;此时应如实告知用户「草稿已不在草稿箱,疑为已发布,请在后台确认」,
不要再盲推一次(会重复进草稿箱)。

> 另:freepublish/batchget 对未开通发布能力的订阅号返回 48001 api unauthorized,
> 不要依赖它判断是否已发布;用工作日志里的 media_id + 草稿箱分页列表做交叉核对即可。

★ 封面必须额外验证「是否被微信裁切」(2026-10-17 事故后必做)

只看「封面是不是本篇那张」不够——微信会把非 2.35:1 的封面居中裁切,
上线后发现图对但文字被裁掉了。所以还要做尺寸 + 剖面比对:

import io, json, re, requests
import numpy as np
from PIL import Image

r = requests.post(f&quot;https://api.weixin.qq.com/cgi-bin/draft/get?access_token={tok}&quot;,
                  data=json.dumps({&quot;media_id&quot;: MID}).encode(),
                  headers={&quot;Content-Type&quot;: &quot;application/json&quot;})
ni = json.loads(r.content.decode(&quot;latin-1&quot;).encode(&quot;latin-1&quot;).decode(&quot;utf-8&quot;))[&quot;news_item&quot;][0]
url = ni[&quot;thumb_url&quot;]                       # 下载线上封面
# (用 curl -L 落盘为 _online_thumb.jpg)

o = Image.open(&quot;_online_thumb.jpg&quot;).convert(&quot;L&quot;).resize((900, 383))
l = Image.open(&quot;01_cover_wechat_900x383.png&quot;).convert(&quot;L&quot;)
r_ = np.corrcoef(o.mean(axis=1), l.mean(axis=1))[0, 1]
print(&quot;线上尺寸 =&quot;, Image.open(&quot;_online_thumb.jpg&quot;).size, &quot;| 行剖面 r =&quot;, round(r_, 4))
# 判定:尺寸 ≈ 上传尺寸 且 r &gt; 0.99 → 未被裁切,封面可用
#      r 明显偏低 → 微信裁切了,改用 900x383 版重推

> 判定标准:线上尺寸 ≈ 上传尺寸 且行剖面 r > 0.99 → 封面完整。
> r 偏低说明被裁,换 01_cover_wechat_900x383.png 重推。

6.5 正文配图上传

url = wp.upload_image(&quot;&lt;本地图片.png&gt;&quot;)   # 返回 url 写进 &lt;img data-src=&quot;...&quot;&gt;

> ⚠️ 外链图(mmbiz.qpic.cn 等)微信不显示。正文里要放图,必须先把本地图
> upload_image 换到素材库、拿到 URL 再替换 data-src,否则线上是空白。
> media/uploadimg 返回的是图文内图床 URL(可直接嵌 &lt;img&gt;),与封面用的
> media/upload(拿 thumb_media_id)不是同一个接口,别混。

批量换图的标准做法(可断点续传,重推不必重传):

# 1) 扫正文里所有本地图 data-src → 去重
# 2) 逐张 wp.upload_image(),把 {本地相对路径: 微信URL} 落盘到 img_url_map.json
# 3) 用映射一次性替换 data-src 与 src;替换后断言 本地图残留 == 0

> 映射文件落盘是关键:中途失败可续跑;重推时自动跳过已上传的(微信图床 URL 长期有效)。
> 推完必须核对:线上图片数 == 本地图片数,且线上 data-src 全部是 mmbiz.qpic.cn。
> 现成脚本:scripts/upload_images_batch.py + scripts/verify_draft_images.py。

正文配图写法(保持统一极简不破版):

&lt;section style=&quot;margin:0 0 8px 0;text-align:center;&quot;&gt;
  &lt;img src=&quot;…&quot; data-src=&quot;…&quot; data-type=&quot;png&quot; data-w=&quot;1080&quot; data-ratio=&quot;0.7&quot;
       style=&quot;width:100%;height:auto;display:block;&quot; type=&quot;block&quot; /&gt;
&lt;/section&gt;
&lt;p style=&quot;…;font-size:15px;…;text-align:center;&quot;&gt;&lt;span leaf=&quot;&quot;&gt;图注&lt;/span&gt;&lt;/p&gt;

> 图片独立 section、宽 100%,与正文共用同一条左右边界;图注 15px #55606B;
> 不新增任何色块。套完头尾用 _chk.py 复核 IMG 也在 L=20/R=370。

6.6 替换已有草稿(严格流程)

1. list_drafts 分页找到目标 → 记录 media_id(并核对标题确为目标)
2. delete_draft(该 media_id)      ← 只删这一个
3. 推送新版
4. list_drafts 重新验证

铁律:只删除明确指定的 media_id,绝不批量删、绝不按标题模糊删。
草稿箱历史草稿很多,删了无法恢复。不碰任何不是本次创建的草稿。


§7 三条铁律

  1. 只推草稿箱,不发布。 点「发布」永远由人工在后台完成。
  2. 删除操作只针对明确指定的 media_id,绝不批量删、绝不按标题模糊删。
  3. 不碰任何不是本次创建的草稿;草稿箱历史草稿很多,删了无法恢复。

> 账号边界:本工作区只服务「易海工程AI」。不得改动其他矩阵号(「篮球后视镜」「动一下」
> 「今日天气真的好」等)的任何草稿。遇冲突先取证核对,无改动则沿用原状继续推进。


§8 错误码速查与缓存

错误码 含义 处置
40125 AppSecret 无效或被重置 检查多余字符/换行;确认没被重置
40164 服务器 IP 不在白名单 报错信息中会给出当前 IP → 引导用户加入白名单(§2.1)
40013 AppID 错误 核对 AppID
45003 标题超过 64 字 缩短标题(超 64 字会报这个)
40007 invalid media_id ≠ 推送失败,见 §6.4
48001 api unauthorized freepublish/batchget 对未开通发布能力的订阅号会返回,不要依赖它
45004 / 45009 接口调用限额 等待后重试,避免高频调用
封面串号 多篇共用同一张封面 每次推送前删 .wechat_cache/thumb_media_id.txt

缓存目录:scripts/.wechat_cache/(跟随脚本所在目录)。
token.json 更换公众号/重置凭据后删;thumb_media_id.txt 每篇推送前都删。

> 🔐 token.json 里只存 appid 指纹(appid_fp = sha256 前 16 位)和 access_token,不存 appid 明文——
> 保证「三包内无明文凭据」的扫描能过。appid 指纹不匹配即视为无缓存,会重新取 token。


§9 收尾:向用户汇报的格式

✅ 已推送到草稿箱(未发布,请在后台确认后手动发布)

- 标题:&lt;标题&gt;
- 封面风格:&lt;①真人 / ②大字报 / ③实景 / ④品牌渐变 / ⑤真实照片满铺&gt;
- 上游成品:头尾已由排版包套好 ✅(署名:编辑 |x / 校对 |x / 审核丨x,已验收)
- 封面:&lt;封面文件名&gt;(已用行剖面 r=… 验证未被裁切)
- media_id:&lt;media_id&gt;
- 草稿箱当前总条数:&lt;分页统计结果&gt;
- 预览页:&lt;xxx_预览.html 路径&gt;

请在公众号后台 → 草稿箱 中预览并发布。

附录 · 执行总流程(速查)

上游:「易海排版技能包」产出成品 HTML(正文 + 品牌头尾 + 署名 + 三链接,diff=0)
      ↓
§0 问用户封面风格(①真人/②大字报/③实景/④品牌渐变/⑤真实照片满铺)——必须问,不许默认
      ↓
§2 链路自检 5 步全 [通过]($SK/scripts/test_draft_flow.py)
      ↓  失败 → §2.1 IP 白名单 / §8 错误码
§3 验收上游成品(§3.1 三条 grep)——不合格退回排版包,本包不代套头尾
      ↓
§4 validate_gzh_html.py(ERROR=0、半角 WARNING=0)+ _chk.py(L=20/R=370)+ 生成预览页
      ↓
§5 按用户选定的封面风格生成封面
      ↓  ①②③⑤ 底图自己生成(用图像生成工具,先告知额度消耗);用户主动给了图才用用户的
      ↓  上传微信首图优先用 900×383(微信不裁)
§6 清 thumb 缓存 → create_draft(author=易海工程AI、need_open_comment=1)
      ↓  分页验证标题/作者/封面 + 行剖面验证封面未被裁
§9 向用户汇报,提示去后台手动发布

常见问题

5 问
答案由本站依据条目字段整理
公众号封面生成与草稿推送怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_a40be762/yhpush。安装方式为未标注。装完刷新技能列表或重开客户端。

公众号封面生成与草稿推送支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

公众号封面生成与草稿推送权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

公众号封面生成与草稿推送收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

公众号封面生成与草稿推送用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 2026-11-06。