Sync a published article into the WeChat Official Account draft box.
This repository contains a standalone sync script, a safe config example, and setup docs. No AppID, AppSecret, local config, or generated payloads are committed.
- Fetches a published article page by URL or Astro
slug - Extracts the article body and rewrites images for WeChat
- Uploads inline images to WeChat
- Creates or updates a draft in the WeChat draft box
- Optionally submits the draft for publish
- Optionally uses frontmatter fields like
wechatDraftMediaIdandwechatPublishId
scripts/sync_wechat_article.py: main sync scriptconfig/wechat.example.json: config templatepackage.json: optional Node dependency for SVG to PNG conversion viasharp
- Python 3.10+
- Node.js 18+ if you want automatic SVG to PNG conversion for cover images
- A WeChat Official Account with
app_idandapp_secret
- Clone the repository:
git clone https://github.com/ax2/astro-to-wechat.git
cd astro-to-wechat- Install the optional Node dependency used for SVG cover conversion:
npm installYou can then use the packaged shortcut:
npm run sync:wechat -- --help- Copy the config example:
cp config/wechat.example.json config/wechat.local.json- Edit
config/wechat.local.json.
Example:
{
"wechat": {
"app_id": "your-wechat-app-id",
"app_secret": "your-wechat-app-secret",
"site_url": "https://example.com",
"author": "Your Name",
"thumb_image_path": "public/wechat-thumb.jpg",
"open_comment": 0,
"fans_can_comment": 0,
"content_root": "../your-astro-site/src/content/blog",
"public_root": "../your-astro-site/public",
"node_modules_root": "."
}
}Field notes:
app_id: WeChat Official Account AppIDapp_secret: WeChat Official Account AppSecretsite_url: your public site root, used to resolve relative URLs and--slugauthor: default author shown in WeChatthumb_image_path: fallback cover image path or URLopen_comment:1to enable comments, otherwise0fans_can_comment:1to restrict comments to followers, otherwise0content_root: optional Astro content directory, used to find a source file byslugand write backwechatDraftMediaIdorwechatPublishIdpublic_root: optional static asset directory, used to resolve local images like/wechat-thumb.jpgnode_modules_root: optional directory containing installed Node packages; usually"."
If content_root is omitted, the script still works, but it will not auto-locate the source markdown file for frontmatter writeback.
Preview generated payload without calling the WeChat API:
python3 scripts/sync_wechat_article.py --slug your-article-slug --dry-run --output tmp/wechat-preview.jsonEquivalent command:
npm run sync:wechat -- --slug your-article-slug --dry-run --output tmp/wechat-preview.jsonCreate a new draft:
python3 scripts/sync_wechat_article.py --slug your-article-slugUse a full URL instead of a slug:
python3 scripts/sync_wechat_article.py https://example.com/blog/your-article/Update an existing draft:
python3 scripts/sync_wechat_article.py --slug your-article-slug --update-media-id MEDIA_IDPublish after creating or updating a draft:
python3 scripts/sync_wechat_article.py --slug your-article-slug --publishPublish an existing draft directly:
python3 scripts/sync_wechat_article.py --publish-existing-media-id MEDIA_IDCreate a draft and send it to all followers:
python3 scripts/sync_wechat_article.py --slug your-article-slug --mode sendallSend only to a specific fan tag:
python3 scripts/sync_wechat_article.py --slug your-article-slug --mode sendall --tag-id 123- If a markdown file under
content_rootalready containswechatDraftMediaId, the script reuses it as the update target when--update-media-idis not explicitly provided. - When updating a draft, the original draft cover is reused unless you explicitly pass
--thumb. - Inline images that cannot be uploaded are left as their original URLs.
- Cover images must be in a WeChat-supported format. SVG covers can be converted to PNG automatically if
sharpis installed. - Relative
--outputpaths are written under this repository.
- Do not commit
config/wechat.local.json. - Do not commit real
app_idorapp_secret. - Review generated payloads in
tmp/before sharing them.
The repository ignores local config and generated preview files by default.