Skip to content

hele211/wechatUploader

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

WeChat Official Account Article Publisher

A Python tool to publish articles to WeChat Official Account (微信公众号) draft box via API. Supports multiple article formats/templates, automatic image upload, and Chinese text.

Features

  • 📝 Publish articles to WeChat Official Account draft box via API
  • 🖼️ Automatic image upload and URL/media_id handling (permanent materials)
  • 📋 Template system for different article formats (standard, news, tutorial, review, etc.)
  • 🇨🇳 Full Chinese text support (UTF-8) with proper encoding
  • 📄 Markdown to HTML conversion with inline styles for WeChat compatibility
  • Validation before publishing (metadata, sections, images)
  • 🔒 Secure credential management via YAML config or environment variables
  • 🖥️ CLI interface with dry-run mode for testing
  • 🗂️ Auto-detection of image folders based on article name

Installation

Prerequisites

  • Python 3.7+
  • WeChat Official Account with API access enabled
  • AppID and AppSecret credentials

Setup

  1. Clone or download this repository

  2. Install dependencies:

pip install -r requirements.txt

Required packages:

  • requests - HTTP client for WeChat API
  • pyyaml - YAML configuration parsing
  • click - CLI framework
  • python-dotenv - Environment variable management
  • jinja2 - Template rendering engine

Configuration

  1. Create config file:
cp config.yaml.example config.yaml
  1. Edit config.yaml with your WeChat API credentials:
wechat:
  app_id: "your_app_id_here"
  app_secret: "your_app_secret_here"
  default_author: "Your Name"
templates:
  directory: "templates"
  default: "standard"

Or use environment variables:

export WECHAT_APP_ID="your_app_id"
export WECHAT_APP_SECRET="your_app_secret"
export WECHAT_DEFAULT_AUTHOR="Your Name"

Getting WeChat API Credentials

  1. Log in to WeChat Official Account Platform
  2. Go to Settings → Developer Settings (设置 → 开发设置)
  3. Enable API interface (启用接口)
  4. Create an AppID and AppSecret
  5. Add your AppID and AppSecret to config.yaml

Note: Keep your credentials secure. Never commit config.yaml to version control.

Usage

Basic Usage

# Publish article (images folder auto-detected)
python src/main.py articles/my_article.md

# Specify template
python src/main.py articles/my_article.md --template news

# Specify images folder explicitly
python src/main.py articles/my_article.md --images ./articles/my_article/images

# Preview without publishing (dry-run)
python src/main.py articles/my_article.md --dry-run

# List available templates
python src/main.py --list-templates

Project Structure

悦彤有佳/
├── articles/                    # Article storage directory
│   ├── example_article.md       # Example article with frontmatter
│   ├── example_article/         # Images for example_article
│   │   ├── cover.jpg
│   │   └── image1.jpg
│   └── README.md                # Article guidelines
├── src/                         # Source code
│   ├── __init__.py
│   ├── main.py                  # CLI entry point
│   ├── article_parser.py        # Markdown parser & HTML converter
│   ├── config.py                # Configuration loader
│   ├── template_manager.py      # Template validation & rendering
│   └── wechat_api.py            # WeChat API client
├── templates/                   # Article templates (YAML)
│   ├── standard.yaml            # Default template
│   ├── news.yaml                # News article format
│   ├── tutorial.yaml            # Tutorial/how-to format
│   └── review.yaml              # Review/analysis format
├── config.yaml                  # Configuration (not in git)
├── config.yaml.example          # Configuration template
├── requirements.txt             # Python dependencies
├── README.md                    # This file
└── QUICKSTART.md                # Quick start guide

Architecture

Core Components

  1. Article Parser (article_parser.py)

    • Parses Markdown with YAML frontmatter
    • Converts Markdown to HTML with inline styles
    • Handles image references (multiple formats)
    • Extracts content sections for template validation
    • Supports headers, lists, blockquotes, emphasis, images
  2. WeChat API Client (wechat_api.py)

    • Access token management with automatic refresh
    • Image upload (permanent materials with URL)
    • Draft creation (supports single/multiple articles)
    • Error handling with custom exceptions
  3. Template Manager (template_manager.py)

    • Loads templates from YAML files
    • Validates articles against template requirements
    • Renders HTML using Jinja2 templates
    • Supports metadata, section, and image validation
  4. Configuration (config.py)

    • Loads from config.yaml or environment variables
    • Supports .env files via python-dotenv
    • Provides access to WeChat and template configs
  5. CLI Interface (main.py)

    • Command-line interface with Click framework
    • Auto-detects image folders
    • Dry-run mode for testing
    • Template listing
    • Comprehensive error messages and progress updates

Article Format

Articles are plain text Markdown files (.md) with YAML frontmatter:

