nevertoday/xposter
GitHub: nevertoday/xposter
xPoster 是一款开源 Chrome 扩展,帮助使用 Markdown 写作的创作者将草稿结构化地导入 X Articles 编辑器,省去手动排版和图片处理的麻烦。
Stars: 121 | Forks: 29
# xPoster
xPoster 是一款专为使用 Markdown 写作并在 X 上发布的创作者开发的免费开源 Chrome 扩展。它提供了一个侧边栏暂存面板,能够检测当前活跃的 X Article 编辑器,导入你的草稿,准备支持的媒体文件,保存可恢复的记录,并将最终的“发布”点击权留给你。
[中文说明](README.zh-CN.md) · [Chrome Web Store](https://chromewebstore.google.com/detail/xposter/iimkimodgdjnnmdopeolboakhjmhfbbj?authuser=0&hl=zh-CN) · [使用指南](docs/usage.md) · [隐私](docs/privacy.md)

## 为什么开发此工具
X Articles 非常适合发布长文,但许多人并不希望在它自带的编辑器中进行 drafting。如果你平时使用 Obsidian、Typora、Notion、VS Code、iA Writer 或任何以 Markdown 为核心的工作流进行写作,发布通常意味着手动重建文章:
- 将段落复制到编辑器中而不破坏原有结构
- 重新制作标题、列表、引用、链接、粗体、斜体和行内代码
- 将图片上传到正确的位置
- 将 Markdown 表格转换为在 X 上易于阅读的格式
- 将推文 URL 粘贴为真正的 X 嵌入内容
- 检查当前活跃的 X 编辑器是否可用
- 在操作部分成功时保留一份备用副本
xPoster 正是为了完成这一交接工作而构建的。Markdown 始终是你的 single source of truth,而 X 始终是最终的发布平台。
## 功能介绍
- **Markdown 转 X Article**:将标题、段落、列表、引用、行内样式、链接、代码、分隔线、图片、表格以及 X/Twitter 嵌入内容导入到 X Article 编辑器中。
- **单个草稿或批量队列**:可粘贴单个草稿、选择 `.md` 文件、拖放单个文件,或将多个 Markdown 文件加入队列并逐一写入。
- **智能图片导入**:处理 Markdown 文件附近的本地图片,在需要时请求获取本地图片文件夹的访问权限,并可针对网络图片请求一次性的 Chrome 权限。
- **X 中的可读表格**:将 Markdown 表格渲染为图片,防止它们在 X 中坍塌成难以阅读的纯文本。
- **标题与封面助手**:在条件允许时,可使用 frontmatter、第一个 H1 标签和第一张图片作为文章元数据。
- **写入前预检**:检查当前活跃的标签页、X Articles 页面、editor bridge、Draft.js 编辑器、媒体上传处理程序、图片就绪状态以及现有的编辑器内容。
- **可恢复的记录**:在本地保留导入记录,以便你搜索、复制、编辑并重新写入之前的 Markdown 内容。
- **文章导出工具**:可在可读的 X Article 标题旁添加简约的 Markdown 复制/下载工具。
- **故障诊断**:包含一个工具栏诊断弹窗和技术记录,用于调试 X 编辑器的更改。
- **默认本地优先**:无 backend、账户、订阅、授权服务器、支付网关或分析工具。
## 适用 / 不适用场景
**最适合**
- 使用 Markdown drafting 长篇 X 文章的创作者
- 希望将 Obsidian、Notion 导出文件、博客笔记或本地 `.md` 文件迁移到 X Articles 的用户
- 包含图片、表格、代码块、推文嵌入和结构化分区的文章
- 需要发布多个文章草稿并希望通过队列管理代替重复复制粘贴的用户
- 倾向于使用可自行检查和修改的开源工具的维护者
**不适合**
- 自动发帖或定时发布
- 绕过 X 的限制、审核或账号限制
- X 线程、新闻通讯或常规的推特编辑器发布
- 在 X 编辑器每次变动中保持完美的 WYSIWYG 保真度
- 私有图片托管(除非 Chrome 能授予所需的主机访问权限)
## 30 秒快速上手
1. 从 [Chrome Web Store 安装 xPoster](https://chromewebstore.google.com/detail/xposter/iimkimodgdjnnmdopeolboakhjmhfbbj?authuser=0&hl=zh-CN)。
2. 在 `https://x.com/compose/articles` 打开或创建一篇 X Article。
3. 打开 xPoster 侧边栏面板。
4. 粘贴 Markdown、选择 `.md` 文件,或将 Markdown 文件拖入面板。
5. 点击 **检查文章**。
6. 点击 **写入 X 草稿**。
7. 在 X 中查看结果,确认无误后手动发布。

## 导入期间发生了什么
当你点击 **写入 X 草稿** 时,xPoster 做的不仅仅是粘贴一大段文本:
1. 将 Markdown 解析为标题、候选封面、文本块、图片、表格、推文、代码块和分隔线。
2. 准备 X 无法作为纯 Markdown 接收的媒体文件,包括本地图片、网络图片以及渲染后的表格图片。
3. 确认当前活跃的标签页仍然是之前通过 **检查文章** 的那个 X Article 编辑器。
4. 在当前设置允许的情况下应用标题和封面。
5. 将文章正文写入 X 的 Draft.js 编辑器中。
6. 将临时标记替换为已上传的图片、渲染后的表格、推文嵌入、代码块或分隔线。
7. 保存本地记录,并对任何无法上传或放置的内容发出警告。
这就是为什么扩展会要求你先运行 **检查文章**。这不仅仅是一个按钮状态检查;它会在导入开始之前锁定真正的编辑器。
## 草稿示例
```
---
title: How I Write Long Posts for X
cover: ./images/cover.png
---
# 我如何为 X 撰写长篇帖子
I draft in Markdown first, then use xPoster for the final handoff.

| Step | Tool |
| --- | --- |
| Draft | Obsidian |
| Publish | X Articles |
https://x.com/xiaoxiaodong01/status/1234567890
```
在此示例中,xPoster 可以使用 frontmatter 中的标题,尝试设置封面图片,上传正文图片,将表格渲染为图片,并在 X 支持的情况下将 X 状态 URL 作为嵌入内容插入。
## 常用工作流
| 任务 | xPoster 如何提供帮助 |
| --- | --- |
| 发布一篇精修的文章 | 粘贴 Markdown,检查 X 编辑器,写入草稿,在 X 中预览。 |
| 迁移带有图片的本地 `.md` 文件 | 选择 Markdown 文件,在提示时授予本地图片文件夹权限,然后写入 X。 |
| 排队多个草稿 | 将多个 Markdown 文件拖入侧边栏面板,并逐一写入。 |
| 修复之前的导入 | 打开记录,搜索保存的 Markdown,进行编辑并重新写入。 |
| 发布包含大量表格的文章 | 在 Markdown 中保留表格;xPoster 会将其渲染为图片以便在 X 上展示。 |
| 在文章中嵌入推文 | 将 X/Twitter 状态 URL 放入草稿中;xPoster 会在支持的 X 编辑器模型中将它们作为嵌入内容插入。 |
| 保留本地技术轨迹 | 在运行“检查”或“写入”之后使用诊断和记录面板。 |
| 将现有的 X Article 复制回 Markdown | 启用文章导出工具,并在可读的文章页面使用标题侧边的复制/下载按钮。 |
## Markdown 与媒体支持
| 输入 | 行为 |
| --- | --- |
| `--- title: My title ---` | 尽可能使用 frontmatter 中的标题。 |
| `# Heading` | 当没有可用的 frontmatter 标题时,使用第一个 H1 作为标题。 |
| 段落、标题、列表、引用 | 将它们转换为 X Article 富文本。 |
| `**bold**`, `*italic*`, `` `code` ``, 链接 | 在 X 支持的范围内保留行内格式。 |
| `` | 当 xPoster 能读取文件时,上传支持的本地或网络图片。 |
| `cover:` frontmatter 或第一张图片 | 当启用此设置时,可将其设为文章封面。 |
| Markdown 表格 | 将表格渲染为图片,以便在 X 上稳定显示。 |
| X/Twitter 状态 URL | 在支持的 X 编辑器模型中插入推文嵌入块。 |
| 代码块和分隔线 | 将它们导入为支持的 X Article 块。 |
包含一份冒烟测试草稿,详见 [fixtures/live-x-smoke.md](fixtures/live-x-smoke.md)。
## 图片
**本地图片**:将图片文件保存在 Markdown 文件附近,并在 xPoster 询问时选择匹配的本地图片文件夹。像 `./images/photo.png` 这样的相对路径只有在 Chrome 授予 xPoster 访问该文件夹的权限后才能生效。
**网络图片**:Chrome 可能会要求获得读取该图片主机的一次性权限。xPoster 需要获取图片的二进制数据,以便将其传递给 X 的上传程序。下载失败的图片将保留为 Markdown 链接,而不是悄无声息地消失。
**私有主机**:公开的源码版本并未开放私有图片主机。如果你维护着一个分支并需要固定的远程图片支持,请仅在你自己的扩展 manifest 中声明受信任的主机。
## 可靠性与恢复
xPoster 是基于“浏览器自动化可能会失败”这一假设构建的:X 可能会更改其编辑器、文件可能丢失、网络图片可能被阻止,或者上传可能停滞。该扩展试图使这些失败变得可见且可恢复:
- **导入前**:预检会检查页面、editor bridge、Draft.js 编辑器、媒体上传路径以及当前草稿状态是否可用。
- **导入期间**:进度消息会显示当前正在运行的阶段,例如解析、准备媒体、设置元数据、写入文本、上传媒体或放置嵌入内容。
- **导入后**:警告会提示你哪些图片、表格或封面资源被保留为 Markdown 格式,而不是成功上传。
- **重试时**:记录会在本地保留原始 Markdown,因此你可以从全新的 X Article 中复制、编辑或重新写入同一份草稿。
- **调试时**:诊断弹窗和证据记录为维护者提供了足够的上下文,以便他们在无需猜测的情况下调查编辑器的更改。
最安全的习惯很简单:运行 **检查文章**,将其写入一个全新的 X Article 草稿中,在 X 中预览结果,并且只有在你满意时才进行发布。
## xPoster 的工作原理
- **它写入真实的 X 编辑器**,而不是伪装成发布 API。这使得最终的预览和发布步骤始终留在 X 内部。
- **它在写入前进行检查**,因为 X 经常更改其编辑器。预检失败总比写出一半的文章要好。
- **它在本地保存记录**,因为浏览器自动化可能会在处理媒体、嵌入内容或编辑器状态更改的中途失败。
- **它不点击“发布”**,因为该扩展旨在协助格式化和内容传输,而不是替你做出最终的编辑决定。
- **它保持轻依赖**,使得扩展始终易于检查和审计。
## 从源码安装
除非你希望自行检查、测试或修改该扩展,否则请使用 Web Store 版本。

1. 下载或克隆本项目。
2. 打开 Chrome 并访问 `chrome://extensions`。
3. 打开 **开发者模式**。
4. 点击 **加载已解压的扩展程序**。
5. 选择 xPoster 项目文件夹,即包含 `manifest.json` 的那个文件夹。
## 隐私与安全
- 草稿和导入记录存储在你浏览器的本地扩展存储中。
- xPoster 在 `x.com` 和 `twitter.com` 上运行,因为它需要填充 X Article 编辑器并读取文章页面以支持可选的 Markdown 导出。
- xPoster 请求 `tabs` 权限仅用于查找并检查当前活跃的 X Article 标签页。
- 仅当草稿使用了需要下载的网络图片时,才会请求可选的主机权限。
- xPoster 不包含分析工具、backend 服务、授权服务器或支付网关。
- xPoster 不会点击“发布”。你始终可以在 X 中预览并手动发布。
请阅读 [docs/privacy.md](docs/privacy.md) 中的简短隐私声明。
## 开发者检查
本项目是轻依赖的。Node 仅用于本地验证。
```
npm run check
npm test
npm run verify
```
`npm run check` 用于验证 JavaScript 语法、`manifest.json` 以及 i18n 覆盖率。
`npm test` 用于验证 fixture、manifest 引用、图标和 Markdown 解析行为。
## 项目结构
```
manifest.json Chrome extension manifest
sidepanel.html Main side panel UI
sidepanel.css Side panel styling
sidepanel.js Side panel workflow, records, queue, and import controls
diagnostics.html Toolbar popup for active-tab checks
diagnostics.js Diagnostics UI logic
src/background.js MV3 service worker and image fetch proxy
src/content.js X page content script, page status, and Markdown export
src/main-world.js MAIN-world Draft.js / X editor adapter
src/shared.js Markdown parser, paste plan, local image helpers
fixtures/ Example Markdown used by checks and demos
docs/ Usage guide, images, privacy notes
scripts/ Local verification scripts
```
## 常见问题
**我在 Chrome 中看不到 xPoster。**
请安装 Web Store 版本,或者启用开发者模式并加载包含 `manifest.json` 的源码文件夹。
**写入 X 草稿被禁用了。**
请先加载或编辑 Markdown 草稿,打开一个 X Article 标签页,然后点击 **检查文章**。
**图片仍然是链接形式。**
本地图片需要选择图片文件夹。网络图片需要 Chrome 授予图片站点权限后方可下载。
**导入的文章看起来不对劲。**
暂时不要发布。请直接在 X 中进行编辑,或者重置草稿并从保存的 Markdown 记录中重试。
**X 更改了其编辑器,导致导入停止工作。**
请提交一个 issue,并附上你的 Chrome 版本、xPoster 版本以及工具栏弹窗中的诊断 JSON 数据。
## 联系方式
在 X 上联系作者:[@xiaoxiaodong01](https://x.com/xiaoxiaodong01)。
## 许可证
MIT。详见 [LICENSE](LICENSE)。
标签:Markdown, MV3, X/Twitter, 内容发布, 效率工具, 数据可视化, 自定义脚本, 调试辅助