# md2wechat **Repository Path**: honj51/md2wechat ## Basic Information - **Project Name**: md2wechat - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-09 - **Last Updated**: 2026-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # md2wechat **Markdown → 微信公众号草稿箱** — 开源的一键发布 HTTP 微服务,附带 Web 管理面板 [](https://opensource.org/licenses/MIT) [](https://hub.docker.com/r/tenisinfinite/md2wechat) [](https://nodejs.org) --- ## 这是什么 `md2wechat` 是一个自托管的 HTTP 微服务,接收 Markdown 文件,自动完成格式转换、图片上传、封面生成,并将文章提交到微信公众号草稿箱。 它的设计目标是成为你内容工作流的**最后一环**——无论内容来自 Claude、Notion、飞书还是人工创作,只需统一转换为 Markdown,`md2wechat` 负责后续的一切。 你可以通过**内置 Web 管理面板**直接在浏览器中操作,也可以通过 **REST API** 集成到任何自动化工作流中。 ``` 你的内容工具(Claude / Notion / 飞书 / 手写) ↓ Markdown 文件 n8n / 脚本 / Web 面板 ↓ POST /api/publish md2wechat ↓ 微信公众号草稿箱 ↓ Webhook 回调 你的通知渠道(Slack / 企业微信 / n8n) ``` --- ## 核心功能 - **Web 管理面板**:浏览器内发布文章、查看历史、管理配置,开箱即用 - **Markdown → 微信兼容 HTML**:代码高亮、数学公式、表格、引用块全支持 - **图片自动处理**:本地图片和外链图片统一上传到微信图床,自动替换链接 - **双模式封面生成** - `sharp` 模式:背景图 + 标题文字合成,支持自定义背景和额外图层 - `ai` 模式:接入 Google Imagen 4 AI 生图,根据标题自动构建 Prompt - **自定义主题包**:支持挂载完整主题包(CSS + 兼容性覆盖),无需修改源码 - **Markdown 插件扩展**:通过配置文件注册任意 `markdown-it` 插件 - **发布历史持久化**:默认 SQLite,可切换为 PostgreSQL - **Webhook 回调**:发布成功后主动通知,支持全局配置和单次覆盖 - **标准 REST API**:任何工具都能调用,天然适配 n8n、Make、自定义脚本 --- ## 快速开始 ### 前置要求 - Docker & Docker Compose - 微信公众号 AppID 和 AppSecret(需已认证,并将服务器 IP 加入白名单) ### 一分钟启动 ```bash # 1. 克隆项目 git clone https://github.com/tenisinfinite/md2wechat.git cd md2wechat # 2. 配置环境变量 cp .env.example .env # 编辑 .env,至少填写 WXGZH_APPID 和 WXGZH_APPSECRET # 3. 构建并启动服务 npm run build docker-compose up -d # 4. 打开 Web 管理面板 open http://localhost:3000 ``` ### Web 管理面板 启动后访问 `http://localhost:3000` 即可使用 Web 管理面板: - **仪表盘**:服务状态一览(微信配置、数据库、AI 封面、Token 缓存) - **发布文章**:拖拽整个文件夹或选择文件,自动识别 Markdown 和图片,选择主题和封面策略,一键发布 - **发布历史**:分页查看所有发布记录,筛选状态,预览封面 - **系统设置**:查看当前配置和可用主题 ### 通过 API 发布 ```bash curl -X POST http://localhost:3000/api/publish \ -H "X-API-Key: your-api-key" \ -F "article=@article.md" \ -F "author=你的名字" \ -F "theme=blue" ``` 附带图片的发布: ```bash curl -X POST http://localhost:3000/api/publish \ -H "X-API-Key: your-api-key" \ -F "article=@output/article.md" \ -F "images[]=@output/images/img1.png" \ -F "images[]=@output/images/img2.png" \ -F "author=你的名字" ``` 成功后登录微信公众号后台 → 草稿箱,即可看到文章。 > **Web 面板提示**:你可以直接将包含 `.md` 文件和 `images/` 目录的整个文件夹拖入发布页面,系统会自动识别文章和图片文件。 --- ## 配置说明 ### 必填配置 | 变量名 | 说明 | |--------|------| | `WXGZH_APPID` | 微信公众号 AppID | | `WXGZH_APPSECRET` | 微信公众号 AppSecret | ### 常用可选配置 | 变量名 | 默认值 | 说明 | |--------|--------|------| | `WXGZH_DEFAULT_AUTHOR` | `tenisinfinite` | 默认作者名 | | `WXGZH_DEFAULT_THEME` | `default` | 默认主题 | | `WXGZH_DEFAULT_COVER_STRATEGY` | `sharp` | 默认封面策略(`sharp` / `ai`) | | `API_KEY` | 空(不鉴权) | 接口鉴权 Key | | `WEBHOOK_URL` | — | 全局 Webhook 回调地址 | | `DATABASE_URL` | SQLite | PostgreSQL 连接串,不填用 SQLite | ### AI 封面配置(Google Imagen 4) 通过 Gemini API 调用 Google Imagen 4 生成封面图。 | 变量名 | 说明 | |--------|------| | `IMAGEN_API_KEY` | Gemini API Key([获取地址](https://aistudio.google.com/apikey)) | | `IMAGEN_MODEL` | 模型名,默认 `imagen-4.0-fast-generate-001` | 可选模型: | 模型 | 特点 | 价格 | |------|------|------| | `imagen-4.0-fast-generate-001` | 快速生成(默认) | $0.02/张 | | `imagen-4.0-generate-001` | 标准质量 | $0.04/张 | | `imagen-4.0-ultra-generate-001` | 最高质量 | $0.06/张 | 未配置 `IMAGEN_API_KEY` 时,AI 封面请求会自动降级为 `sharp` 模式。 完整配置项见 [`.env.example`](.env.example)。 ### 微信 IP 白名单 微信公众号后台 → 设置与开发 → 开发接口管理 → 基本配置 → IP 白名单,将服务器的公网 IP 添加进去。 > 注意:如果使用 Docker 部署,容器的出口 IP 可能与宿主机不同。可通过 `docker exec <容器名> wget -qO- https://ip.sb` 查询容器实际出口 IP。 --- ## API 接口 ### POST /api/publish 发布文章到草稿箱。 **请求**:`multipart/form-data` | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | `article` | File (.md) | ✅ | Markdown 文章文件 | | `images[]` | File[] | — | 文章引用的本地图片(可多个) | | `cover` | File | — | 自定义封面图,优先级最高 | | `author` | string | — | 覆盖默认作者名 | | `theme` | string | — | 主题名(内置或自定义) | | `digest` | string | — | 文章摘要,不填则自动提取 | | `enableComment` | boolean | — | 是否开启评论 | | `coverStrategy` | `sharp` / `ai` | — | 封面生成策略 | | `coverPrompt` | string | — | AI 封面的自定义 Prompt | | `webhookUrl` | string | — | 本次发布的回调地址 | **成功响应**: ```json { "success": true, "data": { "publishId": "uuid", "mediaId": "草稿 media_id", "title": "文章标题", "author": "作者名", "coverUrl": "封面图 URL", "coverStrategy": "sharp", "publishedAt": "2025-01-01T00:00:00Z" } } ``` ### GET /api/history 查询发布历史。支持 `page`、`pageSize`、`status` 参数。 ### GET /api/themes 列出所有可用主题(内置 + 自定义)。 ### GET /api/config 查看当前配置(脱敏)。 ### GET /health 服务健康状态,包含微信配置、数据库连接、AI 封面可用性。 --- ## 进阶用法 ### 自定义主题包 在宿主机创建主题目录,然后挂载到容器: ``` my-theme/ ├── theme.css # 主题样式 ├── compat.css # 可选:覆盖微信兼容性 CSS └── theme.json # 主题元数据 ``` **theme.json**: ```json { "name": "my-theme", "displayName": "我的主题", "version": "1.0.0", "compatOverrides": { "highlight": true } } ``` **docker-compose.yml** 中添加挂载: ```yaml volumes: - ./my-theme:/app/themes/my-theme ``` 发布时指定 `theme=my-theme` 即可使用。 --- ### 自定义 Markdown 插件 在 `config/` 目录下创建 `markdown-plugins.js`: ```javascript // config/markdown-plugins.js module.exports = [ [require('markdown-it-footnote')], [require('markdown-it-container'), 'tip', { render: (tokens, idx) => tokens[idx].nesting === 1 ? '