skills/alpha-hecoding/awesome-skills/wechat-article-maker

wechat-article-maker

SKILL.md

微信公众号文章创作与发布

语言

匹配用户语言:使用用户所用的语言进行回应。用户用中文则用中文回应,用英文则用英文回应。

目录结构

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 格式的封面图(微信也支持)

功能概述

本技能提供完整的微信公众号文章工作流:

  1. 内容创作模式:输入文本内容,智能理解、生成文章
  2. 链接发布模式:输入文章链接,下载、处理并发布
  3. Markdown 转换:内置 Markdown 到 HTML 转换,支持多主题
  4. 图片处理:自动下载、清洗元数据、符合微信规范
  5. 样式转换:自动将 CSS 转为内联样式
  6. 一键发布:支持 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: 内容分析与链接提取

分析用户输入:

  1. 提取所有链接
# 提取 HTTP/HTTPS 链接
echo "$user_input" | grep -oE 'https?://[^\s]+' > /tmp/links.txt
  1. 判断内容类型
    • 如果仅有单个链接且无其他文本 → 转到流程 2: 链接发布流程
    • 如果有文本内容(可选链接)→ 继续内容创作流程

步骤 2: 链接内容获取与理解

如果内容中包含参考链接

  1. 获取每个链接的内容
// 使用 WebFetch 获取并分析
for (const url of links) {
  const content = await WebFetch(url, `
    请提取并总结以下信息:
    1. 文章标题
    2. 作者(如有)
    3. 核心观点(3-5个要点)
    4. 关键数据或案例
    5. 可引用的金句

    以结构化格式返回,便于后续引用。
  `);
}
  1. 整理参考资料
    • 为每个链接创建摘要卡片
    • 标注关键引用点
    • 记录可用图片或数据

步骤 3: 询问创作偏好

使用 AskUserQuestion 询问用户偏好:

文章创作配置

问题1:文章风格
header: "风格"
选项:
- 专业分析 - 深度解读,适合技术或行业分析(推荐)
- 轻松科普 - 通俗易懂,适合大众读者
- 教程指南 - 步骤清晰,适合实操性内容
- 观点评论 - 表达看法,适合热点评论

问题2:文章长度
header: "长度"
选项:
- 短文(800-1200字)- 快速阅读
- 中等(1500-2500字)- 平衡深度与可读性(推荐)
- 长文(3000字+)- 深度长文

问题3:参考资料处理(如有链接)
header: "引用方式"
选项:
- 深度引用和分析 - 详细解读原文观点(推荐)
- 简要提及和链接 - 点到为止
- 仅作背景参考 - 不明确引用

步骤 4: 生成 Markdown 文章

基于用户输入、参考资料和偏好生成文章:

  1. 标题生成要求

文章标题必须包含以下 5 个特点中的至少 3 个:

特点 说明 示例
痛点明确 直击目标读者的具体困扰 《还在手动改代码?这个工具让你开发效率提升 300%》
数字吸引 用具体数字增加可信度 《我花了 3 个月,整理了 1000 个 Python 技巧》
结果导向 承诺可量化的收益或改变 《学会这招,你的代码审查通过率提升 90%》
情绪调动 激发好奇心、紧迫感或共鸣 《千万别再这样写代码了!后果很严重》
悬念设置 制造悬念引发点击欲望 《99% 的程序员都不知道的调试技巧》

标题公式参考

  • 痛点 + 数字 + 结果:《花了 100 小时排错?这 3 个技巧让你秒定位 Bug》
  • 数字 + 悬念:《7 个隐秘的 VS Code 功能,第 5 个太绝了》
  • 情绪 + 痛点:《别再犯这个低级错误!新手程序员最常踩的 5 个坑》
  1. 排版规范

段落结构

  • 每段控制在 3-5 行,避免大段文字
  • 重要数据单独成段并加粗
  • 关键结论前置,细节后置

配图位置

  • 标题下方放置封面图
  • 每个步骤/章节后放置效果示意图
  • 结尾放置总结图或行动号召图

代码块

  • 代码块前后留白(空行分隔)
  • 必须使用语法高亮标注语言类型
  • 关键行添加注释说明

金句设计

  • 核心观点单独成段
  • 使用加粗或引用格式突出
  • 控制在 20 字以内,便于记忆和传播
  1. 文章结构
---
title: 文章标题(遵循 5 大标题原则)
author: 作者名(从 EXTEND.md 或默认值)
summary: 文章摘要(120字以内,突出核心价值)
featureImage: 封面图路径(可选)
date: YYYY-MM-DD
---

# 文章标题(痛点明确 + 数字吸引 + 结果导向)

![封面图](cover.jpg)

引言段落,2-3行即可,
直接点明读者能获得什么价值。

## 第一部分:核心问题

(3-5行,聚焦痛点)

**关键数据单独成段加粗**

配合说明文字,3-4行即可。

![步骤效果图](step1.jpg)

## 第二部分:解决方案

分段讲解,每段 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"
  1. 展示给用户
✓ 文章已生成