---
title: "我的文章标题"
author: "作者名称"
template: "standard"
publish_date: "2024-01-15"
category: "科技"
tags: ["人工智能", "机器学习"]
cover_image: "cover.jpg"
digest: "文章摘要,用于预览"
---

## 文章开头

这是文章内容的第一段。

### 小标题

更多内容,支持以下Markdown语法:

- **粗体文本** 使用 `**text**``__text__`
- *斜体文本* 使用 `*text*``_text_`
- 无序列表使用 `*``-`
- 有序列表使用 `1.` `2.`### 插入图片

![图片描述](image1.jpg)

> 这是引用块,显示为带左边框的样式

---

这是分隔线。

Supported Markdown Features:

  • Headers: #, ##, ###, ####
  • Bold: **text** or __text__
  • Italic: *text* or _text_
  • Lists: Unordered (*, -) and ordered (1., 2.)
  • Blockquotes: > text
  • Horizontal rules: ---
  • Images: ![alt](filename.jpg)

Image Reference Formats:

  • Markdown style: ![描述文字](image.jpg) (recommended)
  • Simple format: [image:image.jpg]
  • Cover image: specified in frontmatter as cover_image: "cover.jpg"

Important Notes:

  • Article file contains only text and image references
  • Actual image files must exist in the article's images folder
  • Images are automatically uploaded to WeChat when publishing
  • All HTML is generated with inline styles for WeChat compatibility
  • Title is limited to 32 bytes (UTF-8 encoded, ~10-11 Chinese characters)
  • Digest is limited to 120 characters

Templates

Templates are YAML files defining article structure and validation rules. Each template specifies:

  • Required and optional metadata fields
  • Required and optional content sections
  • Image requirements (cover, max count)
  • HTML rendering template (Jinja2)

Available templates:

  • standard - Basic article format (default)
  • news - News article format
  • tutorial - Tutorial/how-to format
  • review - Product review format

Template Structure Example:

name: "standard"
display_name: "标准文章"
description: "基本文章模板,适用于一般文章格式"

metadata:
  required: [title, author]
  optional: [publish_date, category, tags, cover_image]

sections:
  required: [body]
  optional: [introduction, conclusion]

images:
  cover_required: false
  inline_allowed: true
  max_count: 20

html_template: |
  <div class="article-standard">
    <h1>{{title}}</h1>
    {% if author %}<div class="author">作者:{{author}}</div>{% endif %}
    <div class="content">{{content}}</div>
  </div>

Creating Custom Templates:

  1. Create a new YAML file in templates/ directory
  2. Define validation rules and HTML template
  3. Use in articles with template: "your_template_name"

Image Handling

Requirements

  • Formats: JPG, JPEG, PNG only
  • Size: Maximum 10MB per image
  • Upload Type: Permanent materials (required for drafts)
  • Returns: Both media_id (for cover) and url (for content images)

Organization

Each article should have its own images folder:

articles/
├── my_article.md
└── my_article/          ← Same name as article file
    ├── cover.jpg
    ├── image1.jpg
    └── image2.png

Upload Process

The tool automatically:

  1. Detects image folder (named after article, or use --images option)
  2. Finds image files referenced in article (case-insensitive matching)
  3. Validates format (.jpg, .jpeg, .png) and size (max 10MB)
  4. Uploads to WeChat permanent material library
  5. Receives media_id and url from WeChat API
  6. Converts Markdown image references to HTML <img> tags with inline styles
  7. Includes both data-mediaid and src attributes for compatibility

Image Conversion

Markdown references are converted to HTML with inline styles:

![Alt text](image1.jpg)

Becomes:

<img data-mediaid="MEDIA_ID_HERE" 
     src="https://mmbiz.qpic.cn/..." 
     data-src="https://mmbiz.qpic.cn/..."
     alt="Alt text" 
     style="max-width: 100%;height: auto;display: block;margin: 10px auto;" />

Advanced Features

Dry Run Mode

Test your article without uploading to WeChat:

python src/main.py articles/my_article.md --dry-run

This will:

  • ✅ Validate article structure and metadata
  • ✅ Check all images exist
  • ✅ Verify template requirements
  • ✅ Show what would be uploaded
  • ❌ Not upload images or create drafts

Auto-Detection

The tool automatically detects:

  • Images folder: Looks for folder with same name as article
  • Template: Uses default if not specified in frontmatter
  • Image format: Supports case-insensitive matching

Debug Information

When publishing, the tool shows detailed progress:

  • Access token status
  • Each image upload with media_id and URL
  • HTML conversion statistics
  • Image tag generation details
  • Duplicate URL detection (warnings)

