{"id":50977852,"url":"https://github.com/addozhang/omnipub","last_synced_at":"2026-06-19T10:03:09.900Z","repository":{"id":356629601,"uuid":"1179537248","full_name":"addozhang/omnipub","owner":"addozhang","description":"一键将 Markdown 文章发布到 11 个技术博客平台","archived":false,"fork":false,"pushed_at":"2026-05-08T23:38:30.000Z","size":501,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-09T01:22:04.444Z","etag":null,"topics":["blog-publishing","chrome-extension","csdn","fastapi","juejin","markdown","multi-platform","publishing-tool","vue3","zhihu"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/addozhang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-12T05:54:46.000Z","updated_at":"2026-05-08T23:38:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/addozhang/omnipub","commit_stats":null,"previous_names":["addozhang/omnipub"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/addozhang/omnipub","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addozhang%2Fomnipub","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addozhang%2Fomnipub/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addozhang%2Fomnipub/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addozhang%2Fomnipub/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/addozhang","download_url":"https://codeload.github.com/addozhang/omnipub/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addozhang%2Fomnipub/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34526073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blog-publishing","chrome-extension","csdn","fastapi","juejin","markdown","multi-platform","publishing-tool","vue3","zhihu"],"created_at":"2026-06-19T10:03:09.021Z","updated_at":"2026-06-19T10:03:09.891Z","avatar_url":"https://github.com/addozhang.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/banner.svg\" alt=\"Omnipub Banner\" width=\"800\"/\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/addozhang/omnipub/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/addozhang/omnipub/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"./LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/addozhang/omnipub/releases\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/addozhang/omnipub\" alt=\"Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/addozhang/omnipub/stargazers\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/addozhang/omnipub?style=social\" alt=\"Stars\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Omnipub\n\n一键将 Markdown 文章发布到 11 个技术博客平台的工具。\n\n**三个子系统：**\n- 🖥️ **Web 管理端** — 写文章、管理发布记录、配置渠道\n- ⚙️ **后端 API** — FastAPI，负责数据存储和业务逻辑\n- 🔌 **Chrome 扩展** — 在各平台编辑器里自动填充内容并发布\n\n## 支持平台\n\n掘金 · CSDN · 知乎 · 博客园 · 今日头条 · 腾讯云 · 51CTO · 思否 · 开源中国 · InfoQ · 哔哩哔哩\n\n## 架构\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"docs/architecture.svg\" alt=\"Omnipub Architecture\" width=\"900\"/\u003e\n\u003c/p\u003e\n\n## 快速启动\n\nOmnipub 由三部分组成，**必须按顺序安装**：先启动服务端，再安装扩展。\n\n### 第一步：启动服务（后端 + 前端）\n\n推荐使用预构建 Docker 镜像：\n\n```bash\n# 1. 下载配置文件\ncurl -O https://raw.githubusercontent.com/addozhang/omnipub/main/docker-compose.yml\ncurl -O https://raw.githubusercontent.com/addozhang/omnipub/main/.env.example\ncp .env.example .env\n\n# 2. 修改 SECRET_KEY（必须）\n# vim .env\n\n# 3. 启动\ndocker compose up -d\n\n# 4. 确认服务正常运行\ncurl -s http://localhost:3000/api/health\n# 应返回 {\"success\":true,...}\n```\n\n服务启动后访问 `http://localhost:3000`（或你的服务器 IP:3000），注册账号并登录。\n\n镜像地址：\n- `ghcr.io/addozhang/omnipub/backend:latest`\n- `ghcr.io/addozhang/omnipub/frontend:latest`\n\n### 第二步：安装 Chrome 扩展\n\n\u003e **先确认服务已正常运行。** 扩展启动后会通过后端校验登录态，如果服务未启动会报 \"Failed to fetch\" 错误。\n\n1. 从 [Releases](https://github.com/addozhang/omnipub/releases) 下载最新的 `omnipub-extension-*.zip`\n2. 打开 `chrome://extensions/`，开启「开发者模式」\n3. 将 `.zip` 拖入页面安装（或解压后「加载已解压的扩展程序」）\n\n### 第三步：配置扩展并登录\n\n1. 点击浏览器工具栏的 Omnipub 扩展图标\n2. **如果服务不在 localhost:3000**（如远程服务器 `http://150.109.196.70:3000`）：在底部「后端地址」填入实际地址并保存\n3. 在前端页面进入「设置」→「API 密钥」，创建 Chrome Session Token\n4. 将 Token 粘贴到扩展弹窗中，点击「登录」\n5. **如果修改过后端地址，刷新前端页面**确保扩展桥接生效\n\n### 第四步：发布文章\n\n1. 在前端页面创建/编辑一篇 Markdown 文章\n2. 进入文章的「发布」页面，选择目标平台\n3. 确保已在各平台（掘金、CSDN 等）的浏览器中登录\n4. 点击「一键发布」，扩展会自动在后台打开各平台编辑器并填充发布\n\n\u003e 可在「设置」页面检查各平台的登录状态。\n\n### 其他启动方式\n\n\u003cdetails\u003e\n\u003csummary\u003e从源码构建（Docker）\u003c/summary\u003e\n\n```bash\ngit clone https://github.com/addozhang/omnipub.git\ncd omnipub\ncp .env.example .env\n\n# docker-compose.override.yml 会自动覆盖为本地 build 模式\ndocker compose up -d --build\n\n# 访问\nopen http://localhost:3000          # 前端\nopen http://localhost:8000/docs     # API 文档（开发模式下可直接访问后端）\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e不用 Docker（纯本地开发）\u003c/summary\u003e\n\n**后端：**\n```bash\npython -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -e \".[dev]\"\ncp .env.example .env\nuvicorn app.main:app --reload\n# http://localhost:8000\n```\n\n**前端：**\n```bash\ncd frontend\nnpm install\nnpm run dev\n# http://localhost:5173（自动代理 /api/ 到 localhost:8000）\n```\n\n纯本地开发时扩展默认连接 `localhost:3000`，需要在扩展弹窗中将后端地址改为 `http://localhost:5173`。\n\n\u003c/details\u003e\n\n### 扩展打包（开发者）\n\n```bash\nbash pack-extension.sh\n# 输出: dist/omnipub-extension-v1.3.3.zip\n```\n\n## 运行测试\n\n```bash\n# 后端测试（230 个）\npytest tests/ -v\n\n# 前端单元测试\ncd frontend \u0026\u0026 npx vitest run\n\n# 前端 Playwright E2E（需先启动 Docker Compose）\ndocker compose up -d\ncd frontend \u0026\u0026 npx playwright test\n\n# 扩展单元测试\ncd extension \u0026\u0026 npx vitest run\n```\n\n## 技术栈\n\n| 层 | 技术 |\n|---|---|\n| 后端 | Python 3.12 · FastAPI · SQLAlchemy 2.0 (async) · JWT · Pydantic v2 |\n| 前端 | Vue 3 · Vite · Tailwind CSS · Pinia · Axios |\n| 扩展 | Chrome MV3 · Service Worker · Content Scripts |\n| 数据库 | SQLite（开发）· PostgreSQL（生产推荐） |\n| 测试 | pytest · httpx · Playwright |\n| CI/CD | GitHub Actions · ghcr.io |\n\n## API 概览\n\n| 模块 | 端点 | 说明 |\n|---|---|---|\n| Auth | `POST /api/auth/register` | 用户注册 |\n| Auth | `POST /api/auth/login` | 登录（返回 JWT） |\n| Articles | `GET /api/articles` | 文章列表 |\n| Articles | `POST /api/articles` | 创建文章（支持 API Key） |\n| Articles | `GET/PUT/DELETE /api/articles/{id}` | 文章 CRUD |\n| Platforms | `GET /api/platforms` | 平台列表 |\n| Platforms | `GET /api/platforms` | 平台列表（id/name/slug/URL/状态） |\n| Publications | `POST /api/articles/{id}/publish` | 创建发布记录 |\n| Publications | `POST /api/articles/report-publish-result` | 上报发布结果 |\n| Publications | `GET /api/articles/{id}/publications` | 查看发布记录 |\n| API Keys | `POST /api/api-keys` | 创建 API Key |\n| API Keys | `GET /api/api-keys` | 列出 API Keys |\n| User | `PUT /api/user/password` | 修改密码 |\n\n完整文档：启动后访问 `http://localhost:8000/docs`\n\n## 部署\n\n见 [DEPLOY.md](./DEPLOY.md)\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddozhang%2Fomnipub","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faddozhang%2Fomnipub","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddozhang%2Fomnipub/lists"}