📄 标题:$title
📏 长度:约 $word_count 字
📁 保存位置:$output_dir/$slug.md

[文章预览内容...]

请选择下一步操作...

步骤 5: 用户确认与优化

使用 AskUserQuestion 询问:

文章已生成,请选择操作

header: "下一步"
选项:
- 直接发布 - 转换为 HTML 并发布到微信(推荐)
- 修改内容 - 说明需要调整的部分
- 重新生成 - 使用不同风格或角度
- 仅保存文件 - 不发布,稍后手动处理

如果用户选择修改

  1. 收集修改意见
  2. 更新文章内容
  3. 重新保存并展示
  4. 再次询问下一步

如果用户选择重新生成

  • 返回步骤 3,重新询问偏好
  • 使用不同的创作角度

步骤 6: 转换为 HTML

使用内置的 Markdown 渲染引擎转换:

  1. 询问主题(如未在 EXTEND.md 中指定):
主题 描述
default 经典主题 - 传统排版,标题居中带底边,二级标题白字彩底
grace 优雅主题 - 文字阴影,圆角卡片,精致引用块(推荐)
simple 简洁主题 - 现代极简风,不对称圆角,清爽留白
  1. 执行转换
npx -y bun "${SKILL_DIR}/scripts/md-to-wechat.ts" \
  "$output_dir/$slug.md" \
  --theme grace \
  --output "$output_dir"
  1. 解析输出 JSON
{
  "title": "文章标题",
  "author": "作者",
  "summary": "摘要",
  "htmlPath": "路径/to/article.html",
  "contentImages": [
    {
      "placeholder": "WECHATIMGPH_1",
      "localPath": "/path/to/image1.jpg",
      "originalPath": "原始路径"
    }
  ]
}

步骤 7: 准备封面图

封面图强制规则(优先级顺序):

  1. 显式指定:检查 Frontmatter 字段(featureImage, coverImage, cover, image)。
  2. 自动首图回退:若未显式指定封面,且文章中包含图片,必须自动提取并使用文章中的第一张图片作为封面。
  3. 自动生成只有在文章中完全没有图片时,才触发封面图生成逻辑。

如果没有指定且文章内无图片,询问用户:

封面图设置(文章中未发现图片)

header: "封面来源"
选项:
- 自动生成 - 基于文章标题生成渐变背景封面(推荐)
- 提供路径 - 指定本地文件或 URL
- 暂不设置 - 稍后手动添加

如果选择自动生成

  1. 优先尝试多模态大模型生成(如果 Agent 支持):

    • 如果当前 Agent 环境具备文生图能力(Text-to-Image),请根据文章标题和摘要生成一张高质量的封面图。
    • 要求:2:1 比例(如 1024x512),风格现代、简洁,适合作为公众号封面。
    • 保存为:$output_dir/$slug-cover.jpg
    • 注意:如果 Agent 无法生成图片(例如无工具支持),则直接使用下方降级方案。
  2. 降级方案(使用脚本生成)

    如果无法使用大模型生成图片,则运行以下命令生成渐变背景文字封面:

# 使用 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 方式发布

  1. 检查 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"
  1. 如果凭证缺失,引导设置:
微信 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=<用户输入>
  1. 执行发布
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: 图片下载与清洗

  1. 创建临时目录
temp_dir="wechat-temp/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$temp_dir/images"
  1. 下载所有图片
# 解析图片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
  1. 图片元数据清洗

脚本 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 转为内联样式。

  1. 保存原始 HTML
echo "$html_content" > "$temp_dir/original.html"
  1. 执行 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
  1. 替换图片路径
# 将远程图片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 相同,遵循封面图强制规则

  1. 优先使用原文提取的 featureImage
  2. 若无显式封面,自动使用下载图片中的第一张作为封面。
  3. 仅在原文完全没有图片时,才询问生成封面。

步骤 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"

步骤说明

  1. 解析 Markdown:提取 frontmatter(title, author, summary 等)
  2. 转换为 HTML:应用主题样式
  3. 处理图片:下载远程图片,替换为本地路径
  4. 发布:同流程 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 - 简洁主题

  • 现代极简风格
  • 不对称圆角设计
  • 清爽留白
  • 适合:教程、短文

自定义主题

  1. scripts/md/themes/ 创建新的 CSS 文件
  2. 基于 base.css 扩展样式
  3. 使用 --theme <name> 参数应用

配置与环境

环境变量

从以下位置加载配置(优先级从高到低):

  1. 环境变量
  2. <cwd>/.awesome-skills/.env
  3. ~/.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 库提供可靠的图片处理能力:

  1. 智能检测:扫描图片前 2KB,检测 AIGC/Coze/Adobe 等非标准元数据标记
  2. 深度清理:使用 sharp 重新编码 JPEG,彻底移除所有元数据
  3. 自动降级:sharp 不可用时,使用手动解析作为后备方案
  4. 尺寸优化:自动调整超大图片(限制 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 到白名单: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

Weekly Installs
53
First Seen
Feb 10, 2026
Installed on
opencode52
gemini-cli51
codex51
github-copilot48
cursor48
amp47