wechat-article-uploader
把本地 md / txt 文章上传到微信公众号草稿箱的命令行工具。
它会自动完成这些事:
- 解析本地文章标题、正文和摘要
- 把正文里的本地图片先上传到公众号素材库,再替换为远程 URL
- 自动套用内置公众号样式,并转换为行内样式,降低微信编辑器兼容问题
- 支持单文件上传、目录批量上传和
dry-run预演
安装
发布到 PyPI 后,直接安装:
python3 -m pip install wechat-article-uploader
如果你是在仓库里本地开发:
uv sync --dev
执行命令时,推荐统一走 uv run:
uv run wechat-article-uploader --help
配置文件
这个项目已经改为使用 config.toml,不再依赖 .env。
你可以用下面两种方式提供配置:
- 在当前运行目录放一个
config.toml - 放到系统默认配置路径
查看默认配置路径:
uv run wechat-article-uploader --print-config-path
创建配置文件最简单的方法:
cp config.example.toml config.toml
配置内容示例:
[wechat_article_uploader]
app_id = "your_app_id"
app_secret = "your_app_secret"
default_author = ""
default_thumb_media_id = ""
default_content_source_url = ""
default_need_open_comment = 0
default_only_fans_can_comment = 0
request_timeout = 20
retry_times = 3
retry_backoff_seconds = 1.5
token_cache_file = ""
style_file = ""
字段说明:
app_id:公众号 AppIDapp_secret:公众号 AppSecretdefault_author:默认作者,可留空default_thumb_media_id:默认封面素材 ID,可留空;留空时会自动使用正文里第一张成功上传到素材库的本地图片default_content_source_url:原文链接,可留空default_need_open_comment:默认评论开关,0或1default_only_fans_can_comment:默认仅粉丝评论,0或1request_timeout:接口超时秒数retry_times:失败重试次数retry_backoff_seconds:每次重试的退避间隔倍率token_cache_file:token 缓存文件路径;留空时使用系统缓存目录style_file:自定义 CSS 文件路径;留空时使用包内默认样式
用法
单文件上传
uv run wechat-article-uploader --file "/path/to/article.md"
目录批量上传
uv run wechat-article-uploader --dir "/path/to/articles"
指定配置文件
uv run wechat-article-uploader --config "/path/to/config.toml" --file "/path/to/article.md"
预演模式
uv run wechat-article-uploader --dir "/path/to/articles" --dry-run
dry-run 不会调用微信接口,适合先检查标题、解析和日志输出。
如果没有显式传 --thumb-media-id,也没有在配置文件中设置 default_thumb_media_id,程序会默认使用正文里第一张成功上传到素材库的本地图片作为封面。
常用覆盖参数
uv run wechat-article-uploader \
--file "/path/to/article.md" \
--author "作者名" \
--thumb-media-id "封面素材ID" \
--digest "摘要文本" \
--content-source-url "https://example.com/source" \
--need-open-comment 0 \
--only-fans-can-comment 0
如果你还在仓库里直接运行,也可以继续用兼容入口:
uv run python main.py --file "/path/to/article.md"
输入规则
- 支持后缀:
md、txt - Markdown:
- 首个非空行为
# 标题或## 标题时,会作为文章标题 - 否则使用文件名作为标题
- 首个非空行为
- Text:
- 首个非空行作为标题
- 后续内容作为正文
日志与失败重试
每次运行会在 logs/ 生成:
upload_results_时间戳.json:完整结果failed.json:仅失败项
你可以根据 failed.json 中的文件路径做二次重传。
开发与发布
本项目已经整理为标准 Python 包结构,支持构建 wheel 和 sdist:
uv build
本地测试:
uv run pytest
如果你准备正式发 GitHub Release 和 PyPI,完整流程见 RELEASING.md。
如果你刚克隆仓库,推荐流程是:
uv sync --dev
uv run pytest
uv build
常见错误
未找到配置文件:先创建config.toml,或通过--config指定缺少配置项:检查app_id、app_secret是否填写未提供封面 thumb_media_id,且自动获取失败:检查素材库权限、IP 白名单,或手动填写default_thumb_media_id加载样式文件失败:检查style_file路径是否正确、文件是否为空创建草稿失败 errcode=...:检查公众号权限、素材 ID 是否有效、内容是否符合微信限制上传素材库图片失败:检查本地图片路径、公众号素材权限、图片格式与大小限制
已知限制
- 微信
draft/add接口当前不支持通过 API 设置“原创声明”和“创作来源” - 若需要这两项,请在公众号后台草稿编辑页手动设置后再发布
发布说明
- 项目许可证已设为
MIT - PyPI 自动发布工作流已配置在
.github/workflows/publish-pypi.yml - 首次公开前,仍建议轮换一次公众号密钥
Release files for wechat-article-uploader 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| wechat_article_uploader-0.1.0.tar.gz | 17.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| wechat_article_uploader-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.4 kB
Release files / wechat_article_uploader-0.1.0.tar.gz
| Download URL | wechat_article_uploader-0.1.0.tar.gz |
|---|---|
| Size | 17.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9b0b45cd0b21febf366961b2eb91641f50f490c9d72df531d4a3499a15787d59
|
|
BLAKE2b-256 checksum How to use checksums |
1827065fa56fb10368cd99198180340b60570889b09d12a87e3bb8e1853bdf2e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|
Release files / wechat_article_uploader-0.1.0-py3-none-any.whl
| Download URL | wechat_article_uploader-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a5c58280167f7559cf44acf26e45f8cfd2952a3fbddc27e40f19e4390dc77d54
|
|
BLAKE2b-256 checksum How to use checksums |
579ef4ea4da955bbdf3bd371faa5adaf1b1e582334ee9101b43e6523de76f4ee
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.10
|