WeChat API Integration

  • Access token caching: Tokens cached for ~2 hours, auto-refresh
  • Permanent materials: Images uploaded as permanent materials (not temporary)
  • Draft API: Uses WeChat draft creation API (not direct publish)
  • URL handling: Converts HTTP to HTTPS automatically
  • Error handling: Detailed error messages with codes

Case-Insensitive Image Matching

The parser supports case-insensitive image filename matching:

  • Article references: ![](Image1.JPG)
  • File on disk: image1.jpg
  • Still works! ✅

Examples

Example 1: Basic Article

File: articles/simple_article.md

---
title: "简单文章"
author: "作者"
---

这是文章内容。

![示例图片](example.jpg)

Folder structure:

articles/
├── simple_article.md
└── simple_article/
    └── example.jpg

Command:

python src/main.py articles/simple_article.md

Example 2: News Article with Template

File: articles/news_article.md

---
title: "重要新闻"
author: "记者"
template: "news"
publish_date: "2024-01-15"
location: "北京"
cover_image: "cover.jpg"
---

这是新闻开头。

![新闻图片](news_photo.jpg)

Folder structure:

articles/
├── news_article.md
└── news_article/
    ├── cover.jpg
    └── news_photo.jpg

Command:

python src/main.py articles/news_article.md --template news

Error Handling & Troubleshooting

Error Messages

The tool provides comprehensive error handling:

  1. Missing credentials

    Error: Configuration error: WeChat API credentials not found
    

    → Create config.yaml or set environment variables

  2. Missing images

    Error: Missing image files in /path/to/images:
      - image1.jpg
      - image2.png
    

    → Create images folder and add missing files

  3. Validation errors

    Validation errors:
      - Missing required metadata field: title
      - Missing required section: body
    

    → Add required fields to article frontmatter

  4. API errors

    Error: Failed to get access token: 40001 - invalid credential
    

    → Check AppID and AppSecret in config

  5. Image format errors

    Error: Unsupported image format: .gif (only JPG/PNG supported)
    

    → Convert images to JPG or PNG

  6. Image size errors

    Error: Image file too large: 12582912 bytes (max 10485760 bytes)
    

    → Compress images to under 10MB

Common Issues

Q: "Images folder not found"

  • Ensure folder exists: articles/my_article/ for articles/my_article.md
  • Or specify explicitly: --images ./path/to/images

Q: "Some images were not converted"

  • Check image filenames match exactly (case-insensitive supported)
  • Ensure image files exist in images folder
  • Use supported reference formats: ![alt](filename.jpg)

Q: "WARNING: All images may be the same!"

  • WeChat returned same URL for different images
  • Check if you accidentally uploaded same image multiple times
  • Verify each image file is unique

Q: "Title truncated to 32 bytes"

  • WeChat limit: 32 bytes UTF-8 (≈10-11 Chinese characters)
  • Tool automatically truncates with "..." suffix
  • Consider shortening title in frontmatter

Q: "Access token expired"

  • Token automatically refreshes (7200s = 2 hours)
  • Manual refresh: restart the tool
  • Check network connection to api.weixin.qq.com

Debug Mode

For detailed debugging, check the .cursor/debug.log file which contains:

  • Image upload details
  • Image mapping information
  • HTML conversion steps
  • API responses

"Image file not found"

  • Check that image files exist in the images folder
  • Verify filenames match exactly (case-sensitive on some systems)
  • Make sure images are JPG or PNG format

"Template not found"

  • Check available templates with --list-templates
  • Verify template name is correct
  • Make sure template YAML files are in templates/ directory

API Errors

  • Check your AppID and AppSecret are correct
  • Verify API access is enabled in WeChat Official Account settings
  • Check rate limits (2000 image uploads per day)
  • Ensure images are valid format and size

Development

Code Quality

The codebase follows Python best practices:

  • Type hints for function parameters and returns
  • Docstrings for all classes and methods
  • Exception handling with custom exception classes
  • Separation of concerns (parsing, API, templates, config)
  • UTF-8 encoding throughout for Chinese text support

Project Structure

src/
├── main.py                  # CLI entry point with Click framework
├── article_parser.py        # Markdown parser & HTML converter
│   └── ArticleParser        # Parse frontmatter, convert Markdown to HTML
├── wechat_api.py            # WeChat API client
│   └── WeChatAPI            # Token management, image upload, draft creation
├── template_manager.py      # Template validation & rendering
│   └── TemplateManager      # Load templates, validate, render with Jinja2
└── config.py                # Configuration loader
    └── Config               # Load from YAML or environment variables

Testing

To test the tool:

  1. Dry run (no upload):

    python src/main.py articles/example_article.md --dry-run
  2. Validate configuration:

    python -c "from src.config import Config; c = Config(); print(c.get_wechat_config())"
  3. List templates:

    python src/main.py --list-templates

