Skill: wuhongchen/mp-draft-push (version 1.0.2)

--- name: mp-draft-push description: 将现成的文章内容发布到微信公众号草稿箱。当用户说"发布文章"、"发布到草稿箱"、"publish to draft"、"推送到公众号"时触发。 homepage: https://github.com/bbwdadfg/wechat-ai-publisher metadata: {"openclaw":{"emoji":"📤","requires":{"bins":["bash","curl","jq"]}}} --- # mp-draft-push ## 功能说明 接收调用方提供的文章内容，上传封面图（可选），并将文章发布到微信公众号草稿箱。 **不负责**：内容采集、AI 写作、图片生成。 --- ## 所需参数 调用方（用户或其他 Skill）需要提供： | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `title` | string | ✅ | 文章标题（不超过 64 字节，约 21 个中文字符） | | `digest` | string | ✅ | 文章摘要（显示在分享卡片上） | | `content_html` | string | ✅ | 文章正文 HTML（使用内联样式） | | `cover_image_path` | string | ❌ | 封面图本地路径（如不提供则用兜底 URL 或无封面） | --- ## 执行流程 ``` 1. 接收参数 ↓ 2. 获取 access_token ↓ 3. 上传封面图到微信素材库（获取 thumb_media_id） ↓ 4. 创建草稿（发布到草稿箱） ↓ 5. 提示用户前往后台检查 ``` --- ## 配置信息 - **AppID**: `WECHAT_APPID`（通过环境变量配置） - **AppSecret**: `WECHAT_SECRET`（通过环境变量配置） - **作者**: `WECHAT_AUTHOR`（可选，默认 `W`） 配置方法见 `README.md`。 --- ## Step 1: 接收参数 **不要主动提问**，等待调用方传入上述参数。 若调用方没有提供 `cover_image_path`，检查环境变量 `DEFAULT_COVER_URL`： - 有值：先下载到本地临时文件 `/tmp/wechat_cover_default.png`，再上传 - 无值：`thumb_media_id` 留空（草稿不含封面） --- ## Step 2 & 3: 上传封面图并创建草稿 加载脚本： ```bash source ./scripts.sh ``` ### 获取 access_token ```bash [REDACTED_SECRET]) ``` ### 上传封面图（如有） ```bash MEDIA_RESPONSE=$(upload_wechat_image "$TOKEN" "$cover_image_path") THUMB_MEDIA_ID=$(echo "$MEDIA_RESPONSE" | jq -r '.media_id') ``` ### 构建草稿 JSON 并创建草稿 `content_html` 注意事项： - 所有样式必须内联（`style="..."`），微信会过滤 `<style>` 标签 - 图片只能使用 `mmbiz.qpic.cn` 域名（如有文章内图片，需提前上传到微信） - JSON 序列化必须使用 `ensure_ascii=False`，否则中文乱码 ```bash DRAFT_JSON="/tmp/draft_$(date +%Y%m%d%H%M%S).json" jq -n \ --arg title "$title" \ --arg author "${WECHAT_AUTHOR:-koo AI}" \ --arg digest "$digest" \ --arg content "$content_html" \ --arg thumb_media_id "$THUMB_MEDIA_ID" \ '{ articles: [{ title: $title, author: $author, digest: $digest, content: $content, thumb_media_id: $thumb_media_id, need_open_comment: 1, only_fans_can_comment: 0 }] }' > "$DRAFT_JSON" DRAFT_RESPONSE=$(create_draft "$TOKEN" "$DRAFT_JSON") DRAFT_MEDIA_ID=$(echo "$DRAFT_RESPONSE" | jq -r '.media_id') rm -f "$DRAFT_JSON" ``` 若 `DRAFT_MEDIA_ID` 为空或 `null`，说明创建失败，打印 `DRAFT_RESPONSE` 排查。 --- ## Step 4: 提示用户检查 发布完成后输出： ``` ✅ 草稿发布成功！ 📝 文章信息 - 标题：{title} - 摘要：{digest} - 草稿 ID：{DRAFT_MEDIA_ID} 📌 请前往微信公众号后台检查并发布： https://mp.weixin.qq.com ⚠️ 检查要点： 1. 图片是否正常显示 2. 排版是否正确 3. 标题和摘要是否合适 4. 确认无误后点击"发布" ``` --- ## HTML 内联样式参考 ```html <section style="font-family: -apple-system, sans-serif; line-height: 1.8; color: #333; padding: 15px;"> <p style="margin-bottom: 20px;">段落内容</p> <h2 style="border-bottom: 1px solid #eee; padding-bottom: 8px;">标题</h2> <p style="text-align: center; margin: 25px 0;"> <img src="{mmbiz_img_url}" style="max-width: 100%; border-radius: 6px;"> </p> <blockquote style="background: #f6f8fa; border-left: 4px solid #ddd; padding: 12px 16px;"> 引用内容 </blockquote> </section> ``` --- ## 注意事项 1. **中文编码**：JSON 必须用 `ensure_ascii=False`，`jq` 默认已处理 2. **标题长度**：最多 64 字节（约 21 个中文字符） 3. **access_token**：有效期 2 小时，每次需重新获取 4. **图片域名**：文章内图片只能使用微信返回的 `mmbiz.qpic.cn` URL

