微信公众号文章创作与发布
语言
匹配用户语言:使用用户所用的语言进行回应。用户用中文则用中文回应,用英文则用英文回应。
目录结构
wechat-article-maker/
├── scripts/ # TypeScript 源文件
│ ├── wechat-api.ts # API 发布逻辑
│ ├── wechat-article.ts # 浏览器发布逻辑
│ ├── wechat-browser.ts # 图文发布逻辑
│ ├── image-utils.ts # 图片处理工具(sharp 集成)
│ ├── generate-cover.ts # 封面生成逻辑
│ ├── md-to-wechat.ts # Markdown 转换逻辑
│ ├── ensure-deps.ts # 依赖自动安装
│ └── md/ # Markdown 渲染引擎
│ ├── render.ts
│ ├── themes/ # 主题样式
│ └── extensions/ # 扩展插件
├── references/ # 参考文档
├── SKILL.md # 技能文档
└── README.md # 项目说明
Agent 执行:确定此 SKILL.md 目录为 SKILL_DIR,所有命令通过 npx -y bun 运行:
运行方式
# 设置技能目录
SKILL_DIR="${SKILL_DIR}"
# 所有脚本通过 npx -y bun 运行(跨平台统一)
npx -y bun "${SKILL_DIR}/scripts/wechat-api.ts" article.md --inline-css
npx -y bun "${SKILL_DIR}/scripts/md-to-wechat.ts" article.md --theme grace
npx -y bun "${SKILL_DIR}/scripts/generate-cover.ts" --title "标题" --output cover.jpg
依赖自动安装:脚本首次运行时会自动检测并安装所需依赖,无需手动操作。
依赖安装
自动安装:所有依赖会在脚本首次运行时自动安装,无需手动操作。
运行时要求:
- ✅ Bun(推荐,通过
npx -y bun使用)
依赖说明(自动安装):
front-matter- Frontmatter 解析highlight.js- 代码高亮marked- Markdown 渲染引擎reading-time- 阅读时间计算juice- CSS 内联转换@napi-rs/canvas- 高性能图片生成(可选,用于封面)sharp- 图片处理库(内置,用于图片清理和封面生成)
依赖说明:
sharp会在首次运行时通过scripts/ensure-deps.ts自动安装- 如果可选依赖未安装,
generate-cover会自动生成 SVG 格式的封面图(微信也支持)
功能概述
本技能提供完整的微信公众号文章工作流:
- 内容创作模式:输入文本内容,智能理解、生成文章
- 链接发布模式:输入文章链接,下载、处理并发布
- Markdown 转换:内置 Markdown 到 HTML 转换,支持多主题
- 图片处理:自动下载、清洗元数据、符合微信规范
- 样式转换:自动将 CSS 转为内联样式
- 一键发布:支持 API(快速)和浏览器(可视化)两种方式
偏好设置(EXTEND.md)
使用 Bash 检查 EXTEND.md 存在性(优先级顺序):
# 检查项目级别
test -f .awesome-skills/wechat-article-maker/EXTEND.md && echo "project"
# 检查用户级别(跨平台:$HOME 在 macOS/Linux/WSL 上都可用)
test -f "$HOME/.awesome-skills/wechat-article-maker/EXTEND.md" && echo "user"
┌────────────────────────────────────────────────────────────┬───────────────────┐ │ 路径 │ 位置 │ ├────────────────────────────────────────────────────────────┼───────────────────┤ │ .awesome-skills/wechat-article-maker/EXTEND.md │ 项目目录 │ ├────────────────────────────────────────────────────────────┼───────────────────┤ │ $HOME/.awesome-skills/wechat-article-maker/EXTEND.md │ 用户主目录 │ └────────────────────────────────────────────────────────────┴───────────────────┘
┌───────────┬───────────────────────────────────────────────────────────────────────────┐ │ 结果 │ 操作 │ ├───────────┼───────────────────────────────────────────────────────────────────────────┤ │ 找到 │ 读取、解析、应用设置 │ ├───────────┼───────────────────────────────────────────────────────────────────────────┤ │ 未找到 │ 使用默认值 │ └───────────┴───────────────────────────────────────────────────────────────────────────┘
EXTEND.md 支持:默认主题 | 默认发布方法(api/browser)| 默认作者 | Chrome 配置文件路径
工作流程选择
根据用户输入自动选择工作流程:
| 输入类型 | 识别方式 | 工作流程 |
|---|---|---|
| 纯文本内容 | 不包含链接 | 内容创作流程 |
| 文本 + 参考链接 | 包含链接,但主体是文本描述 | 内容创作流程(含链接分析) |
| 单个文章链接 | 仅包含 URL,或明确说"发布这篇文章" | 链接发布流程 |
| Markdown 文件路径 | 以 .md 结尾的文件路径 | Markdown 转换发布流程 |
| HTML 文件路径 | 以 .html 结尾的文件路径 | 直接发布流程 |
流程 1: 内容创作与发布
当用户输入文本内容(可选包含参考链接)时使用此流程。
创作进度清单
复制此清单并在完成时勾选:
内容创作进度:
- [ ] 步骤 0: 加载偏好设置
- [ ] 步骤 1: 内容分析与链接提取
- [ ] 步骤 2: 链接内容获取与理解
- [ ] 步骤 3: 询问创作偏好
- [ ] 步骤 4: 生成 Markdown 文章
- [ ] 步骤 5: 用户确认与优化
- [ ] 步骤 6: 转换为 HTML
- [ ] 步骤 7: 准备封面图
- [ ] 步骤 8: 发布到微信
- [ ] 步骤 9: 完成报告
步骤 0: 加载偏好设置
检查并加载 EXTEND.md 设置(见上方偏好设置部分)。
步骤 1: 内容分析与链接提取
分析用户输入:
- 提取所有链接:
# 提取 HTTP/HTTPS 链接
echo "$user_input" | grep -oE 'https?://[^\s]+' > /tmp/links.txt
- 判断内容类型:
- 如果仅有单个链接且无其他文本 → 转到流程 2: 链接发布流程
- 如果有文本内容(可选链接)→ 继续内容创作流程
步骤 2: 链接内容获取与理解
如果内容中包含参考链接:
- 获取每个链接的内容:
// 使用 WebFetch 获取并分析
for (const url of links) {
const content = await WebFetch(url, `
请提取并总结以下信息:
1. 文章标题
2. 作者(如有)
3. 核心观点(3-5个要点)
4. 关键数据或案例
5. 可引用的金句
以结构化格式返回,便于后续引用。
`);
}
- 整理参考资料:
- 为每个链接创建摘要卡片
- 标注关键引用点
- 记录可用图片或数据
步骤 3: 询问创作偏好
使用 AskUserQuestion 询问用户偏好:
文章创作配置
问题1:文章风格
header: "风格"
选项:
- 专业分析 - 深度解读,适合技术或行业分析(推荐)
- 轻松科普 - 通俗易懂,适合大众读者
- 教程指南 - 步骤清晰,适合实操性内容
- 观点评论 - 表达看法,适合热点评论
问题2:文章长度
header: "长度"
选项:
- 短文(800-1200字)- 快速阅读
- 中等(1500-2500字)- 平衡深度与可读性(推荐)
- 长文(3000字+)- 深度长文
问题3:参考资料处理(如有链接)
header: "引用方式"
选项:
- 深度引用和分析 - 详细解读原文观点(推荐)
- 简要提及和链接 - 点到为止
- 仅作背景参考 - 不明确引用
步骤 4: 生成 Markdown 文章
基于用户输入、参考资料和偏好生成文章:
- 标题生成要求:
文章标题必须包含以下 5 个特点中的至少 3 个:
| 特点 | 说明 | 示例 |
|---|---|---|
| 痛点明确 | 直击目标读者的具体困扰 | 《还在手动改代码?这个工具让你开发效率提升 300%》 |
| 数字吸引 | 用具体数字增加可信度 | 《我花了 3 个月,整理了 1000 个 Python 技巧》 |
| 结果导向 | 承诺可量化的收益或改变 | 《学会这招,你的代码审查通过率提升 90%》 |
| 情绪调动 | 激发好奇心、紧迫感或共鸣 | 《千万别再这样写代码了!后果很严重》 |
| 悬念设置 | 制造悬念引发点击欲望 | 《99% 的程序员都不知道的调试技巧》 |
标题公式参考:
- 痛点 + 数字 + 结果:《花了 100 小时排错?这 3 个技巧让你秒定位 Bug》
- 数字 + 悬念:《7 个隐秘的 VS Code 功能,第 5 个太绝了》
- 情绪 + 痛点:《别再犯这个低级错误!新手程序员最常踩的 5 个坑》
- 排版规范:
段落结构:
- 每段控制在 3-5 行,避免大段文字
- 重要数据单独成段并加粗
- 关键结论前置,细节后置
配图位置:
- 标题下方放置封面图
- 每个步骤/章节后放置效果示意图
- 结尾放置总结图或行动号召图
代码块:
- 代码块前后留白(空行分隔)
- 必须使用语法高亮标注语言类型
- 关键行添加注释说明
金句设计:
- 核心观点单独成段
- 使用加粗或引用格式突出
- 控制在 20 字以内,便于记忆和传播
- 文章结构:
---
title: 文章标题(遵循 5 大标题原则)
author: 作者名(从 EXTEND.md 或默认值)
summary: 文章摘要(120字以内,突出核心价值)
featureImage: 封面图路径(可选)
date: YYYY-MM-DD
---
# 文章标题(痛点明确 + 数字吸引 + 结果导向)

