Back to skills
SkillHub ClubShip Full StackFull Stack
md2wechat
Imported from https://github.com/geekjourneyx/md2wechat-skill.
Packaged view
This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.
Stars
628
Hot score
99
Updated
March 20, 2026
Overall rating
C4.8
Composite score
4.8
Best-practice grade
F19.6
Install command
npx @skill-hub/cli install geekjourneyx-md2wechat-skill-md2wechat
Repository
geekjourneyx/md2wechat-skill
Skill path: skill/md2wechat
Imported from https://github.com/geekjourneyx/md2wechat-skill.
Open repositoryBest for
Primary workflow: Ship Full Stack.
Technical facets: Full Stack.
Target audience: everyone.
License: Unknown.
Original source
Catalog source: SkillHub Club.
Repository owner: geekjourneyx.
This is still a mirrored public skill entry. Review the repository before installing into production workflows.
What it helps with
- Install md2wechat into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
- Review https://github.com/geekjourneyx/md2wechat-skill before adding md2wechat to shared team environments
- Use md2wechat for development workflows
Works across
Claude CodeCodex CLIGemini CLIOpenCode
Favorites: 0.
Sub-skills: 0.
Aggregator: No.
Original source / Raw SKILL.md
---
name: md2wechat
description: Convert Markdown articles to WeChat Official Account formatted HTML with styled CSS and optionally upload to draft box. Supports API mode for quick conversion and AI mode for beautiful themed layouts (autumn-warm, spring-fresh, ocean-calm). Also supports assisted writing with customizable creator styles (default: Dan Koe - profound, sharp, grounded) and AI trace removal (humanizer) to make AI-generated text sound more natural. Users can add custom styles in writers/ directory. Use when user wants to write articles, convert markdown to WeChat format, remove AI writing traces, or publish to WeChat Official Account.
---
# MD to WeChat
Converts Markdown articles to WeChat Official Account formatted HTML with inline CSS and optionally uploads to draft box. Supports two modes:
- **API Mode**: Fast conversion using md2wechat.cn API
- **AI Mode**: Beautiful themed layouts powered by Claude AI
## Quick Start
```bash
# Preview HTML (API mode, fast)
bash skill/md2wechat/scripts/run.sh convert article.md --preview
# Preview HTML (AI mode, themed)
bash skill/md2wechat/scripts/run.sh convert article.md --mode ai --theme autumn-warm --preview
# Upload to WeChat draft box
bash skill/md2wechat/scripts/run.sh convert article.md --draft --cover cover.jpg
```
### Natural Language Image Generation
You can also ask me to generate images using natural language:
#### Generate Image for Article (Insert into Markdown)
```
"Help me generate a product concept image at the beginning of article.md"
"Add an image showing the product features after the second paragraph"
"Create a diagram for the comparison section in article.md"
```
I will:
1. Read the article to understand the context
2. Insert the AI image generation syntax at the appropriate location
3. Call the conversion command to generate and upload the image
#### Generate Standalone Image (Not for Article)
```
"Generate an image of a cute cat sitting on a windowsill"
"Create a product concept image: modern smart home device, white design"
"Make a diagram showing the user flow"
```
I will:
1. Call the image generation command directly
2. Return the generated image URL and WeChat material ID
### Natural Language Writing Assistance
You can also ask me to help write articles using creator styles:
#### Write Article from Idea
```
"Write an article about self-discipline using Dan Koe style"
"Help me write a post about productivity with a sharp, grounded tone"
"Create a story-style article about my travel experience"
```
I will:
1. Understand your idea or topic
2. Use the appropriate writing style (default: Dan Koe)
3. Generate article structure and content
4. Extract memorable quotes
5. Optionally generate matching cover image
#### Refine Existing Content
```
"Rewrite this article with a more engaging style"
"Polish my article.md with Dan Koe's writing style"
"Make this content more profound and sharp"
```
I will:
1. Read your existing content
2. Apply the selected writing style
3. Maintain original meaning while improving expression
#### Generate Cover Only
```
"Generate a cover image for my article about self-discipline"
"Create a Victorian woodcut style cover for my philosophy piece"
```
#### AI Writing Trace Removal (Humanizer)
```
"Remove AI traces from this article: article.md"
"Humanize this text to make it sound more natural"
"Remove AI writing traces with gentle intensity"
"Rewrite this to sound less like AI generated"
```
I will:
1. Read the text to identify AI writing patterns (24 types)
2. Remove or rewrite problematic phrases
3. Inject natural human-like expressions
4. Preserve core meaning and tone
5. Return quality score (5 dimensions, /50)
**Humanizer can be combined with writing styles:**
```
"Write with Dan Koe style and remove AI traces"
"Use dan-koe style, then humanize the result"
```
#### List Available Styles
```
"Show me all available writing styles"
"What writing styles can I use?"
```
**Available Writing Styles:**
- **Dan Koe** (default): Profound, sharp, grounded - great for personal growth and opinion pieces
Users can add custom styles in `writers/` directory. See `writers/README.md` for details.
## Workflow Checklist
Copy this checklist to track progress:
```
Progress:
- [ ] Step 1: Analyze Markdown structure and images
- [ ] Step 2: Confirm conversion mode (API/AI) and theme
- [ ] Step 3: Generate HTML with inline CSS
- [ ] Step 4: Process images (upload to WeChat)
- [ ] Step 5: Replace image URLs in HTML
- [ ] Step 6: Preview or upload to draft
```
---
## Step 1: Analyze Markdown
Read the markdown file and extract:
| Element | How to Extract |
|---------|----------------|
| **Title** | First `# heading` or filename |
| **Author** | Look for `Author:` or `作者:` in frontmatter |
| **Digest** | First paragraph or generate from content (max 120 chars) |
| **Images** | Collect all `` references |
| **Structure** | Headings, lists, code blocks, quotes, tables |
**Image Reference Types**:
| Type | Syntax | Processing |
|------|--------|------------|
| Local | `` | Upload to WeChat |
| Online | `` | Download then upload |
| AI Generate | `` | Generate via AI then upload |
---
## Step 2: Confirm Mode and Theme
### Conversion Mode
| Mode | Speed | Style | Best For |
|------|-------|-------|----------|
| **API** | Fast (seconds) | Clean, standard | Quick publishing, technical content |
| **AI** | Slower (10-30s) | Beautiful themed | Important articles, brand content |
### AI Themes
| Theme | Description | Best For |
|-------|-------------|----------|
| **autumn-warm** | Warm orange tones, emotional, literary | Stories, lifestyle, essays |
| **spring-fresh** | Fresh green tones, natural, vibrant | Travel, nature, outdoor |
| **ocean-calm** | Calm blue tones, professional, rational | Tech articles, business analysis |
| **custom** | Use custom prompt | Brand customization |
### API Themes (Fast)
| Theme | Description | Best For |
|-------|-------------|----------|
| **default** | Default theme, clean and professional | General content |
| **bytedance** | ByteDance style | Tech news |
| **apple** | Apple minimalist style | Product reviews |
| **sports** | Active sports style | Sports content |
| **chinese** | Traditional Chinese culture style | Cultural articles |
| **cyber** | Cyberpunk style | Frontier tech |
**Ask the user**: "Which mode and theme would you like?" - Only ask if the user doesn't specify in their request.
- **API mode** (fast): default, bytedance, apple, sports, chinese, cyber
- **AI mode** (themed): autumn-warm, spring-fresh, ocean-calm
**Default**: Use `API mode` if user doesn't specify.
Read detailed style prompts from [references/themes.md](references/themes.md)
---
## Step 3: Generate HTML
### API Mode
Call md2wechat CLI:
```bash
bash skill/md2wechat/scripts/run.sh convert article.md --mode api
```
### AI Mode
Read the selected style prompt from `references/themes.md` and generate HTML with **inline CSS**.
**Important Rules**:
1. All CSS must be **inline** (in `style` attributes)
2. No external stylesheets or scripts
3. Use WeChat-safe HTML tags only
4. Image placeholder format: `<!-- IMG:0 -->`, `<!-- IMG:1 -->`, etc.
**Safe HTML Tags**:
- `<p>`, `<br>`, `<strong>`, `<em>`, `<u>`, `<a>`
- `<h1>` to `<h6>`
- `<ul>`, `<ol>`, `<li>`
- `<blockquote>`, `<pre>`, `<code>`
- `<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`
- `<section>`, `<span>` (with inline styles)
**Avoid**:
- `<script>`, `<iframe>`, `<form>`
- External CSS/JS references
- Complex positioning (fixed, absolute)
**Critical for WeChat**:
- Create a main `<div>` container immediately after `<body>` to hold all global styles
- Specify `color` explicitly for each `<p>` tag (WeChat resets to black otherwise)
- Use two `<span>` tags for heading symbols: one with color+text-shadow, one with solid color
---
## Step 4: Process Images
### Image Generation Methods
There are **three ways** to generate AI images:
#### Method 1: Natural Language - For Article (Recommended)
Simply describe what you want in plain language:
```
User: "Generate a product concept image at the beginning of article.md"
User: "Add a comparison chart after the third paragraph"
User: "Create an image showing the workflow diagram in article.md"
```
**How I process natural language requests:**
1. **Understand the intent** - Identify where to insert the image
2. **Read the article** - Analyze context to create an appropriate prompt
3. **Insert the syntax** - Add `` at the correct location
4. **Show the prompt** - Display the generated prompt for transparency
5. **Generate and upload** - Call the conversion command to complete
**Note**: Proceed directly with generation. Only ask for confirmation if the prompt is complex or ambiguous.
**Example conversation:**
```
User: "Add a product image at the start of my article"
Claude: "I'll add a product concept image at the beginning of article.md.
Based on your article about 'Smart Home Hub', I'll use this prompt:
'A modern smart home hub device, sleek white design with LED indicator
lights, minimalist product photography on a clean white background'
I'll proceed with generating the image."
```
#### Method 2: Natural Language - Standalone Image
Generate an image without any article:
```
User: "Generate an image of a cute cat sitting on a windowsill"
User: "Create a product concept: modern smart home device"
User: "Make a diagram showing user signup flow"
```
**I will:**
1. Create an appropriate prompt based on your description
2. Call: `bash skill/md2wechat/scripts/run.sh generate_image "prompt"`
3. Return the WeChat URL and media ID
**Use when:** You just need an image, not for any article.
#### Method 3: Manual Syntax
Write the image generation syntax directly in Markdown:
```markdown

```
**Syntax format:** ``
---
### Processing Images by Type
For each image reference in order:
#### Local Image
```bash
bash skill/md2wechat/scripts/run.sh upload_image "/path/to/image.png"
```
Response:
```json
{"success": true, "wechat_url": "https://mmbiz.qpic.cn/...", "media_id": "xxx"}
```
#### Online Image
```bash
bash skill/md2wechat/scripts/run.sh download_and_upload "https://example.com/image.png"
```
#### AI Generated Image (via CLI)
```bash
# Generate with default size (2048x2048 square)
bash skill/md2wechat/scripts/run.sh generate_image "A cute cat sitting on a windowsill"
# Generate with 16:9 ratio for WeChat cover (recommended)
bash skill/md2wechat/scripts/run.sh generate_image --size 2560x1440 "prompt"
```
**WeChat Cover Images**: For article covers, use 16:9 horizontal ratio (2560x1440 recommended) as it displays better in WeChat's feed and article list. Square images (2048x2048) are cropped in preview.
**Note**: AI image generation requires `IMAGE_API_KEY` environment variable.
**Image Processing Pipeline**:
1. If AI generation: Call image API → get URL
2. If online: Download image to temp
3. If local: Read file
4. Compress if width > 1920px (configurable)
5. Upload to WeChat material API
6. Return `wechat_url` and `media_id`
7. Store result for HTML replacement
---
## Step 5: Replace Image URLs
Replace placeholders in HTML:
```html
<!-- Before -->
<!-- IMG:0 -->
<!-- IMG:1 -->
<!-- After -->
<img src="https://mmbiz.qpic.cn/..." />
<img src="https://mmbiz.qpic.cn/..." />
```
Use the WeChat URLs returned from image processing.
---
## Step 6: Preview or Upload
Ask user:
1. **Preview only** - Show HTML for review
2. **Upload to draft** - Create WeChat draft article
### Preview Mode
Display HTML in markdown code block for user to copy.
### Upload Mode
Create draft and run:
```bash
bash skill/md2wechat/scripts/run.sh convert article.md --draft --cover cover.jpg
```
**Required for draft**:
- `WECHAT_APPID` environment variable
- `WECHAT_SECRET` environment variable
- Cover image (use `--cover` or first image in content)
Response:
```json
{"success": true, "media_id": "draft_media_id", "draft_url": "https://mp.weixin.qq.com/..."}
```
---
## Configuration
### Required for WeChat API
| Variable | Description | Required |
|----------|-------------|----------|
| `WECHAT_APPID` | WeChat Official Account AppID | Yes, for draft upload |
| `WECHAT_SECRET` | WeChat API Secret | Yes, for draft upload |
### Optional for AI Features
| Variable | Description | Required |
|----------|-------------|----------|
| `IMAGE_API_KEY` | Image generation API key | For AI images |
| `IMAGE_API_BASE` | Image API base URL | For AI images |
| `COMPRESS_IMAGES` | Compress images > 1920px (true/false) | No, default true |
| `MAX_IMAGE_WIDTH` | Max width in pixels | No, default 1920 |
### How to Get AppID and Secret
1. Visit [WeChat Developer Platform](https://developers.weixin.qq.com/platform)
2. Login and select your Official Account
3. Go to **Settings & Development** → **Basic Configuration**
4. Find in **Developer ID** section:
- **Developer ID (AppID)**: Copy directly
- **Developer Password (AppSecret)**: Click "Reset" to get
5. Add these values to environment variables or config file
> **Warning**: AppSecret is very important, keep it secure!
### Config File Location
```
~/.config/md2wechat/config.yaml # Global config
./md2wechat.yaml # Project config (higher priority)
```
---
## Error Handling
| Error | Action |
|-------|--------|
| Missing config | Ask user to set environment variable or run `md2wechat config init` |
| Image upload fails | Log error, continue with placeholder |
| WeChat API fails | Show error message, return HTML for manual upload |
| Markdown parse error | Ask user to check file format |
| IP not in whitelist | Guide user to add IP to WeChat whitelist (see Troubleshooting) |
---
## Complete Examples
### Example 1: Simple Article (No Images)
**Input**: `simple.md`
```markdown
# My First Article
This is a simple article with no images.
```
**Process**:
1. Generate HTML with API mode
2. Skip image processing
3. Ask: preview or upload?
4. If upload → create draft
### Example 2: Article with Local Images
**Input**: `with-images.md`
```markdown
# Travel Diary
Day 1 in Paris:

```
**Process**:
1. Analyze: 1 local image
2. Generate HTML with `<!-- IMG:0 -->` placeholder
3. Run: `upload_image "./photos/eiffel.jpg"`
4. Replace placeholder with WeChat URL
5. Preview or upload
### Example 3: AI Mode with Theme
**Input**: `story.md`
```markdown
# The Old Library
A story about memories...
```
**Process**:
1. User selects AI mode + autumn-warm theme
2. Read theme prompt from references/themes.md
3. Generate themed HTML with inline CSS
4. Preview or upload
### Example 4: AI Image Generation via Natural Language
**User Request:**
```
"Help me add a product concept image at the beginning of article.md"
```
**Process:**
1. Read article.md to understand the product
2. Create an appropriate image prompt based on context
3. Confirm with user: "I'll use this prompt: '...'"
4. Insert `` at line 2
5. Run conversion command to generate and upload
**Result:** Image generated and uploaded to WeChat
---
### Example 5: Article with Pre-written Image Syntax
**Input**: `mixed.md`
```markdown
# Tech Review



```
**Process:**
1. Process 3 images in order
2. Each returns WeChat URL
3. Replace all placeholders
4. Final HTML with all WeChat-hosted images
---
## References
- [Style Themes](references/themes.md) - Detailed style prompts for AI themes
- [HTML Guide](references/html-guide.md) - WeChat HTML constraints and best practices
- [Image Syntax](references/image-syntax.md) - Image reference syntax and generation
- [Writing Guide](references/writing-guide.md) - Writer style assistant documentation
- [Humanizer](references/humanizer.md) - AI writing trace removal documentation 🆕
- [WeChat API](references/wechat-api.md) - API reference
---
## Troubleshooting
### Configuration Issues
**Q: "AppID not configured" error**
A: Set `WECHAT_APPID` and `WECHAT_SECRET` environment variables, or run:
```bash
bash skill/md2wechat/scripts/run.sh config init
```
**Q: Config file not working**
A: Check config file location. Supported locations:
- `./md2wechat.yaml` (current directory, highest priority)
- `~/.md2wechat.yaml`
- `~/.config/md2wechat/config.yaml`
### Image Issues
**Q: Image upload fails with "invalid filetype"**
A: WeChat supports JPG, PNG, GIF. Ensure image is in correct format:
```bash
# Convert using ImageMagick
convert input.tiff output.jpg
```
**Q: Images not showing in draft**
A: Images must use WeChat-hosted URLs (`mmbiz.qpic.cn`), not external URLs.
**Q: AI image generation fails**
A: Check `IMAGE_API_KEY` is set and API base URL is correct.
### WeChat API Issues
**Q: "IP not in whitelist" error**
A: Add your server IP to WeChat whitelist:
1. Get your public IP:
```bash
curl ifconfig.me
# or
curl ip.sb
```
2. Add IP to WeChat:
- Visit [WeChat Developer Platform](https://developers.weixin.qq.com/platform)
- Go to **Settings & Development** → **Basic Configuration**
- Find **IP Whitelist** section
- Click "Set" and add your IP
- Wait a few minutes for changes to take effect
**Q: "access_token expired" error**
A: Program auto-refreshes tokens. If persists:
```bash
# Check config
bash skill/md2wechat/scripts/run.sh config show
# Re-init if needed
bash skill/md2wechat/scripts/run.sh config init
```
**Q: "create draft failed" error**
A: Possible causes:
1. Insufficient permissions - ensure account is verified
2. Sensitive content - check article content
3. Draft limit reached - check existing drafts
**Q: API rate limit exceeded**
A: WeChat has API limits. Wait and retry:
```bash
# Wait 60 seconds
sleep 60
# Retry
bash skill/md2wechat/scripts/run.sh convert article.md --draft
```
### HTML/Style Issues
**Q: Styles not working in WeChat editor**
A: Check:
1. CSS uses inline `style` attributes (not `<style>` tags)
2. CSS properties are in allowed list (see HTML Guide)
3. No syntax errors (unclosed tags, etc.)
**Q: Background color lost in WeChat**
A: WeChat strips `<body>` styles. Use main container:
```html
<div style="background-color: #faf9f5; padding: 40px 10px;">
<!-- All content here -->
</div>
```
**Q: Text color not as expected**
A: WeChat resets `<p>` color to black. Always specify:
```html
<p style="color: #4a413d;">Your text here</p>
```
### Command Issues
**Q: "command not found: md2wechat"**
A: The `run.sh` script will auto-download the binary on first run. If you want to install manually:
```bash
# Use the script - it will handle installation
bash skill/md2wechat/scripts/run.sh --help
# Or download from releases
# Visit: https://github.com/geekjourneyx/md2wechat-skill/releases
```
**Q: AI mode very slow**
A: AI mode requires Claude API call and takes 10-30 seconds. For faster results, use API mode.
---
## CLI Commands Reference
All commands go through the `run.sh` wrapper, which handles auto-installation:
```bash
# Show help
bash skill/md2wechat/scripts/run.sh --help
# Convert and preview
bash skill/md2wechat/scripts/run.sh convert article.md --preview
# Convert with AI theme
bash skill/md2wechat/scripts/run.sh convert article.md --mode ai --theme autumn-warm --preview
# Convert and upload to draft
bash skill/md2wechat/scripts/run.sh convert article.md --draft --cover cover.jpg
# Upload single image
bash skill/md2wechat/scripts/run.sh upload_image photo.jpg
# Download and upload online image
bash skill/md2wechat/scripts/run.sh download_and_upload https://example.com/image.jpg
# Generate AI image (requires IMAGE_API_KEY)
bash skill/md2wechat/scripts/run.sh generate_image "A cute cat sitting on a windowsill"
# Generate with 16:9 ratio for WeChat cover (recommended)
bash skill/md2wechat/scripts/run.sh generate_image --size 2560x1440 "prompt"
# Initialize config
bash skill/md2wechat/scripts/run.sh config init
# Show config
bash skill/md2wechat/scripts/run.sh config show
# List available writing styles
bash skill/md2wechat/scripts/run.sh write --list
# Write with creator style (interactive)
bash skill/md2wechat/scripts/run.sh write
# Write with specific style
bash skill/md2wechat/scripts/run.sh write --style dan-koe
# Generate cover prompt only
bash skill/md2wechat/scripts/run.sh write --style dan-koe --cover-only
# Remove AI writing traces (humanize)
bash skill/md2wechat/scripts/run.sh humanize article.md
# Humanize with intensity
bash skill/md2wechat/scripts/run.sh humanize article.md --intensity aggressive
# Write with humanize
bash skill/md2wechat/scripts/run.sh write --style dan-koe --humanize
```
---
## Referenced Files
> The following files are referenced in this skill and included for context.
### references/themes.md
```markdown
# 微信公众号主题风格指南
## 主题概览
本项目支持多种主题风格,涵盖 AI 生成模式和 API 模式。
### AI 模式主题(推荐)
| 主题 | 命令参数 | 风格描述 | 适合内容 |
|------|----------|----------|----------|
| 🟠 **秋日暖光** | `--theme autumn-warm` | 温暖治愈,橙色调,文艺美学 | 情感故事、生活随笔 |
| 🟢 **春日清新** | `--theme spring-fresh` | 清新自然,绿色调,生机盎然 | 旅行日记、自然主题 |
| 🔵 **深海静谧** | `--theme ocean-calm` | 深邃冷静,蓝色调,理性专业 | 技术文章、商业分析 |
| ⚪ **自定义** | `--theme custom` | 使用自定义提示词 | 特殊需求 |
### API 模式主题
| 主题 | 命令参数 | 风格描述 | 适合内容 |
|------|----------|----------|----------|
| **default** | `--mode api` 或默认 | 默认主题,简洁专业 | 通用内容 |
| **bytedance** | `--theme bytedance` | 字节跳动风格 | 科技资讯 |
| **apple** | `--theme apple` | Apple 极简风格 | 产品评测 |
| **sports** | `--theme sports` | 运动活力风格 | 体育内容 |
| **chinese** | `--theme chinese` | 中国传统文化风格 | 文化文章 |
| **cyber** | `--theme cyber` | 赛博朋克风格 | 前沿科技 |
---
## AI 主题详情
### 主题 1: autumn-warm(秋日暖光)
#### 整体感觉
温暖治愈、橙色调、文艺美学,适合情感表达和生活方式内容。
#### 配色方案
```css
主背景: #faf9f5 (暖白)
文字色: #4a413d (深褐灰)
主强调色: #d97758 (秋日暖橙)
副强调色: #c06b4d (橙红)
引用背景: #fef4e7 (淡橙)
```
#### 设计特点
- 卡片式布局,米白方格纹理
- 圆角 18px,柔和阴影
- 标题使用 ▶ 符号 + 暖橙文字
- 引用块带内阴影和暖橙左边框
#### 提示词关键词
```
温暖治愈、秋日暖光、橙色调、文艺美学、卡片布局、柔和光效
```
#### 生成指令示例
```
使用秋日暖光主题生成微信公众号 HTML:
- 暖白背景 #faf9f5,深褐灰文字 #4a413d
- 主强调色 #d97758(秋日暖橙)
- 卡片式布局,圆角 18px
- 标题使用 ▶ 符号
- 所有 CSS 必须内联(style 属性)
- 图片使用占位符 <!-- IMG:index -->
```
---
### 主题 2: spring-fresh(春日清新)
#### 整体感觉
清新自然、绿色调、生机盎然,适合户外和自然主题。
#### 配色方案
```css
主背景: #f5f8f5 (淡绿)
文字色: #3d4a3d (深绿灰)
主强调色: #6b9b7a (春日嫩绿)
副强调色: #4a8058 (草地翠绿)
引用背景: #e8f0e8 (淡绿)
```
#### 设计特点
- 清新点状纹理背景
- 圆角 16px,清新阴影
- 标题使用 ❀ 符号 + 绿色文字
- 引用块带清新绿色调
#### 提示词关键词
```
清新自然、春日花园、绿色调、生机盎然、点状纹理、清新阴影
```
#### 生成指令示例
```
使用春日清新主题生成微信公众号 HTML:
- 淡绿背景 #f5f8f5,深绿灰文字 #3d4a3d
- 主强调色 #6b9b7a(春日嫩绿)
- 清新点状纹理背景
- 标题使用 ❀ 符号
- 所有 CSS 必须内联
- 图片使用占位符 <!-- IMG:index -->
```
---
### 主题 3: ocean-calm(深海静谧)
#### 整体感觉
深邃冷静、蓝色调、理性专业,适合技术和商业内容。
#### 配色方案
```css
主背景: #f0f4f8 (淡蓝)
文字色: #3a4150 (深蓝灰)
主强调色: #4a7c9b (深海蔚蓝)
副强调色: #3d6a8a (静谧石蓝)
引用背景: #e8f0f8 (淡蓝)
```
#### 设计特点
- 淡蓝网格纹理背景
- 圆角 14px,深邃阴影
- 标题使用 ◆ 符号 + 蓝色文字
- 引用块带静谧蓝色调
#### 提示词关键词
```
深海静谧、理性专业、蓝色调、网格纹理、深邃蓝调、清晰层次
```
#### 生成指令示例
```
使用深海静谧主题生成微信公众号 HTML:
- 淡蓝背景 #f0f4f8,深蓝灰文字 #3a4150
- 主强调色 #4a7c9b(深海蔚蓝)
- 淡蓝网格纹理背景
- 标题使用 ◆ 符号
- 所有 CSS 必须内联
- 图片使用占位符 <!-- IMG:index -->
```
---
### 主题 4: custom(自定义)
#### 用途
允许用户提供自定义提示词,实现完全个性化的排版风格。
#### 使用方法
```bash
md2wechat convert article.md --mode ai --custom-prompt "你的自定义提示词"
```
#### 自定义提示词模板
```
请将以下 Markdown 转换为微信公众号 HTML:
配色要求:
- 主色:#your_color
- 副色:#your_color
- 背景:#your_color
字体要求:
- 字号:16px
- 行高:1.8
- 字体:系统默认无衬线
技术要求:
1. 所有 CSS 必须内联(style 属性)
2. 使用安全的 HTML 标签
3. 图片使用占位符 <!-- IMG:index -->
4. 不使用外部样式表
请转换以下 Markdown内容:
```
---
## API 模式主题
### 主题: default(默认)
#### 说明
调用 [md2wechat.cn](https://md2wechat.cn) API 进行快速转换。
#### 特点
- 响应速度快(秒级)
- 样式稳定规范
- 无需 AI 调用
#### 使用方法
```bash
# 默认就是 API 模式
md2wechat convert article.md
# 或显式指定
md2wechat convert article.md --mode api
```
---
## 通用技术规范(所有 AI 主题)
### 容器结构(关键)
```html
<!-- 必须在 body 后立即创建主容器 -->
<div style="background-color: #xxx; padding: 40px 10px; letter-spacing: 0.5px;">
<!-- 所有内容放在这里 -->
</div>
```
### 卡片结构
```html
<section style="max-width: 800px; padding: 25px; background: #fff; border-radius: 16px;">
<!-- 内容 -->
</section>
```
### 安全 HTML 标签
```html
section, p, span, strong, em, u, a, h1-h6, ul, ol, li,
blockquote, pre, code, table, thead, tbody, tr, th, td,
img, br, hr
```
### 图片占位符格式
```html
<!-- IMG:0 -->
<!-- IMG:1 -->
<!-- IMG:2 -->
```
---
## 主题选择建议
| 内容类型 | 推荐主题 | 理由 |
|----------|----------|------|
| 情感故事、生活随笔 | autumn-warm | 温暖色调营造情感氛围 |
| 旅行日记、自然主题 | spring-fresh | 清新绿色契合自然主题 |
| 技术文章、商业分析 | ocean-calm | 专业蓝色调传达可信感 |
| 快速发布 | API 模式 | 秒级响应,稳定可靠 |
| 品牌定制内容 | custom | 完全自定义风格 |
---
## 在 Claude Code 中使用
### 方法 1: 通过 md2wechat 命令
```bash
# 在 Claude Code 中直接调用
md2wechat convert article.md --mode ai --theme autumn-warm --preview
```
### 方法 2: 通过 Skill
在 Claude Code 中直接说:
```
请用秋日暖光主题将 article.md 转换为微信公众号格式
```
---
## 主题文件位置
主题配置文件位于项目 `themes/` 目录:
**AI 主题:**
- `themes/autumn-warm.yaml` - 秋日暖光
- `themes/spring-fresh.yaml` - 春日清新
- `themes/ocean-calm.yaml` - 深海静谧
- `themes/custom.yaml` - 自定义
**API 主题:**
- `themes/default.yaml` - 默认主题
- `themes/bytedance.yaml` - 字节跳动风格
- `themes/apple.yaml` - Apple 极简风格
- `themes/sports.yaml` - 运动活力风格
- `themes/chinese.yaml` - 中国传统文化风格
- `themes/cyber.yaml` - 赛博朋克风格
每个主题文件包含完整的 AI 提示词模板,确保生成效果一致。
---
## 完整主题切换示例
### 秋日暖光(情感故事)
```markdown
# 那些年,我们一起追过的梦
还记得青春年少时...

```
```bash
md2wechat convert story.md --mode ai --theme autumn-warm --preview
```
### 春日清新(旅行日记)
```markdown
# 春日游园记
三月的公园,花开正盛...

```
```bash
md2wechat travel.md --mode ai --theme spring-fresh --preview
```
### 深海静谧(技术文章)
```markdown
# 微服务架构最佳实践
在现代应用开发中...

```
```bash
md2wechat tech-post.md --mode ai --theme ocean-calm --preview
```
```
### references/html-guide.md
```markdown
# 微信公众号 HTML 规范
本文档描述微信公众号编辑器的 HTML 限制和最佳实践。了解这些规范有助于生成兼容的 HTML。
## 安全标签清单
微信公众号编辑器支持的 HTML 标签:
| 标签 | 属性限制 | 说明 |
|------|----------|------|
| `section` | style | 容器标签,推荐用于整体包裹 |
| `p` | style | 段落 |
| `span` | style | 内联容器 |
| `strong` | style | 加粗 |
| `em` | style | 斜体 |
| `u` | style | 下划线 |
| `a` | style, href | 链接(href 仅支持 https) |
| `h1` - `h6` | style | 标题 |
| `ul`, `ol` | style | 列表 |
| `li` | style | 列表项 |
| `blockquote` | style | 引用块 |
| `pre` | style | 预格式化文本 |
| `code` | style | 代码 |
| `table` | style | 表格 |
| `thead`, `tbody` | style | 表头/表体 |
| `tr`, `th`, `td` | style | 表格行/单元格 |
| `br` | - | 换行 |
| `img` | src, style, alt | 图片(src 必须是微信域名) |
| `hr` | style | 分割线 |
## 禁止使用的标签
```html
<!-- 脚本相关 -->
<script>...</script>
<noscript>...</noscript>
<iframe>...</iframe>
<!-- 表单相关 -->
<form>...</form>
<input />
<button>...</button>
<textarea>...</textarea>
<select>...</select>
<!-- 其他 -->
<object>...</object>
<embed>...</embed>
<video>...</video>
<audio>...</audio>
<style>...</style>
<link>...</link>
<meta>...</meta>
```
## CSS 属性限制
### 允许的 CSS 属性
```css
/* 文字 */
color
font-size
font-weight
font-style
font-family
line-height
letter-spacing
text-align
text-decoration
text-indent
/* 背景 */
background-color
background-image (仅限 https 图片)
/* 边框 */
border
border-left
border-right
border-top
border-bottom
border-radius
/* 间距 */
margin
margin-top
margin-bottom
margin-left
margin-right
padding
padding-top
padding-bottom
padding-left
padding-right
/* 尺寸 */
width
max-width
min-width
height
max-height
min-height
/* 定位 */
display (仅限 block, inline-block, none)
float (仅限 left, right, none)
clear
overflow
/* 阴影 */
box-shadow
text-shadow
```
### 禁止的 CSS 属性
```css
/* 定位相关 */
position: absolute
position: fixed
position: sticky
/* 复杂布局 */
flexbox
grid
transform
/* 动画 */
transition
animation
@keyframes
/* 其他 */
filter
clip-path
backdrop-filter
```
## AI 主题特殊要求
### 主容器结构(关键)
微信公众号编辑器会剥离 `<body>` 标签的样式,因此必须在 `<body>` 后立即创建主容器:
```html
<body>
<!-- 主容器:承载所有全局样式 -->
<div style="background-color: #faf9f5; padding: 40px 10px; letter-spacing: 0.5px;">
<!-- 卡片/内容 -->
<section style="max-width: 800px; margin: 0 auto;">
...
</section>
</div>
</body>
```
### 段落文字颜色
微信编辑器会强制重置 `<p>` 标签的颜色为黑色。必须为每个 `<p>` 明确指定颜色:
```html
<!-- 错误:颜色可能被重置 -->
<p>这段文字颜色不确定</p>
<!-- 正确:明确指定颜色 -->
<p style="color: #4a413d;">这段文字显示为指定颜色</p>
```
### 卡片式布局
AI 主题使用卡片式布局,确保使用内联样式:
```html
<section style="max-width: 800px; margin: 0 auto; padding: 25px;
background-color: #ffffff; border-radius: 18px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.04);">
<!-- 卡片内容 -->
</section>
```
## 最佳实践
### 1. 容器结构
```html
<section style="max-width:677px;margin:0 auto;padding:20px;background-color:#FFFFFF;">
<!-- 内容 -->
</section>
```
### 2. 图片处理
```html
<!-- 正确:使用微信 CDN 图片 -->
<img src="https://mmbiz.qpic.cn/..." style="max-width:100%;height:auto;display:block;margin:20px auto;" />
<!-- 错误:外部图片不会显示 -->
<img src="https://example.com/image.jpg" />
```
### 3. 链接处理
```html
<!-- 正确:https 链接 -->
<a href="https://example.com" style="color:#007AFF;">链接文字</a>
<!-- 错误:http 链接可能被拦截 -->
<a href="http://example.com">链接</a>
```
### 4. 代码块
```html
<pre style="background-color:#F0F0F0;padding:16px;overflow-x:auto;border-radius:4px;margin:20px 0;">
<code style="font-family:monospace;font-size:14px;color:#333333;">
代码内容
</code>
</pre>
```
### 5. 表格
```html
<table style="width:100%;border-collapse:collapse;margin:20px 0;">
<thead>
<tr style="background-color:#F9F9F9;">
<th style="padding:12px;text-align:left;border-bottom:2px solid #EEEEEE;">标题1</th>
<th style="padding:12px;text-align:left;border-bottom:2px solid #EEEEEE;">标题2</th>
</tr>
</thead>
<tbody>
<tr>
<td style="padding:12px;border-bottom:1px solid #EEEEEE;">内容1</td>
<td style="padding:12px;border-bottom:1px solid #EEEEEE;">内容2</td>
</tr>
</tbody>
</table>
```
## 内容限制
| 限制项 | 限制值 |
|--------|--------|
| 标题长度 | 64 字符 |
| 摘要长度 | 120 字符 |
| 正文长度 | 建议 2000-10000 字符 |
| 单张图片大小 | < 5MB |
| 图片总数量 | < 100 张 |
| 外链数量 | 建议 < 10 个 |
## 常见问题
### Q: 为什么我的样式没有生效?
A: 检查:
1. CSS 是否使用内联 `style` 属性
2. CSS 属性是否在允许列表中
3. 是否有语法错误(未闭合的标签等)
### Q: 图片显示为空白?
A: 图片必须使用微信 CDN 域名:
- `mmbiz.qpic.cn`
- 其他微信允许的域名
外部图片需要先上传到微信素材库。
### Q: 链接无法点击?
A: 确保:
1. 链接是 `https://` 开头
2. 链接域名在微信白名单中
3. 链接没有被编辑器过滤
### Q: 代码块显示混乱?
A: 确保:
1. 使用 `<pre>` 和 `<code>` 包裹
2. 特殊字符已转义(`<` → `<`, `>` → `>`)
3. 设置 `overflow-x: auto` 允许横向滚动
### Q: 背景颜色在微信中丢失?
A: 微信会剥离 `<body>` 标签的样式。解决方案:
1. 使用主 `<div>` 容器包裹所有内容
2. 将背景色应用在主容器上,而不是 `<body>` 上
```html
<!-- 正确做法 -->
<div style="background-color: #faf9f5; padding: 40px 10px;">
<!-- 所有内容 -->
</div>
```
### Q: 标题符号显示异常?
A: 确保:
1. 使用两个 `<span>` 标签分别包裹符号和文字
2. 符号 `<span>` 应用颜色和 text-shadow
3. 文字 `<span>` 只应用纯色(不要用渐变)
```html
<!-- 秋日暖光主题示例 -->
<h2 style="...">
<span style="color: #d97758; text-shadow: 0 0 12px rgba(217, 119, 88, 0.5);">▶</span>
<span style="color: #d97758;">标题文字</span>
</h2>
```
```
### references/image-syntax.md
```markdown
# 图片语法说明
## 图片生成方式
md2wechat 支持 **三种方式** 生成 AI 图片:
### 方式一:自然语言对话 - 文章配图(推荐)
直接用自然语言告诉 Claude 在文章中生成图片:
```
用户: "帮我在文章开头生成一张产品概念图"
用户: "在第三段后添加一张对比图"
用户: "为 article.md 生成一张封面图"
```
**Claude 会自动:**
1. 读取文章理解上下文
2. 创建合适的图片提示词
3. 在正确位置插入图片生成语法
4. 调用转换命令完成生成和上传
---
### 方式二:自然语言对话 - 独立生成
只生成一张图片,不关联任何文章:
```
用户: "生成一张可爱的猫坐在窗台上的图片"
用户: "创建一个产品概念图:现代智能家居设备"
用户: "画一张用户注册流程图"
```
**Claude 会调用:**
```bash
md2wechat generate_image "你的提示词"
```
**返回结果:**
```json
{
"success": true,
"data": {
"prompt": "你的提示词",
"original_url": "https://...",
"wechat_url": "https://mmbiz.qpic.cn/...",
"media_id": "..."
}
}
```
---
### 方式三:Markdown 语法
在 Markdown 中直接写入图片生成语法:
```markdown

```
**语法格式:** ``
- `__generate:` 是固定前缀
- `prompt` 是图片生成提示词
- 支持中英文提示词
---
## 图片引用类型
在 Markdown 中,支持三种图片引用方式:
### 1. 本地图片
```markdown



```
**处理流程**:
1. 读取本地文件
2. 压缩(如果宽度 > 1920px)
3. 上传到微信素材库
4. 替换为微信 CDN URL
**支持的格式**:JPG, PNG, GIF
### 2. 在线图片
```markdown


```
**处理流程**:
1. 下载图片到临时目录
2. 压缩(如果宽度 > 1920px)
3. 上传到微信素材库
4. 替换为微信 CDN URL
**注意**:必须确保图片可访问,且格式正确
### 3. AI 生成图片(手动语法)
```markdown

```
**语法**:``
- `__generate:` 是固定前缀
- `prompt` 是图片生成提示词
- 支持中英文提示词
**处理流程**:
1. 提取 prompt 内容
2. 调用图片生成 API(TuZi 或 OpenAI)
3. 获取生成的图片 URL
4. 下载图片
5. 压缩(如果宽度 > 1920px)
6. 上传到微信素材库
7. 替换为微信 CDN URL
**配置要求**:
- `IMAGE_API_KEY`: 图片 API 密钥
- `IMAGE_API_BASE`: 图片 API 基础 URL
- `IMAGE_PROVIDER`: 服务提供商(tuzi 或 openai)
> **提示**:更推荐使用自然语言对话方式,无需记忆语法。
## 图片占位符
在生成 HTML 时,使用占位符标记图片位置:
```html
<!-- IMG:0 -->
<!-- IMG:1 -->
<!-- IMG:2 -->
```
索引从 0 开始,按图片在 Markdown 中出现的顺序编号。
## 图片处理命令
### 上传本地图片
```bash
bash scripts/run.sh upload_image "/path/to/image.png"
```
**响应**:
```json
{
"success": true,
"wechat_url": "https://mmbiz.qpic.cn/mmbiz_jpg/xxx/0?wx_fmt=jpeg",
"media_id": "media_id_xxx",
"width": 1920,
"height": 1080
}
```
### 下载并上传在线图片
```bash
bash scripts/run.sh download_and_upload "https://example.com/image.jpg"
```
**响应**:同上
### AI 生成图片
```bash
# 默认尺寸 (2048x2048 方形)
bash scripts/run.sh generate_image "A futuristic city skyline at sunset"
# 16:9 比例 (推荐用于公众号封面)
bash scripts/run.sh generate_image --size 2560x1440 "prompt"
```
**公众号封面图建议**:
- 使用 16:9 横向比例(2560x1440)作为文章封面
- 在微信 feed 流和文章列表中显示效果更好
- 方形图片(2048x2048)在预览时会被裁剪
**响应**:
```json
{
"success": true,
"prompt": "A futuristic city...",
"original_url": "https://image-api.example.com/generated/xxx.jpg",
"wechat_url": "https://mmbiz.qpic.cn/mmbiz_jpg/xxx/0?wx_fmt=jpeg",
"media_id": "media_id_xxx",
"width": 1024,
"height": 1024
}
```
## 图片压缩规则
| 条件 | 处理方式 |
|------|----------|
| 宽度 > 1920px | 等比缩放至 1920px |
| 文件大小 > 2MB | 压缩质量 |
| 格式不支持 | 转换为 JPG |
## 错误处理
| 错误 | 处理方式 |
|------|----------|
| 本地文件不存在 | 返回错误,跳过该图片 |
| 在线图片下载失败 | 返回错误,跳过该图片 |
| AI 生成失败 | 返回错误,跳过该图片 |
| 微信上传失败 | 返回错误,跳过该图片 |
| 图片格式不支持 | 尝试转换,失败则跳过 |
## 示例
### 示例 0:自然语言方式(推荐)
**用户请求:**
```
"帮我在 article.md 开头加一张产品概念图"
```
**Claude 处理:**
1. 读取 article.md
2. 理解产品类型和内容
3. 创建图片提示词
4. 在开头插入 ``
5. 运行转换命令
**结果:** 图片自动生成并上传到微信
---
### 示例 1:纯本地图片
```markdown
# 巴黎旅行日记
## 第一天:埃菲尔铁塔
终于来到了梦寐以求的巴黎!

傍晚的铁塔格外美丽...
```
**处理**:
1. 检测到 1 张本地图片
2. 上传 `./photos/eiffel.jpg`
3. HTML 中使用 `<!-- IMG:0 -->` 占位
4. 替换为微信 URL
### 示例 2:混合类型
```markdown
# 科技产品评测
## 产品外观

## 概念设计

## 规格参数
详见下表:
```
**处理**:
1. 检测到 2 张图片(1 张在线,1 张 AI 生成)
2. 处理在线图片
3. 处理 AI 生成图片
4. 按顺序替换占位符
### 示例 3:AI 生成多图
```markdown
# 未来城市系列
## 概念图 1

## 概念图 2

## 概念图 3

```
**处理**:
1. 检测到 3 张 AI 生成图片
2. 依次调用图片生成 API
3. 每张图片独立上传到微信
4. 按顺序替换占位符
```
### references/writing-guide.md
```markdown
# 写作功能指南 (Writing Guide)
> **风格写作 (`write`)** 命令让你只需提供一个想法,AI 就能自动生成符合特定创作者风格的文章。
## 概述
写作功能是 md2wechat 的辅助写作工具,特点:
- **零基础友好**:只需一个观点或想法,AI 自动扩展成完整文章
- **创作者风格**:内置 Dan Koe 等风格,支持自定义
- **封面自动生成**:根据文章内容自动匹配封面提示词
- **AI 模式**:返回结构化提示词,由 Claude 等大模型生成内容
---
## 命令格式
### 基本命令
```bash
# 交互式写作(最简单)
bash skill/md2wechat/scripts/run.sh write
# 查看所有可用风格
bash skill/md2wechat/scripts/run.sh write --list
# 指定风格写作
bash skill/md2wechat/scripts/run.sh write --style dan-koe
# 只生成封面提示词
bash skill/md2wechat/scripts/run.sh write --style dan-koe --cover-only
# 同时生成文章和封面
bash skill/md2wechat/scripts/run.sh write --style dan-koe --cover
```
### 输入类型
| 类型 | 参数 | 说明 | 示例 |
|------|------|------|------|
| **观点** | `--input-type idea` | 一个观点或想法 | "我觉得自律是个伪命题" |
| **片段** | `--input-type fragment` | 内容片段,需要润色扩展 | 现有的草稿或未完成的文章 |
| **大纲** | `--input-type outline` | 文章大纲,需要填充内容 | 有结构,需要填充内容 |
| **标题** | `--input-type title` | 仅标题,围绕标题写作 | "自律是个谎言" |
### 其他参数
| 参数 | 说明 |
|------|------|
| `--style` | 写作风格(默认: dan-koe) |
| `--length` | 文章长度:short/medium/long |
| `--title` | 文章标题 |
| `-o, --output` | 输出文件路径 |
| `--cover` | 同时生成封面提示词 |
| `--cover-only` | 仅生成封面提示词 |
| `--list` | 列出所有可用风格 |
| `--detail` | 显示详细风格信息 |
---
## 使用场景
### 场景 1:从零开始写文章
**输入**:一个想法或观点
```bash
bash skill/md2wechat/scripts/run.sh write
```
然后输入:
```
我觉得自律是个伪命题
```
**输出**:
- 完整的文章结构
- 丰富的内容扩展
- 精彩的金句
- 可选的封面提示词
### 场景 2:润色现有文章
```bash
bash skill/md2wechat/scripts/run.sh write --style dan-koe --input-type fragment article.md
```
### 场景 3:只生成封面
```bash
bash skill/md2wechat/scripts/run.sh write --style dan-koe --cover-only
```
输入文章内容后,获得:
- 封面生成提示词
- 封面设计思路说明
---
## AI 模式说明
`write` 命令默认使用 **AI 模式**:
1. 命令返回结构化的提示词(JSON 格式)
2. 由 Claude 等大模型处理提示词
3. 生成最终文章内容
**在 Claude Code 中使用时,这个流程是自动的。**
### AI 模式输出
```json
{
"success": true,
"mode": "ai",
"action": "ai_write_request",
"style": "Dan Koe",
"prompt": "结构化的写作提示词..."
}
```
### 带封面的输出
```json
{
"success": true,
"prompt": "文章提示词...",
"cover_prompt": "封面提示词...",
"cover_explanation": "封面设计思路..."
}
```
---
## 内置风格
### Dan Koe 风格
**特点**:
- 深刻但不晦涩
- 犀利但不刻薄
- 有哲学深度但接地气
**适合内容**:
- 个人成长类文章
- 观点评述
- 人生感悟
- 方法论分享
---
## 自定义风格
在 `writers/` 目录下创建 YAML 文件即可添加自定义风格:
```yaml
name: "我的风格"
english_name: "my-style"
description: "简洁有力"
writing_prompt: |
你是一位简洁有力的写作者。
用最少的字表达最清晰的观点。
避免废话,直击要点。
cover_prompt: |
为文章生成一个简洁有力的封面提示词。
使用极简主义风格。
cover_style: "minimalist"
cover_mood: "professional"
cover_color_scheme: ["#000000", "#FFFFFF", "#FF0000"]
```
详细格式参考 `writers/dan-koe.yaml`。
---
## 完整工作流程
```mermaid
flowchart LR
A[你提供想法] --> B[选择写作风格]
B --> C[构建结构化提示词]
C --> D{AI 处理}
D --> E[生成完整文章]
E --> F{需要封面?}
F -->|是| G[生成封面提示词]
F -->|否| H[输出文章]
G --> I[AI 生成封面图]
I --> J[上传到微信素材库]
H --> K[转换为微信格式]
J --> K
K --> L[发送到草稿箱]
```
---
## 自然语言使用
在 Claude Code 中,可以直接用自然语言:
```
"用 Dan Koe 风格写一篇关于 AI 时代程序员怎么搞钱的文章"
"帮我的文章润色一下,用更犀利的风格"
"生成一个匹配的封面"
```
Claude 会自动调用 `write` 命令并处理结果。
---
## 封面生成
### 封面尺寸建议
| 用途 | 推荐尺寸 | 说明 |
|------|----------|------|
| **文章封面** | 2560x1440 (16:9) | 横向比例,在微信 feed 流和文章列表显示效果更好 |
| **默认生成** | 2048x2048 (1:1) | 方形图片,在预览时会被裁剪 |
### 生成封面图
```bash
# 生成 16:9 封面图(推荐)
bash skill/md2wechat/scripts/run.sh generate_image --size 2560x1440 "封面提示词"
```
---
## 常见问题
**Q: 必须会写文章才能用吗?**
A: 不需要。写作功能专为小白设计,只需提供一个想法即可。
**Q: 生成的文章可以直接发公众号吗?**
A: 生成的是 Markdown 格式,需要用 `convert` 命令转换为微信格式:
```bash
bash skill/md2wechat/scripts/run.sh convert article.md --preview
```
**Q: 可以修改生成的内容吗?**
A: 当然可以。生成的文章是起点,你可以直接修改 Markdown 文件。
**Q: 如何添加我喜欢的作家风格?**
A: 在 `writers/` 目录下创建 YAML 配置文件,格式参考 `writers/dan-koe.yaml`。
---
## 相关文档
- [writers/README.md](../../writers/README.md) - 自定义风格完整指南
- [docs/WRITING_FAQ.md](../../docs/WRITING_FAQ.md) - 写作功能问答
```
### references/humanizer.md
```markdown
# Humanizer: AI 写作去痕
去除文本中的 AI 生成痕迹,使文章听起来更自然、更像人类书写。
## 概述
Humanizer 是一个独立的文本处理模块,与写作风格系统并行工作:
| 特性 | 写作风格 (Style) | Humanizer |
|------|------------------|-----------|
| **作用** | 控制"怎么写" | 去除"AI 味" |
| **默认状态** | 启用 | 关闭(可选) |
| **独立性** | 可单独使用 | 可单独使用 |
| **组合使用** | - | 可与风格组合 |
## 处理能力
Humanizer 基于维基百科的"AI 写作特征"指南,检测并处理 **24 种 AI 痕迹模式**:
### 内容模式
- 过度强调意义、遗产和更广泛的趋势
- 过度强调知名度和媒体报道
- 以 -ing 结尾的肤浅分析
- 宣传和广告式语言
- 模糊归因和含糊措辞
- 公式化的"挑战与未来展望"部分
### 语言和语法模式
- 过度使用的"AI 词汇"(此外、至关重要、深入探讨、彰显等)
- 避免使用"是"(系动词回避)
- 否定式排比(不仅…而且…)
- 三段式法则过度使用
- 刻意换词(同义词循环)
- 虚假范围
### 风格模式
- 破折号过度使用
- 粗体过度使用
- 内联标题垂直列表
- 表情符号装饰
### 填充词和回避
- 填充短语(为了实现这一目标、在这个时间点等)
- 过度限定
- 通用积极结论
### 交流痕迹
- 协作交流痕迹(希望这对您有帮助、当然!等)
- 知识截止日期免责声明
- 谄媚/卑躬屈膝的语气
## CLI 使用
### 独立命令
```bash
# 基本用法
md2wechat humanize article.md
# 指定处理强度
md2wechat humanize article.md --intensity gentle
md2wechat humanize article.md --intensity aggressive
# 显示修改对比和质量评分
md2wechat humanize article.md --show-changes
# 输出到文件
md2wechat humanize article.md -o output.md
```
### 与写作风格组合
```bash
# 写作 + 去痕
md2wechat write --style dan-koe --humanize
# 指定去痕强度
md2wechat write --style dan-koe --humanize --humanize-intensity aggressive
```
## 处理强度
| 强度 | 描述 | 适用场景 |
|------|------|---------|
| `gentle` | 温和处理,只修改明显的问题 | 已经比较自然的文本 |
| `medium` | 平衡处理(默认) | 大多数场景 |
| `aggressive` | 激进处理,深度去除 AI 痕迹 | AI 味很重的文本 |
## 风格优先原则
当 Humanizer 与写作风格组合使用时,遵循**风格优先原则**:
```
用户: md2wechat write --style dan-koe --humanize
处理流程:
1. 用 Dan Koe 风格生成文章
2. 应用 Humanizer 去痕
3. 保留 Dan Koe 风格的核心特征(如破折号)
4. 只去除无意的 AI 痕迹
```
## 输出格式
Humanizer 处理后返回:
```json
{
"success": true,
"content": "处理后的文本...",
"report": "修改说明...",
"changes": [
{
"type": "filler_phrase",
"original": "为了实现这一目标",
"revised": "为了实现这一点",
"reason": "删除填充短语"
}
],
"score": {
"total": 42,
"directness": 8,
"rhythm": 9,
"trust": 8,
"authenticity": 9,
"conciseness": 8,
"rating": "良好 - 仍有改进空间"
}
}
```
## 质量评分
Humanizer 使用 5 个维度评分(总分 50):
| 维度 | 说明 | 评分标准 |
|------|------|---------|
| **直接性** | 直接陈述事实还是绕圈 | 10 分:直截了当;1 分:充满铺垫 |
| **节奏** | 句子长度是否变化 | 10 分:长短交错;1 分:机械重复 |
| **信任度** | 是否尊重读者智慧 | 10 分:简洁明了;1 分:过度解释 |
| **真实性** | 听起来像真人说话吗 | 10 分:自然流畅;1 分:机械生硬 |
| **精炼度** | 还有可删减的内容吗 | 10 分:无冗余;1 分:大量废话 |
**评级标准**:
- **45-50 分**:优秀,已去除 AI 痕迹
- **35-44 分**:良好,仍有改进空间
- **低于 35 分**:需要重新修订
## Claude Code 自然语言使用
```
"去除这篇文章的 AI 痕迹:article.md"
"把这篇文章重写得更像人写的"
"用温和强度处理这篇文章"
"用 Dan Koe 风格写一篇文章,并去除 AI 痕迹"
```
## 常见问题
### Q: Humanizer 会改变文章意思吗?
A: 不会。Humanizer 只修改表达方式,不改变核心信息。
### Q: 与写作风格冲突怎么办?
A: 风格优先。Humanizer 会识别并保留风格刻意为之的特征(如 Dan Koe 的破折号)。
### Q: 可以只处理特定类型的痕迹吗?
A: 可以。使用 `--focus` 参数指定聚焦模式(当前仅限 API 调用)。
### Q: 处理失败怎么办?
A: Humanizer 失败时会返回原始文章,不会丢失内容。
```
### references/wechat-api.md
```markdown
# 微信公众号 API 参考
## SDK 使用
使用 `github.com/silenceper/wechat/v2` SDK。
```go
import (
"github.com/silenceper/wechat/v2"
"github.com/silenceper/wechat/v2/officialaccount/config"
"github.com/silenceper/wechat/v2/officialaccount/material"
"github.com/silenceper/wechat/v2/officialaccount/draft"
)
```
## 初始化
```go
// 创建微信实例
wc := wechat.NewWechat()
// 配置缓存(必需)
memory := cache.NewMemory()
// 配置公众号参数
cfg := &config.Config{
AppID: appID,
AppSecret: appSecret,
Cache: memory,
}
// 获取公众号实例
officialAccount := wc.GetOfficialAccount(cfg)
```
## API 1: 上传永久素材
上传图片到微信素材库,返回 media_id 和 URL。
### 调用方式
```bash
md2wechat upload_image <file_path>
md2wechat download_and_upload <url>
```
### Go 实现
```go
// 获取素材管理器
materialManager := officialAccount.GetMaterial()
// 上传永久素材
mediaID, url, err := materialManager.AddMaterial(
material.MediaTypeImage, // 素材类型
file, // *os.File 或 io.Reader
)
```
### 响应格式
```json
{
"success": true,
"media_id": "media_id_xxx",
"wechat_url": "https://mmbiz.qpic.cn/mmbiz_jpg/xxx/0?wx_fmt=jpeg"
}
```
### 错误码
| 错误码 | 说明 | 处理方式 |
|--------|------|----------|
| 40001 | AppID 错误 | 检查配置 |
| 40004 | 文件为空 | 检查文件路径 |
| 40005 | 文件类型不支持 | 检查图片格式 |
| 40006 | 文件大小超限 | 压缩图片 |
| 42001 | AppSecret 错误 | 检查配置 |
## API 2: 新建草稿
创建图文草稿到公众号草稿箱。
### 调用方式
```bash
md2wechat create_draft <json_file>
```
### Go 实现
```go
// 获取草稿管理器
draftManager := officialAccount.GetDraft()
// 构建文章
articles := []draft.Article{
{
Title: "文章标题",
Author: "作者",
Digest: "摘要(120字符)",
Content: "<!DOCTYPE html><html>...</html>",
ThumbMediaID: "封面图的 media_id",
ShowCoverPic: 1, // 是否显示封面图
ContentSourceURL: "原文链接",
},
}
// 创建草稿
mediaID, err := draftManager.AddDraft(articles)
```
### 响应格式
```json
{
"success": true,
"media_id": "draft_media_id_xxx",
"draft_url": "https://mp.weixin.qq.com/..."
}
```
### 文章字段说明
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| Title | string | 是 | 标题,不超过 64 字符 |
| Author | string | 否 | 作者 |
| Digest | string | 否 | 摘要,不超过 120 字符 |
| Content | string | 是 | HTML 正文 |
| ThumbMediaID | string | 是 | 封面图 media_id |
| ShowCoverPic | int | 否 | 是否显示封面,0 或 1 |
| ContentSourceURL | string | 否 | 原文链接 |
## 认证配置
### 环境变量
```bash
export WECHAT_APPID="your_appid"
export WECHAT_SECRET="your_secret"
```
### Go 代码读取
```go
func loadConfig() (*Config, error) {
return &Config{
AppID: os.Getenv("WECHAT_APPID"),
AppSecret: os.Getenv("WECHAT_SECRET"),
}, nil
}
```
## 图片生成 API
使用兼容 OpenAI DALL-E 的 API。
### 配置
```bash
export IMAGE_API_KEY="your_api_key"
export IMAGE_API_BASE="https://api.example.com/v1"
```
### 调用
```go
// 生成图片
type ImageAPIRequest struct {
Prompt string `json:"prompt"`
Size string `json:"size"` // 1024x1024
N int `json:"n"` // 1
}
type ImageAPIResponse struct {
Data []struct {
URL string `json:"url"`
} `json:"data"`
}
// POST /images/generations
```
### 错误处理
| 错误 | 处理方式 |
|------|----------|
| API Key 无效 | 返回错误,提示检查配置 |
| 配额超限 | 返回错误,提示稍后重试 |
| 生成失败 | 返回错误,跳过该图片 |
| 超时 | 重试 1 次,仍失败则跳过 |
## 最佳实践
### 1. 并发限制
微信公众号 API 有调用频率限制:
| API | 限制 |
|-----|------|
| 上传素材 | 100 次/天 |
| 创建草稿 | 100 次/天 |
建议:
- 批量处理时控制并发数
- 失败后等待 1 秒再重试
### 2. 缓存策略
```go
// 缓存已上传的图片,避免重复上传
type ImageCache struct {
sync.RWMutex
cache map[string]string // localPath -> mediaID
}
func (c *ImageCache) Get(path string) (string, bool) {
c.RLock()
defer c.RUnlock()
id, ok := c.cache[path]
return id, ok
}
func (c *ImageCache) Set(path, id string) {
c.Lock()
defer c.Unlock()
c.cache[path] = id
}
```
### 3. 错误重试
```go
func retry(fn func() error, maxAttempts int) error {
var err error
for i := 0; i < maxAttempts; i++ {
err = fn()
if err == nil {
return nil
}
time.Sleep(time.Second)
}
return err
}
```
### 4. 日志记录
```go
type Logger struct {
*zap.Logger
}
func (l *Logger) LogUpload(filePath string, mediaID, url string, duration time.Duration) {
l.Info("image uploaded",
zap.String("file", filePath),
zap.String("media_id", maskMediaID(mediaID)),
zap.String("url", url),
zap.Duration("duration", duration),
)
}
func maskMediaID(id string) string {
if len(id) < 8 {
return "***"
}
return id[:4] + "***" + id[len(id)-4:]
}
```
## 完整调用示例
```go
package main
import (
"fmt"
"os"
"github.com/silenceper/wechat/v2"
"github.com/silenceper/wechat/v2/cache"
"github.com/silenceper/wechat/v2/officialaccount/config"
"github.com/silenceper/wechat/v2/officialaccount/material"
"github.com/silenceper/wechat/v2/officialaccount/draft"
)
func main() {
// 1. 初始化
wc := wechat.NewWechat()
memory := cache.NewMemory()
cfg := &config.Config{
AppID: os.Getenv("WECHAT_APPID"),
AppSecret: os.Getenv("WECHAT_SECRET"),
Cache: memory,
}
oa := wc.GetOfficialAccount(cfg)
// 2. 上传图片
mat := oa.GetMaterial()
file, _ := os.Open("image.jpg")
defer file.Close()
mediaID, url, _ := mat.AddMaterial(material.MediaTypeImage, file)
fmt.Printf("Uploaded: %s, %s\n", mediaID, url)
// 3. 创建草稿
dm := oa.GetDraft()
articles := []draft.Article{
{
Title: "测试文章",
Content: "<p>正文内容</p>",
ThumbMediaID: mediaID,
ShowCoverPic: 1,
},
}
draftID, _ := dm.AddDraft(articles)
fmt.Printf("Draft: %s\n", draftID)
}
```
```