path: scripts.sh
content: #!/bin/bash
# 微信公众号草稿箱发布工具 - 辅助脚本
# 使用方法: source scripts.sh

# 通过环境变量提供（推荐：使用 .env + `set -a; source .env; set +a`）

require_cmd() {
    command -v "$1" >/dev/null 2>&1 || {
        echo "ERROR: missing command: $1" >&2
        return 1
    }
}

require_env() {
    local name=$1
    local val
    eval "val=\${${name}:-}"
    if [[ -z "$val" ]]; then
        echo "ERROR: missing env var: ${name}" >&2
        return 1
    fi
}

# ============ 公众号 API ============

# 获取 access_token
# 用法: get_wechat_token
get_wechat_token() {
    require_cmd curl || return 1
    require_cmd jq   || return 1
    require_env WECHAT_APPID  || return 1
    require_env WECHAT_SECRET || return 1
    curl -s "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${WECHAT_APPID}&[REDACTED_SECRET]" \
        | jq -r '.access_token'
}

# 上传图片到公众号永久素材库（封面图专用）
# 用法: upload_wechat_image <token> <image_path>
# 返回: JSON，含 media_id 字段
upload_wechat_image() {
    require_cmd curl || return 1
    local token=$1
    local image_path=$2
    curl -s -X POST \
        "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=${token}&type=image" \
        -F "media=@${image_path}"
}

# 创建草稿
# 用法: create_draft <token> <json_file>
# 返回: JSON，含 media_id 字段（草稿 ID）
create_draft() {
    require_cmd curl || return 1
    local token=$1
    local json_file=$2
    curl -s -X POST \
        "https://api.weixin.qq.com/cgi-bin/draft/add?access_token=${token}" \
        -H "Content-Type: application/json" \
        -d @"${json_file}"
}

echo "脚本已加载。可用函数:"
echo "  get_wechat_token     - 获取公众号 access_token"
echo "  upload_wechat_image  - 上传封面图到素材库，返回 media_id"
echo "  create_draft         - 创建草稿，返回草稿 media_id"


path: README.md
content: # mp-draft-push (Skill)

> 最小化微信公众号发布技能：接收**现成的文章内容**，上传封面图，发布到草稿箱。不负责内容采集、AI 写作或图片生成。

---

## 目录结构

```
mp-draft-push/
├── SKILL.md          # 技能定义（AI 助手读取）
├── scripts.sh        # 辅助脚本（bash/zsh 均可用）
├── .env.example      # 环境变量模板
└── README.md
```

---

## 安装

### OpenClaw

