wx-uploader

Crates.iowx-uploader
lib.rswx-uploader
version0.6.0
created_at2025-08-02 22:58:32.339346+00
updated_at2025-09-13 05:17:06.125917+00
descriptionA tool to upload articles to WeChat Official Account
homepagehttps://github.com/tyrchen/wx-uploader
repositoryhttps://github.com/tyrchen/wx-uploader
max_upload_size
id1779189
size223,749
Tyr Chen (tyrchen)

documentation

https://docs.rs/wx-uploader

README

wx-uploader

A command-line tool to upload markdown files to WeChat public account with automatic AI-powered cover image generation. See README_CN.md for Chinese version.

Installation

Install directly from crates.io:

cargo install wx-uploader

Or build from source:

git clone https://github.com/tyrchen/wx-uploader.git
cd wx-uploader
cargo install --path .

Prerequisites

Before using this tool, you need to set up the following environment variables:

# Required: WeChat public account credentials
export WECHAT_APP_ID="your_app_id"
export WECHAT_APP_SECRET="your_app_secret"

# Optional: OpenAI API key for automatic cover image generation
export OPENAI_API_KEY="your_openai_api_key"

Usage

Upload all markdown files in a directory

# Upload all .md files that don't have `published: true` in their frontmatter
wx-uploader .

# Upload from a specific directory
wx-uploader ./posts

# Enable verbose output
wx-uploader --verbose ./posts

Upload a specific file

# Force upload a specific file (ignores publish status)
wx-uploader ./2025/08/01-chat-with-ai.md

How it works

  1. The tool scans for markdown files with YAML frontmatter
  2. If a file doesn't have published: true in its frontmatter, it will be uploaded
  3. If no cover image is specified and OpenAI API key is available, generates a Studio Ghibli-style cover image using GPT-5 and gpt-image-1
  4. When specifying a single file, it will be uploaded regardless of its publish status
  5. After successful upload, the frontmatter is updated with published: draft and the cover filename (if generated)

Frontmatter Example

---
title: My Article Title
published: draft  # or 'true' to skip upload
cover: cover.png  # optional, auto-generated if missing and OpenAI key is set
description: Article description
author: Author Name
theme: lapis  # optional theme
---

Your markdown content here...

AI Cover Generation

When the OPENAI_API_KEY environment variable is set, the tool will automatically generate beautiful cover images for articles that don't have one specified.

How it works

  1. Content Analysis: GPT-5-mini analyzes your markdown content to create a vivid scene description
  2. Prompt Generation: Creates an optimized prompt for image generation focusing on Studio Ghibli-style artwork
  3. Image Generation: gpt-image-1 generates a high-quality 16:9 aspect ratio cover image
  4. Auto-Save: Downloads and saves the image in the same directory as your markdown file
  5. Metadata Update: Updates your frontmatter with the generated cover filename

Features

  • Studio Ghibli Style: Beautiful, artistic aesthetic with soft colors and natural elements
  • Content-Aware: Scene descriptions are based on your actual article content
  • High Quality: 1536x1024 resolution images optimized for web display
  • Automatic Naming: Generated files use unique names to prevent conflicts
  • Graceful Fallback: Continues normal upload process if image generation fails
  • Base64 Support: Handles both URL and base64-encoded image responses

Example Output

For an article about "Building Rust Applications", the AI might generate a scene like:

"A cozy workshop filled with intricate gears and glowing mechanical tools, where a craftsman carefully assembles clockwork mechanisms. Warm golden light streams through tall windows, illuminating floating rust particles that sparkle like fireflies in the dusty air."

This becomes a beautiful Studio Ghibli-style cover image that visually represents your content.

Features

  • 📝 Batch Upload: Process entire directories of markdown files
  • 🎨 AI Cover Generation: Automatic cover images using OpenAI's latest models
  • 🔄 Smart Processing: Skip already published articles
  • 📊 Progress Tracking: Clear console output with colored status indicators
  • 🛡️ Error Recovery: Graceful handling of API failures
  • 🔐 Secure: API keys stored in environment variables only

Development

Running Tests

The project includes comprehensive unit and integration tests:

# Run all tests
cargo test

# Run tests with output
cargo test -- --nocapture

# Run specific test module
cargo test test_frontmatter

# Run integration tests only
cargo test --test integration_tests

Code Quality

# Run clippy for linting
cargo clippy --all-targets --all-features

# Check for security vulnerabilities
cargo audit

# Format code
cargo fmt

# Generate documentation
cargo doc --open

Project Structure

wx-uploader/
├── src/
│   ├── main.rs          # CLI entry point
│   ├── lib.rs           # Public API
│   ├── cli.rs           # Command-line interface
│   ├── error.rs         # Error handling
│   ├── models.rs        # Data structures
│   ├── markdown.rs      # Markdown parsing
│   ├── openai.rs        # AI integration
│   ├── output.rs        # Console output formatting
│   └── wechat.rs        # WeChat API integration
└── tests/
    └── integration_tests.rs  # Integration tests

Notes

  • Files with published: true will be skipped during directory scans
  • Single file uploads always force upload regardless of publish status
  • The tool preserves all other frontmatter fields when updating
  • Cover images are saved in the same directory as the markdown file
  • Supports both string ("true") and boolean (true) values for the published field

License

MIT

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Commit count: 30

cargo fmt