引言段落,2-3行即可,
直接点明读者能获得什么价值。
## 第一部分:核心问题
(3-5行,聚焦痛点)
**关键数据单独成段加粗**
配合说明文字,3-4行即可。

## 第二部分:解决方案
分段讲解,每段 3-5 行。
```python
# 代码块前后留白
# 标注语言类型实现语法高亮
def solution():
return "success"
金句:核心观点单独成段,增强记忆点

第三部分:实战案例
具体步骤 + 效果图, 让读者有代入感。
总结
简洁有力的结论,2-3 行。

参考资料:
2. **保存文件**:
```bash
# 生成 slug(文件名)
title="文章标题"
slug=$(echo "$title" | \
iconv -t ascii//TRANSLIT 2>/dev/null | \
tr '[:upper:]' '[:lower:]' | \
tr ' ' '-' | \
tr -cd '[:alnum:]-' | \
cut -c1-50)
# 创建目录并保存
output_dir="wechat-articles/$(date +%Y-%m-%d)"
mkdir -p "$output_dir"
echo "$article_content" > "$output_dir/$slug.md"
- 展示给用户:
✓ 文章已生成
📄 标题:$title
📏 长度:约 $word_count 字
📁 保存位置:$output_dir/$slug.md
[文章预览内容...]
请选择下一步操作...
步骤 5: 用户确认与优化
使用 AskUserQuestion 询问:
文章已生成,请选择操作
header: "下一步"
选项:
- 直接发布 - 转换为 HTML 并发布到微信(推荐)
- 修改内容 - 说明需要调整的部分
- 重新生成 - 使用不同风格或角度
- 仅保存文件 - 不发布,稍后手动处理
如果用户选择修改:
- 收集修改意见
- 更新文章内容
- 重新保存并展示
- 再次询问下一步
如果用户选择重新生成:
- 返回步骤 3,重新询问偏好
- 使用不同的创作角度
步骤 6: 转换为 HTML
使用内置的 Markdown 渲染引擎转换:
- 询问主题(如未在 EXTEND.md 中指定):
| 主题 | 描述 |
|---|---|
default | 经典主题 - 传统排版,标题居中带底边,二级标题白字彩底 |
grace | 优雅主题 - 文字阴影,圆角卡片,精致引用块(推荐) |
simple | 简洁主题 - 现代极简风,不对称圆角,清爽留白 |
- 执行转换:
npx -y bun "${SKILL_DIR}/scripts/md-to-wechat.ts" \
"$output_dir/$slug.md" \
--theme grace \
--output "$output_dir"
- 解析输出 JSON:
{
"title": "文章标题",
"author": "作者",
"summary": "摘要",
"htmlPath": "路径/to/article.html",
"contentImages": [
{
"placeholder": "WECHATIMGPH_1",
"localPath": "/path/to/image1.jpg",
"originalPath": "原始路径"
}
]
}
步骤 7: 准备封面图
封面图强制规则(优先级顺序):
- 显式指定:检查 Frontmatter 字段(
featureImage,coverImage,cover,image)。 - 自动首图回退:若未显式指定封面,且文章中包含图片,必须自动提取并使用文章中的第一张图片作为封面。
- 自动生成:只有在文章中完全没有图片时,才触发封面图生成逻辑。
如果没有指定且文章内无图片,询问用户:
封面图设置(文章中未发现图片)
header: "封面来源"
选项:
- 自动生成 - 基于文章标题生成渐变背景封面(推荐)
- 提供路径 - 指定本地文件或 URL
- 暂不设置 - 稍后手动添加
如果选择自动生成:
-
优先尝试多模态大模型生成(如果 Agent 支持):
- 如果当前 Agent 环境具备文生图能力(Text-to-Image),请根据文章标题和摘要生成一张高质量的封面图。
- 要求:2:1 比例(如 1024x512),风格现代、简洁,适合作为公众号封面。
- 保存为:
$output_dir/$slug-cover.jpg - 注意:如果 Agent 无法生成图片(例如无工具支持),则直接使用下方降级方案。
-
降级方案(使用脚本生成):
如果无法使用大模型生成图片,则运行以下命令生成渐变背景文字封面:
# 使用 Node.js 脚本生成(无系统依赖)
npx -y bun "${SKILL_DIR}/scripts/generate-cover.ts" \
--title "$title" \
--output "$output_dir/$slug-cover.jpg" \
--gradient-start "#667eea" \
--gradient-end "#764ba2"
封面要求:
- 格式:JPEG, PNG, GIF 或 WebP
- 推荐尺寸:900x500px(2:1 比例)
- 文件大小:< 2MB
步骤 8: 发布到微信
询问发布方式:
发布方式选择
header: "发布方法"
选项:
- API 方式 - 快速发布,需要 API 凭证(推荐)
- 浏览器方式 - 可视化操作,需要 Chrome
- 仅输出 HTML - 保存文件,稍后手动发布
选项 A: API 方式发布
- 检查 API 凭证:
# 检查项目级别
test -f .awesome-skills/.env && grep -q "WECHAT_APP_ID" .awesome-skills/.env && echo "project"
# 检查用户级别
test -f "$HOME/.awesome-skills/.env" && grep -q "WECHAT_APP_ID" "$HOME/.awesome-skills/.env" && echo "user"
- 如果凭证缺失,引导设置:
微信 API 凭证未找到
获取凭证步骤:
1. 访问 https://mp.weixin.qq.com
2. 进入:开发 → 基本配置
3. 复制 AppID 和 AppSecret
保存位置?
A) 项目级别:.awesome-skills/.env(仅此项目)
B) 用户级别:~/.awesome-skills/.env(所有项目)
创建 .env 文件:
WECHAT_APP_ID=<用户输入>
WECHAT_APP_SECRET=<用户输入>
- 执行发布:
npx -y bun "${SKILL_DIR}/scripts/wechat-api.ts" \
"$output_dir/$slug.html" \
--title "$title" \
--summary "$summary" \
--cover "$cover_image" \
--inline-css
重要:--inline-css 参数将 CSS 转为内联样式,微信公众号不支持 <style> 标签。
选项 B: 浏览器方式发布
npx -y bun "${SKILL_DIR}/scripts/wechat-article.ts" \
--html "$output_dir/$slug.html" \
--title "$title" \
--summary "$summary"
首次运行:会打开 Chrome 浏览器,需要扫码登录微信公众号。
选项 C: 仅输出 HTML
echo "✓ HTML 文件已保存至:$output_dir/$slug.html"
echo ""
echo "文件包含:"
echo "• 内联样式(符合微信规范)"
echo "• 完整的文章内容"
echo "• 本地图片路径"
步骤 9: 完成报告
发布成功后,显示摘要:
✓ 微信公众号文章创作与发布完成!
创作信息:
• 输入:用户文本内容
• 参考链接:$link_count 个
• 文章风格:$style
• 文章长度:$word_count 字
发布信息:
• 标题:$title
• 作者:$author
• 摘要:$summary
• 主题:$theme
• 图片:$image_count 张
• 封面:$cover_source
发布方式:API / 浏览器
结果:
✓ 草稿已保存到微信公众号
• media_id: $media_id
下一步:
→ 管理草稿:https://mp.weixin.qq.com(登录后进入「内容管理」→「草稿箱」)
生成的文件:
• $output_dir/$slug.md(Markdown 源文件)
• $output_dir/$slug.html(HTML 文件)
• $output_dir/$slug-cover.jpg(封面图)
流程 2: 链接文章发布
当用户输入单个文章链接时使用此流程。
发布进度清单
复制此清单并在完成时勾选:
链接发布进度:
- [ ] 步骤 0: 加载偏好设置
- [ ] 步骤 1: 链接验证
- [ ] 步骤 2: 文章下载与解析
- [ ] 步骤 3: 图片下载与清洗
- [ ] 步骤 4: 样式转换(CSS 内联)
- [ ] 步骤 5: 用户确认
- [ ] 步骤 6: 准备封面图
- [ ] 步骤 7: 执行发布
- [ ] 步骤 8: 完成报告
步骤 0: 加载偏好设置
检查并加载 EXTEND.md 设置。
步骤 1: 链接验证
验证链接可访问性:
# 检查链接状态
status_code=$(curl -sI -w "%{http_code}" -o /dev/null "$url")
if [ "$status_code" = "200" ]; then
echo "链接有效"
else
echo "链接无法访问,状态码: $status_code"
fi
步骤 2: 文章下载与解析
使用 WebFetch 获取文章内容:
const article = await WebFetch(url, `
请提取以下信息并以 JSON 格式返回:
{
"title": "文章标题",
"author": "作者(如果有)",
"summary": "文章摘要或简介(120字以内)",
"content": "HTML 格式的正文内容,保留原始样式和结构",
"images": ["图片URL数组"],
"featureImage": "封面图URL(如果有)",
"publishDate": "发布日期(如果有)"
}
注意:
- content 需要包含完整的 HTML 标签和样式
- images 包含文章中所有的图片URL
- 保留原文的段落、标题、列表等结构
`);
步骤 3: 图片下载与清洗
- 创建临时目录:
temp_dir="wechat-temp/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$temp_dir/images"
- 下载所有图片:
# 解析图片URL数组并下载
image_index=1
for img_url in "${images[@]}"; do
# 获取文件扩展名
ext="${img_url##*.}"
ext="${ext%%\?*}" # 移除URL参数
# 下载图片
output_file="$temp_dir/images/image_${image_index}.${ext}"
curl -L -o "$output_file" "$img_url" 2>/dev/null
image_index=$((image_index + 1))
done
- 图片元数据清洗:
脚本 wechat-api.ts 会自动执行以下清洗:
- 检测 JPEG 图片中的非标准元数据
- 清除 AIGC/Coze 标记(微信不支持)
- 保留有效的 EXIF 数据和图像内容
- 自动重试:如果上传失败(错误码 40113),强制清洗后重试
算法(参考 scripts/wechat-api.ts:105-180):
function cleanImageMetadata(buffer: Buffer): Buffer {
// 检查 JPEG 签名
if (buffer[0] !== 0xff || buffer[1] !== 0xd8) return buffer;
// 检测 AIGC 标记
const headerStr = buffer.slice(0, 2048).toString('binary');
const hasAigcMarker = headerStr.includes('AIGC{') || headerStr.includes('Coze');
if (!hasAigcMarker) return buffer;
// 跳过非标准 APP 段(0xeb, 0xec 等)
// 保留标准段(APP0-APP9, DQT, SOF 等)
// 返回清洗后的 buffer
}
步骤 4: 样式转换(CSS 内联)
关键步骤:微信公众号不支持 <style> 标签,必须将 CSS 转为内联样式。
- 保存原始 HTML:
echo "$html_content" > "$temp_dir/original.html"
- 执行 CSS 内联转换:
# 使用 wechat-api.ts 的内联转换功能
# 注意:这里先生成处理后的 HTML,不立即发布
npx -y bun "${SKILL_DIR}/scripts/wechat-api.ts" \
"$temp_dir/original.html" \
--inline-css \
--output "$temp_dir/processed.html" \
--dry-run
- 替换图片路径:
# 将远程图片URL替换为本地路径
for i in {1..${#images[@]}}; do
sed -i "s|${images[$i-1]}|$temp_dir/images/image_$i.jpg|g" "$temp_dir/processed.html"
done
步骤 5: 用户确认
展示处理结果并询问:
文章处理完成
📄 标题:$title
✍️ 作者:$author
📝 摘要:$summary
🌐 原文:$original_url
🖼️ 图片:共 $image_count 张(已下载并清洗元数据)
🎨 样式:已转换为内联样式(符合微信规范)
HTML 已保存至:$temp_dir/processed.html
请选择操作
使用 AskUserQuestion:
header: "发布选项"
选项:
- 直接发布(API)- 快速发布到草稿箱(推荐)
- 浏览器发布 - 打开浏览器可视化操作
- 仅输出 HTML - 保存文件,稍后手动处理
- 取消 - 不保存
步骤 6: 准备封面图
与流程 1 的步骤 7 相同,遵循封面图强制规则:
- 优先使用原文提取的
featureImage。 - 若无显式封面,自动使用下载图片中的第一张作为封面。
- 仅在原文完全没有图片时,才询问生成封面。
步骤 7: 执行发布
根据用户选择执行:
选项 A: 直接发布(API)
npx -y bun "${SKILL_DIR}/scripts/wechat-api.ts" \
"$temp_dir/processed.html" \
--title "$title" \
--summary "$summary" \
--cover "$cover_image" \
--inline-css
API 方式特性:
- ✓ 自动下载远程图片
- ✓ 自动清洗图片元数据(AIGC/Coze 标记)
- ✓ 如果上传失败(40113),强制清洗后重试
- ✓ 支持格式:JPEG, PNG, GIF, WebP
选项 B: 浏览器发布
npx -y bun "${SKILL_DIR}/scripts/wechat-article.ts" \
--html "$temp_dir/processed.html" \
--title "$title" \
--summary "$summary"
选项 C: 仅输出 HTML
# 复制到永久位置
output_path="wechat-articles/$(date +%Y-%m-%d)/$slug.html"
mkdir -p "$(dirname "$output_path")"
cp "$temp_dir/processed.html" "$output_path"
cp -r "$temp_dir/images" "$(dirname "$output_path")/"
echo "✓ HTML 已保存至:$output_path"
echo "✓ 图片已保存至:$(dirname "$output_path")/images/"
步骤 8: 完成报告
✓ 链接文章发布完成!
原文信息:
• 链接:$original_url
• 标题:$title
• 作者:$author
处理信息:
• 下载并转换 HTML
• 清洗 $image_count 张图片元数据
• 转换样式为内联格式
• 生成封面图:$cover_source
发布信息:
• 方式:API / 浏览器
• 主题:保留原样式
• 状态:✓ 草稿已保存
结果:
• media_id: $media_id
下一步:
→ 管理草稿:https://mp.weixin.qq.com(登录后进入「内容管理」→「草稿箱」)
生成的文件:
• $output_path(处理后的 HTML)
• $(dirname "$output_path")/images/(清洗后的图片)
流程 3: Markdown 文件发布
当用户提供 .md 文件路径时使用此流程。
快速发布
# 一键转换并发布
npx -y bun "${SKILL_DIR}/scripts/md-to-wechat.ts" \
"$markdown_file" \
--theme grace \
--output ./output
# 然后使用 API 发布
npx -y bun "${SKILL_DIR}/scripts/wechat-api.ts" \
"$html_output" \
--inline-css \
--cover "$cover_image"
步骤说明
- 解析 Markdown:提取 frontmatter(title, author, summary 等)
- 转换为 HTML:应用主题样式
- 处理图片:下载远程图片,替换为本地路径
- 发布:同流程 1 的步骤 8
流程 4: HTML 文件直接发布
当用户提供 .html 文件路径时使用此流程。
快速发布
# 直接发布(自动内联 CSS)
npx -y bun "${SKILL_DIR}/scripts/wechat-api.ts" \
"$html_file" \
--title "文章标题" \
--summary "摘要" \
--cover "$cover_image" \
--inline-css
注意:必须使用 --inline-css 参数,否则样式会丢失。
图文发布(图文消息)
用于发布短内容 + 多张图片(最多 9 张)。
使用方法
# 从 Markdown 文件发布
npx -y bun "${SKILL_DIR}/scripts/wechat-browser.ts" \
--markdown article.md \
--images ./images/
# 直接指定内容和图片
npx -y bun "${SKILL_DIR}/scripts/wechat-browser.ts" \
--title "标题" \
--content "内容" \
--image img1.png \
--image img2.png \
--submit
参数说明
| 参数 | 描述 |
|---|---|
--markdown <path> | Markdown 文件 |
--title <text> | 标题 |
--content <text> | 内容文字 |
--image <path> | 图片路径(可多次使用) |
--images <dir> | 图片目录 |
--submit | 自动提交 |
详见:references/image-text-posting.md
主题样式
内置三种主题(位于 scripts/md/themes/):
default - 经典主题
- 传统排版风格
- 标题居中,带底边装饰
- 二级标题:白字彩底
- 适合:正式文章、行业报告
grace - 优雅主题(推荐)
- 文字带柔和阴影
- 圆角卡片式引用块
- 精致的列表样式
- 适合:科普文章、个人博客
simple - 简洁主题
- 现代极简风格
- 不对称圆角设计
- 清爽留白
- 适合:教程、短文
自定义主题
- 在
scripts/md/themes/创建新的 CSS 文件 - 基于
base.css扩展样式 - 使用
--theme <name>参数应用
配置与环境
环境变量
从以下位置加载配置(优先级从高到低):
- 环境变量
<cwd>/.awesome-skills/.env~/.awesome-skills/.env
必需的环境变量(API 发布方式):
WECHAT_APP_ID=your_app_id
WECHAT_APP_SECRET=your_app_secret
可选的环境变量:
WECHAT_BROWSER_CHROME_PATH=/path/to/chrome # 自定义 Chrome 路径
EXTEND.md 配置示例
# wechat-article-maker 配置
## 默认设置
- 主题:grace
- 发布方式:api
- 作者:宝玉
- Chrome 配置文件:~/.chrome-wechat
## 自动操作
- 自动生成封面:true
- 自动清洗图片:true
- 自动内联样式:true
## 创作偏好
- 默认文章风格:专业分析
- 默认文章长度:中等(1500-2500字)
- 默认引用方式:深度引用和分析
技术细节
Markdown 渲染引擎
使用 markdown-it 及扩展(位于 scripts/md/):
- 基础渲染:
render.ts - 扩展插件:
alert.ts- GitHub 风格提示块footnotes.ts- 脚注支持katex.ts- 数学公式toc.ts- 目录生成infographic.ts- 信息图ruby.ts- 注音slider.ts- 滑块plantuml.ts- UML 图表
图片处理算法
元数据清洗(scripts/image-utils.ts):
内置 sharp 库提供可靠的图片处理能力:
- 智能检测:扫描图片前 2KB,检测 AIGC/Coze/Adobe 等非标准元数据标记
- 深度清理:使用 sharp 重新编码 JPEG,彻底移除所有元数据
- 自动降级:sharp 不可用时,使用手动解析作为后备方案
- 尺寸优化:自动调整超大图片(限制 1920x1080)以符合微信规范
// 图片处理流程
const result = await cleanImage(buffer, forceClean);
// 返回: { buffer, wasCleaned, method: "sharp"|"manual"|"none", originalSize, cleanedSize }
双引擎清理策略:
| 方法 | 优先级 | 说明 |
|---|---|---|
| Sharp 重新编码 | 首选 | 完全重新编码图片,100% 移除元数据 |
| 手动解析 | 后备 | 解析 JPEG 段结构,跳过非标准标记 |
自动重试逻辑:
try {
await uploadImage(imageBuffer);
} catch (error) {
if (error.code === 40113) {
// 强制使用 sharp 深度清理后重试
const cleanedBuffer = await cleanImage(imageBuffer, true);
await uploadImage(cleanedBuffer);
}
}
CSS 内联转换
使用 juice 或类似库将 CSS 规则转换为内联样式:
之前:
<style>
h1 { color: blue; font-size: 24px; }
</style>
<h1>标题</h1>
之后:
<h1 style="color: blue; font-size: 24px;">标题</h1>
为什么需要:微信公众号编辑器不支持 <style> 标签,只接受内联样式。
封面图生成
方式 1: 多模态大模型生成(推荐)
如果 Agent 具备文生图能力,优先根据文章内容生成定制化封面图。这能提供更具吸引力和相关性的视觉效果。
方式 2: 纯 Node.js(无系统依赖)
脚本:scripts/generate-cover.ts
npx -y bun "${SKILL_DIR}/scripts/generate-cover.ts" \
--title "文章标题" \
--output cover.jpg \
--gradient-start "#667eea" \
--gradient-end "#764ba2" \
--width 900 \
--height 500
特性:
- ✓ 无需 ImageMagick
- ✓ 支持多种图片库(@napi-rs/canvas、sharp、SVG)
- ✓ 自动换行长标题
- ✓ 可自定义颜色和尺寸
- ✓ 跨平台(Node.js/Bun)
方式 2: ImageMagick(如已安装)
convert -size 900x500 \
-define gradient:angle=135 \
gradient:'#667eea'-'#764ba2' \
-gravity center \
-font "DejaVu-Sans-Bold" \
-pointsize 48 \
-fill white \
-annotate +0-30 "标题第一行" \
-pointsize 36 \
-annotate +0+30 "标题第二行" \
cover.jpg
故障排查
| 问题 | 解决方案 |
|---|---|
| 依赖未安装 | 依赖会在首次运行时自动安装 |
| Cannot find module | 尝试重新运行命令,会自动安装缺失依赖 |
| 封面图生成 SVG 而非 PNG/JPEG | 可选依赖未安装,运行 cd ${SKILL_DIR}/scripts && npm install @napi-rs/canvas 或接受 SVG 格式 |
| 链接无法访问 | 检查网络连接,尝试使用代理或 VPN |
| 图片上传失败 (40113) | sharp 自动深度清理元数据后重试,无需手动处理 |
| 样式丢失 | 确保使用了 --inline-css 参数 |
| API 错误 40001 | access_token 无效或过期,检查 API 凭证 |
| API 错误 40164 (invalid ip) | 在微信公众号后台添加服务器 IP 到白名单:<br/>mp.weixin.qq.com → 开发 → 基本配置 → IP白名单 |
| Chrome 未找到 | 设置环境变量 WECHAT_BROWSER_CHROME_PATH |
| 标题/摘要缺失 | 手动指定 --title 和 --summary 参数 |
| 粘贴失败(浏览器方式) | 检查系统剪贴板权限 |
| Markdown 转换错误 | 检查 Markdown 语法,确保 frontmatter 格式正确 |
最佳实践
1. 内容创作
- ✓ 提供清晰的创作意图和目标读者
- ✓ 引用链接时说明如何使用(深度分析 vs 简要提及)
- ✓ 预览后再发布,避免返工
- ✓ 保存 Markdown 源文件,便于后续修改
- ✓ 标题必须包含至少 3 个特点:痛点明确、数字吸引、结果导向、情绪调动、悬念设置
- ✓ 段落控制 3-5 行,重要数据单独成段加粗
- ✓ 金句单独成段,控制在 20 字以内,便于传播
2. 链接发布
- ✓ 确认链接可访问(避免需要登录的页面)
- ✓ 检查原文图片质量(模糊图片建议替换)
- ✓ 优先使用 API 方式(快速可靠)
- ✓ 发布前预览处理后的 HTML
3. 样式与排版
- ✓ 专业文章用
default主题 - ✓ 大众内容用
grace主题(推荐) - ✓ 教程类用
simple主题 - ✓ 确保图片清晰度(推荐 2x 分辨率)
- ✓ 封面图使用 2:1 比例(900x500px)
4. 发布流程
- ✓ 首次使用先配置 API 凭证
- ✓ 发布前在草稿箱预览
- ✓ 保留源文件(markdown/html)以便后续修改
- ✓ 定期备份已发布的文章
5. 图片处理
- ✓ 使用高质量原图(避免二次压缩)
- ✓ 图片尺寸适中(宽度 800-1200px)
- ✓ 文件大小控制在 1MB 以内
- ✓ 如有 AIGC 图片,让脚本自动清洗
6. 排版与可读性
段落结构:
- ✓ 每段 3-5 行,避免视觉疲劳
- ✓ 重要数据/结论单独成段并加粗
- ✓ 复杂内容分点说明,不要堆砌
配图策略:
- ✓ 标题下方必放封面图
- ✓ 关键步骤后放置效果图/示意图
- ✓ 文章结尾放置总结图或 CTA 图
代码展示:
- ✓ 代码块前后留空行
- ✓ 必须标注编程语言实现语法高亮
- ✓ 关键行添加注释,辅助理解
金句设计:
- ✓ 核心观点提炼成金句,单独成段
- ✓ 使用
**加粗**或> 引用突出 - ✓ 长度控制在 20 字内,朗朗上口
功能对比
| 功能 | 内容创作 | 链接发布 | Markdown 发布 | HTML 发布 | 图文发布 |
|---|---|---|---|---|---|
| 输入类型 | 文本 + 链接 | 单个链接 | .md 文件 | .html 文件 | 短文 + 图片 |
| 内容理解 | ✓ | ✓ | ✗ | ✗ | ✗ |
| 文章生成 | ✓ | ✗ | ✗ | ✗ | ✗ |
| Markdown 转换 | ✓ | ✗ | ✓ | ✗ | ✓ |
| 主题样式 | ✓ | 保留原样 | ✓ | 保留原样 | ✗ |
| 图片清洗 | ✓ | ✓ | ✓ | ✓ | ✗ |
| CSS 内联 | ✓ | ✓ | ✓ | ✓ | ✗ |
| 封面生成 | ✓ | ✓ | ✓ | ✓ | ✗ |
| API 发布 | ✓ | ✓ | ✓ | ✓ | ✗ |
| 浏览器发布 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 适用场景 | 原创内容 | 转载/分享 | 本地文章 | 现成 HTML | 图片展示 |
使用示例
示例 1: 创作新文章(纯文本)
用户:创作一篇关于 AI 编程助手发展趋势的文章
Agent:
✓ 分析内容类型 → 纯文本创作模式
✓ 询问文章风格、长度 → 用户选择"专业分析"、"中等"
✓ 生成文章并展示
✓ 用户确认后转换为 HTML(grace 主题)
✓ 自动生成封面图
✓ 使用 API 发布到草稿箱
结果:
• 文章保存至 wechat-articles/2026-02-09/ai-coding-assistant-trends.md
• HTML 输出至 wechat-articles/2026-02-09/ai-coding-assistant-trends.html
• 封面图:wechat-articles/2026-02-09/ai-coding-assistant-trends-cover.jpg
• 微信草稿箱 media_id: abc123...
示例 2: 基于链接创作
用户:基于这篇文章创作一篇公众号文章,深度分析其中的观点:
https://example.com/ai-future
Agent:
✓ 提取链接并获取内容
✓ 整理关键观点和数据
✓ 询问创作方向 → 用户选择"专业分析"、"深度引用"
✓ 生成文章,引用原文 3 个核心观点,加入自己的分析
✓ 用户确认后发布
结果:
• 生成了 2300 字的深度分析文章
• 引用了原文 3 个观点和 2 个数据
• 添加了参考资料链接
• 已发布到微信草稿箱
示例 3: 直接发布链接文章
用户:发布这篇文章到公众号:https://blog.example.com/great-article
Agent:
✓ 识别为链接发布模式
✓ 下载文章 HTML 和 5 张图片
✓ 清洗图片元数据(检测到 2 张含 AIGC 标记,已清洗)
✓ 转换样式为内联格式
✓ 展示处理结果
✓ 用户确认"直接发布"
✓ 使用 API 发布
结果:
• 处理后 HTML:wechat-temp/20260209-153000/processed.html
• 清洗后图片:wechat-temp/20260209-153000/images/ (5张)
• 微信草稿箱 media_id: xyz789...
示例 4: Markdown 文件发布
用户:发布这个 Markdown 文件:./posts/my-article.md
Agent:
✓ 读取文件,解析 frontmatter
✓ 询问主题 → 用户选择 "grace"
✓ 转换为 HTML,应用主题样式
✓ 下载文章中的 3 张远程图片
✓ 自动生成封面图(基于标题)
✓ 发布到微信
结果:
• HTML 输出至 ./posts/my-article.html
• 封面图:./posts/my-article-cover.jpg
• 已发布到草稿箱
示例 5: 图文消息发布
用户:发布一组产品图片到公众号,标题是"新品上市"
Agent:
✓ 识别为图文发布模式
✓ 打开浏览器,定位到图文消息编辑器
✓ 填写标题
✓ 上传 6 张图片
✓ 提交发布
结果:
• 图文消息已保存到草稿箱
• 包含 6 张产品图片
参考文档
| 主题 | 文档 |
|---|---|
| 图文发布参数、自动压缩 | references/image-text-posting.md |
| 文章主题、图片处理 | references/article-posting.md |
权限要求
- 网络访问:获取链接内容、下载图片
- 文件读写:保存文章、图片和配置
- 环境变量:读取微信 API 凭证
- 外部命令:调用 bun/npx 执行 TypeScript 脚本
- 浏览器(可选):Chrome 用于浏览器发布方式
依赖与许可
核心依赖
- Bun/Node.js:运行 TypeScript 脚本(Node.js >= 18.0.0)
- npm/bun:包管理器(用于安装依赖)
自动安装的依赖
脚本会在首次运行时通过 scripts/ensure-deps.ts 自动安装以下依赖:
必需包:
front-matter- Frontmatter 解析highlight.js- 代码高亮marked- Markdown 渲染引擎reading-time- 阅读时间计算juice- CSS 内联转换库
可选包(封面图生成):
@napi-rs/canvas- 高性能图片生成sharp- 图片处理库
运行时依赖(可选)
- Chrome/Chromium:浏览器发布方式需要
- 微信公众号 API 凭证:API 发布方式需要
许可证
- Markdown 渲染引擎基于 MIT 许可证
- 微信公众号 API 使用需遵守微信公众平台服务协议
致谢
本技能整合了以下功能和技术:
- Markdown 渲染:基于 marked 及扩展插件
- 样式主题:参考微信公众号优秀排版实践
- 图片处理:JPEG 元数据清洗算法
- 微信 API:官方文档和最佳实践
更新日志
v1.0.3 (2026-02-10)
- ✓ 优化封面图规则:设置为强制逻辑。未指定封面时,若文章中有图则默认使用第一张,仅在文章无图时才生成默认封面。
v1.0.2 (2026-02-10)
- ✓ 优化配图策略:优先使用多模态大模型生成高质量封面图
- ✓ 修正
md-to-wechat.ts脚本支持--output参数
v1.0.1 (2026-02-10)
- ✓ 新增标题生成 5 大原则(痛点明确、数字吸引、结果导向、情绪调动、悬念设置)
- ✓ 新增文章排版规范(段落结构、配图位置、代码块、金句设计)
- ✓ 优化内容创作流程,提升文章可读性和传播性
v1.0.0 (2026-02-09)
- ✓ 整合内容创作和链接发布功能
- ✓ 内置 Markdown 转 HTML 转换器
- ✓ 支持三种主题样式(default, grace, simple)
- ✓ 自动图片元数据清洗
- ✓ CSS 自动内联转换
- ✓ 封面图生成(无系统依赖)
- ✓ API 和浏览器两种发布方式
- ✓ 完整的工作流程和错误处理
技能版本:1.0.3 最后更新:2026-02-10 作者:整合自 wechat-article-writer 和 baoyu-post-to-wechat