Extending the Tool

Adding New Templates:

  1. Create a new YAML file in templates/
  2. Define metadata requirements, sections, and HTML template
  3. Reference in articles: template: "your_template"

Adding New Image Reference Formats: Edit article_parser.py and add pattern to IMAGE_PATTERNS:

IMAGE_PATTERNS = [
    (r'!\[([^\]]*)\]\(([^)]+)\)', 'markdown'),
    (r'\[image:([^\]]+)\]', 'simple'),
    (r'YOUR_NEW_PATTERN', 'custom'),
]

Adding New Markdown Features: Edit the convert_to_html() method in article_parser.py

Dependencies

Package Version Purpose
requests ≥2.31.0 HTTP client for WeChat API calls
pyyaml ≥6.0 Parse YAML configuration and templates
click ≥8.1.0 CLI framework for command-line interface
python-dotenv ≥1.0.0 Load environment variables from .env
jinja2 ≥3.1.0 Template rendering engine for HTML

API Reference

WeChat Official Account APIs Used

  1. Get Access Token

    • Endpoint: /cgi-bin/token
    • Method: GET
    • Params: grant_type, appid, secret
    • Cached for ~2 hours (7200s)
  2. Upload Permanent Material

    • Endpoint: /cgi-bin/material/add_material
    • Method: POST
    • Type: image
    • Returns: media_id and url
    • Max size: 10MB
    • Formats: JPG, PNG
  3. Create Draft

    • Endpoint: /cgi-bin/draft/add
    • Method: POST
    • Accepts: Array of articles with title, author, content, thumb_media_id
    • Returns: Draft media_id

Configuration Options

config.yaml:

wechat:
  app_id: "wx..."              # WeChat AppID (required)
  app_secret: "..."            # WeChat AppSecret (required)
  default_author: "作者"        # Default author name (optional)

templates:
  directory: "templates"       # Templates directory (default: "templates")
  default: "standard"          # Default template (default: "standard")

Environment Variables:

  • WECHAT_APP_ID - WeChat AppID
  • WECHAT_APP_SECRET - WeChat AppSecret
  • WECHAT_DEFAULT_AUTHOR - Default author name

Contributing

Contributions welcome! Areas for improvement:

  • Support for more Markdown features (tables, code blocks with syntax highlighting)

  • Batch publishing multiple articles

  • Direct publish (not just draft)

  • Support for video uploads

  • Web interface (Flask/FastAPI)

  • Article scheduling

  • Image optimization/compression before upload

  • Retry logic for failed uploads

  • Progress bar for large batches

  • Image optimization/compression before upload

  • Retry logic for failed uploads

  • Progress bar for large batches

Security Notes

⚠️ Important Security Practices:

  • Never commit config.yaml with real credentials to version control (already in .gitignore)
  • Use .env files for local development (also gitignored)
  • Rotate AppSecret regularly via WeChat Official Account platform
  • Use environment variables in production environments
  • Keep requirements.txt updated for security patches
  • Limit API access - only enable necessary permissions
  • Monitor usage - WeChat has rate limits (2000 image uploads/day)

Known Limitations

  • Title limited to 32 bytes UTF-8 (≈10-11 Chinese characters) due to WeChat API
  • Digest limited to 120 characters
  • Maximum 20 images per article (can be configured in template)
  • Maximum 10MB per image
  • Only JPG and PNG formats supported
  • Creates drafts only (not direct publish)
  • No support for video/audio yet
  • No batch processing of multiple articles

Changelog

Current Version

  • ✅ Markdown to HTML conversion with inline styles
  • ✅ Multiple template support (standard, news, tutorial, review)
  • ✅ Permanent material upload with URL support
  • ✅ Case-insensitive image matching
  • ✅ Dry-run mode for testing
  • ✅ Comprehensive error handling
  • ✅ Auto-detection of image folders
  • ✅ Debug logging for troubleshooting
  • ✅ UTF-8 Chinese text support throughout

Acknowledgments

  • WeChat Official Account Platform API documentation
  • Python community for excellent libraries (requests, click, jinja2, pyyaml)
  • Contributors and testers

License

This project is provided as-is for educational and personal use purposes.

Support

For issues or questions:

  1. Check the Error Handling & Troubleshooting section above
  2. Review QUICKSTART.md for step-by-step guide
  3. Check WeChat Official Account API documentation
  4. Verify your API credentials and permissions
  5. Look at example articles in articles/ directory

Last Updated: January 2026
Python Version: 3.7+
Platform: Cross-platform (macOS, Linux, Windows)
Author: 悦彤有佳 Development Team

About

微信公众号文章自动排版上传工具

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages