Skip to main content

One-Click WeChat Publishing with Claude Skills

Handcrafted

Step-by-step guide to auto-publishing Markdown to WeChat Official Account using the baoyu-post-to-wechat Skill, covering installation, configuration, and the full workflow

·10 min read

If you've ever maintained a WeChat Official Account, you know the drill: you carefully format an article in your editor, paste it into the WeChat backend, and watch the formatting fall apart. Images need to be re-uploaded one by one. Code blocks turn into plain text. Spacing and font sizes you painstakingly adjusted need to be redone. Just formatting a single technical article can eat up half an hour.

I write my blog in Markdown, and to solve this problem, I built an automated publishing workflow based on Claude Skills. Now the entire process takes just one sentence — "Publish this article to WeChat" — and Claude automatically handles rendering, formatting, image uploading, and draft submission.

This article documents the complete setup process so you can replicate it directly.

If you're not yet familiar with what Skills are, I recommend reading What Are Claude Skills first. For more on creating and using Skills, check out Claude Skills Practical Guide.

Prerequisites

Before getting started, make sure you have the following:

RequirementDetails
Claude CodeInstall the Claude Code CLI — official installation guide
WeChat Official AccountA verified account with AppID and AppSecret
Node.jsRuntime environment; the Skill script runs via npx -y bun

How to get your WeChat API credentials: Log in to mp.weixin.qq.com → "Settings & Development" in the left menu → "Basic Configuration" → copy the Developer ID (AppID) and Developer Secret (AppSecret).

Note: The AppSecret is only shown once when reset — store it securely. You also need to add your server IP to the whitelist under "Basic Configuration."

Installing the Skill

baoyu-post-to-wechat is hosted on GitHub and can be installed with a single Claude Code command:

claude skill install jimliu/baoyu-skills --skill baoyu-post-to-wechat

After installation, the following file structure is generated in your project:

your-project/
├── .agents/skills/
│   └── baoyu-post-to-wechat/
│       ├── SKILL.md              # Core Skill instructions
│       ├── scripts/
│       │   ├── wechat-api.ts     # API publishing script
│       │   ├── wechat-browser.ts # Browser publishing script
│       │   └── md/               # Markdown rendering engine
│       │       ├── render.ts
│       │       └── themes/       # Theme CSS files
│       └── references/           # Detailed reference docs
└── skills-lock.json              # Skill version lock

skills-lock.json records the source and version hash of installed Skills, ensuring all team members use the same version:

{
  "version": 1,
  "skills": {
    "baoyu-post-to-wechat": {
      "source": "jimliu/baoyu-skills",
      "sourceType": "github",
      "computedHash": "cb28e409..."
    }
  }
}

Configuration

Configuration involves two steps: API credentials and preferences.

API Credentials

Create a .baoyu-skills/.env file with your WeChat Official Account credentials:

# Project-level config (applies to current project only)
mkdir -p .baoyu-skills
cat > .baoyu-skills/.env << 'EOF'
WECHAT_APP_ID=your_AppID
WECHAT_APP_SECRET=your_AppSecret
EOF

You can also place it in your home directory to share across all projects:

# User-level config (applies to all projects)
mkdir -p ~/.baoyu-skills
cat > ~/.baoyu-skills/.env << 'EOF'
WECHAT_APP_ID=your_AppID
WECHAT_APP_SECRET=your_AppSecret
EOF

Credential lookup priority: environment variables > project-level .baoyu-skills/.env > user-level ~/.baoyu-skills/.env.

Security tip: .baoyu-skills/.env contains sensitive information. Make sure to add .baoyu-skills/ to your .gitignore to prevent accidental commits.

Preferences (EXTEND.md)

Configure default preferences in .baoyu-skills/baoyu-post-to-wechat/EXTEND.md. Here's my configuration:

# WeChat Publishing Preferences

## Default Settings

- default_theme: yudesk
- default_author: yux

Supported configuration options:

OptionDefaultDescription
default_themedefaultRendering theme (default, grace, simple, yudesk)
default_publish_methodapiPublishing method (api or browser)
default_authoremptyDefault author name
need_open_comment1Whether to enable comments
only_fans_can_comment0Whether only followers can comment

Configuration priority: CLI arguments > article frontmatter > EXTEND.md > Skill defaults.

Writing Articles

Just write in standard Markdown format. My blog uses MDX custom components (BlogImage, QuoteCard, VideoEmbed, etc.), and the Skill automatically converts them to standard Markdown during publishing — no manual processing needed.

Conversion rules:

MDX ComponentConverts ToExample
<BlogImage>![alt](src) + captionImage + italic caption
<QuoteCard>> quote — authorBlockquote
<VideoEmbed>> 🎬 video title + linkBlockquote + video link
<ArticleCard>> 📄 article title + linkBlockquote + article link
<GlossaryCard>> 📖 term: definitionBlockquote
<ProfileCard>**name** — roleBold text

Additionally, internal blog links (/blog/..., /docs/...) are automatically converted to plain text, and import/export statements are removed. This means you can publish your blog's MDX files directly without maintaining two copies of the content.

Article Frontmatter

The following frontmatter fields are used during publishing:

---
title: Article Title
author: Author Name
description: Article summary (used as the WeChat article digest)
coverImage: cover.png  # Cover image (local path or URL)
---

If no cover image is provided, the Skill searches in this order: coverImage/featureImage/cover/image in frontmatter → imgs/cover.png in the article directory → first image in the article.

Publishing

Once everything is set up, publishing is straightforward.

Option 1: Conversational Publishing

In Claude Code, simply say:

