WeChat Official Account Article Publisher
Publish Markdown articles to WeChat Official Account via the API — convert MD to WeChat-compatible HTML and upload as drafts or published articles.
File Organization — One Article Per Folder (MANDATORY)
Every article MUST live in its own folder. No loose files in the root directory. This keeps cover images, screenshots, preview HTML, and article-specific scripts together.
公众号/
├── AI工具前沿观察/
│ ├── AI工具前沿观察_2026-07-07.md
│ ├── AI工具前沿观察_2026-07-07.preview.html
│ └── ai-tools-frontier-2026-07-07.jpg
├── LaTeX教程/
│ ├── LaTeX教程-从零基础到学术公式自由.md
│ ├── latex_tutorial_screenshot.png
│ └── latex-tutorial-article.py
├── _scripts/ ← shared publish scripts only
│ ├── wechat_publish.py
│ └── batch_publish_*.py
├── images/ ← shared image assets (not article-specific)
├── api.md ← shared credentials
└── cover.jpg ← default cover (override per-article)
Rules:
- Before writing any article file, create its folder first (use Chinese folder name matching the article title)
- All files belonging to one article —
.md,.preview.html, cover.jpg,.pngscreenshots, article-specific.py— go into that folder - Only shared/utility files stay at root level or in
_scripts/,_参考/,images/ - When batch-publishing, output each article into its own folder, not a flat directory
Prerequisites
The user must have ready:
- AppID + AppSecret: From 微信公众号后台 → 设置与开发 → 基本配置
- IP whitelist: Their current public IP must be added to the whitelist on the same page
- Each time the user's network changes, the new IP must be added
- To check current IP:
curl ifconfig.meor search "my ip"
- Cover image: 900×500 pixels, jpg/png format
- Account type: Must be an 认证服务号 (Verified Service Account); 订阅号不支持 API
Workflow
Step 1: Gather Information
Before any upload, collect these from the user:
- AppID & AppSecret — ask if not provided (user may have them in a config file)
- Author name — WARNING: Draft API limits Chinese author to 2 hanzi or 4 mixed chars (e.g., "AI气象", "耄耋AI" OK; "人工智能大气科学" = 8 hanzi → FAIL)
- Cover image — 900×500 jpg/png. Resize/conver t if needed with PIL
- Digest (optional) — keep under ~40 Chinese chars (API limit ~120 bytes, each hanzi = 3 bytes)
Step 2: Write / Locate the Markdown Article
First, create a folder for the article under the working directory (e.g., 公众号/). Use the article title (Chinese) as the folder name. Then write or locate the Markdown file inside that folder.
All article-specific files (cover images, screenshots, preview HTML, helper scripts) go into this same folder.
Step 3: Convert and Upload
Run the publish script, pointing to the article inside its folder:
python _scripts/wechat_publish.py "文章文件夹/article.md" --author "署名" --thumb "文章文件夹/cover.jpg"
Optional flags:
| Flag | Effect |
|---|---|
--publish | Publish immediately (default: save as draft) |
--digest "xxx" | Manual summary (default: auto-extract first 40 chars) |
--preview | Generate preview HTML only, don't connect to API |
--title "xxx" | Override title (default: first # heading in MD) |
--source-url "url" | Original source link |
Step 4: Verify in Backend
After successful upload → mp.weixin.qq.com → 草稿箱 → preview → publish manually.
Critical Gotchas (from painful experience)
These are documented in detail in references/api-limits.md. The three most important:
1. json.dumps(ensure_ascii=False) IS MANDATORY
requests.post(json=...) internally calls json.dumps(ensure_ascii=True), which encodes all Chinese as \uXXXX. WeChat stores these escape sequences as literal text. Always use:
payload = json.dumps(data, ensure_ascii=False).encode("utf-8")
requests.post(url, data=payload, headers={"Content-Type": "application/json; charset=utf-8"})
2. Author field: 2 Chinese chars max
WeChat draft/add has a draconian limit: ~8 bytes for the author field. Each Chinese character = 3 bytes in UTF-8. Therefore: 2 hanzi max for pure Chinese names. Mixed Chinese+ASCII can stretch to ~4 chars (e.g., "耄耋AI").
3. No <style> tags — inline styles only
WeChat editor strips <style> blocks and renders their CSS content as visible body text. Use inline style="" attributes sparingly. Also keep total content under ~20,000 chars for the API.
Script Location
The publish script wechat_publish.py should be placed in your project's shared scripts directory (e.g., _scripts/wechat_publish.py).
Recommended structure:
- Shared publish script:
<project>/_scripts/wechat_publish.py - Each article in its own folder:
<project>/<文章标题>/ - Shared credentials:
<project>/api.md
The publish script handles:
- markdown → WeChat HTML conversion (Python-Markdown + fenced_code, tables)
- Cover image upload (thumb material API)
- Draft creation with correct JSON encoding
- Optional auto-publish
- Preview mode (local HTML without API calls)
Get the latest script from: https://github.com/0183ty2512/wechat-article-publisher