```bash
# 方式一：放入 workspace skills（推荐）
cp -r mp-draft-push ~/.openclaw/workspace/skills/

# 方式二：放入全局 skills
cp -r mp-draft-push ~/.openclaw/skills/
```

### 其他 AI 工具

| AI 工具 | Skills 路径 |
|---------|------------|
| Codex | `~/.codex/skills/mp-draft-push/` |
| Claude Code | `~/.claude/skills/mp-draft-push/` |
| Gemini | `~/.gemini/skills/mp-draft-push/` |

---

## 配置

```bash
cd ~/.openclaw/workspace/skills/mp-draft-push   # 进入技能目录
cp .env.example .env
```

编辑 `.env`：

```bash
WECHAT_APPID=你的AppID
WECHAT_SECRET=你的AppSecret
WECHAT_AUTHOR=koo AI          # 可选，文章署名
DEFAULT_COVER_URL=             # 可选，无封面图时的兜底 URL
```

让环境变量在 OpenClaw 运行时生效（加入 Shell 配置）：

```bash
# ~/.zshrc 或 ~/.bashrc 末尾添加：
set -a; source ~/.openclaw/workspace/skills/mp-draft-push/.env; set +a
```

> AppID / AppSecret 在**微信公众号后台 → 设置与开发 → 基本配置**中获取。

---

## 在 OpenClaw 中调用

### 触发词

在对话框直接说：

```
发布文章
发布到草稿箱
publish to draft
推送到公众号
```

### 调用示例

**最简调用**（让 AI 引导你填信息）：

```
发布文章到草稿箱
```

**完整参数调用**（一次性传入所有信息，AI 直接执行）：

```
发布以下文章到微信草稿箱：
- 标题：教你用 AI 写公众号
- 摘要：3步搞定公众号排版和发布
- 封面图：/tmp/cover.png
- 正文 HTML：<section style="...">文章内容</section>
```

### 定时自动发布（OpenClaw Cron）

```bash
# 每天 09:00（上海时区）由另一个 Skill 生成内容后调用本技能发布
openclaw cron add \
  --name "daily-mp-push" \
  --cron "0 9 * * *" \
  --tz "Asia/Shanghai" \
  --session isolated \
  --message "生成今日 AI 简报并发布到草稿箱；不要提问，直接执行"

# 查看 / 删除
openclaw cron list
openclaw cron delete --name "daily-mp-push"
```

> Cron 需要 OpenClaw Gateway 常驻运行。

---

## 直接调用脚本

```bash
source ./scripts.sh

# 1. 获取 token
[REDACTED_SECRET])

# 2. 上传封面图（返回 media_id）
RESP=$(upload_wechat_image "$TOKEN" "/path/to/cover.png")
THUMB_ID=$(echo "$RESP" | jq -r '.media_id')

# 3. 构建并发布草稿
jq -n \
  --arg title "文章标题" \
  --arg author "${WECHAT_AUTHOR:-koo AI}" \
  --arg digest "文章摘要" \
  --arg content "<p style='color:#333'>正文 HTML</p>" \
  --arg thumb_media_id "$THUMB_ID" \
  '{articles:[{title:$title,author:$author,digest:$digest,content:$content,thumb_media_id:$thumb_media_id,need_open_comment:1,only_fans_can_comment:0}]}' \
  > /tmp/draft.json

create_draft "$TOKEN" /tmp/draft.json
```

---

## 依赖

```bash
brew install jq   # 如未安装（bash/curl macOS 已自带）
```

---

## 注意事项

- `.env` 已加入 `.gitignore`，不会提交到仓库
- `thumb_media_id` 为必填字段，不能为空字符串
- 文章内图片只能使用微信返回的 `mmbiz.qpic.cn` 域名 URL（需提前调 `/media/uploadimg` 接口上传）
- HTML 样式必须全部内联，微信会过滤 `<style>` 标签
- 标题最多 64 字节（约 21 个中文字符）
- `access_token` 有效期 2 小时，脚本每次调用自动重新获取


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (CRITICAL)