Publish content/blog/my-article.mdx to WeChat

Claude automatically recognizes the intent, loads the baoyu-post-to-wechat Skill, and executes the workflow: load preferences → detect file type → render HTML → upload images → submit draft.

Option 2: Command-Line Publishing

You can also call the script directly:

npx -y bun .agents/skills/baoyu-post-to-wechat/scripts/wechat-api.ts article.md --author yux

Supported parameters:

ParameterDescription
--theme <name>Theme: default, grace, simple, yudesk
--author <name>Author name (max 16 characters)
--summary <text>Article summary (max 128 characters)
--cover <path>Cover image path
--dry-runRender only without publishing; for preview

Publishing Flow Explained

When publishing, the following steps happen behind the scenes:

Markdown File


① MDX preprocessing: BlogImage → ![](), QuoteCard → blockquote ...


② Markdown rendering: marked engine + highlight.js code highlighting


③ Theme application: base.css + yudesk.css, CSS variable resolution


④ CSS inlining: juice converts <style> to inline styles (required by WeChat)


⑤ Image upload: iterate <img> tags, upload to WeChat CDN, replace src


⑥ Cover processing: upload cover image, obtain thumb_media_id


⑦ Submit draft: call draft/add API, save to WeChat drafts

Key technical details:

  • CSS inlining: WeChat Official Account doesn't support <style> tags or external stylesheets — all CSS must be inlined into element style attributes. The Skill uses the juice library to handle this automatically, also replacing CSS variables (e.g., var(--md-primary-color)#0F4C81) and calc() expressions with actual values.
  • Image uploading: WeChat requires all article images to be stored on WeChat's CDN. The Skill iterates through every <img> tag in the HTML, uploads local or external URL images to the WeChat media library, then replaces the original src with WeChat CDN URLs.
  • Brand elements: During publishing, brand header and footer images are automatically added to maintain visual consistency across your account's articles.

Advanced: Custom Themes

The Skill includes 4 built-in themes: default (classic), grace (elegant), simple (minimal), and yudesk (tech blog). To create your own theme, simply add a CSS file to the themes/ directory.

Taking the yudesk theme I use as an example, its design philosophy is "clean, professional, and code-friendly":

/* yudesk theme core styles */

/* Headings: centered, dark */
h1, h2 { text-align: center; color: #1a1a1a; font-weight: bold; }

/* Paragraphs: moderate letter spacing, gray text */
p { letter-spacing: 0.05em; color: #555; }

/* Blockquotes: primary color left border */
blockquote { border-left: 3px solid var(--md-primary-color); background: var(--blockquote-background); }

/* Code blocks: GitHub style, light gray background */
pre.code__pre { background: #f6f8fa !important; border: 1px solid #e1e4e8; border-radius: 4px; }

/* Inline code: primary color */
code { color: var(--md-primary-color); background: rgba(15, 76, 129, 0.08); }

Steps to create a custom theme:

  1. Create a new my-theme.css file under .agents/skills/baoyu-post-to-wechat/scripts/md/themes/
  2. Refer to yudesk.css and write styles (overriding h1h6, p, blockquote, pre, code, table, etc.)
  3. Set default_theme: my-theme in EXTEND.md, or specify --theme my-theme when publishing

Theme CSS can use CSS variables like var(--md-primary-color) and var(--md-font-size) — the rendering engine automatically replaces them with actual values during the CSS inlining phase.

Gotchas and Lessons Learned

Here are some issues I encountered during actual use.

Code Blocks Wrapping on Mobile

WeChat's mobile client handles code blocks in a peculiar way. If white-space: pre is set (preserving original line breaks), long lines overflow horizontally. If set to pre-wrap (auto-wrapping), code indentation and formatting get broken.

The yudesk theme's solution is to keep white-space: pre while setting overflow-x: auto, allowing code blocks to scroll horizontally. It also limits max-height: 500px to prevent excessively long code blocks from taking over the entire mobile screen.

Summary Truncation

WeChat limits article summaries to 128 characters. If the article's description exceeds this limit, the Skill truncates intelligently: it looks for the nearest Chinese punctuation mark (period, comma, semicolon) around the 120-character mark and breaks there, avoiding mid-word truncation.

Cover Image Is Required

Articles of type news (standard articles) must include a cover image (thumb_media_id) — missing it causes an error. It's recommended to place a imgs/cover.png in the article directory as a default cover, or specify coverImage in the frontmatter.

CSS Variable Compatibility

WeChat's rendering engine doesn't support CSS variables (var(...)) or calc() expressions. The Skill's rendering engine replaces all variables with actual values during the CSS inlining phase:

var(--md-primary-color) → #0F4C81
hsl(var(--foreground))  → #3f3f3f
calc(16px * 1.3)        → 21px

This step is handled automatically — no manual intervention needed.

Complete Workflow Summary

The full workflow from writing to publishing:

StepActionNotes
1. Write articleWrite content in Markdown/MDXMDX components supported; auto-converted
2. Install Skillclaude skill install jimliu/baoyu-skillsFirst time only
3. Configure credentialsFill in .baoyu-skills/.envFirst time only
4. Set preferencesEdit EXTEND.mdOptional; set default theme/author
5. Publish"Publish to WeChat" or npx -y bun ... wechat-api.tsOne-click publishing
6. ReviewLog in to mp.weixin.qq.com → Content Management → DraftsPreview before publishing

After publishing, the article is saved to your WeChat drafts (it won't go live immediately). You can preview and edit it in the backend before officially publishing.

Further Reading

Comments

One-Click WeChat Publishing with Claude Skills | Yu's Cyber Desk