Publish Markdown articles to the WeChat Official Account draft box with one click.
When to use
- When you have a finished Official Account article (markdown) that needs to be uploaded to the draft box
- Batch publish content to the WeChat Official Account
- One link in an automated content distribution pipeline
- When other agents (Xiao Content, etc.) need to publish Official Account content
Not applicable
- ❌ Need to publish officially directly (not a draft) — currently only draft saving is supported, with final publishing done manually
- ❌ Video content — only image-text messages are supported
- ❌ Need to edit published articles
Prerequisites
| Condition | Description | How to check |
|---|---|---|
| Playwright | Python playwright library | pip show playwright |
| OpenClaw Browser | Browser service is running | openclaw browser status or check 127.0.0.1:18800 |
| WeChat Cookie | Playwright state file is valid | cat ~/.playwright-data/wechat/state-default.json | python3 -c "import json,sys; d=json.load(sys.stdin); print(f'Cookies: {len(d.get(\"cookies\",[]))}')" |
| Cookie has not expired | cookies contain qname and uin | Check the qname field in the cookie |
Input
输入参数:
article_path: string # Markdown 文件路径
cover_path: string # 封面图路径 (jpg/png, 推荐 2.35:1 比例, ≥900x383)
decision: draft # 当前仅支持 draft
Markdown format requirements
# 标题(文章标题,≤64字)
正文内容,支持 **加粗**、*斜体*、`行内代码` 等常见 Markdown 语法。
## 子标题
段落文字...
Output
输出:
status: ok | error
draft_saved: true/false
draft_url: string # 草稿箱URL
screenshot_path: string # 截图路径
title: string # 实际使用的标题
content_length: number # 正文字数
How to use
Method 1: Run the script directly
python3 ~/clawd/skills/wechat-mp-smart-publish/scripts/publish.py \
--article /path/to/article.md \
--cover /path/to/cover.jpg \
--decision draft
Method 2: Call as a module
import asyncio
from scripts.publish import publish_to_wechat
result = asyncio.run(publish_to_wechat(
article_path="/path/to/article.md",
cover_path="/path/to/cover.jpg",
decision="draft",
))
print(result)
Method 3: Agent call (recommended)
Other agents request Xiao Code to execute via sessions_send:
请发布文章到微信公众号草稿箱:
- 文章: ~/clawd/docs/daily-content/2026-04-14/gzh/amd-gaia-article.md
- 封面: ~/clawd/docs/daily-content/2026-04-14/gzh/cover.jpg
Core workflow
解析 Markdown → Markdown→HTML 转换 → 启动浏览器 → 加载 Cookie
→ 打开公众号首页 → 点击"新的创作" → 上传封面图
→ 填充标题 → 切换到图文消息 → 粘贴正文HTML
→ 截图 → 存草稿
Formatting specifications
| Parameter | Value |
|---|---|
| Body font size | 15px |
| Body text color | #3f3f3f |
| Line height | 1.75x |
| Paragraph spacing | 1em |
| Heading font size | H2: 18px bold, H3: 16px bold |
| Code block | Background #f6f8fa, left border 3px solid #fe6 |
Key Selectors (verified 2026-04-14)
| Element | CSS Selector | Description |
|---|---|---|
| Homepage entry | "新的创作" (button/tab text) | Create new image-text |
| Cover image upload | input[type="file"] |
Image upload input |
| Title input | input[name="title"] |
Article title |
| Image-text toggle | "图文" (tab text) | Switch to rich text editor |
| Rich text editor | #ueditor_0 iframe or .edit_area |
UEditor iframe |
| Preview button | "预览" (button text) | Preview draft |
| Save draft button | "保存" (button text) | Save as draft |
Edge case handling
1. 64-character title limit
The title is automatically truncated when it exceeds 64 characters.
2. Markdown→HTML conversion
Use basic conversion rules:
# H1→<h1>**bold**→<strong>bold</strong>*italic*→<em>italic</em>`code`→<code>code</code>- Blank line →
<br> ---→<hr>
3. UEditor special filling
UEditor is a rich text iframe, and its content cannot be manipulated directly. It must be done through:
# 切换到编辑模式
await page.evaluate('''() => {
const editor = document.querySelector('#ueditor_0');
if (editor && editor.contentWindow) {
editor.contentWindow.postMessage({type: 'setContent', content: html}, '*');
}
}''')
4. Cover image aspect ratio
WeChat cover image recommended ratio 2.35:1, minimum size 900x383.
5. Cookie Management
- Cookie file location:
~/.playwright-data/wechat/state-default.json - Valid for approximately 7-30 days, requires periodic renewal by logging in via browser
- Loading method:
await context.add_cookies(cookies_from_state) - Check login: The page showing the "新的创作" button means you are logged in
Frequently Asked Questions
Q: Cannot find the "新的创作" button on the page?
A: Cookie expired, need to log in again by scanning the QR code. Execute:openclaw browser open --url https://mp.weixin.qq.com
Q: The rich text editor cannot be filled with content?
A: UEditor needs to be switched to edit mode. First click the editor area to activate it, then execute the JS injection.
Q: Browser connection failed?
A: Check whether OpenClaw browser is running:curl -s http://127.0.0.1:18800/json/version
Q: What to do if the Cookie expires?
A: Daniel needs to log in to the WeChat Official Account Platform via browser and save the Playwright state:
openclaw browser open --url https://mp.weixin.qq.com
# 手动扫码登录后
# Cookie 会自动保存
Dependencies
playwright>=1.40.0
Pillow>=10.0.0 (图片验证)
markdown>=3.4.0 (可选,markdown→html)
Trigger Words
- "发布到公众号", "发布微信公众号", "发微信"
- "公众号草稿", "wechat publish", "wechat mp"
- "公众号发布", "mp.weixin publish"
Update Log
- v1.0.0 (2026-04-14): Initial version
- Basic Markdown→HTML conversion
- UEditor rich text filling
- Cover image upload
- Draft box saving